Kernel
Threads by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- 26 participants
- 24367 discussions
From: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
driver inclusion
category: feature
bugzilla: https://atomgit.com/openeuler/kernel/issues/9708
CVE: NA
---------------------------------
The current driver has both chinese comment and english comment, translate all to english.
Signed-off-by: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
Reviewed-by: Qiujun <roland.qiu(a)huawei.com<mailto:roland.qiu@huawei.com>>
Reviewed-by: chiqijun <chiqijun(a)huawei.com<mailto:chiqijun@huawei.com>>
---
.../src/dpu_develop_interface/base_type.h | 12 +-
.../drv_sdk_intf/hisdk/hinic5_chip_info.h | 46 +-
.../drv_sdk_intf/hisdk/hinic5_common.h | 161 +-
.../drv_sdk_intf/hisdk/hinic5_crm.h | 1363 +++-----
.../drv_sdk_intf/hisdk/hinic5_hinic5_cqm.h | 913 ------
.../hisdk/hinic5_hinic5_cqm_adpt.h | 58 -
.../hisdk/hinic5_hinic5_vram_api.h | 57 -
.../drv_sdk_intf/hisdk/hinic5_hw.h | 667 ++--
.../drv_sdk_intf/hisdk/hinic5_lld.h | 266 +-
.../drv_sdk_intf/hisdk/hinic5_mt.h | 836 ++---
.../drv_sdk_intf/hisdk/hinic5_profile.h | 146 +-
.../drv_sdk_intf/hisdk/hinic5_wq.h | 136 +-
.../drv_sdk_intf/ossl/nic_kcompat.h | 78 +-
.../drv_sdk_intf/ossl/ossl_knl.h | 24 +-
.../drv_sdk_intf/ossl/ossl_knl_linux.h | 334 +-
.../drv_sdk_intf/ossl/ossl_knl_linux_nic.h | 81 +-
.../drv_sdk_intf/ossl/sdk_kcompat.h | 38 +-
.../drv_srvc_intf/drv_bond_api.h | 221 +-
.../drv_srvc_intf/nic/drv_nic_api.h | 237 +-
.../fw_msg_intf/bond/bond_common_defs.h | 61 +-
.../fw_msg_intf/bond/bond_mpu_cmd_defs.h | 83 +-
.../fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd.h | 10 -
.../cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 228 +-
.../fw_msg_intf/cfm/cfm_cmd.h | 28 +-
.../fw_msg_intf/cfm/fast_msg_common_define.h | 15 +-
.../hinic5_cqm/hinic5_cqm_npu_cmd.h | 26 -
.../hinic5_cqm/hinic5_cqm_npu_cmd_defs.h | 86 -
.../fw_msg_intf/macsec/macsec_mpu_cmd.h | 96 +-
.../fw_msg_intf/macsec/macsec_mpu_cmd_defs.h | 425 ++-
.../fw_msg_intf/mag/mag_mpu_cmd.h | 37 +-
.../fw_msg_intf/mag/mag_mpu_cmd_defs.h | 1120 +++----
.../fw_msg_intf/mpu/mpu_board_defs.h | 275 +-
.../fw_msg_intf/mpu/mpu_cmd_base_defs.h | 201 +-
.../fw_msg_intf/mpu/mpu_inband_cmd.h | 324 +-
.../fw_msg_intf/mpu/mpu_inband_cmd_defs.h | 1732 +++++-----
.../fw_msg_intf/mpu/mpu_mailbox_msg_header.h | 65 +-
.../fw_msg_intf/nic/nic_cfg_comm.h | 1018 +++---
.../fw_msg_intf/nic/nic_mpu_cmd.h | 421 +--
.../fw_msg_intf/nic/nic_mpu_cmd_extend.h | 13 +-
.../fw_msg_intf/nic/nic_mpu_cmd_structs.h | 2043 ++++++------
.../nic/nic_mpu_cmd_structs_extend.h | 14 +-
.../fw_msg_intf/nic/nic_mpu_tc_cmd_defs.h | 20 +-
.../fw_msg_intf/nic/nic_npu_cmd.h | 111 +-
.../fw_msg_intf/nic/nic_tc_rule_defs.h | 48 +-
.../fw_msg_intf/public/comm_defs.h | 85 +-
.../fw_msg_intf/public/hinic5_comm_cmd.h | 55 +-
.../fw_msg_intf/public/npu_cmdq_base_defs.h | 73 +-
.../public/sml_table_struct_dict_def.h | 29 +-
.../host/cfm/bond/hinic5_bond.c | 1116 +++----
.../host/cfm/bond/hinic5_bond_event.c | 276 +-
.../host/cfm/bond/hinic5_bond_inner.h | 77 +-
.../host/cfm/fast_msg/hinic5_fast_msg.c | 110 +-
.../host/cfm/fast_msg/hinic5_fast_msg_init.c | 151 +-
.../host/include/cfm/bond/hinic5_bond.h | 34 +-
.../include/cfm/fast_msg/hinic5_fast_msg.h | 64 +-
.../cfm/fast_msg/hinic5_fast_msg_init.h | 11 +-
.../include/sdk/knldk/hinic5_hinic5_vram.h | 40 -
.../host/include/sdk/knldk/hinic5_id_tbl.h | 93 +-
.../include/sdk/knldk/hinic5_vram_common.h | 186 --
.../host/include/typedef.h | 10 -
.../host/sdk/knldk/crm/hinic5_hw_cfg.c | 660 ++--
.../host/sdk/knldk/crm/hinic5_hw_cfg.h | 354 +-
.../host/sdk/knldk/crm/hinic5_hw_comm.c | 752 +++--
.../host/sdk/knldk/crm/hinic5_hw_comm.h | 48 +-
.../host/sdk/knldk/crm/hinic5_hwdev.c | 1332 +++-----
.../host/sdk/knldk/crm/hinic5_prof_adap.c | 20 +-
.../host/sdk/knldk/crm/hinic5_prof_adap.h | 28 +-
.../hinic5_cqm_182x_cmdq_ops.c | 88 -
.../hinic5_cqm_182x_cmdq_ops.h | 48 -
.../hinic5_cqm_187x_cmdq_ops.c | 87 -
.../hinic5_cqm_187x_cmdq_ops.h | 61 -
.../sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.c | 2864 -----------------
.../sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.h | 265 --
.../hinic5_cqm/hinic5_cqm_bitmap_table.c | 1748 ----------
.../hinic5_cqm/hinic5_cqm_bitmap_table.h | 85 -
.../knldk/hinic5_cqm/hinic5_cqm_bloomfilter.c | 524 ---
.../knldk/hinic5_cqm/hinic5_cqm_bloomfilter.h | 60 -
.../sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.c | 214 --
.../sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.h | 47 -
.../sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq.h | 33 -
.../knldk/hinic5_cqm/hinic5_cqm_cmdq_adapt.c | 21 -
.../host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.c | 575 ----
.../host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.h | 43 -
.../knldk/hinic5_cqm/hinic5_cqm_fast_msg.c | 169 -
.../knldk/hinic5_cqm/hinic5_cqm_fast_msg.h | 45 -
.../sdk/knldk/hinic5_cqm/hinic5_cqm_main.c | 2078 ------------
.../sdk/knldk/hinic5_cqm/hinic5_cqm_main.h | 512 ---
.../sdk/knldk/hinic5_cqm/hinic5_cqm_object.c | 1707 ----------
.../sdk/knldk/hinic5_cqm/hinic5_cqm_object.h | 390 ---
.../hinic5_cqm/hinic5_cqm_object_intern.c | 1481 ---------
.../hinic5_cqm/hinic5_cqm_object_intern.h | 124 -
.../knldk/hinic5_vram/hinic5_hinic5_vram.c | 296 --
.../knldk/hinic5_vram/hinic5_vram_common.c | 214 --
.../host/sdk/knldk/hwif/hinic5_api_cmd.c | 269 +-
.../host/sdk/knldk/hwif/hinic5_cmdq.c | 764 +++--
.../host/sdk/knldk/hwif/hinic5_common.c | 19 +-
.../host/sdk/knldk/hwif/hinic5_enhance_cmdq.c | 128 +-
.../host/sdk/knldk/hwif/hinic5_eqs.c | 617 ++--
.../host/sdk/knldk/hwif/hinic5_hw_api.c | 115 +-
.../host/sdk/knldk/hwif/hinic5_hwif.c | 482 +--
.../host/sdk/knldk/hwif/hinic5_mbox.c | 726 +++--
.../host/sdk/knldk/hwif/hinic5_mgmt.c | 393 ++-
.../host/sdk/knldk/hwif/hinic5_sm_lt.h | 56 +-
.../host/sdk/knldk/hwif/hinic5_sml_lt.c | 54 +-
.../host/sdk/knldk/hwif/hinic5_wq.c | 54 +-
.../host/sdk/knldk/include/hinic5_api_cmd.h | 324 +-
.../host/sdk/knldk/include/hinic5_cmdq.h | 156 +-
.../sdk/knldk/include/hinic5_cmdq_enhance.h | 231 +-
.../host/sdk/knldk/include/hinic5_csr_inner.h | 308 +-
.../host/sdk/knldk/include/hinic5_eqs.h | 168 +-
.../host/sdk/knldk/include/hinic5_hw_api.h | 19 +-
.../host/sdk/knldk/include/hinic5_hwdev.h | 245 +-
.../sdk/knldk/include/hinic5_hwif_inner.h | 328 --
.../host/sdk/knldk/include/hinic5_lld_inner.h | 18 +-
.../host/sdk/knldk/include/hinic5_mbox.h | 351 +-
.../host/sdk/knldk/include/hinic5_mgmt.h | 152 +-
.../sdk/knldk/include/hinic5_typedef_inner.h | 27 -
.../host/sdk/knldk/lld/hinic5_bus.c | 38 +-
.../host/sdk/knldk/lld/hinic5_bus.h | 28 +-
.../host/sdk/knldk/lld/hinic5_dev_mgmt.c | 474 +--
.../host/sdk/knldk/lld/hinic5_dev_mgmt.h | 142 +-
.../host/sdk/knldk/lld/hinic5_lld.c | 340 +-
.../host/sdk/knldk/lld/hinic5_lld_private.h | 9 +-
.../host/sdk/knldk/lld/hinic5_pcie.c | 322 +-
.../host/sdk/knldk/lld/hinic5_pcie.h | 20 +-
.../host/sdk/knldk/lld/hinic5_sriov.c | 80 +-
.../host/sdk/knldk/lld/hinic5_sriov.h | 11 +-
.../host/sdk/knldk/lld/hinic5_sysfs.c | 32 +-
.../host/sdk/knldk/lld/hinic5_sysfs.h | 11 +-
.../host/sdk/knldk/lld/hinic5_ubus.c | 203 +-
.../host/sdk/knldk/lld/hinic5_ubus.h | 56 +-
.../host/sdk/knldk/lld/hinic5_ubus_sriov.c | 231 +-
.../host/sdk/knldk/lld/hinic5_ubus_sriov.h | 9 +-
.../host/sdk/knldk/mt/hinic5_devlink.c | 229 +-
.../host/sdk/knldk/mt/hinic5_devlink.h | 57 +-
.../host/sdk/knldk/mt/hinic5_fw_update.c | 336 +-
.../host/sdk/knldk/mt/hinic5_fw_update.h | 33 +-
.../host/sdk/knldk/mt/hinic5_hw_mt.c | 219 +-
.../host/sdk/knldk/mt/hinic5_hw_mt.h | 56 +-
.../host/sdk/knldk/mt/hinic5_nictool.c | 554 ++--
.../host/sdk/knldk/mt/hinic5_nictool.h | 18 +-
.../host/sdk/knldk/mt/hinic5_non_ptp.c | 226 +-
.../host/sdk/knldk/mt/hinic5_non_ptp.h | 9 +-
.../host/sdk/knldk/mt/hinic5_sdk_attack.c | 59 +-
.../host/sdk/knldk/mt/hinic5_sdk_attack.h | 18 +-
.../sdk/ossl/linux/kernel/ossl_knl_linux.c | 84 +-
.../host/service/include/hinic5_srv_nic.h | 173 +-
.../nic/comm/182x_cmdq_adapt/182x_cmdq_ops.c | 145 +-
.../nic/comm/182x_cmdq_adapt/182x_cmdq_ops.h | 23 +-
.../nic/comm/187x_cmdq_adapt/187x_cmdq_ops.c | 132 +-
.../nic/comm/187x_cmdq_adapt/187x_cmdq_ops.h | 23 +-
.../host/service/nic/comm/hinic5_cmdq_adapt.c | 11 +-
.../host/service/nic/comm/hinic5_mag_cfg.c | 754 +++--
.../host/service/nic/comm/hinic5_nic.h | 96 +-
.../host/service/nic/comm/hinic5_nic_cfg.c | 887 ++---
.../host/service/nic/comm/hinic5_nic_cfg_vf.c | 265 +-
.../host/service/nic/comm/hinic5_nic_cmdq.h | 191 +-
.../host/service/nic/comm/hinic5_nic_dbg.c | 37 +-
.../host/service/nic/comm/hinic5_nic_event.c | 441 ++-
.../host/service/nic/comm/hinic5_nic_io.c | 726 +++--
.../host/service/nic/comm/hinic5_rss_cfg.c | 189 +-
.../host/service/nic/include/hinic5_mag_cfg.h | 33 +-
.../host/service/nic/include/hinic5_nic_cfg.h | 146 +-
.../service/nic/include/hinic5_nic_cfg_vf.h | 15 +-
.../host/service/nic/include/hinic5_nic_dbg.h | 9 +-
.../service/nic/include/hinic5_nic_event.h | 14 +-
.../host/service/nic/include/hinic5_nic_io.h | 99 +-
.../host/service/nic/include/hinic5_nic_rq.h | 113 +-
.../host/service/nic/include/hinic5_nic_sq.h | 124 +-
.../host/service/nic/linux/1588/hinic5_ptp.c | 123 +-
.../host/service/nic/linux/1588/hinic5_ptp.h | 14 +-
.../host/service/nic/linux/Makefile | 299 +-
.../host/service/nic/linux/ctrl/hinic5_irq.c | 72 +-
.../host/service/nic/linux/ctrl/hinic5_irq.h | 13 +-
.../host/service/nic/linux/ctrl/hinic5_main.c | 683 ++--
.../host/service/nic/linux/ctrl/hinic5_main.h | 35 +-
.../nic/linux/ethtool/hinic5_ethtool.c | 173 +-
.../nic/linux/ethtool/hinic5_ethtool.h | 56 +-
.../linux/ethtool/hinic5_ethtool_coalesce.c | 191 +-
.../linux/ethtool/hinic5_ethtool_coalesce.h | 24 +-
.../linux/ethtool/hinic5_ethtool_lb_test.c | 332 +-
.../linux/ethtool/hinic5_ethtool_lb_test.h | 17 +-
.../linux/ethtool/hinic5_ethtool_link_stats.c | 172 +-
.../linux/ethtool/hinic5_ethtool_link_stats.h | 33 +-
.../linux/ethtool/hinic5_ethtool_port_stats.c | 352 +-
.../linux/ethtool/hinic5_ethtool_port_stats.h | 93 +-
.../linux/ethtool/hinic5_ethtool_priv_flags.c | 44 +-
.../linux/ethtool/hinic5_ethtool_priv_flags.h | 13 +-
.../service/nic/linux/ethtool/hinic5_ntuple.c | 392 ++-
.../service/nic/linux/ethtool/hinic5_ntuple.h | 27 +-
.../service/nic/linux/ethtool/hinic5_rss.c | 314 +-
.../service/nic/linux/ethtool/hinic5_rss.h | 32 +-
.../service/nic/linux/ethtool/hinic5_tc.c | 687 ++--
.../service/nic/linux/ethtool/hinic5_tc.h | 252 +-
.../host/service/nic/linux/ioctl/hinic5_dbg.c | 635 ++--
.../host/service/nic/linux/ioctl/hinic5_dbg.h | 19 +-
.../host/service/nic/linux/ioctl/hinic5_dcb.c | 143 +-
.../host/service/nic/linux/ioctl/hinic5_dcb.h | 45 +-
.../nic/linux/macsec/hinic5_macsec_api.h | 16 +-
.../nic/linux/macsec/hinic5_macsec_common.h | 48 +-
.../nic/linux/macsec/hinic5_macsec_dev.h | 32 +-
.../nic/linux/macsec/hinic5_macsec_dfx.c | 108 +-
.../nic/linux/macsec/hinic5_macsec_dfx.h | 30 +-
.../nic/linux/macsec/hinic5_macsec_main.c | 110 +-
.../nic/linux/macsec/hinic5_macsec_mgmt.c | 200 +-
.../nic/linux/macsec/hinic5_macsec_nictool.c | 450 ++-
.../nic/linux/macsec/hinic5_macsec_protocol.c | 538 ++--
.../nic/linux/macsec/hinic5_macsec_service.c | 280 +-
.../service/nic/linux/netdev/hinic5_filter.c | 100 +-
.../service/nic/linux/netdev/hinic5_filter.h | 17 +-
.../nic/linux/netdev/hinic5_netdev_ops.c | 937 +++---
.../nic/linux/netdev/hinic5_netdev_ops.h | 15 +-
.../service/nic/linux/netdev/hinic5_nic_dev.h | 174 +-
.../host/service/nic/linux/nicio/hinic5_rx.c | 547 ++--
.../host/service/nic/linux/nicio/hinic5_rx.h | 119 +-
.../host/service/nic/linux/nicio/hinic5_tx.c | 284 +-
.../host/service/nic/linux/nicio/hinic5_tx.h | 89 +-
.../host/service/nic/linux/nicio/hinic5_xdp.c | 172 +-
.../host/service/nic/linux/nicio/hinic5_xdp.h | 32 +-
.../include/drv_fw_msg/cfm/bond_cfm_cmd.h | 179 +-
.../include/drv_fw_msg/cfm/qos_base_cmd.h | 161 +-
.../drv_fw_msg/mpu/inband_mpu_cmd_defs.h | 351 +-
.../include/drv_tool_msg/bond_pub_cmd.h | 27 +-
.../include/drv_tool_msg/hisec_pub_cmd.h | 58 +-
.../include/drv_tool_msg/macsec_pub_cmd.h | 70 +-
.../include/drv_tool_msg/nic_pub_cmd.h | 182 +-
.../include/drv_tool_msg/sdk_pub_cmd.h | 37 +-
.../dpu_platform_library/include/fw_typedef.h | 24 +-
.../src/tools/micro_log/hinic5_micro_log.c | 744 +++--
.../src/tools/micro_log/hinic5_micro_log.h | 37 +-
.../src/tools/micro_log/micro_log_comm.c | 32 +-
.../src/tools/micro_log/micro_log_comm.h | 38 +-
.../src/tools/micro_log/micro_log_index.c | 89 +-
.../src/tools/micro_log/micro_log_index.h | 15 +-
.../tools/micro_log/micro_log_procfs_cmd.c | 110 +-
.../tools/micro_log/micro_log_procfs_cmd.h | 10 -
236 files changed, 22783 insertions(+), 37075 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm_adpt.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_vram_api.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_hinic5_vram.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq_adapt.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_hinic5_vram.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_vram_common.c
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwif_inner.h
delete mode 100644 drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_typedef_inner.h
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/base_type.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/base_type.h
index 296cd57c7..4251233e8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/base_type.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/base_type.h
@@ -1,14 +1,10 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : base_type.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : basic data types, all basic type definitions should only be encapsulated here, other headers are prohibited from encapsulating basic types
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Version : Initial
+ * Created : 2023/12/12
+ * Description : basic data types, 所有对基础类型的定义只能在这里完成封装,禁止其他头文件封装基础类型
*/
-
#ifndef BASE_TYPE_H
#define BASE_TYPE_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_chip_info.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_chip_info.h
index 9123ab368..8281ace8a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_chip_info.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_chip_info.h
@@ -1,13 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_chip_info.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : sdk's inner chip related structure and macro defined here.
- */
-
+/* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: sdk's inner chip related structure and macro defined here.
+ * Note: TODO : put it in sdk's inner include folder after decoupling.
+ * Create: 2025-08-13
+*/
#ifndef HINIC5_CHIP_INFO_H
#define HINIC5_CHIP_INFO_H
@@ -17,25 +13,25 @@
/**
* @brief struct card_node
- * @details define a struct named card_node, representing a network card node
+ * @details 定义一个名为card_node的结构体,表示一个网卡节点
*/
struct card_node {
- struct list_head node; /**< list head */
- struct list_head func_list; /**< function list head */
- char chip_name[IFNAMSIZ]; /**< chip name storage */
- void *log_info; /**< log information pointer */
- void *dbgtool_info; /**< debug tool information pointer */
- spinlock_t dbgtool_info_lock; /**< protects fm_show update context */
- void *func_handle_array[MAX_FUNCTION_NUM]; /**< function handle storage */
- u16 func_num; /**< function count */
+ struct list_head node; /**< 表示一个列表头 */
+ struct list_head func_list; /**< 表示一个功能列表头 */
+ char chip_name[IFNAMSIZ]; /**< 存储芯片名称 */
+ void *log_info; /**< 指向日志信息 */
+ void *dbgtool_info; /**< 指向调试工具信息 */
+ spinlock_t dbgtool_info_lock; /**< 保护fm_show更新上下文 */
+ void *func_handle_array[MAX_FUNCTION_NUM]; /**< 存储功能句柄 */
+ u16 func_num; /**< function数量 */
u32 rsvd1;
- atomic_t channel_busy_cnt; /**< channel busy count */
- void *priv_data; /**< private data pointer */
+ atomic_t channel_busy_cnt; /**< 储通道忙碌计数 */
+ void *priv_data; /**< 指向私有数据 */
u64 rsvd2;
- void *fw_update_context; /**< firmware update context pointer */
- spinlock_t fw_update_context_lock; /**< protects firmware update context */
- struct hinic5_non_ptp_info *non_ptp_info; /**< non-ptp time difference information */
- bool exception_flag; /**< fatal exception occurred flag */
- u64 id; /**< chip unique id */
+ void *fw_update_context; /**< 指向固件更新上下文 */
+ spinlock_t fw_update_context_lock; /**< 保护固件更新上下文 */
+ struct hinic5_non_ptp_info *non_ptp_info; /**< 非ptp时间差信息 */
+ bool exception_flag; /**< 是否出现致命异常 */
+ u64 id; /**< 芯片唯一性id标识 */
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_common.h
index 00c23e61a..70a6ac2a4 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_common.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_common.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_common.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_COMMON_H
#define HINIC5_COMMON_H
@@ -16,49 +9,39 @@
/**
* @brief struct hinic5_dma_addr_align
- * @details DMA address alignment structure
+ * @details DMA地址对齐结构体
*/
struct hinic5_dma_addr_align {
- u32 real_size; /**< real size */
-
- void *ori_vaddr; /**< original virtual address */
- dma_addr_t ori_paddr; /**< original physical address */
+ u32 real_size; /**< 真实大小 */
- void *align_vaddr; /**< aligned virtual address */
- dma_addr_t align_paddr; /**< aligned physical address */
-};
+ void *ori_vaddr; /**< 原始虚拟地址 */
+ dma_addr_t ori_paddr; /**< 原始物理地址 */
-/**
- * @brief enum hinic5_wait_return - wait processing return value enum
- * @details there are three cases: processing completed, processing in progress, processing error
- */
-enum hinic5_wait_return {
- WAIT_PROCESS_CPL = 0, /**< processing completed, can proceed to next step */
- WAIT_PROCESS_WAITING = 1, /**< processing in progress, need to continue waiting */
- WAIT_PROCESS_ERR = 2, /**< processing error, need error handling */
+ void *align_vaddr; /**< 对齐的虚拟地址 */
+ dma_addr_t align_paddr; /**< 对齐的物理地址 */
};
/**
* @brief struct hinic5_sge
- * @details hardware scatter-gather entry
+ * @details 硬件标识符
*/
struct hinic5_sge {
- u32 hi_addr; /**< high 32 bits of address */
- u32 lo_addr; /**< low 32 bits of address */
- u32 len; /**< data size */
+ u32 hi_addr; /**< 地址的高32位 */
+ u32 lo_addr; /**< 地址的低32位 */
+ u32 len; /**< 数据大小 */
};
/**
- * @brief allocate device-related memory with specified alignment
- * @param dev_hdl: device handle for memory allocation
- * @param size: memory size to allocate
- * @param align: memory address alignment
- * @param flag: memory allocation flags
- * @param mem_align: returned memory address alignment information
+ * @brief 分配一块设备相关的内存,并且内存地址需要按照一定的对齐方式进行对齐
+ * @param dev_hdl:分配内存的设备句柄
+ * @param size:需要分配的内存大小
+ * @param align:内存地址对齐方式
+ * @param flag:分配内存的标志
+ * @param mem_align:返回的内存地址对齐信息
*
- * @details allocate device-related memory with specified alignment
+ * @details 分配一块设备相关的内存,并且内存地址需要按照一定的对齐方式进行对齐
*
- * @return success or failure
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -67,51 +50,24 @@ int hinic5_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
struct hinic5_dma_addr_align *mem_align);
/**
- * @brief free DMA coherent memory
- * @param dev_hdl: device handle
- * @param mem_align: memory alignment structure pointer
+ * @brief 释放DMA的内存
+ * @param dev_hdl:设备句柄
+ * @param mem_align:内存对齐结构体指针
*
- * @details this function frees DMA memory allocated by hinic5_dma_alloc_coherent_align()
+ * @details 此函数用于释放通过hinic5_dma_alloc_coherent_align()函数分配的DMA内存
*
* @return void
*/
void hinic5_dma_free_coherent_align(void *dev_hdl,
struct hinic5_dma_addr_align *mem_align);
-
/**
- * @brief define a function pointer type named wait_cpl_handler
- * @param priv_data: private data, can be any type of data
+ * @brief 将数据从CPU字节序转换为大端字节序
+ * @param data 要转换的数据
+ * @param len 数据长度
*
- * @return returns hinic5_wait_return enum type
- */
-typedef enum hinic5_wait_return (*wait_cpl_handler)(void *priv_data);
-
-/**
- * @brief wait for a period of time and then check if completed
- * @param priv_data: private data for passing
- * @param handler: handler function for wait operation
- * @param wait_total_ms: total wait time in milliseconds
- * @param wait_once_us: single wait duration in microseconds
- *
- * @details wait for a period of time and then check if completed
- *
- * @return check result
- * @retval 0: success
- * @retval -EINVAL: invalid parameter
- * @retval -EIO: processing error
- * @retval -ETIMEDOUT: timeout
- */
-int hinic5_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-/**
- * @brief convert data from CPU byte order to big-endian byte order
- * @param data data to convert
- * @param len data length
- *
- * @details this function converts data from CPU byte order to big-endian byte order.
- * parameter data is the data to convert, len is the data length.
+ * @details 此函数将数据从CPU字节序转换为大端字节序。
+ * 参数data表示要转换的数据,len表示数据长度。
*
* @return void
*/
@@ -133,12 +89,12 @@ static inline void hinic5_cpu_to_be32(void *data, int len)
}
/**
- * @brief convert 32-bit big-endian data to CPU byte order
- * @param data pointer to data to convert
- * @param len length of data to convert
+ * @brief 将大端模式的32位数据转换为当前CPU的字节序
+ * @param data 要转换的数据的指针
+ * @param len 要转换的数据的长度
*
- * @details this function converts 32-bit big-endian data to CPU byte order.
- * parameter data points to the data to convert, len is the length of data to convert.
+ * @details 此函数将大端模式的32位数据转换为当前CPU的字节序。
+ * 参数data指向要转换的数据,len表示要转换的数据的长度。
*
* @return void
*/
@@ -160,10 +116,10 @@ static inline void hinic5_be32_to_cpu(void *data, int len)
}
/**
- * @brief set values for hinic5_sge structure
- * @param sge pointer to hinic5_sge structure to set
- * @param addr address to set
- * @param len length to set
+ * @brief 设置hinic5_sge结构体的值
+ * @param sge 要设置的hinic5_sge结构体指针
+ * @param addr 要设置的地址
+ * @param len 要设置的长度
*
* @return void
*/
@@ -176,23 +132,34 @@ static inline void hinic5_set_sge(struct hinic5_sge *sge, dma_addr_t addr,
}
#ifdef HW_CONVERT_ENDIAN
-#define hinic5_hw_be32(val) (val) /**< convert 32-bit value to big-endian, return original value directly */
-#define hinic5_hw_cpu64(val) (val) /**< convert 64-bit value to CPU byte order, return original value directly */
-#define hinic5_hw_cpu32(val) (val) /**< convert 32-bit value to CPU byte order, return original value directly */
-#define hinic5_hw_cpu16(val) (val) /**< convert 16-bit value to CPU byte order, return original value directly */
+#define hinic5_hw_be32(val) (val) /**< 将32位值转换为大端序,此处直接返回原值 */
+#define hinic5_hw_cpu64(val) \
+ (val) /**< 将64位值转换为CPU字节序,此处直接返回原值 */
+#define hinic5_hw_cpu32(val) \
+ (val) /**< 将32位值转换为CPU字节序,此处直接返回原值 */
+#define hinic5_hw_cpu16(val) \
+ (val) /**< 将16位值转换为CPU字节序,此处直接返回原值 */
#else
-#define hinic5_hw_be32(val) cpu_to_be32(val) /**< convert 32-bit value to big-endian, call cpu_to_be32 for conversion */
-#define hinic5_hw_cpu64(val) be64_to_cpu(val) /**< convert 64-bit value to CPU byte order, call be64_to_cpu for conversion */
-#define hinic5_hw_cpu32(val) be32_to_cpu(val) /**< convert 32-bit value to CPU byte order, call be32_to_cpu for conversion */
-#define hinic5_hw_cpu16(val) be16_to_cpu(val) /**< convert 16-bit value to CPU byte order, call be16_to_cpu for conversion */
+#define hinic5_hw_be32(val) \
+ cpu_to_be32( \
+ val) /**< 将32位值转换为大端序,此处调用cpu_to_be32函数进行转换 */
+#define hinic5_hw_cpu64(val) \
+ be64_to_cpu( \
+ val) /**< 将64位值转换为CPU字节序,此处调用be64_to_cpu函数进行转换 */
+#define hinic5_hw_cpu32(val) \
+ be32_to_cpu( \
+ val) /**< 将32位值转换为CPU字节序,此处调用be32_to_cpu函数进行转换 */
+#define hinic5_hw_cpu16(val) \
+ be16_to_cpu( \
+ val) /**< 将16位值转换为CPU字节序,此处调用be16_to_cpu函数进行转换 */
#endif
/**
- * @brief convert data from host byte order to network byte order
- * @param data data to convert
- * @param len data length
+ * @brief 将数据从主机字节序转换为网络字节序
+ * @param data 要转换的数据
+ * @param len 数据长度
*
- * @return void
+ * @return 无
*/
static inline void hinic5_hw_be32_len(void *data, int len)
{
@@ -214,11 +181,11 @@ static inline void hinic5_hw_be32_len(void *data, int len)
}
/**
- * @brief this function converts data from CPU to HW 32-bit data
- * @param data data to convert
- * @param len length of data to convert
+ * @brief 该函数用于将数据从CPU端转换为HW端的32位数据
+ * @param data 要转换的数据
+ * @param len 要转换的数据的长度
*
- * @return void
+ * @return 无
*/
static inline void hinic5_hw_cpu32_len(void *data, int len)
{
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_crm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_crm.h
index 428e2b75a..5981b0e5a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_crm.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_crm.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_crm.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_CRM_H
#define HINIC5_CRM_H
@@ -14,493 +7,66 @@
#include <asm-generic/int-ll64.h>
#include <linux/types.h>
#include <linux/time.h>
+#include <linux/pci.h>
#include <linux/spinlock.h>
#include "mag_mpu_cmd_defs.h"
-#define HINIC5_DRV_VERSION "100.0.1.102" /* driver version information */
-#define HINIC5_DRV_DESC "Intelligent Network Interface Card Driver" /* driver description */
+#include "hinic5_service.h"
+
+#define HINIC5_DRV_VERSION GLOBAL_VERSION_STR /**< 用于存储驱动版本信息 */
+#define HINIC5_DRV_DESC \
+ "Intelligent Network Interface Card Driver" /**< 用于表示驱动的描述信息 */
+
+#define ARRAY_LEN(arr) \
+ ((int)((int)sizeof(arr) / \
+ (int)sizeof((arr)[0]))) /**< 计算数组长度的宏 */
-#define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof((arr)[0]))) /* macro for calculating array length */
+#define HINIC5_MGMT_VERSION_MAX_LEN 32 /**< 定义HINIC5管理版本最大长度 */
-#define HINIC5_MGMT_VERSION_MAX_LEN 32 /* HINIC5 management version max length */
+#define HINIC5_FW_VERSION_NAME 16 /**< 定义固件版本名称的长度 */
-#define HINIC5_FW_VERSION_NAME 16 /* firmware version name length */
+#define HISDK5_DCB_UP_MAX \
+ 0x8 /**< 定义网络接口控制数据包(DCB)的最大用户优先级(UP) */
+
+/**
+ * @brief function device bus type
+ */
+enum hinic5_dev_type {
+ HINIC5_DEVICE_T_PCI = 0, /**< 设备通过pci bus连接 */
+ HINIC5_DEVICE_T_UB = 1, /**< 设备通过ub bus连接 */
+ HINIC5_DEVICE_T_MAX = 2, /**< 支持的bus类型个数 */
+};
-#define HISDK5_DCB_UP_MAX 0x8 /* DCB max user priority */
/**
* @brief struct hinic5_fw_version
- * @details define a struct for storing firmware version information
+ * @details 定义了一个结构体,用于存储固件的版本信息
*/
struct hinic5_fw_version {
u8 mgmt_ver[HINIC5_FW_VERSION_NAME];
u8 microcode_ver[HINIC5_FW_VERSION_NAME];
u8 boot_ver[HINIC5_FW_VERSION_NAME];
};
-#define HINIC5_MGMT_CMD_UNSUPPORTED 0xFF /* management command unsupported */
-
-/**
- * @brief enum hinic5_service_type
- * @details service type enum,
- * show each drivers only such as nic_service_cap,
- * toe_service_cap structure, but not show service_cap
- */
-enum hinic5_service_type {
- SERVICE_T_NIC = 0,
- SERVICE_T_OVS = 1,
- SERVICE_T_ROCE = 2,
- SERVICE_T_TOE = 3,
- SERVICE_T_IOE = 4,
- SERVICE_T_FC = 5,
- SERVICE_T_VBS = 6,
- SERVICE_T_IPSEC = 7,
- SERVICE_T_VIRTIO = 8,
- SERVICE_T_MIGRATE = 9,
- SERVICE_T_PPA = 10,
- SERVICE_T_CUSTOM = 11,
- SERVICE_T_VROCE = 12,
- SERVICE_T_UB = 13,
- SERVICE_T_JBOF = 14,
- SERVICE_T_MACSEC = 15,
- SERVICE_T_DMMU = 16,
- SERVICE_T_CFM = 17,
- SERVICE_T_BIFUR = 18,
- SERVICE_T_HIHTR = 19,
- SERVICE_T_MAX = 20,
-
- /* Only used for interruption resource management,
- * mark the request module
- */
- SERVICE_T_INTF = (1 << 15),
- SERVICE_T_HINIC5_CQM = (1 << 16),
-};
+#define HINIC5_LOGICAL_OPTICAL_UNSUPPORTED 0xEF /**< 表示逻辑光模块信息不支持 */
+#define HINIC5_MGMT_CMD_UNSUPPORTED 0xFF /**< 表示管理命令不支持的情况 */
/**
* @brief enum hinic5_ppf_flr_type
- * @details define hinic5_ppf_flr_type enum
+ * @details 定义hinic5_ppf_flr_type枚举类型
*/
enum hinic5_ppf_flr_type {
- STATELESS_FLR_TYPE, /* stateless FLR type */
- STATEFUL_FLR_TYPE, /* stateful FLR type */
-};
-
-/**
- * @brief struct nic_service_cap
- * @details network interface service capability structure
- */
-struct nic_service_cap {
- u16 max_sqs; /* max send queue count */
- u16 max_rqs; /* max receive queue count */
- u16 default_num_queues; /* default queue count */
-};
-
-/**
- * @brief struct ppa_service_cap
- * @details ppa service capability structure
- */
-struct ppa_service_cap {
- u16 qpc_fake_vf_start; /* start virtual function number */
- u16 qpc_fake_vf_num; /* available virtual function count */
- u32 qpc_fake_vf_ctx_num; /* available virtual function context count */
- u32 pctx_sz; /* context size 512B */
- u32 bloomfilter_length; /* bloomfilter length */
- u8 bloomfilter_en; /* bloomfilter enable flag */
- u8 rsvd;
- u16 rsvd1;
-};
-
-/**
- * @brief struct vbs_service_cap
- * @details VBS service capability structure
- */
-struct vbs_service_cap {
- u16 vbs_max_volq; /* max volume queue count */
- u16 vbs_main_pf_enable : 1; /* main PF enable */
- u16 vbs_vsock_pf_enable : 1; /* vsock PF enable */
- u16 vbs_fushion_queue_pf_enable : 1; /* fusion queue PF enable */
- u16 vbs_host_dma_data_cos : 3; /* host DMA data priority */
- u16 vbs_vmio_cpy_data_cos : 3; /* VMIO copy data priority */
- u16 vbs_volq_cos : 3; /* volume queue priority */
- u16 rsvd1 : 4;
- u32 vbs_child_ctx_num;
- u32 vbs_hash_bucket_num;
-};
-
-/**
- * @brief struct migr_service_cap
- * @details migration service capability structure
- */
-struct migr_service_cap {
- u8 master_host_id; /* host ID */
- u8 rsvd[3];
-};
-
-/**
- * @brief struct ub_dev_cap_sdk_res
- * @details resource application related information in sdk
- */
-struct ub_dev_cap_sdk_res {
- u32 max_jfc; /* max Job Function Controller count */
- u32 max_jfr; /* max Job Function Record count */
- u32 max_tp; /* max Transmission Port count */
- u32 max_tpg; /* max Transmission Port Group count */
- u32 max_jetty; /* max Jetty count */
- u32 max_jetty_grp; /* max Jetty Group count */
- u32 max_mpts; /* max Multi-Path Termination Point count */
- u32 max_vtp; /* max Virtual Transmission Port count */
- u32 max_gid; /* max GID count */
- u32 max_utp; /* max Unicast Transmission Port count */
- u32 max_jfrc; /* max Job Function Record Cache count */
-
- u32 srqc_entry_sz; /* Shared Receive Queue Controller entry size */
- u32 mpt_entry_sz; /* Multi-Path Termination Point entry size */
- u32 cqc_entry_sz; /* Completion Queue Controller entry size */
- u32 qpc_entry_sz; /* Queue Pair Context entry size */
-
- u32 dmtt_cl_start; /* Data Move To Target start address */
- u32 dmtt_cl_end; /* Data Move To Target end address */
- u32 dmtt_cl_sz; /* Data Move To Target size */
-
- u32 cmtt_cl_start; /* Control Move To Target start address */
- u32 cmtt_cl_end; /* Control Move To Target end address */
- u32 cmtt_cl_sz; /* Control Move To Target size */
-
- u32 wqe_cl_start; /* Work Request Element start address */
- u32 wqe_cl_end; /* Work Request Element end address */
- u32 wqe_cl_sz; /* Work Request Element size */
-};
-
-/**
- * @brief struct ub_net_dev_cap
- * @details network device capability structure
- */
-struct ub_net_dev_cap {
- u32 is_tpf; /* transparent forwarding support */
- u32 vf_cnt; /* virtual function count */
- u32 port_cnt; /* port count */
- u32 max_mtu; /* max transmission unit size */
- u32 comp_vector_cnt; /* interrupt vector count */
-};
-
-/**
- * @brief struct ub_service_cap
- * @details service capability structure
- */
-struct ub_service_cap {
- struct ub_dev_cap_sdk_res sdk_res; /* device capability SDK response */
- struct ub_net_dev_cap net_dev_cap; /* network device capability */
-};
-
-/**
- * @brief struct jbof_service_cap
- * @details define a struct for describing JBOF service capability
- */
-struct jbof_service_cap {
- u32 max_parent_qpc_num; /* max parent QPC count */
- u32 max_child_qpc_num; /* max child QPC count */
- u32 parent_qpc_size; /* parent QPC size */
- u32 child_qpc_size; /* child QPC size */
- u32 hash_bucket_num; /* hash bucket count */
-};
-
-/**
- * @brief struct dmmu_service_cap
- * @details define a struct for describing dmmu service capability
- */
-struct dmmu_service_cap {
- u32 pasid_min;
- u32 pasid_max;
- u32 cl_start;
- u32 cl_end;
-};
-
-/**
- * @brief CFM(Common Function Module) service capability
- */
-struct cfm_service_cap {
- /* CCP - Congestion Control Platform */
- u32 ccp_max_child_ctx;
- u16 ccp_child_ctx_sz;
- u16 rsvd1;
-
- u64 rsvd[0xF];
-};
-
-/**
- * @brief struct dev_toe_svc_cap
- * @details PF/VF ToE service resource structure
- */
-struct dev_toe_svc_cap {
- /* PF resources */
- u32 max_pctxs; /* Parent Context: max specifications 1M */
- u32 max_cctxt;
- u32 max_cqs;
- u16 max_srqs;
- u32 srq_id_start;
- u32 max_mpts;
-};
-
-/**
- * @brief struct toe_service_cap
- * @details ToE services
- */
-struct toe_service_cap {
- struct dev_toe_svc_cap dev_toe_cap;
-
- bool alloc_flag;
- u32 pctx_sz; /* 1KB */
- u32 scqc_sz; /* 64B */
-};
-
-/**
- * @brief struct dev_fc_svc_cap
- * @details PF FC service resource structure defined
- */
-struct dev_fc_svc_cap {
- /* PF Parent QPC */
- u32 max_parent_qpc_num; /* max number is 2048 */
-
- /* PF Child QPC */
- u32 max_child_qpc_num; /* max number is 2048 */
- u32 child_qpc_id_start;
-
- /* PF SCQ */
- u32 scq_num; /* 16 */
-
- /* PF supports SRQ */
- u32 srq_num; /* Number of SRQ is 2 */
-
- u8 vp_id_start;
- u8 vp_id_end;
-};
-
-/**
- * @brief struct fc_service_cap
- * @details FC services
- */
-struct fc_service_cap {
- struct dev_fc_svc_cap dev_fc_cap;
-
- /* Parent QPC */
- u32 parent_qpc_size; /* 256B */
-
- /* Child QPC */
- u32 child_qpc_size; /* 256B */
-
- /* SQ */
- u32 sqe_size; /* 128B(in linked list mode) */
-
- /* SCQ */
- u32 scqc_size; /* Size of the Context 32B */
- u32 scqe_size; /* 64B */
-
- /* SRQ */
- u32 srqc_size; /* Size of SRQ Context (64B) */
- u32 srqe_size; /* 32B */
-};
-
-struct dev_roce_svc_own_cap {
- u32 max_qps;
- u32 max_cqs;
- u32 max_srqs;
- u32 max_mpts;
- u32 max_drc_qps;
-
- u32 reserved_qps; /* roce_rsvd_qp */
- u32 reserved_qps_back; /* roce_rsvd_qp_back */
- u32 reserved_cqs; /* roce_rsvd_cq */
- u32 reserved_cqs_back; /* roce_rsvd_cq_back */
- u32 reserved_srqs; /* roce_rsvd_srq */
- u32 reserved_srqs_back; /* roce_rsvd_srq_back */
- u32 max_pd; /* roce_max_pd */
- u32 max_xrcd; /* roce_max_xrcd */
- u32 max_gid; /* roce_max_gid */
-
- u32 cmtt_cl_start;
- u32 cmtt_cl_end;
- u32 cmtt_cl_sz;
-
- u32 dmtt_cl_start;
- u32 dmtt_cl_end;
- u32 dmtt_cl_sz;
-
- u32 wqe_cl_start;
- u32 wqe_cl_end;
- u32 wqe_cl_sz;
-
- u32 qpc_entry_sz;
- u32 max_wqes;
- u32 max_rq_sg;
- u32 max_sq_inline_data_sz;
- u32 max_rq_desc_sz;
-
- u32 rdmarc_entry_sz;
- u32 max_qp_init_rdma;
- u32 max_qp_dest_rdma;
-
- u32 max_srq_wqes;
- u32 max_srq_sge;
- u32 srqc_entry_sz;
-
- u32 max_msg_sz; /* Message size 2GB */
- u32 max_child_ctx_num;
-};
-
-/**
- * @brief struct dev_rdma_svc_cap
- * @details RDMA service capability structure
- */
-struct dev_rdma_svc_cap {
- struct dev_roce_svc_own_cap roce_own_cap; /* ROCE service unique parameter structure */
-};
-
-/**
- * @brief enum
- * @details Defines the RDMA service capability flag
- */
-enum {
- RDMA_BMME_FLAG_LOCAL_INV = (1 << 0),
- RDMA_BMME_FLAG_REMOTE_INV = (1 << 1),
- RDMA_BMME_FLAG_FAST_REG_WR = (1 << 2),
- RDMA_BMME_FLAG_RESERVED_LKEY = (1 << 3),
- RDMA_BMME_FLAG_TYPE_2_WIN = (1 << 4),
- RDMA_BMME_FLAG_WIN_TYPE_2B = (1 << 5),
-
- RDMA_DEV_CAP_FLAG_XRC = (1 << 6),
- RDMA_DEV_CAP_FLAG_MEM_WINDOW = (1 << 7),
- RDMA_DEV_CAP_FLAG_ATOMIC = (1 << 8),
- RDMA_DEV_CAP_FLAG_APM = (1 << 9),
-};
-
-/**
- * @brief struct rdma_service_cap
- * @details RDMA services
- */
-struct rdma_service_cap {
- struct dev_rdma_svc_cap dev_rdma_cap;
-
- u8 log_mtt; /* 1. the number of MTT PA must be integer power of 2
- * 2. represented by logarithm. Each MTT table can
- * contain 1, 2, 4, 8, and 16 PA)
- */
-
- u32 num_mtts; /* Number of MTT table (4M),
- * is actually MTT seg number
- */
- u32 log_mtt_seg;
- u32 mtt_entry_sz; /* MTT table size 8B, including 1 PA(64bits) */
- u32 mpt_entry_sz; /* MPT table size (64B) */
-
- u32 dmtt_cl_start;
- u32 dmtt_cl_end;
- u32 dmtt_cl_sz;
-
- u8 log_rdmarc; /* 1. the number of RDMArc PA must be integer power of 2
- * 2. represented by logarithm. Each MTT table can
- * contain 1, 2, 4, 8, and 16 PA)
- */
-
- u32 reserved_qps; /* Number of reserved QP */
- u32 max_sq_sg; /* Maximum SGE number of SQ (8) */
- u32 max_sq_desc_sz; /* WQE maximum size of SQ(1024B), inline maximum
- * size if 960B(944B aligned to the 960B),
- * 960B=>wqebb alignment=>1024B
- */
- u32 wqebb_size; /* Currently, the supports 64B and 128B,
- * defined as 64Bytes
- */
-
- u32 max_cqes; /* Size of the depth of the CQ (64K-1) */
- u32 reserved_cqs; /* Number of reserved CQ */
- u32 cqc_entry_sz; /* Size of the CQC (64B/128B) */
- u32 cqe_size; /* Size of CQE (32B) */
-
- u32 reserved_mrws; /* Number of reserved MR/MR Window */
-
- u32 max_fmr_maps; /* max MAP of FMR,
- * (1 << (32-ilog2(num_mpt)))-1;
- */
-
- u32 log_rdmarc_seg; /* table number of each RDMArc seg(3) */
-
- /* Timeout time. Formula:Tr=4.096us*2(local_ca_ack_delay), [Tr,4Tr] */
- u32 local_ca_ack_delay;
- u32 num_ports; /* Physical port number */
-
- u32 db_page_size; /* Size of the DB (4KB) */
- u32 direct_wqe_size; /* Size of the DWQE (256B) */
-
- u32 num_pds; /* Maximum number of PD (128K) */
- u32 reserved_pds; /* Number of reserved PD */
- u32 max_xrcds; /* Maximum number of xrcd (64K) */
- u32 reserved_xrcds; /* Number of reserved xrcd */
-
- u32 max_gid_per_port; /* gid number (16) of each port */
- u32 gid_entry_sz; /* RoCE v2 GID table is 32B,
- * compatible RoCE v1 expansion
- */
-
- u32 reserved_lkey; /* local_dma_lkey */
- u32 num_comp_vectors; /* Number of complete vector (32) */
- u32 page_size_cap; /* Supports 4K,8K,64K,256K,1M and 4M page_size */
-
- u32 flags; /* RDMA some identity */
- u32 max_frpl_len; /* Maximum number of pages frmr registration */
- u32 max_pkeys; /* Number of supported pkey group */
-};
-
-/**
- * @brief struct dev_ovs_svc_cap
- * @details PF OVS service resource structure defined
- */
-struct dev_ovs_svc_cap {
- u32 max_pctxs; /* Parent Context: max specifications 1M */
- u32 fake_vf_max_pctx;
- u16 fake_vf_num;
- u16 fake_vf_start_id;
- u8 dynamic_qp_en;
-};
-
-/**
- * @brief struct ovs_service_cap
- * @details OVS services
- */
-struct ovs_service_cap {
- struct dev_ovs_svc_cap dev_ovs_cap;
-
- u32 pctx_sz; /* 512B */
-};
-
-/**
- * @brief struct dev_ipsec_svc_cap
- * @details PF IPsec service resource structure defined
- */
-struct dev_ipsec_svc_cap {
- u32 max_sactxs; /* max IPsec SA context num */
- u16 max_cqs; /* max IPsec SCQC num */
- u16 rsvd0;
- u32 max_spctxs; /* max IPsec SP context num */
- u32 sa_hash_bucket_num;
- u32 sp_hash_bucket_num;
-};
-
-/**
- * @brief struct ipsec_service_cap
- * @details IPsec services
- */
-struct ipsec_service_cap {
- struct dev_ipsec_svc_cap dev_ipsec_cap;
- u32 sactx_sz; /* 512B */
+ STATELESS_FLR_TYPE, /**< 无状态FLR类型 */
+ STATEFUL_FLR_TYPE, /**< 有状态FLR类型 */
};
struct hisdk5_dcb_state {
- u8 dcb_on; /* dcb on or off */
- u8 default_cos; /* Default COS value, valid range 0~7 */
- u8 trust; /* trust state, 0-PCP mode, 1-DSCP mode */
- u8 rsvd1; /* reserved */
- u8 pcp2cos[HISDK5_DCB_UP_MAX]; /* PCP to COS mapping */
- u8 dscp2cos[64]; /* DSCP to COS mapping value */
- u32 rsvd2[7]; /* reserved */
+ u8 dcb_on; /**< dcb on or off */
+ u8 default_cos; /**< Default COS值, 合法范围0~7 */
+ u8 trust; /**< trust状态, 0-PCP模式, 1-DSCP模式 */
+ u8 rsvd1; /**< reserved */
+ u8 pcp2cos[HISDK5_DCB_UP_MAX]; /**< PCP到COS的映射 */
+ u8 dscp2cos[64]; /**< DSCP到COS的映射值 */
+ u32 rsvd2[7]; /**< reserved */
};
enum hisdk5_dcb_state_op {
@@ -513,46 +79,46 @@ enum hisdk5_dcb_state_op {
* @details Defines the IRQ information structure
*/
struct irq_info {
- u16 msix_entry_idx; /* IRQ corresponding index number */
- u32 irq_id; /* the IRQ number from OS */
+ u16 msix_entry_idx; /**< IRQ corresponding index number */
+ u32 irq_id; /**< the IRQ number from OS */
};
/**
* @brief struct interrupt_info
- * @details interrupt information structure
+ * @details 中断信息结构体
*/
struct interrupt_info {
- u32 lli_set; /* low latency interrupt enable */
- u32 interrupt_coalesc_set; /* interrupt coalesce enable */
- u16 msix_index; /* msix index */
- u8 lli_credit_limit; /* low latency interrupt credit value */
- u8 lli_timer_cfg; /* low latency interrupt timer value */
+ u32 lli_set; /**< low latency interrupt enable */
+ u32 interrupt_coalesc_set; /**< interrupt coalesce enable */
+ u16 msix_index; /**< msix index */
+ u8 lli_credit_limit; /**< low latency interrupt credit value */
+ u8 lli_timer_cfg; /**< low latency interrupt timer value */
u8 pending_limt;
- u8 coalesc_timer_cfg; /* interrupt coalesce timer value*/
- u8 resend_timer_cfg; /* interrupt resend timer value*/
+ u8 coalesc_timer_cfg; /**< interrupt coalesce timer value*/
+ u8 resend_timer_cfg; /**< interrupt resend timer value*/
};
/**
* @brief enum hinic5_msix_state
- * @details MSI-X state definition
+ * @details 定义中断消息传递(MSI-X)的状态
*/
enum hinic5_msix_state {
- HINIC5_MSIX_ENABLE, /* enable MSI-X */
- HINIC5_MSIX_DISABLE, /* disable MSI-X */
+ HINIC5_MSIX_ENABLE, /**< 启用MSI-X */
+ HINIC5_MSIX_DISABLE, /**< 禁用MSI-X */
};
/**
* @brief enum hinic5_msix_auto_mask
- * @details interrupt processing enum type
+ * @details 定义中断处理的枚举类型
*/
enum hinic5_msix_auto_mask {
- HINIC5_CLR_MSIX_AUTO_MASK, /* clear MSIX auto mask */
- HINIC5_SET_MSIX_AUTO_MASK, /* set MSIX auto mask */
+ HINIC5_CLR_MSIX_AUTO_MASK, /**< 清除MSIX自动掩码 */
+ HINIC5_SET_MSIX_AUTO_MASK, /**< 设置MSIX自动掩码 */
};
/**
* @brief enum func_type
- * @details function type
+ * @details 表示函数的类型
*/
enum func_type {
TYPE_PF,
@@ -563,58 +129,57 @@ enum func_type {
/**
* @brief struct hinic5_init_para
- * @details hinic5 initialization parameter structure
+ * @details 用于初始化hinic5的参数结构体
*/
struct hinic5_init_para {
/* Record hinic_pcidev or NDIS_Adapter pointer address */
- void *adapter_hdl; /* record hinic_pcidev or NDIS_Adapter pointer address */
+ void *adapter_hdl; /**< 记录hinic_pcidev或NDIS_Adapter指针地址 */
#ifdef __UEFI__
/**
- * Record pcidev or Handler pointer address
- * for example: ioremap interface input parameter
- */
- void *busdev_hdl; /* record pcidev or ub dev pointer address */
+ * Record pcidev or Handler pointer address
+ * for example: ioremap interface input parameter
+ */
+ void *busdev_hdl; /**< 记录pcidev或ub dev指针地址 */
#endif
/**
- * Record pcidev->dev or Handler pointer address which used to
- * dma address application or dev_err print the parameter
- */
- void *dev_hdl; /* record pcidev->dev or Handler pointer address,
- * used for DMA address application or dev_err print parameter
- */
-
- void *fers2_reg_base; /* FERS2 register base address */
+ * Record pcidev->dev or Handler pointer address which used to
+ * dma address application or dev_err print the parameter
+ */
+ void *dev_hdl; /**< 记录pcidev->dev或Handler指针地址,用于DMA地址应用或dev_err打印参数 */
+
+ void *fers2_reg_base; /**< FERS2 register base address */
/* Configure virtual address, PF is bar1, VF is bar0/1 */
- void *cfg_reg_base; /* configure virtual address, PF is bar1, VF is bar0/1 */
+ void *cfg_reg_base; /**< 配置虚拟地址,PF是bar1,VF是bar0/1 */
/* interrupt configuration register address, PF is bar2, VF is bar2/3 */
- void *intr_reg_base; /* interrupt configuration register address, PF is bar2, VF is bar2/3 */
+ void *intr_reg_base; /**< 中断配置寄存器地址,PF是bar2,VF是bar2/3 */
/* for PF bar3 virtual address, if function is VF should set to NULL */
- void *mgmt_reg_base; /* for PF bar3 virtual address, if function is VF should set to NULL */
+ void *mgmt_reg_base; /**< 对于PF的bar3虚拟地址,如果函数是VF,应设置为NULL */
- u64 db_dwqe_len; /* doorbell and direct wqe length */
- u64 db_base_phy; /* doorbell base physical address */
+ u64 db_dwqe_len; /**< 用于记录doorbell和direct wqe的长度 */
+ u64 db_base_phy; /**< doorbell的基础物理地址 */
/* the doorbell address, bar4/5 higher 4M space */
- void *db_base; /* doorbell address, bar4/5 higher 4M space */
+ void *db_base; /**< doorbell地址,bar4/5高4M空间 */
/* direct wqe 4M, follow the doorbell address space */
- void *dwqe_mapping; /* direct wqe 4M, follow the doorbell address space */
- void **hwdev; /* hardware device pointer */
- void *chip_node; /* chip node pointer */
+ void *dwqe_mapping; /**< 直接wqe 4M,跟随doorbell地址空间 */
+ void **hwdev; /**< 硬件设备指针 */
+ void *chip_node; /**< 芯片节点指针 */
/* if use polling mode, set it true */
- bool poll; /* if use polling mode, set to true */
+ bool poll; /**< 如果使用轮询模式,设置为true */
- u16 probe_fault_level; /* probe fault level */
+ u16 probe_fault_level; /**< 探测故障级别 */
};
-#define HINIC5_DB_DWQE_SIZE 0x100000000 /* Maximum support size of BAR45, DB & DWQE are both half */
+#define HINIC5_DB_DWQE_SIZE \
+ 0x100000000 /**< Maximum support size of BAR45, DB & DWQE are both half */
-#define HINIC5_DB_PAGE_SIZE 0x00001000ULL /* db page size: 4K */
-#define HINIC5_DWQE_OFFSET 0x00000800ULL /* dwqe page size: 4K */
+#define HINIC5_DB_PAGE_SIZE 0x00001000ULL /**< db page size: 4K */
+#define HINIC5_DWQE_OFFSET 0x00000800ULL /**< dwqe page size: 4K */
/**
- * @brief define a macro for calculating max database area count
- * @param HINIC5_DB_MAX_AREAS max database area count
- * @param HINIC5_DB_DWQE_SIZE each database area size
- * @param HINIC5_DB_PAGE_SIZE each database page size
+ * @brief 定义一个宏,用于计算最大的数据库区域数量
+ * @param HINIC5_DB_MAX_AREAS 表示最大的数据库区域数量
+ * @param HINIC5_DB_DWQE_SIZE 表示每个数据库区域的大小
+ * @param HINIC5_DB_PAGE_SIZE 表示每个数据库页的大小
*/
#define HINIC5_DB_MAX_AREAS (HINIC5_DB_DWQE_SIZE / HINIC5_DB_PAGE_SIZE)
@@ -623,48 +188,48 @@ struct hinic5_init_para {
#endif
#define MAX_FUNCTION_NUM 4096
-#define HINIC5_SYNFW_TIME_PERIOD (60 * 60 * 1000) /* firmware sync time period */
+#define HINIC5_SYNFW_TIME_PERIOD (60 * 60 * 1000) /**< 表示同步固件的时间周期 */
#define FAULT_SHOW_STR_LEN 16
/**
* @brief enum hinic5_fault_source_type
- * @details fault source type enum
+ * @details 错误源类型枚举
*/
enum hinic5_fault_source_type {
/* same as FAULT_TYPE_CHIP */
- HINIC5_FAULT_SRC_HW_MGMT_CHIP = 0, /* hardware management chip error */
+ HINIC5_FAULT_SRC_HW_MGMT_CHIP = 0, /**< 硬件管理芯片错误 */
/* same as FAULT_TYPE_UCODE */
- HINIC5_FAULT_SRC_HW_MGMT_UCODE, /* hardware management microcode error */
+ HINIC5_FAULT_SRC_HW_MGMT_UCODE, /**< 硬件管理微码错误 */
/* same as FAULT_TYPE_MEM_RD_TIMEOUT */
- HINIC5_FAULT_SRC_HW_MGMT_MEM_RD_TIMEOUT, /* hardware management memory read timeout error */
+ HINIC5_FAULT_SRC_HW_MGMT_MEM_RD_TIMEOUT, /**< 硬件管理内存读取超时错误 */
/* same as FAULT_TYPE_MEM_WR_TIMEOUT */
- HINIC5_FAULT_SRC_HW_MGMT_MEM_WR_TIMEOUT, /* hardware management memory write timeout error */
+ HINIC5_FAULT_SRC_HW_MGMT_MEM_WR_TIMEOUT, /**< 硬件管理内存写入超时错误 */
/* same as FAULT_TYPE_REG_RD_TIMEOUT */
- HINIC5_FAULT_SRC_HW_MGMT_REG_RD_TIMEOUT, /* hardware management register read timeout error */
+ HINIC5_FAULT_SRC_HW_MGMT_REG_RD_TIMEOUT, /**< 硬件管理寄存器读取超时错误 */
/* same as FAULT_TYPE_REG_WR_TIMEOUT */
- HINIC5_FAULT_SRC_HW_MGMT_REG_WR_TIMEOUT, /* hardware management register write timeout error */
- HINIC5_FAULT_SRC_SW_MGMT_UCODE, /* software management microcode error */
- HINIC5_FAULT_SRC_MGMT_WATCHDOG, /* management watchdog error */
- HINIC5_FAULT_SRC_MGMT_RESET = 8, /* management reset error */
- HINIC5_FAULT_SRC_HW_PHY_FAULT, /* hardware PHY error */
- HINIC5_FAULT_SRC_TX_PAUSE_EXCP, /* transmit pause exception error */
- HINIC5_FAULT_SRC_PCIE_LINK_DOWN = 20, /* PCIE link down error */
- HINIC5_FAULT_SRC_HOST_HEARTBEAT_LOST = 21, /* host heartbeat lost error */
- HINIC5_FAULT_SRC_TX_TIMEOUT, /* transmit timeout error */
- HINIC5_FAULT_SRC_TYPE_MAX, /* fault source type max value */
+ HINIC5_FAULT_SRC_HW_MGMT_REG_WR_TIMEOUT, /**< 硬件管理寄存器写入超时错误 */
+ HINIC5_FAULT_SRC_SW_MGMT_UCODE, /**< 软件管理微码错误 */
+ HINIC5_FAULT_SRC_MGMT_WATCHDOG, /**< 管理看门狗错误 */
+ HINIC5_FAULT_SRC_MGMT_RESET = 8, /**< 管理重置错误 */
+ HINIC5_FAULT_SRC_HW_PHY_FAULT, /**< 硬件PHY错误 */
+ HINIC5_FAULT_SRC_TX_PAUSE_EXCP, /**< 发送暂停异常错误 */
+ HINIC5_FAULT_SRC_PCIE_LINK_DOWN = 20, /**< PCIE链路断开错误 */
+ HINIC5_FAULT_SRC_HOST_HEARTBEAT_LOST = 21, /**< 主机心跳丢失错误 */
+ HINIC5_FAULT_SRC_TX_TIMEOUT, /**< 发送超时错误 */
+ HINIC5_FAULT_SRC_TYPE_MAX, /**< 错误源类型最大值 */
};
/**
* @brief union hinic5_fault_hw_mgmt
- * @details used for handling hardware management error information
+ * @details 用于处理硬件管理中的错误信息
*/
union hinic5_fault_hw_mgmt {
u32 val[4];
/* valid only type == FAULT_TYPE_CHIP */
struct {
u8 node_id;
- u8 err_level; /* enum hinic_fault_err_level */
+ u8 err_level; /**< enum hinic_fault_err_level */
u16 err_type;
u32 err_csr_addr;
u32 err_csr_value;
@@ -686,8 +251,8 @@ union hinic5_fault_hw_mgmt {
} ucode;
/* valid only if type == FAULT_TYPE_MEM_RD_TIMEOUT ||
- * FAULT_TYPE_MEM_WR_TIMEOUT
- */
+ * FAULT_TYPE_MEM_WR_TIMEOUT
+ */
struct {
u32 err_csr_ctrl;
u32 err_csr_data;
@@ -696,8 +261,8 @@ union hinic5_fault_hw_mgmt {
} mem_timeout;
/* valid only if type == FAULT_TYPE_REG_RD_TIMEOUT ||
- * FAULT_TYPE_REG_WR_TIMEOUT
- */
+ * FAULT_TYPE_REG_WR_TIMEOUT
+ */
struct {
u32 err_csr;
u32 rsvd6;
@@ -715,87 +280,98 @@ union hinic5_fault_hw_mgmt {
u32 op_data;
u32 rsvd10;
} phy_fault;
+
+ /* valid only if type == FAULT_TYPE_HEARTBEAT_LOST */
+ struct {
+ /* 丢失类型:
+ * 1: MPU与SMU的心跳
+ * 2: 主/从MPU的心跳
+ * 3: MPU与IMP的心跳
+ */
+ u32 err_type;
+ u32 rsv[0x3];
+ } heartbeat_lost;
};
/* defined by chip */
/**
* @brief struct hinic5_fault_event
- * @details used for representing HINIC5 fault event
+ * @details 用于表示HINIC5的故障事件
*/
struct hinic5_fault_event {
/* enum hinic_fault_type */
- u8 type; /* fault type */
- u8 fault_level; /* fault level written by SDK, used for ULDOVENT */
+ u8 type; /**< 故障类型 */
+ u8 fault_level; /**< SDK写入故障级别,用于ULDOVENT */
u8 rsvd0[2];
- union hinic5_fault_hw_mgmt event; /* fault hardware management event */
+ union hinic5_fault_hw_mgmt event; /**< 故障硬件管理事件 */
};
/**
* @brief struct hinic5_cmd_fault_event
- * @details define a struct for storing fault event
+ * @details 定义了一个用于存储故障事件的结构体
*/
struct hinic5_cmd_fault_event {
- u8 status; /* status field */
- u8 version; /* version field */
+ u8 status; /**< 状态字段 */
+ u8 version; /**< 版本字段 */
u8 rsvd0[6];
- struct hinic5_fault_event event; /* fault event structure */
+ struct hinic5_fault_event event; /**< 故障事件结构体 */
};
/**
* @brief struct hinic5_sriov_state_info
- * @details define a struct for storing SR-IOV state information
+ * @details 定义一个结构体,用于存储SR-IOV的状态信息
*/
struct hinic5_sriov_state_info {
- u8 enable; /* SR-IOV enable flag */
- u16 num_vfs; /* virtual function count */
- u32 vf_id; /* func id to operate */
+ u8 enable; /**< 表示SR-IOV是否启用 */
+ u16 num_vfs; /**< 表示虚拟函数的数量 */
+ u32 vf_id; /**< 待操作的func id */
};
/**
* @brief enum hinic5_comm_event_type
- * @details communication event type enum
+ * @details 通信事件类型枚举
*/
enum hinic5_comm_event_type {
- EVENT_COMM_PCIE_LINK_DOWN, /* PCIE link down event */
- EVENT_COMM_HEART_LOST, /* heartbeat lost event */
- EVENT_COMM_FAULT, /* device fault event */
- EVENT_COMM_SRIOV_STATE_CHANGE, /* SR-IOV state change event */
- EVENT_COMM_CARD_REMOVE, /* device remove event */
- EVENT_COMM_MGMT_WATCHDOG, /* management monitor watchdog event */
+ EVENT_COMM_PCIE_LINK_DOWN, /**< PCIE链路断开事件 */
+ EVENT_COMM_HEART_LOST, /**< 心跳丢失事件 */
+ EVENT_COMM_FAULT, /**< 设备故障事件 */
+ EVENT_COMM_SRIOV_STATE_CHANGE, /**< SR-IOV状态变化事件 */
+ EVENT_COMM_CARD_REMOVE, /**< 设备移除事件 */
+ EVENT_COMM_MGMT_WATCHDOG, /**< 管理监视器看门狗事件 */
};
/**
* @brief enum hinic5_event_service_type
- * @details event service type enum
+ * @details 定义了事件服务类型的枚举
*/
enum hinic5_event_service_type {
- EVENT_SRV_COMM = 0, /* common event service type */
-#define SERVICE_EVENT_BASE (EVENT_SRV_COMM + 1) /* service event base value */
- /* network interface card event service type */
- EVENT_SRV_NIC = SERVICE_EVENT_BASE + SERVICE_T_NIC,
- /* migration event service type */
- EVENT_SRV_MIGRATE = SERVICE_EVENT_BASE + SERVICE_T_MIGRATE,
+ EVENT_SRV_COMM = 0, /**< 通用事件服务类型 */
+#define SERVICE_EVENT_BASE (EVENT_SRV_COMM + 1) /**< 定义服务事件基础值 */
+ EVENT_SRV_NIC = SERVICE_EVENT_BASE +
+ SERVICE_T_NIC, /**< 网络接口卡事件服务类型 */
+ EVENT_SRV_MIGRATE =
+ SERVICE_EVENT_BASE + SERVICE_T_MIGRATE, /**< 迁移事件服务类型 */
};
/**
- * @brief define a macro for generating service event type encoding
- * @param svc service type, range 0-65535
- * @param type event type, range 0-65535
+ * @brief 定义一个宏,用于生成服务事件类型的编码
+ * @param svc 服务类型,取值范围为0-65535
+ * @param type 事件类型,取值范围为0-65535
*
- * @details this macro combines service type and event type into a 32-bit unsigned integer,
- * where service type occupies high 16 bits, event type occupies low 16 bits.
+ * @details 这个宏将服务类型和事件类型的值合并为一个32位的无符号整数,
+ * 其中服务类型占用高16位,事件类型占用低16位。
*
- * @return returns the generated event type encoding
+ * @return 返回生成的事件类型编码
*/
#define HINIC5_SRV_EVENT_TYPE(svc, type) ((((u32)(svc)) << 16) | (type))
/**
* @brief struct hinic5_event_info
- * @details hinic5 event information structure
+ * @details 定义了hinic5事件信息的结构体
*/
struct hinic5_event_info {
- u16 service; /* enum type hinic5_event_service_type */
- u16 type; /* event type */
- u8 event_data[104]; /* event data, max length 104 bytes */
+ u16 service; /**< 枚举类型hinic5_event_service_type */
+ u16 type; /**< 事件类型 */
+ u8 event_data[104]; /**< 事件数据,最大长度104字节 */
};
/**
@@ -831,12 +407,11 @@ void hinic5_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx,
* @param interrupt_para: interrupt info
* @param channel: channel id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hinic5_set_interrupt_cfg_direct(void *hwdev,
- struct interrupt_info *info,
+int hinic5_set_interrupt_cfg_direct(void *hwdev, struct interrupt_info *info,
u16 channel);
/**
* @brief Set interrupt cfg
@@ -844,9 +419,9 @@ int hinic5_set_interrupt_cfg_direct(void *hwdev,
* @param interrupt_info: Interrupt info
* @param channel: command message channel id is defined in enum hinic5_channel_id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_set_interrupt_cfg(void *dev, struct interrupt_info info,
u16 channel);
@@ -857,9 +432,9 @@ int hinic5_set_interrupt_cfg(void *dev, struct interrupt_info info,
* @param info: interrupt info
* @param channel: channel id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info,
u16 channel);
@@ -872,9 +447,9 @@ int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info,
* @param irq_info_array: alloc irq info
* @param act_num: alloc actual number
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_alloc_irqs(void *hwdev, enum hinic5_service_type type, u16 num,
struct irq_info *irq_info_array, u16 *act_num);
@@ -895,9 +470,9 @@ void hinic5_free_irq(void *hwdev, enum hinic5_service_type type, u32 irq_id);
* @param ceq_id_array: alloc ceq_id_array
* @param act_num: alloc actual number
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_alloc_ceqs(void *hwdev, enum hinic5_service_type type, int num,
int *ceq_id_array, int *act_num);
@@ -931,9 +506,9 @@ void hinic5_write_ts_data(void *hwdev, const struct timespec64 *ts);
* @param hwdev: device pointer to hwdev
* @param flags: update flags
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_ts_up_en(void *hwdev, u32 flags);
@@ -964,8 +539,8 @@ void hinic5_ptp_ts_update(void *hwdev, s32 delta_ns);
* @param chip_time: get chip_time pointer
*
* @return get success or fail
- * @retval zero: success
- * @retval non-zero: failure
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_non_ptp_chip_time(void *dev, u64 *chip_time);
@@ -976,8 +551,8 @@ int hinic5_get_non_ptp_chip_time(void *dev, u64 *chip_time);
* @param time_diff: get time_diff pointer
*
* @return get success or fail
- * @retval zero: success
- * @retval non-zero: failure
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_non_ptp_time_diff(void *dev, s64 *time_diff);
#endif
@@ -1003,209 +578,20 @@ int hinic5_get_chip_present_flag(const void *hwdev);
* @param hwdev: device pointer to hwdev
*
* @return heartbeat status
- * @retval 0 normal
- * @retval 1 heart lost
- * @retval 0xFFFFFFFF link down
+ * @retval 0 normal
+ * @retval 1 heart lost
+ * @retval 0xFFFFFFFF link down
*/
u32 hinic5_get_heartbeat_status(void *hwdev);
-/**
- * @brief hinic5_support_nic - function support nic
- * @param hwdev: device pointer to hwdev
- * @param cap: nic service capbility
- *
- * @return whether device supports NIC service
- * @retval true: function support nic
- * @retval false: function not support nic
- */
-bool hinic5_support_nic(void *hwdev, struct nic_service_cap *cap);
-
-/**
- * @brief hinic5_support_ipsec - function support ipsec
- * @param hwdev: device pointer to hwdev
- * @param cap: ipsec service capbility
- *
- * @return whether hardware supports IPsec service
- * @retval true: function support ipsec
- * @retval false: function not support ipsec
- */
-bool hinic5_support_ipsec(void *hwdev, struct ipsec_service_cap *cap);
-
-/**
- * @brief hinic5_support_macsec - function support macsec
- * @param hwdev: device pointer to hwdev
- *
- * @return whether hardware supports MACsec service
- * @retval true: function support macsec
- * @retval false: function not support macsec
- */
-bool hinic5_support_macsec(void *hwdev);
-
-/**
- * @brief hinic5_support_roce - function support roce
- * @param hwdev: device pointer to hwdev
- * @param cap: roce service capbility
- *
- * @return whether device supports RoCE
- * @retval true: function support roce
- * @retval false: function not support roce
- */
-bool hinic5_support_roce(void *hwdev, struct rdma_service_cap *cap);
-
-/**
- * @brief hinic5_support_fc - function support fc
- * @param hwdev: device pointer to hwdev
- * @param cap: fc service capbility
- *
- * @return whether device supports fc
- * @retval true: function support fc
- * @retval false: function not support fc
- */
-bool hinic5_support_fc(void *hwdev, struct fc_service_cap *cap);
-
-/**
- * @brief hinic5_support_rdma - function support rdma
- * @param hwdev: device pointer to hwdev
- * @param cap: rdma service capbility
- *
- * @return whether device supports rdma
- * @retval true: function support rdma
- * @retval false: function not support rdma
- */
-bool hinic5_support_rdma(void *hwdev, struct rdma_service_cap *cap);
-
-/**
- * @brief hinic5_is_rdma_en - is rdma enable
- * @param hwdev: device pointer to hwdev
- * @param cap: rdma service capbility
- *
- * @return whether RDMA service is enabled
- * @retval true: rdma is enabled
- * @retval false: rdma is disabled
- */
-bool hinic5_is_rdma_en(void *hwdev, struct rdma_service_cap *cap);
-
-/**
- * @brief hinic5_support_ovs - function support ovs
- * @param hwdev: device pointer to hwdev
- * @param cap: ovs service capbility
- *
- * @return whether device supports ovs
- * @retval true: function support ovs
- * @retval false: function not support ovs
- */
-bool hinic5_support_ovs(void *hwdev, struct ovs_service_cap *cap);
-
-/**
- * @brief hinic5_support_vbs - function support vbs
- * @param hwdev: device pointer to hwdev
- * @param cap: vbs service capbility
- *
- * @return whether device supports vbs
- * @retval true: function support vbs
- * @retval false: function not support vbs
- */
-bool hinic5_support_vbs(void *hwdev, struct vbs_service_cap *cap);
-
-/**
- * @brief hinic5_support_toe - sync time to hardware
- * @param hwdev: device pointer to hwdev
- * @param cap: toe service capbility
- *
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
- */
-bool hinic5_support_toe(void *hwdev, struct toe_service_cap *cap);
-
-/**
- * @brief hinic5_support_ppa - function support ppa
- * @param hwdev: device pointer to hwdev
- * @param cap: ppa service capbility
- *
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
- */
-bool hinic5_support_ppa(void *hwdev, struct ppa_service_cap *cap);
-
-/**
- * @brief hinic5_support_migr - function support migrate
- * @param hwdev: device pointer to hwdev
- * @param cap: migrate service capbility
- *
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
- */
-bool hinic5_support_migr(void *hwdev, struct migr_service_cap *cap);
-
-/**
- * @brief hinic5_support_ub - function support ub
- * @param hwdev: device pointer to hwdev
- * @param cap: ub service capbility
- *
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
- */
-bool hinic5_support_ub(void *hwdev, struct ub_service_cap *cap);
-
-/**
- * @brief hinic5_support_jbof - function support jbof
- * @param hwdev: device pointer to hwdev
- * @param cap: jbof service capbility
- *
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
- */
-bool hinic5_support_jbof(void *hwdev, struct jbof_service_cap *cap);
-
-/**
- * @brief hinic5_support_vroce - function support vroce
- * @param hwdev: device pointer to hwdev
- * @param cap: roce service capbility
- *
- * @return whether function supports vroce
- * @retval true: function support roce
- * @retval false: function not support roce
- */
-bool hinic5_support_vroce(void *hwdev, struct rdma_service_cap *cap);
-
-/**
- * @brief hinic5_support_dmmu - function support dmmu
- * @param hwdev: device pointer to hwdev
- * @param cap: dmmu service capbility
- * @retval true: function support dmmu
- * @retval false: function not support dmmu
- */
-bool hinic5_support_dmmu(void *hwdev, struct dmmu_service_cap *cap);
-
-/**
- * @brief hinic5_support_biufr - function support biufr
- * @param hwdev: device pointer to hwdev
- * @retval true: function support biufr
- * @retval false: function not support biufr
- */
-bool hinic5_support_bifur(void *hwdev);
-
-/**
- * @brief hinic5_support_hihtr - function support hihtr
- * @param hwdev: device pointer to hwdev
- * @retval true: function support biufr
- * @retval false: function not support hihtr
- */
-bool hinic5_support_hihtr(void *hwdev);
-
/**
* @brief hinic5_sync_time - sync time to hardware
* @param hwdev: device pointer to hwdev
* @param time: time to sync
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_sync_time(void *hwdev, u64 time);
@@ -1219,9 +605,9 @@ void hinic5_disable_mgmt_msg_report(void *hwdev);
* @brief hinic5_func_for_mgmt - get function service type
* @param hwdev: device pointer to hwdev
*
- * @return whether function supports management
- * @retval true: function for mgmt
- * @retval false: function is not for mgmt
+ * @return 函数是否支持管理功能
+ * @retval true: function for mgmt
+ * @retval false: function is not for mgmt
*/
bool hinic5_func_for_mgmt(void *hwdev);
@@ -1235,9 +621,9 @@ void hinic5_set_pcie_order_cfg(void *handle);
* @brief hinic5_init_hwdev - call to init hwdev
* @param para: device pointer to para
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_init_hwdev(struct hinic5_init_para *para);
@@ -1270,20 +656,20 @@ void hinic5_shutdown_hwdev(void *hwdev);
* @param hwdev: device pointer to hwdev
* @param ppf_flr_type: ppf flr type
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_set_ppf_flr_type(void *hwdev, enum hinic5_ppf_flr_type flr_type);
-/* *
+/**
* @brief hinic5_set_ppf_tbl_hotreplace_flag - set os hotreplace flag in ppf function table
* @param hwdev: device pointer to hwdev
* @param flag : os hotreplace flag : 0-not in os hotreplace 1-in os hotreplace
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag);
@@ -1293,9 +679,9 @@ int hinic5_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag);
* @param mgmt_ver: output management version
* @param channel: channel id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
u16 channel);
@@ -1306,9 +692,9 @@ int hinic5_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
* @param fw_ver: firmware version
* @param channel: channel id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_fw_version(void *hwdev, struct hinic5_fw_version *fw_ver,
u16 channel);
@@ -1321,14 +707,6 @@ int hinic5_get_fw_version(void *hwdev, struct hinic5_fw_version *fw_ver,
*/
u16 hinic5_global_func_id(void *hwdev);
-/**
- * @brief hinic_ppf_idx - get ppf function id
- * @param hwdev: device pointer to hwdev
- *
- * @return ppf function id
- */
-u8 hinic5_ppf_idx(void *hwdev);
-
/**
* @brief hinic5_vector_to_eqn - vector to eq id
* @param hwdev: device pointer to hwdev
@@ -1400,9 +778,9 @@ bool hinic5_in_spu(void *hwdev);
* @brief hinic5_func_max_qnum - get host total function number
* @param hwdev: device pointer to hwdev
*
- * @return total function count calculated or obtained
- * @retval non-zero: host total function number
- * @retval zero: failure
+ * @return 计算或获取到的功能总数
+ * @retval non-zero: host total function number
+ * @retval zero: failure
*/
u16 hinic5_host_total_func(void *hwdev);
@@ -1410,25 +788,25 @@ u16 hinic5_host_total_func(void *hwdev);
* @brief hinic5_func_max_qnum - get max nic queue number
* @param hwdev: device pointer to hwdev
*
- * @return max queue count of network device
- * @retval non-zero: max nic queue number
- * @retval zero: failure
+ * @return 网络设备的最大队列数量
+ * @retval non-zero: max nic queue number
+ * @retval zero: failure
*/
u16 hinic5_func_max_nic_qnum(void *hwdev);
/**
- * @brief get function cos mask mode
- * @param hwdev hardware device pointer
+ * @brief 获取函数cos掩码模式
+ * @param hwdev 硬件设备指针
*
- * @return u8 return cos mask mode
+ * @return u8 返回cos掩码模式
*/
u8 hinic5_func_cos_mask_mode(void *hwdev);
/**
- * @brief get function default cos value
- * @param hwdev hardware device pointer
+ * @brief 获取函数默认的cos值
+ * @param hwdev 硬件设备指针
*
- * @return return cos value
+ * @return 返回cos值
*/
u8 hinic5_func_dev_default_cos(void *hwdev);
@@ -1436,9 +814,9 @@ u8 hinic5_func_dev_default_cos(void *hwdev);
* @brief hinic5_func_max_qnum - get max queue number
* @param hwdev: device pointer to hwdev
*
- * @return get device max queue count
- * @retval non-zero: max queue number
- * @retval zero: failure
+ * @return 获取设备的最大队列数
+ * @retval non-zero: max queue number
+ * @retval zero: failure
*/
u16 hinic5_func_max_qnum(void *hwdev);
@@ -1470,9 +848,9 @@ u8 hinic5_physical_port_id(void *hwdev); /* Obtain service_cap.port_id */
* @brief hinic5_func_max_vf - get vf number
* @param hwdev: device pointer to hwdev
*
- * @return return max virtual function count
- * @retval non-zero: vf number
- * @retval zero: failure
+ * @return 返回最大虚拟功能数量
+ * @retval non-zero: vf number
+ * @retval zero: failure
*/
u16 hinic5_func_max_vf(void *hwdev); /* Obtain service_cap.max_vf */
@@ -1485,9 +863,9 @@ u8 hinic5_max_pf_num(void *hwdev);
* @brief hinic5_host_pf_num - get current host pf number
* @param hwdev: device pointer to hwdev
*
- * @return return obtained PF count
- * @retval non-zero: pf number
- * @retval zero: failure
+ * @return 返回获取到的PF数量
+ * @retval non-zero: pf number
+ * @retval zero: failure
*/
u32 hinic5_host_pf_num(void *hwdev); /* Obtain service_cap.pf_num */
@@ -1495,9 +873,9 @@ u32 hinic5_host_pf_num(void *hwdev); /* Obtain service_cap.pf_num */
* @brief hinic5_host_pf_id_start - get current host pf id start
* @param hwdev: device pointer to hwdev
*
- * @return get device PF count
- * @retval non-zero: pf id start
- * @retval zero: failure
+ * @return 获取设备的PF数量
+ * @retval non-zero: pf id start
+ * @retval zero: failure
*/
u32 hinic5_host_pf_id_start(void *hwdev); /* Obtain service_cap.pf_num */
@@ -1521,9 +899,9 @@ u8 hinic5_vf_in_pf(void *hwdev);
* @brief hinic5_cos_valid_bitmap - get cos valid bitmap
* @param hwdev: device pointer to hwdev
*
- * @return success or failure
- * @retval non-zero: valid cos bit map
- * @retval zero: failure
+ * @return 是否成功
+ * @retval non-zero: valid cos bit map
+ * @retval zero: failure
*/
int hinic5_cos_valid_bitmap(void *hwdev, u8 *func_dft_cos, u8 *port_cos_bitmap);
@@ -1531,9 +909,9 @@ int hinic5_cos_valid_bitmap(void *hwdev, u8 *func_dft_cos, u8 *port_cos_bitmap);
* @brief hinic5_stateful_init - init stateful resource
* @param hwdev: device pointer to hwdev
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_stateful_init(void *hwdev);
@@ -1556,29 +934,30 @@ void hinic5_free_stateful(void *hwdev);
bool hinic5_need_init_stateful_default(void *hwdev);
/**
- * @brief hinic5_hinic5_get_card_present_state - get card present state
+ * @brief hinic5_get_card_present_state - get card present state
* @param hwdev: device pointer to hwdev
* @param card_present_state: return card present state
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hinic5_hinic5_get_card_present_state(void *hwdev, bool *card_present_state);
+int hinic5_get_card_present_state(void *hwdev, bool *card_present_state);
/**
* @brief hinic5_func_rx_tx_flush - function flush
* @param hwdev: device pointer to hwdev
* @param channel: channel id
- * @param flr_timeout_ms: flr timeout in ms
+ * @param flr_timeout_ms: flr超时时间,以ms为单位
*
- * @attention when flr_timeout_ms is 0, use default flr timeout HINIC5_FLR_TIMEOUT(40s)
+ * @attention 当flr_timeout_ms为0时,使用flr超时默认值HINIC5_FLR_TIMEOUT(40s)
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hinic5_func_rx_tx_flush(void *hwdev, u16 channel, bool wait_io, u32 flr_timeout_ms);
+int hinic5_func_rx_tx_flush(void *hwdev, u16 channel, bool wait_io,
+ u32 flr_timeout_ms);
/**
* @brief hinic5_flush_mgmt_workq - when remove function should flush work queue
@@ -1631,41 +1010,41 @@ void hinic5_probe_success(void *hwdev);
* @param state: function used state
* @param channel: channel id
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state,
u16 channel);
/**
- * @brief hinic5_hinic5_get_self_test_result - get self test result
+ * @brief hinic5_get_self_test_result - get self test result
* @param hwdev: device pointer to hwdev
*
* @return self test result
*/
-u32 hinic5_hinic5_get_self_test_result(void *hwdev);
+u32 hinic5_get_self_test_result(void *hwdev);
/**
- * @brief hinic5_set_slave_host_enable - set slave host enable
+ * @brief set_slave_host_enable - set slave host enable
* @param hwdev: device pointer to hwdev
* @param host_id: set host id
* @param slave_en-zero: slave is enable
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-void hinic5_set_slave_host_enable(void *hwdev, u8 host_id, bool enable);
+void set_slave_host_enable(void *hwdev, u8 host_id, bool enable);
/**
* @brief hinic5_get_slave_bitmap - get slave host bitmap
* @param hwdev: device pointer to hwdev
* @param slave_host_bitmap-zero: slave host bitmap
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_slave_bitmap(void *hwdev, u8 *slave_host_bitmap);
@@ -1675,9 +1054,9 @@ int hinic5_get_slave_bitmap(void *hwdev, u8 *slave_host_bitmap);
* @param host_id: get host id
* @param slave_en-zero: slave is enable
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_slave_host_enable(void *hwdev, u8 host_id, u8 *slave_en);
@@ -1687,9 +1066,9 @@ int hinic5_get_slave_host_enable(void *hwdev, u8 host_id, u8 *slave_en);
* @param host_id: get host id
* @param slave_en-zero: migrate is enable
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_set_host_migrate_enable(void *hwdev, u8 host_id, bool enable);
@@ -1699,161 +1078,195 @@ int hinic5_set_host_migrate_enable(void *hwdev, u8 host_id, bool enable);
* @param host_id: get host id
* @param slave_en-zero: migrte enable ptr
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_host_migrate_enable(void *hwdev, u8 host_id, u8 *migrate_en);
/**
- * @brief judge whether it is from host
- * @param hwdev hardware device pointer
+ * @brief 判断是否是从主机
+ * @param hwdev 硬件设备指针
*
- * @return whether it is from host
- * @retval true means yes
- * @retval false means no
+ * @return 是否是从主机
+ * @retval true表示是
+ * @retval false表示不是
*/
bool hinic5_is_slave_host(void *hwdev);
/**
- * @brief judge whether it is master host
- * @param hwdev hardware device pointer
+ * @brief 判断是否是主主机
+ * @param hwdev 硬件设备指针
*
- * @return whether it is master host
- * @retval true means yes
- * @retval false means no
+ * @return 是否是主主机
+ * @retval true表示是
+ * @retval false表示不是
*/
bool hinic5_is_master_host(void *hwdev);
/**
- * @brief judge whether it is multi-core device
- * @param hwdev device handle
+ * @brief 判断是否是多核心设备
+ * @param hwdev 设备句柄
*
- * @return whether it is multi-core device
- * @retval true yes
- * @retval false no
+ * @return 是不是多核心设备
+ * @retval true 是
+ * @retval false 不是
*/
bool hinic5_is_multi_bm(void *hwdev);
/**
- * @brief set plugin service bitmap
- * @param hwdev hardware device
- * @param srv_type service type
- * @param func_id function ID
- * @param attach_en enable or not
+ * @brief 设置插件服务位图
+ * @param hwdev 硬件设备
+ * @param srv_type 服务类型
+ * @param func_id 功能ID
+ * @param attach_en 是否启用
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 attach_en);
+int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 attach_en);
/**
- * @brief get plugin service bitmap
- * @param hwdev hardware device
- * @param srv_type service type
- * @param func_id function ID
- * @param attach_en whether plugin service is enabled
+ * @brief 获取插件服务位图
+ * @param hwdev 硬件设备
+ * @param srv_type 服务类型
+ * @param func_id 功能ID
+ * @param attach_en 是否启用插件服务
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 *attach_en);
+int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 *attach_en);
/**
- * @brief get device capability
- * @param hwdev device handle
+ * @brief 获取设备能力
+ * @param hwdev 设备句柄
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_get_dev_cap(void *hwdev);
/**
- * @brief get whether it is HTN device
- * @param hwdev device handle
+ * @brief 获取是否是HTN设备
+ * @param hwdev 设备句柄
*
- * @return whether it is HTN device
- * @retval true: yes
- * @retval false: no
+ * @return 是不是HTN设备
+ * @retval true: 是
+ * @retval false: 不是
*/
bool hinic5_support_htn(void *hwdev);
/**
- * @brief get whether current VF runs independently
- * @param hwdev device handle
+ * @brief 获取当前 VF 是否独立运行
+ * @param hwdev 设备句柄
*
- * @details when VF depends on PF, its management messages need to be sent to PF instead of Mgmt
- * @note this configuration is meaningless for PF
+ * @details VF 依赖 PF 运行时,其管理面消息需要发送给 PF 而不是 Mgmt
+ * @note 该配置对于 PF 无意义
*
- * @return whether VF runs independently
+ * @return VF 是否独立运行
*/
bool hinic5_is_vf_isolation(void *hwdev);
/**
- * @brief set heartbeat detection period and link_down check count
- * @param hwdev: device handle
- * @param heartbeat_period: heartbeat detection period
- * @param linkdown_threshold: link_down check count
+ * @brief 设置心跳检测周期和link_down检查次数
+ * @param hwdev:设备句柄
+ * @param heartbeat_period:心跳检测周期
+ * @param linkdown_threshold:link_down检查次数
*
- * @details when hwdev is NULL or both heartbeat period and link down count are 0, return -EINVAL;
- * when heartbeat period is not 0, update heartbeat period;
- * when link down count is not 0, update link down count;
+ * @details hwdev为空或心跳检测周期和断链检测次数均为0时,返回-EINVAL;
+ * 当心跳检测周期不为0时,更新心跳检测周期;
+ * 当断链检测次数不为0时,更新断链检测次数;
*
- * @attention supports updating only period/count, set not updated parameters to 0;
+ * @attention 支持仅更新检测周期/检测次数,不更新的参数直接置0即可;
*
- * @return success or failure
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hinic5_set_heartbeat_period_and_linkdown_cnt(void *hwdev, u32 heartbeat_period, u32 linkdown_threshold);
+int hinic5_set_heartbeat_period_and_linkdown_cnt(void *hwdev,
+ u32 heartbeat_period,
+ u32 linkdown_threshold);
/**
- * @brief set/get dcb state
- * @param hwdev[in]: device handle
- * @param op[in]: operation type, HISDK5_DCB_STATE_GET(get)/HISDK5_DCB_STATE_SET(set)
- * @param dcb_state[in]: dcb state that business driver writes to sdk
- * [out]: dcb state obtained from sdk
+ * @brief 设置/获取dcb state
+ * @param hwdev[in]:设备句柄
+ * @param op[in]:操作类型,HISDK5_DCB_STATE_GET(获取)/HISDK5_DCB_STATE_SET(设置)
+ * @param dcb_state[in]:存储业务驱动要写入到sdk的dcb state
+ * [out]:存储从sdk中获取的dcb state
*
- * @details op == HISDK5_DCB_STATE_GET, get scb state from sdk and save to business passed dcb state pointer memory, return to upper business;
- * op == HISDK5_DCB_STATE_SET, save business passed dcb state to sdk;
+ * @details op == HISDK5_DCB_STATE_GET,从sdk中获取scb state保存到业务传入的dcb state指针对应的内存中,返回给上层业务;
+ * op == HISDK5_DCB_STATE_SET,将业务传入的dcb state保存到sdk中;
*
- * @attention in struct hisdk5_dcb_state, when dcb_on == 0(dcb off), only default_cos is valid;
- * when dcb_on != 0(dcb on), all parameters are valid, can check current priority mode according to trust,
- * can check corresponding mapping according to pcp2cos/dscp2cos;
+ * @attention 在struct hisdk5_dcb_state中,当dcb_on == 0(dcb off)时,仅default_cos有效;
+ * 当dcb_on != 0(dcb on)时,参数均有效,可根据trust查看当前优先级模式,
+ * 根据pcp2cos/dscp2cos查看对应的映射关系;
*
- * @return success or failure
- * @retval 0: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval 0: 成功
+ * @retval 非0: 失败
*/
-int hinic5_dcb_state_op(void *hwdev, enum hisdk5_dcb_state_op op, struct hisdk5_dcb_state *dcb_state);
+int hinic5_dcb_state_op(void *hwdev, enum hisdk5_dcb_state_op op,
+ struct hisdk5_dcb_state *dcb_state);
/**
- * @brief get device port info
+ * @brief 获取设备端口速率
*
* @param hwdev: device pointer to hwdev
* @param port_info: port info
* @param channel: channel id
- * @return: command execution result.
- * @retval 0 success
- * @retval non-zero failure
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_get_port_info(void *hwdev, struct mag_port_info *port_info, u16 channel);
+int hinic5_get_port_info(void *hwdev, struct mag_port_info *port_info,
+ u16 channel);
/**
- * @brief get device port speed
+ * @brief 获取设备端口速率
*
* @param hwdev device pointer to hwdev
- * @param speed output port speed info
- * @param channel channel id, mailbox send channel id
- * @details query device corresponding port, send mailbox message to MPU to get port speed
- * @attention: function involves sending mailbox messages which will sleep, prohibit calling in interrupt context or other processes that do not allow sleeping
- * @return: device port speed get success or failure
- * @retval 0 success
- * @retval non-zero failure
+ * @param speed 输出端口速率信息
+ * @param channel channel id, mailbox发送使用的channel id
+ * @details 通过查询设备对应端口,发送mailbox消息给MPU获取端口速率
+ * @attention: 函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
+ * @return: 设备端口速率获取返回成功或者失败
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_get_speed(void *hwdev, enum mag_cmd_port_speed *speed, u16 channel);
+/**
+ * @brief 获取设备指针
+ *
+ * @param hwdev device pointer to hwdev
+ * @return 设备指针
+ */
+struct device *hinic5_get_device(void *hwdev);
+
+/**
+ * @brief 获取设备总线类型
+ *
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] type 设备总线类型
+ *
+ * @return 0 on success, non-zero otherwise.
+ */
+int hinic5_get_bus_type(void *hwdev, enum hinic5_dev_type *type);
+
+/**
+ * @brief 获取chip ip
+ *
+ * @param[in] hwdev device pointer to hwdev
+ * @param[out] chip_node_id 输出chip_node_id
+ *
+ * @return 0 on success, non-zero otherwise.
+ */
+int hinic5_get_chip_node_id_by_hwdev(void *hwdev, u64 *chip_node_id);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm.h
deleted file mode 100644
index 5a016a34d..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm.h
+++ /dev/null
@@ -1,913 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hinic5_cqm.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_HINIC5_CQM_H
-#define HINIC5_HINIC5_CQM_H
-
-#include <linux/types.h>
-#include <linux/completion.h>
-
-#include "hinic5_crm.h"
-#include "hinic5_hinic5_cqm_adpt.h"
-#include "hinic5_hinic5_vram_api.h"
-
-#define HINIC5_CQM_SUCCESS 0 /* Success result code */
-#define HINIC5_CQM_FAIL (-1) /* Failure result code */
-#define HINIC5_CQM_CONTINUE 1 /* Continue result code */
-
-#define HINIC5_CQM_WQE_WF_NORMAL 0 /* Normal WQE Format */
-#define HINIC5_CQM_WQE_WF_LINK 1 /* Link WQE format */
-
-#define HINIC5_CQM_QUEUE_LINK_MODE 0 /* Linked queue mode */
-#define HINIC5_CQM_QUEUE_RING_MODE 1 /* Ring queue mode */
-#define HINIC5_CQM_QUEUE_TOE_SRQ_LINK_MODE 2 /* SRQ queue mode */
-#define HINIC5_CQM_QUEUE_RDMA_QUEUE_MODE 3 /* RDMA queue mode */
-
-/**
- * @brief Link WQE common structure
- */
-typedef struct tag_hinic5_cqm_linkwqe {
- u32 rsv1 : 14; /* Reserved */
- u32 wf : 1; /* WQE format */
- u32 rsv2 : 14; /* Reserved */
- u32 ctrlsl : 2; /* Length of the control segment */
- u32 o : 1; /* Owner bit */
-
- u32 rsv3 : 31; /* Reserved */
- u32 lp : 1; /* Loop Back valid */
-
- u32 next_page_gpa_h; /* High 32 bits of next page physical address, used by chip */
- u32 next_page_gpa_l; /* Low 32 bits of next page physical address, used by chip */
-
- u32 next_buffer_addr_h; /* High 32 bits of next page virtual address, used by driver */
- u32 next_buffer_addr_l; /* Low 32 bits of next page virtual address, used by driver */
-} hinic5_cqm_linkwqe_s;
-
-/**
- * @brief SRQ Link WQE structure
- * @note WQE size must not exceed normal RQE size
- */
-typedef struct tag_hinic5_cqm_srq_linkwqe {
- hinic5_cqm_linkwqe_s linkwqe; /* Link WQE common data */
- u32 current_buffer_gpa_h; /* High 32 bits of current page physical address,
- * used when driver releases container and unmaps
- */
- u32 current_buffer_gpa_l; /* Low 32 bits of current page physical address,
- * used when driver releases container and unmaps
- */
- u32 current_buffer_addr_h; /* High 32 bits of current page virtual address,
- * used when driver releases container
- */
- u32 current_buffer_addr_l; /* Low 32 bits of current page virtual address,
- * used when driver releases container
- */
-
- u32 fast_link_page_addr_h; /* High 32 bits of fastlink page virtual address where container resides,
- * used when driver releases fastlink
- */
- u32 fast_link_page_addr_l; /* Low 32 bits of fastlink page virtual address where container resides,
- * used when driver releases fastlink
- */
-
- u32 fixed_next_buffer_addr_h; /* High 32 bits of next container virtual address,
- * for driver resource release, cannot be modified by driver
- */
- u32 fixed_next_buffer_addr_l; /* Low 32 bits of next container virtual address,
- * for driver resource release, cannot be modified by driver
- */
-} hinic5_cqm_srq_linkwqe_s;
-
-/**
- * @brief First 64B of standard 128B WQE
- */
-typedef union tag_hinic5_cqm_linkwqe_first64B {
- hinic5_cqm_linkwqe_s basic_linkwqe; /* Link WQE common data */
- hinic5_cqm_srq_linkwqe_s toe_srq_linkwqe; /* SRQ linkwqe structure */
- u32 value[16]; /* Reserved fields */
-} hinic5_cqm_linkwqe_first64B_s;
-
-/**
- * @brief Second 64B of standard 128B WQE
- */
-typedef struct tag_hinic5_cqm_linkwqe_second64B {
- u32 rsvd0[4]; /* First 16B, Reserved */
- u32 rsvd1[4]; /* Second 16B, Reserved */
-
- union {
- struct {
- u32 rsvd0[3]; /* Reserved */
- u32 rsvd1 : 29; /* Reserved */
- u32 toe_o : 1; /* TOE owner bit */
- u32 resvd2 : 2; /* Reserved */
- } bs;
- u32 value[4];
- } third_16B; /* Third 16B */
-
- union {
- struct {
- u32 rsvd0[2]; /* Reserved */
- u32 rsvd1 : 31; /* Reserved */
- u32 ifoe_o : 1; /* IFoE onwer bit */
- u32 rsvd2; /* Reserved */
- } bs;
- u32 value[4];
- } forth_16B; /* Fourth 16B */
-} hinic5_cqm_linkwqe_second64B_s;
-
-/**
- * @brief Standard 128B WQE structure
- */
-typedef struct tag_hinic5_cqm_linkwqe_128B {
- hinic5_cqm_linkwqe_first64B_s first64B; /* First 64B of standard 128B WQE */
- hinic5_cqm_linkwqe_second64B_s second64B; /* Second 64B of standard 128B WQE */
-} hinic5_cqm_linkwqe_128B_s;
-
-/**
- * @brief AEQ type definition
- */
-typedef enum {
- HINIC5_CQM_AEQ_BASE_T_NIC = 0, /* NIC: 15 events 0~14 */
- HINIC5_CQM_AEQ_BASE_T_DMMU = 15, /* DMMU: 1 event 15 */
- HINIC5_CQM_AEQ_BASE_T_ROCE = 16, /* ROCE: 32 events 16~47 */
- HINIC5_CQM_AEQ_BASE_T_FC = 48, /* FC: 8 events 48~55 */
- HINIC5_CQM_AEQ_BASE_T_IOE = 56, /* IOE: 8 events 56~63 */
- HINIC5_CQM_AEQ_BASE_T_TOE = 64, /* TOE: 16 events 64~79 */
- HINIC5_CQM_AEQ_BASE_T_UB = 80, /* UB: 16 events 80~95 */
- HINIC5_CQM_AEQ_BASE_T_VBS = 96, /* VBS: 16 events 96~111 */
- HINIC5_CQM_AEQ_BASE_T_IPSEC = 112, /* IPSEC: 16 events 112~127 */
- HINIC5_CQM_AEQ_BASE_T_MAX = 128 /* Maximum 128 event types */
-} hinic5_cqm_aeq_event_type_e;
-
-/**
- * @brief HINIC5_CQM service extension description
- */
-typedef struct tag_service_register_template {
- u32 service_type; /* Service type */
- u32 srq_ctx_size; /* SRQ context size */
- u32 scq_ctx_size; /* SCQ context size */
- void *service_handle; /* Pointer passed to service driver in ceq/aeq callback */
- /* CEQ callback: shared CQ */
- void (*shared_cq_ceq_callback)(void *service_handle, u32 cqn, void *cq_priv);
- /* CEQ callback: embedded CQ */
- void (*embedded_cq_ceq_callback)(void *service_handle, u32 xid, void *qpc_priv);
- /* CEQ callback: no CQ */
- void (*no_cq_ceq_callback)(void *service_handle, u32 xid, u32 qid, void *qpc_priv);
- u8 (*aeq_level_callback)(void *service_handle, u8 event_type, u8 *val); /* AEQ level callback */
- void (*aeq_callback)(void *service_handle, u8 event_type, u8 *val); /* AEQ callback */
-} service_register_template_s;
-
-/**
- * @brief HINIC5_CQM object type
- */
-typedef enum hinic5_cqm_object_type {
- HINIC5_CQM_OBJECT_ROOT_CTX = 0, /* Root context. Reserved for future root ctx management */
- HINIC5_CQM_OBJECT_SERVICE_CTX, /* QPC, Service context, connection management object */
- HINIC5_CQM_OBJECT_MPT, /* RDMA Memory Protection Table */
-
- HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_RQ = 10, /* Non-RDMA RQ, managed by LINKWQE */
- HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_SQ, /* Non-RDMA SQ, managed by LINKWQE */
- HINIC5_CQM_OBJECT_NONRDMA_SRQ, /* Non-RDMA SRQ, managed by MTT,
- * but HINIC5_CQM allocates MTT itself
- */
- HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_CQ, /* Non-RDMA embedded CQ, managed by LINKWQE */
- HINIC5_CQM_OBJECT_NONRDMA_SCQ, /* Non-RDMA SCQ, managed by LINKWQE */
-
- HINIC5_CQM_OBJECT_RESV = 20, /* Reserved */
-
- HINIC5_CQM_OBJECT_RDMA_QP = 30, /* RDMA Queue Pair */
- HINIC5_CQM_OBJECT_RDMA_SRQ, /* RDMA Shared Receive Queue */
- HINIC5_CQM_OBJECT_RDMA_SCQ, /* RDMA Shared Completion Queue */
-
- HINIC5_CQM_OBJECT_MTT = 50, /* RDMA Memory Translation Table */
- HINIC5_CQM_OBJECT_RDMARC, /* RDMA Reliable Connection */
-} hinic5_cqm_object_type_e;
-
-/**
- * @brief BITMAP table allocation failure return value
- */
-#define HINIC5_CQM_INDEX_INVALID ~(0U)
-
-/**
- * @brief New field definition compatible with XID=0xFFFFFFFF default XID allocation rule. Macro naming is low 3bit comparison bits
- */
-#define HINIC5_CQM_XID_LOW_BIT_1_1_1 0x0 /* mask is 0x7 */
-#define HINIC5_CQM_XID_LOW_BIT_0_1_1 0x4 /* mask is 0x3 */
-#define HINIC5_CQM_XID_LOW_BIT_0_1_0 0x5 /* mask is 0x2 */
-#define HINIC5_CQM_XID_LOW_BIT_0_0_1 0x6 /* mask is 0x1 */
-#define HINIC5_CQM_XID_LOW_BIT_NONE 0x7 /* mask is 0x0 */
-#define HINIC5_CQM_XID_SEARCH_RANGE 0x0
-#define HINIC5_CQM_XID_SEARCH_ALL 0x1
-
-#define HINIC5_CQM_XID_SEARCH_MODE_SHIFT 27
-#define HINIC5_CQM_XID_LB_MODE_SHIFT 24
-#define HINIC5_CQM_XID_LOW_BITS_SHIFT 21
-#define HINIC5_CQM_XID_SEARCH_MODE_MASK 0x1
-#define HINIC5_CQM_XID_LB_MODE_MASK 0x7
-#define HINIC5_CQM_XID_LOW_BITS_MASK 0x7
-#define HINIC5_CQM_DYNAMIC_XID_MASK 0x1FFFFF
-
-/**
- * @brief Construct XID
- * @param[in] search_mode Search mode
- * @param[in] lb_mode Load balance mode
- * @param[in] xid_low Low 2 bits of XID
- *
- * @details search_mode: 0---search in specified XID range [bp_start, bp_end); 1---search in entire dynamic area
- * lb_mode:
- * 0--When dynamically allocating XID, select xid[2:0]=xid_low[2:0]
- * 4--When dynamically allocating XID, select xid[1:0]=xid_low[1:0]
- * 5--When dynamically allocating XID, select xid[0]=xid_low[0]
- * 6--When dynamically allocating XID, select xid[1]=xid_low[1]
- * 7--All xids can be allocated
- * xid_low: xid_low[2:0] used for matching
- *
- * @return Constructed XID
- */
-#define HINIC5_CQM_DYNAMIC_XID_MOD(search_mode, lb_mode, xid_low) \
- ((((search_mode) & HINIC5_CQM_XID_SEARCH_MODE_MASK) << HINIC5_CQM_XID_SEARCH_MODE_SHIFT) | \
- (((lb_mode) & HINIC5_CQM_XID_LB_MODE_MASK) << HINIC5_CQM_XID_LB_MODE_SHIFT) | \
- (((xid_low) & HINIC5_CQM_XID_LOW_BITS_MASK) << HINIC5_CQM_XID_LOW_BITS_SHIFT) | \
- HINIC5_CQM_DYNAMIC_XID_MASK)
-
-#define HINIC5_CQM_RDMA_Q_ROOM_1 (1) /* First Q buffer space for ROCE Q buffer resize */
-#define HINIC5_CQM_RDMA_Q_ROOM_2 (2) /* Second Q buffer space for ROCE Q buffer resize */
-
-#define HINIC5_CQM_HARDWARE_DOORBELL (1) /* Current Q doorbell mode: hardware doorbell */
-#define HINIC5_CQM_SOFTWARE_DOORBELL (2) /* Current Q doorbell mode: software doorbell */
-#define HINIC5_CQM_SECURE_BUFFER_EN (1) /* Flag indicating buffer is allocated from secure memory */
-
-/**
- * @brief HINIC5_CQM buffer single node structure
- */
-typedef struct tag_hinic5_cqm_buf_list {
- void *va; /* Virtual address */
- dma_addr_t pa; /* Physical address */
- u32 refcount; /* Buffer reference count, for internal buffer management */
-} hinic5_cqm_buf_list_s;
-
-/**
- * @brief HINIC5_CQM buffer single node structure, for WIN adaptation
- */
-struct huge_buf_addr {
- void *huge_buf_vaddr; /* Virtual address */
- dma_addr_t huge_buf_paddr; /* Physical address */
- u32 huge_buf_size; /* Single node buffer size */
-};
-
-/**
- * @brief HINIC5_CQM buffers management structure
- */
-typedef struct tag_hinic5_cqm_buf {
- hinic5_cqm_buf_list_s *buf_list; /* Buffer linked list */
- hinic5_cqm_buf_list_s direct; /* Re-mapped buf_list as contiguous virtual address, only va member is valid */
- u32 page_number; /* Total physical page number */
- u32 buf_number; /* Buffer linked list length */
- u32 buf_size; /* Buffer size */
-#ifdef __WIN__
- struct huge_buf_addr *bufs_addr; /* Buffer linked list */
- u32 huge_buf_number; /* Buffer linked list node count */
-#endif
- u32 secure_mem_flag; /* Secure memory flag, default 0 (not using secure memory) */
- struct hinic5_vram_buf_info buf_info;
-} hinic5_cqm_buf_s;
-
-/**
- * @brief HINIC5_CQM object structure, abstraction of context/queue/table
- */
-typedef struct tag_hinic5_cqm_object {
- u32 service_type; /* Service type */
- u32 object_type; /* Object type, such as context, queue, mpt, mtt, etc. */
- u32 object_size; /* Object size,
- For non-RDMA queues, this is queue depth;
- For queue/ctx/MPT, unit is Byte;
- For MTT/RDMARC, unit is entry count;
- For container, unit is container count */
- atomic_t refcount; /* Reference count */
- struct completion free; /* Free completion */
- void *hinic5_cqm_handle; /* hinic5_cqm_handle */
-} hinic5_cqm_object_s;
-
-/**
- * @brief QPC/MPT object
- */
-typedef struct tag_hinic5_cqm_qpc_mpt {
- hinic5_cqm_object_s object; /* Object base class */
- u32 xid; /* XID.
- When xid[20:0] < 1M, indicates statically allocated xid;
- When xid[20:0] = all 1s, indicates dynamically allocated;
- xid[22:21] specifies low 2 bits;
- xid[24:23] is lb_mode;
- xid[25] is search_mode */
- dma_addr_t paddr; /* QPC/MTT memory physical address */
- void *priv; /* Service driver's private info for this object */
- u8 *vaddr; /* QPC/MTT memory virtual address */
-} hinic5_cqm_qpc_mpt_s;
-
-/**
- * @brief Queue header structure
- */
-typedef struct tag_hinic5_cqm_queue_header {
- u64 doorbell_record; /* SQ/RQ doorbell content */
- u64 ci_record; /* CQ doorbell content */
- u64 rsv1; /* Custom area for driver and firmware information exchange */
- u64 rsv2; /* Custom area for driver and firmware information exchange */
-} hinic5_cqm_queue_header_s;
-
-/**
- * @brief Queue management structure
- * @details For non-RDMA services, embedded queues use linkwqe management, SRQ and SCQ use MTT management, MTT is allocated by HINIC5_CQM;
- * For RDMA services, queues use MTT management
- */
-typedef struct tag_hinic5_cqm_queue {
- hinic5_cqm_object_s object; /* Object base class */
- u32 index; /* Embedded queues and QP have no index, SRQ and SCQ have */
- void *priv; /* Service driver's private info for this object */
- u32 current_q_doorbell; /* Current queue doorbell type, roce QP uses both HW/SW */
- u32 current_q_room; /* roce: currently valid room buf */
- hinic5_cqm_buf_s q_room_buf_1; /* nonrdma: can only select q_room_buf_1 as q_room_buf */
- hinic5_cqm_buf_s q_room_buf_2; /* RDMA CQ will reallocate queue room size */
- hinic5_cqm_queue_header_s *q_header_vaddr; /* Queue header virtual address */
- dma_addr_t q_header_paddr; /* Queue header physical address */
- u8 *q_ctx_vaddr; /* SRQ and SCQ ctx virtual address */
- dma_addr_t q_ctx_paddr; /* SRQ and SCQ ctx physical address */
- u32 valid_wqe_num; /* Number of validWQEs created successfully */
- u8 *tail_container; /* SRQ container tail pointer */
- u8 *head_container; /* SRQ container head pointer */
- u8 queue_link_mode; /* Queue link mode determined at creation: link, ring, etc. */
-} hinic5_cqm_queue_s;
-
-/**
- * @brief MTT/RDMARC management structure
- */
-typedef struct tag_hinic5_cqm_mtt_rdmarc {
- hinic5_cqm_object_s object; /* Object base class */
- u32 index_base; /* index_base */
- u32 index_number; /* index_number */
- u8 *vaddr; /* Buffer virtual address */
-} hinic5_cqm_mtt_rdmarc_s;
-
-/**
- * @brief Command buffer structure
- */
-typedef struct tag_hinic5_cqm_cmd_buf {
- void *buf; /* Command buffer virtual address */
- dma_addr_t dma; /* Command buffer physical address */
- u16 size; /* Command buffer size */
-} hinic5_cqm_cmd_buf_s;
-
-/**
- * @brief ACK sending method definition
- */
-typedef enum {
- HINIC5_CQM_CMD_ACK_TYPE_CMDQ = 0, /* ACK writeback to cmdq */
- HINIC5_CQM_CMD_ACK_TYPE_SHARE_CQN = 1, /* ACK reported via root ctx SCQ */
- HINIC5_CQM_CMD_ACK_TYPE_APP_CQN = 2 /* ACK reported via service SCQ */
-} hinic5_cqm_cmd_ack_type_e;
-
-/**
- * @brief HINIC5_CQM initialization
- * @param[in] ex_handle Device handle
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_init(void *ex_handle);
-
-/**
- * @brief HINIC5_CQM uninitialization
- * @param[in] ex_handle Device handle
- */
-void hinic5_cqm3_uninit(void *ex_handle);
-
-/**
- * @brief HINIC5_CQM initialize specified Fake VF
- * @param[in] ex_handle Device handle
- * @param[in] vf_id Function id to initialize
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- * @retval -EINVAL Invalid argument
- */
-int hinic5_cqm3_init_fake_vf(void *ex_handle, u32 vf_id);
-
-/**
- * @brief Register service extension capability
- * @param[in] ex_handle Device handle
- * @param[in] service_template Service extension description
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_service_register(void *ex_handle, service_register_template_s *service_template);
-
-/**
- * @brief Unregister service extension capability
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- */
-void hinic5_cqm3_service_unregister(void *ex_handle, u32 service_type);
-
-/**
- * @brief Declare number of Fake VFs managed by device
- * @param[in] ex_handle Device handle
- * @param[in] fake_vf_num_cfg Fake VF number, must not exceed device maximum
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
-
-/**
- * @brief Create FC SRQ
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] wqe_number WQE number
- * @param[in] wqe_size WQE size
- * @param[in] object_priv Object private data pointer
- *
- * @details Number of validWQEs in queue must meet the specified WQE count.
- * Since linkwqe can only be placed at page tail, actual valid count exceeds requirement, service needs to be informed of extra created count
- *
- * @return Queue structure pointer
- */
-hinic5_cqm_queue_s *hinic5_cqm3_object_fc_srq_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-
-/**
- * @brief Create RQ
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] init_rq_num Container number
- * @param[in] container_size Container size
- * @param[in] wqe_size WQE size
- * @param[in] object_priv Object private data pointer
- *
- * @details RQ queue creation when using SRQ
- *
- * @return Queue structure pointer
- */
-hinic5_cqm_queue_s *hinic5_cqm3_object_recv_queue_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 init_rq_num, u32 container_size,
- u32 wqe_size, void *object_priv);
-
-/**
- * @brief Create TOE SRQ
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] container_number Container number
- * @param[in] container_size Container size
- * @param[in] wqe_size WQE size
- *
- * @return Queue structure pointer
- */
-hinic5_cqm_queue_s *hinic5_cqm3_object_share_recv_queue_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 container_number,
- u32 container_size, u32 wqe_size);
-
-/**
- * @brief Create QPC/MPT
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] object_size Object size in Byte
- * @param[in] object_priv Object private data pointer
- * @param[in] index QPN to reserve based on this value, fill HINIC5_CQM_INDEX_INVALID for auto allocation
- * @param[in] bitmap_start Start index for range XID allocation
- * @param[in] bitmap_end End index for range XID allocation
- *
- * @attention This interface may sleep
- *
- * @return QPC/MPT structure pointer
- */
-hinic5_cqm_qpc_mpt_s *hinic5_cqm3_object_qpc_mpt_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 object_size, void *object_priv,
- u32 index, u32 bitmap_start, u32 bitmap_end);
-
-/**
- * @brief Create non-RDMA service queue
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] wqe_number Number of linkWQEs included
- * @param[in] wqe_size Fixed size, value is 2^n
- * @param[in] object_priv Object private data pointer
- *
- * @attention This interface may sleep
- *
- * @return Queue structure pointer
- */
-hinic5_cqm_queue_s *hinic5_cqm3_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-
-/**
- * @brief Create RDMA service queue
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] object_size Object size
- * @param[in] object_priv Object private data pointer
- * @param[in] room_header_alloc Whether to allocate queue room and header space
- * @param[in] xid QPN to reserve based on this value, fill HINIC5_CQM_INDEX_INVALID for auto allocation
- * @param[in] bitmap_start Start index for range XID allocation
- * @param[in] bitmap_end End index for range XID allocation
- *
- * @attention This interface may sleep
- *
- * @return Queue structure pointer
- */
-hinic5_cqm_queue_s *hinic5_cqm3_object_rdma_queue_create(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 object_size, void *object_priv,
- bool room_header_alloc, u32 xid,
- u32 bitmap_start, u32 bitmap_end);
-
-/**
- * @brief Create RDMA service MTT/RDMARC
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] object_type Object type
- * @param[in] index_base Starting index number
- * @param[in] index_number Index count
- *
- * @return MTT/RDMARC structure pointer
- */
-hinic5_cqm_mtt_rdmarc_s *hinic5_cqm3_object_rdma_table_get(void *ex_handle, u32 service_type,
- hinic5_cqm_object_type_e object_type,
- u32 index_base, u32 index_number);
-
-/**
- * @brief Allocate a cmd buffer
- * @param[in] ex_handle Device handle
- *
- * @attention Buffer size is fixed at 2K, buffer content is not cleared, service needs to clear it
- *
- * @return Cmd buffer pointer
- */
-hinic5_cqm_cmd_buf_s *hinic5_cqm3_cmd_alloc(void *ex_handle);
-
-/**
- * @brief Free a cmd buffer
- * @param[in] ex_handle Device handle
- * @param[in] cmd_buf Cmd buffer pointer to free
- */
-void hinic5_cqm3_cmd_free(void *ex_handle, hinic5_cqm_cmd_buf_s *cmd_buf);
-
-/**
- * @brief Send cmd
- * @param[in] ex_handle Device handle
- * @param[in] mod Module
- * @param[in] cmd Command code
- * @param[in] buf_in Input command buffer
- * @param[out] buf_out Output command buffer
- * @param[out] out_param Udata (user data) returned by command
- * @param[in] timeout Command timeout in ms
- * @param[in] channel Caller channel id
- *
- * @details Send a cmdq cmd in box mode
- *
- * @attention This interface will block on completion, causing sleep
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_send_cmd_box(void *ex_handle, u8 mod, u8 cmd,
- hinic5_cqm_cmd_buf_s *buf_in, hinic5_cqm_cmd_buf_s *buf_out,
- u64 *out_param, u32 timeout, u16 channel);
-
-/**
- * @brief Send cmd
- * @param[in] ex_handle Device handle
- * @param[in] mod Module
- * @param[in] cmd Command code
- * @param[in] cos_id CMDQ queue
- * @param[in] buf_in Input command buffer
- * @param[out] buf_out Output command buffer
- * @param[out] out_param Udata (user data) returned by command
- * @param[in] timeout Command timeout in ms
- * @param[in] channel Caller channel id
- *
- * @details Send a cmdq cmd in box mode with specified CMDQ queue
- *
- * @attention This interface will block on completion, causing sleep
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
- hinic5_cqm_cmd_buf_s *buf_in, hinic5_cqm_cmd_buf_s *buf_out,
- u64 *out_param, u32 timeout, u16 channel);
-
-/**
- * @brief Send cmd
- * @param[in] ex_handle Device handle
- * @param[in] mod Module
- * @param[in] cmd Command code
- * @param[in] buf_in Input command buffer
- * @param[out] out_param Udata (user data) returned by command
- * @param[in] timeout Command timeout in ms
- * @param[in] channel Caller channel id
- *
- * @details Send a cmdq cmd in imm mode
- *
- * @attention This interface will block on completion, causing sleep
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd,
- hinic5_cqm_cmd_buf_s *buf_in,
- u64 *out_param, u32 timeout, u16 channel);
-
-/**
- * @brief Allocate hardware doorbell and dwqe
- * @param[in] ex_handle Device handle
- * @param[out] db_addr Doorbell physical address
- * @param[out] dwqe_addr Dwqe physical address
- *
- * @details Allocate one page of hardware doorbell and dwqe with same index, both are physical addresses, each function has maximum 1K
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_db_addr_alloc(void *ex_handle, void __iomem **db_addr, void __iomem **dwqe_addr);
-
-/**
- * @brief Free hardware doorbell and dwqe
- * @param[in] ex_handle Device handle
- * @param[in] db_addr Doorbell physical address
- * @param[in] dwqe_addr Dwqe physical address
- */
-void hinic5_cqm3_db_addr_free(void *ex_handle, const void __iomem *db_addr, void __iomem *dwqe_addr);
-
-/**
- * @brief Get hardware doorbell virtual address
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- *
- * @return Doorbell virtual address
- */
-
-void *hinic5_cqm3_get_db_addr(void *ex_handle, u32 service_type);
-
-/**
- * @brief Get hardware doorbell physical address
- * @param[in] ex_handle Device handle
- * @param[out] addr Pointer to store doorbell physical address
- * @param[in] service_type Service type
- *
- * @details Get hardware doorbell physical address
- *
- * @return Doorbell address
- */
-s32 hinic5_cqm3_get_hardware_db_addr(void *ex_handle, u64 *addr, enum hinic5_service_type service_type);
-
-/**
- * @brief Ring a hardware DB
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] db_count PI[7:0] in doorbell that exceeds 64b
- * @param[in] db The content of hardware doorbell
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db);
-
-/**
- * @brief Ring a direct wqe hardware DB to chip
- * @param[in] ex_handle Device handle
- * @param[in] service_type Service type
- * @param[in] db_count The bit[7:0] of PI can't be store in 64-bit db
- * @param[in] direct_wqe The content of direct_wqe
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count, void *direct_wqe);
-
-/**
- * @brief Ring a software DB
- * @param[in] ex_handle device handle
- * @param[in] object Object pointer
- * @param[in] db_record The content of software doorbell
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_ring_software_db(hinic5_cqm_object_s *object, u64 db_record);
-
-/**
- * @brief Bloom filter increase reference count
- * @param[in] ex_handle Device handle
- * @param[in] func_id Function id
- * @param[in] id Bloom filter id
- *
- * @details Set API when transitioning from 0 -> 1
- *
- * @attention This interface may sleep
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id);
-
-/**
- * @brief Bloom filter decrease reference count
- * @param[in] ex_handle Device handle
- * @param[in] func_id Function id
- * @param[in] id Bloom filter id
- *
- * @details Clear API when transitioning to 0
- *
- * @attention This interface may sleep
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id);
-
-/**
- * @brief Get SMF Timer spoke list base address
- * @param[in] ex_handle Device handle
- *
- * @return Virtual address
- */
-void *hinic5_cqm3_timer_base(void *ex_handle);
-
-/**
- * @brief Clear SMF Timer spoke list
- * @param[in] ex_handle Device handle
- * @param[in] function_id Function id
- */
-void hinic5_cqm3_function_timer_clear(void *ex_handle, u32 function_id);
-
-/**
- * @brief Clear hash buffer
- * @param[in] ex_handle Device handle
- * @param[in] global_funcid Function id
- */
-void hinic5_cqm3_function_hash_buf_clear(void *ex_handle, s32 global_funcid);
-
-/**
- * @brief SRQ allocate new container, ready for linking after creation
- * @param[in] common Queue structure pointer
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_object_share_recv_queue_add_container(hinic5_cqm_queue_s *common);
-
-/**
- * @brief SRQ allocate new container, not linked after creation, service completes linking
- * @param[in] common Queue structure pointer
- * @param[out] container_addr Returned container address
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_object_srq_add_container_free(hinic5_cqm_queue_s *common, u8 **container_addr);
-
-/**
- * @brief Get object by index
- * @param[in] ex_handle Device handle
- * @param[in] object_type Object type
- * @param[in] index Index supports qpn, mptn, scqn, srqn
- * @param[in] bh Whether to disable interrupt bottom half
- *
- * @return Object pointer
- */
-hinic5_cqm_object_s *hinic5_cqm3_object_get(void *ex_handle, hinic5_cqm_object_type_e object_type,
- u32 index, bool bh);
-
-/**
- * @brief Put (release) object
- * @param[in] object Object pointer
- */
-void hinic5_cqm3_object_put(hinic5_cqm_object_s *object);
-
-/**
- * @brief Delete object
- * @param[in] object Object pointer
- *
- * @details Delete created object, this function will sleep until all operations on this object are complete before returning
- *
- * @attention This interface may sleep
- */
-void hinic5_cqm3_object_delete(hinic5_cqm_object_s *object);
-
-/**
- * @brief Get function ID that owns the object
- * @param[in] object Object pointer
- *
- * @return
- * @retval >=0 function ID
- * @retval -1 failure
- */
-s32 hinic5_cqm3_object_funcid(hinic5_cqm_object_s *object);
-
-/**
- * @brief Allocate new space for object
- * @param[in] object Object pointer
- * @param[in] object_size New buffer size
- *
- * @details Currently only useful for roce service, adjusts CQ buffer size but cqn and cqc remain unchanged,
- * allocates new buffer space, does not free old buffer space, current valid buffer is still old buffer
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_object_resize_alloc_new(hinic5_cqm_object_s *object, u32 object_size);
-
-/**
- * @brief Free newly allocated buffer space for object
- * @param[in] object Object pointer
- *
- * @details This function frees newly allocated buffer space, used for service exception handling
- */
-void hinic5_cqm3_object_resize_free_new(hinic5_cqm_object_s *object);
-
-/**
- * @brief Free old buffer space for object
- * @param[in] object Object pointer
- *
- * @details This function frees old buffer and sets current valid buffer to new buffer
- */
-void hinic5_cqm3_object_resize_free_old(hinic5_cqm_object_s *object);
-
-/**
- * @brief Release container
- * @param[in] object Object pointer
- * @param[in] container Container pointer to release
- *
- * @details Release container
- */
-void hinic5_cqm3_srq_used_rq_container_delete(hinic5_cqm_object_s *object, u8 *container);
-
-/**
- * @brief Get physical and virtual address at specified offset in object buffer
- * @param[in] object Object pointer
- * @param[in] offset For rdma table, offset is absolute index number
- * @param[out] paddr Only returns physical address for rdma table
- *
- * @details Only supports rdma table lookup, gets physical and virtual address at specified offset in object buffer
- *
- * @return u8 * Virtual address at specified offset in buffer
- */
-u8 *hinic5_cqm3_object_offset_addr(hinic5_cqm_object_s *object, u32 offset, dma_addr_t *paddr);
-
-/**
- * @brief Create DTOE SRQ
- * @param[in] ex_handle Device handle
- * @param[in] context_size Context size
- * @param[out] index_count Number of indices allocated
- * @param[out] index Starting index allocated
- *
- * @return Success or failure
- * @retval 0 success
- * @retval -1 failure
- */
-s32 hinic5_cqm3_dtoe_share_recv_queue_create(void *ex_handle, u32 context_size,
- u32 *index_count, u32 *index);
-
-/**
- * @brief Free DTOE SRQ bitmap
- * @param[in] ex_handle Device handle
- * @param[in] index_count Number of indices to free
- * @param[in] index Starting index to free
- */
-void hinic5_cqm3_dtoe_free_srq_bitmap_index(void *ex_handle, u32 index_count, u32 index);
-
-#endif /* HINIC5_HINIC5_CQM_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm_adpt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm_adpt.h
deleted file mode 100644
index 7fffe7f2f..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_cqm_adpt.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hinic5_cqm_adpt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_HINIC5_CQM_ADPT_H
-#define HINIC5_HINIC5_CQM_ADPT_H
-
-#define hinic5_cqm_init hinic5_cqm3_init /**< Initialize HINIC5_CQM */
-#define hinic5_cqm_uninit hinic5_cqm3_uninit /**< Uninitialize HINIC5_CQM */
-#define hinic5_cqm_init_fake_vf hinic5_cqm3_init_fake_vf /**< Initialize specified Fake VF for HINIC5_CQM */
-#define hinic5_cqm_service_register hinic5_cqm3_service_register /**< Register service */
-#define hinic5_cqm_service_unregister hinic5_cqm3_service_unregister /**< Unregister service */
-#define hinic5_cqm_bloomfilter_dec hinic5_cqm3_bloomfilter_dec /**< Decrease bloom filter counter */
-#define hinic5_cqm_bloomfilter_inc hinic5_cqm3_bloomfilter_inc /**< Increase bloom filter counter */
-#define hinic5_cqm_cmd_alloc hinic5_cqm3_cmd_alloc /**< Allocate command */
-#define hinic5_cqm_get_hardware_db_addr hinic5_cqm3_get_hardware_db_addr /**< Get hardware database address */
-#define hinic5_cqm_cmd_free hinic5_cqm3_cmd_free /**< Free command */
-#define hinic5_cqm_send_cmd_box hinic5_cqm3_send_cmd_box /**< Send command box */
-#define hinic5_cqm_lb_send_cmd_box hinic5_cqm3_lb_send_cmd_box /**< Send load balanced command box */
-#define hinic5_cqm_send_cmd_imm hinic5_cqm3_send_cmd_imm /**< Send immediate command */
-#define hinic5_cqm_db_addr_alloc hinic5_cqm3_db_addr_alloc /**< Allocate database address */
-#define hinic5_cqm_db_addr_free hinic5_cqm3_db_addr_free /**< Free database address */
-#define hinic5_cqm_ring_hardware_db hinic5_cqm3_ring_hardware_db /**< Ring hardware database */
-#define hinic5_cqm_ring_software_db hinic5_cqm3_ring_software_db /**< Ring software database */
-#define hinic5_cqm_object_fc_srq_create hinic5_cqm3_object_fc_srq_create /**< Create FC SRQ object */
-#define hinic5_cqm_object_share_recv_queue_create hinic5_cqm3_object_share_recv_queue_create /**< Create shared receive queue object */
-#define hinic5_cqm_object_share_recv_queue_add_container hinic5_cqm3_object_share_recv_queue_add_container /**< Add container to shared receive queue */
-#define hinic5_cqm_object_srq_add_container_free hinic5_cqm3_object_srq_add_container_free /**< Free SRQ add container */
-#define hinic5_cqm_object_recv_queue_create hinic5_cqm3_object_recv_queue_create /**< Create receive queue object */
-#define hinic5_cqm_object_qpc_mpt_create hinic5_cqm3_object_qpc_mpt_create /**< Create QPC MPT object */
-#define hinic5_cqm_object_nonrdma_queue_create hinic5_cqm3_object_nonrdma_queue_create /**< Create non-RDMA queue object */
-#define hinic5_cqm_object_rdma_queue_create hinic5_cqm3_object_rdma_queue_create /**< Create RDMA queue object */
-#define hinic5_cqm_object_rdma_table_get hinic5_cqm3_object_rdma_table_get /**< Get RDMA table */
-#define hinic5_cqm_object_delete hinic5_cqm3_object_delete /**< Delete object */
-#define hinic5_cqm_object_offset_addr hinic5_cqm3_object_offset_addr /**< Get offset address */
-#define hinic5_cqm_object_get hinic5_cqm3_object_get /**< Get object */
-#define hinic5_cqm_object_put hinic5_cqm3_object_put /**< Put object */
-#define hinic5_cqm_object_funcid hinic5_cqm3_object_funcid /**< Get function ID */
-#define hinic5_cqm_object_resize_alloc_new hinic5_cqm3_object_resize_alloc_new /**< Reallocate object with new size */
-#define hinic5_cqm_object_resize_free_new hinic5_cqm3_object_resize_free_new /**< Free object with new size */
-#define hinic5_cqm_object_resize_free_old hinic5_cqm3_object_resize_free_old /**< Free object with old size */
-#define hinic5_cqm_function_timer_clear hinic5_cqm3_function_timer_clear /**< Clear function timer */
-#define hinic5_cqm_function_hash_buf_clear hinic5_cqm3_function_hash_buf_clear /**< Clear function hash buffer */
-#define hinic5_cqm_srq_used_rq_container_delete hinic5_cqm3_srq_used_rq_container_delete /**< Delete used RQ container */
-#define hinic5_cqm_timer_base hinic5_cqm3_timer_base /**< Timer base */
-#define hinic5_cqm_dtoe_free_srq_bitmap_index hinic5_cqm3_dtoe_free_srq_bitmap_index /**< Free SRQ bitmap index */
-#define hinic5_cqm_dtoe_share_recv_queue_create hinic5_cqm3_dtoe_share_recv_queue_create /**< Create shared receive queue */
-#define hinic5_cqm_get_db_addr hinic5_cqm3_get_db_addr /**< Get database address */
-#define hinic5_cqm_ring_direct_wqe_db hinic5_cqm3_ring_direct_wqe_db /**< Direct ring WQE database */
-#define hinic5_cqm_fake_vf_num_set hinic5_cqm3_fake_vf_num_set /**< Set fake VF number */
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_vram_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_vram_api.h
deleted file mode 100644
index 2380f1443..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hinic5_vram_api.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hinic5_vram_api.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_HINIC5_VRAM_API_H
-#define HINIC5_HINIC5_VRAM_API_H
-
-#if !defined(__UEFI__) && !defined(__WIN__)
-#include <linux/notifier.h>
-#include <linux/numa.h>
-#endif
-
-#define HINIC5_VRAM_NUMA_NODE0 0
-#define HINIC5_VRAM_NUMA_NODE1 1
-#define HINIC5_CQM_OVS_PAGESIZE_ORDER 9
-#define HINIC5_VRAM_NAME_APPLY_LEN 64
-
-struct hinic5_vram_buf_info {
- char buf_hinic5_vram_name[HINIC5_VRAM_NAME_APPLY_LEN];
- int use_hinic5_vram;
-};
-
-#if defined(__UEFI__) || defined(__WIN__) || defined(__VMWARE__)
-#define hinic5_hinic5_vram_kalloc_node(name, size, numa) 0
-#define hinic5_hinic5_vram_kfree(vaddr, name, size)
-#define get_use_hinic5_vram_flag() 0
-#else
-
-/**
- * @brief alloc hinic5_vram memory
- * @param name name of hinic5_vram memory
- * @param size size of hinic5_vram memory
- * @param numa hinic5_vram numa node. if greater than environment numa num, apply for idle nodes
- **/
-void __iomem *hinic5_hinic5_vram_kalloc_node(char *name, u64 size, u8 numa);
-/**
- * @brief free hinic5_vram memory
- * @param vaddr virtual address of hinic5_vram memory
- * @param name name of hinic5_vram memory
- * @param size size of hinic5_vram memory
- **/
-void hinic5_hinic5_vram_kfree(void __iomem *vaddr, char *name, u64 size);
-/**
- * @brief get use-hinic5_vram flag
- * @return
- * - Zero for not-use-hinic5_vram. Non-zero for use-hinic5_vram.
- **/
-int get_use_hinic5_vram_flag(void);
-
-#endif
-#endif /* HINIC5_HINIC5_VRAM_API_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hw.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hw.h
index c3c116c03..4a9d8f41d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hw.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_hw.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_HW_H
#define HINIC5_HW_H
@@ -17,11 +10,11 @@
#include "hinic5_crm.h"
#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 0x4321 /**< Big endian byte order */
+#define BIG_ENDIAN 0x4321 /**< 表示大端字节序 */
#endif
#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 0x1234 /**< Little endian byte order */
+#define LITTLE_ENDIAN 0x1234 /**< 表示小端字节序 */
#endif
#ifdef BYTE_ORDER
@@ -30,17 +23,20 @@
/* X86 */
#define BYTE_ORDER LITTLE_ENDIAN
/* to use 0-level CLA, page size must be: SQ 16B(wqe) * 64k(max_q_depth) */
-#define HINIC5_DEFAULT_WQ_PAGE_SIZE 0x100000 /**< Default work queue page size */
-#define HINIC5_HW_WQ_PAGE_SIZE 0x1000 /**< Hardware send queue page size */
-#define HINIC5_MAX_WQ_PAGE_SIZE_ORDER 8 /**< Maximum work queue page size order */
-#define SPU_HOST_ID 4 /**< Host ID */
+#define HINIC5_DEFAULT_WQ_PAGE_SIZE \
+ 0x100000 /**< 定义了默认的工作队列页面大小 */
+#define HINIC5_HW_WQ_PAGE_SIZE 0x1000 /**< 定义硬件发送队列的页面大小 */
+#define HINIC5_MAX_WQ_PAGE_SIZE_ORDER 8 /**< 定义最大工作队列页面大小 */
+#define SPU_HOST_ID 4 /**< 表示主机的ID */
+
+#define HINIC5_NIC_RES BIT(RES_TYPE_NIC) /**< 表示网络接口控制器(NIC)资源 */
-/**< NIC resource type indicator */
-#define HINIC5_NIC_RES BIT(RES_TYPE_NIC)
+#define HINIC5_AEQ_MAX_PAGES 4
+#define HINIC5_CEQ_MAX_PAGES 8
/**
- * @brief enum hinic5_channel_id - Channel type
- * @details Defines the enumeration type for Hinic5 channels
+ * @brief enum hinic5_channel_id - 通道类型
+ * @details 定义了Hinic5通道的枚举类型
*/
enum hinic5_channel_id {
HINIC5_CHANNEL_DEFAULT,
@@ -63,202 +59,206 @@ enum hinic5_channel_id {
};
/**
- * @brief struct hinic5_cmd_buf - dma buffer object
- * @details Defines a dma buffer structure
+ * @brief struct hinic5_cmd_buf - dma buffer 对象
+ * @details 定义一个dma缓冲结构体
*/
struct hinic5_cmd_buf {
- void *buf; /**< va for buffer */
- dma_addr_t dma_addr; /**< dma address for buffer */
- u16 size; /**< buffer size */
- atomic_t ref_cnt; /**< buffer reference count */
+ void *buf; /**< va for buffer */
+ dma_addr_t dma_addr; /**< dma address for buffer */
+ u16 size; /**< buffer size */
+ atomic_t ref_cnt; /**< buffer reference count */
};
/**
- * @brief struct hinic5_cmdq_cmd_param - cmdq request object
- * @details Stores cmdq request parameters
+ * @brief struct hinic5_cmdq_cmd_param - cmdq请求对象
+ * @details 存储cmdq请求的参数
*/
struct hinic5_cmdq_cmd_param {
- u8 mod; /**< mod id */
- u8 cmd; /**< cmd opcode */
- struct hinic5_cmd_buf *buf_in; /**< input buf, only support 32B/96B/160B for inline data mode */
- struct hinic5_cmd_buf *buf_out; /**< output buf writed by chip to return data */
- u64 *out_param; /**< output data, only support 8B */
+ u8 mod; /**< mod id */
+ u8 cmd; /**< cmd opcode */
+ struct hinic5_cmd_buf *
+ buf_in; /**< input buf, only support 32B/96B/160B for inline data mode */
+ struct hinic5_cmd_buf
+ *buf_out; /**< output buf writed by chip to return data */
+ u64 *out_param; /**< output data, only support 8B */
};
-/**
- * @brief enum hinic5_hwdev_init_state
- * @details Defines the enumeration type for hardware device initialization state
- */
-enum hinic5_hwdev_init_state {
- HINIC5_HWDEV_NONE_INITED = 0, /**< Device not initialized */
- HINIC5_HWDEV_MGMT_INITED, /**< Device management module initialized */
- HINIC5_HWDEV_MBOX_INITED, /**< Device mailbox module initialized */
- HINIC5_HWDEV_CMDQ_INITED, /**< Device cmdq module initialized */
+struct hinic5_ceq_addr {
+ void *align_vaddr; /**< 对齐的虚拟地址 */
+ dma_addr_t align_paddr; /**< 对齐的物理地址 */
};
/**
- * @brief struct hinic5_ceq_info - CEQ configuration info description
+ * @brief struct hinic5_ceq_info - 描述ceq的配置信息
* @details NA
*/
struct hinic5_ceq_info {
- u32 q_len; /**< ceq length */
+ u32 q_len; /**< ceq length */
u32 page_size; /**< ceq page size */
u16 elem_size; /**< ceq element size */
- u16 num_pages; /**< number of ceq pages*/
+ u16 num_pages; /**< number of ceq pages*/
u32 num_elem_in_pg; /**< number of ceq element in one page */
+ struct hinic5_ceq_addr ceq_addr[HINIC5_CEQ_MAX_PAGES];
};
/**
- * @brief enum hinic5_ceq_event - CEQE event type
- * @details Defines Hinic5 interrupt event types
+ * @brief enum hinic5_ceq_event - ceqe的类型
+ * @details 定义了Hinic5的中断事件类型
*/
enum hinic5_ceq_event {
- HINIC5_NON_L2NIC_SCQ, /**< Non-L2NIC SCQ interrupt event */
- HINIC5_NON_L2NIC_ECQ, /**< Non-L2NIC ECQ interrupt event */
- HINIC5_NON_L2NIC_NO_CQ_EQ, /**< Non-L2NIC no CQ interrupt event */
- HINIC5_CMDQ, /**< Command queue interrupt event */
- HINIC5_L2NIC_SQ, /**< L2NIC send queue interrupt event */
- HINIC5_L2NIC_RQ, /**< L2NIC receive queue interrupt event */
- HINIC5_CEQ_EVENT_RSVD, /**< Reserved interrupt event */
- HINIC5_FAST_MSG_RQ, /**< Fast message receive queue interrupt event */
- HINIC5_MAX_CEQ_EVENTS, /**< Number of CEQE types */
+ HINIC5_NON_L2NIC_SCQ, /**< 非L2NIC的SCQ中断事件 */
+ HINIC5_NON_L2NIC_ECQ, /**< 非L2NIC的ECQ中断事件 */
+ HINIC5_NON_L2NIC_NO_CQ_EQ, /**< 非L2NIC没有CQ的中断事件 */
+ HINIC5_CMDQ, /**< 命令队列中断事件 */
+ HINIC5_L2NIC_SQ, /**< L2NIC的发送队列中断事件 */
+ HINIC5_L2NIC_RQ, /**< L2NIC的接收队列中断事件 */
+ HINIC5_CEQ_EVENT_RSVD, /**< 保留的中断事件 */
+ HINIC5_FAST_MSG_RQ, /**< 快速消息接收队列中断事件 */
+ HINIC5_MAX_CEQ_EVENTS, /**< ceqe的类型个数 */
};
/**
* @brief enum hinic5_mbox_seg_errcode
- * @details Mailbox error code enumeration type
+ * @details mailbox错误码枚举类型
*/
enum hinic5_mbox_seg_errcode {
- MBOX_ERRCODE_NO_ERRORS = 0,
- MBOX_ERRCODE_VF_TO_WRONG_FUNC = 0x100, /**< VF sends mailbox data to wrong target device */
- MBOX_ERRCODE_PPF_TO_WRONG_FUNC = 0x200, /**< PPF sends mailbox data to wrong target device */
- MBOX_ERRCODE_PF_TO_WRONG_FUNC = 0x300, /**< PF sends mailbox data to wrong target device */
- MBOX_ERRCODE_ZERO_DATA_SIZE = 0x400, /**< Mailbox data size set to all zeros */
- MBOX_ERRCODE_UNKNOWN_SRC_FUNC = 0x500, /**< Unknown source device */
- MBOX_ERRCODE_UNKNOWN_DES_FUNC = 0x600, /**< Unknown destination device */
+ MBOX_ERRCODE_NO_ERRORS = 0,
+ MBOX_ERRCODE_VF_TO_WRONG_FUNC =
+ 0x100, /**< VF发送邮箱数据到错误的目标设备 */
+ MBOX_ERRCODE_PPF_TO_WRONG_FUNC =
+ 0x200, /**< PPF发送邮箱数据到错误的目标设备 */
+ MBOX_ERRCODE_PF_TO_WRONG_FUNC =
+ 0x300, /**< PF发送邮箱数据到错误的目标设备 */
+ MBOX_ERRCODE_ZERO_DATA_SIZE = 0x400, /**< 邮箱数据大小设置为全零 */
+ MBOX_ERRCODE_UNKNOWN_SRC_FUNC = 0x500, /**< 未知的原设备 */
+ MBOX_ERRCODE_UNKNOWN_DES_FUNC = 0x600, /**< 未知的目标设备 */
};
/**
- * @brief Callback type for handling CEQE events
- * @param pri_handle Callback private data
- * @param ceqe_data CEQE data
+ * @brief 处理ceqe事件的回调类型
+ * @param pri_handle 回调私有数据
+ * @param ceqe_data ceqe数据
*
* @return NA
*/
typedef void (*hinic5_ceq_event_cb)(void *pri_handle, u32 ceqe_data);
/**
- * @brief Define function pointer type named hinic5_aeq_swe_cb
- * @param pri_handle Parameter is a void pointer representing private handle
- * @param event Parameter is a u8 type representing event
- * @param data Parameter is a u8 pointer representing data
+ * @brief 定义一个名为hinic5_aeq_swe_cb的函数指针类型
+ * @param pri_handle 参数为一个void类型的指针,表示私有句柄
+ * @param event 参数为一个u8类型,表示事件
+ * @param data 参数为一个u8类型的指针,表示数据
*
- * @return Return value is u8 type function pointer
+ * @return 返回值为u8类型的函数指针
*/
typedef u8 (*hinic5_aeq_swe_cb)(void *pri_handle, u8 event, u8 *data);
/**
- * @brief Define a function pointer type for handling virtual function mailbox callback
- * @param pri_handle Pointer to private handle
- * @param cmd Command
- * @param buf_in Input buffer
- * @param in_size Input buffer size
- * @param buf_out Output buffer
- * @param out_size Pointer to output buffer size
+ * @brief 定义一个函数指针类型,用于处理虚拟函数邮箱的回调函数
+ * @param pri_handle 指向私有句柄的指针
+ * @param cmd 命令
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
+ * @param buf_out 输出缓冲区
+ * @param out_size 输出缓冲区大小的指针
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-typedef int (*hinic5_vf_mbox_cb)(void *pri_handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out, u16 *out_size);
+typedef int (*hinic5_vf_mbox_cb)(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
/**
- * @brief Define a function pointer type for handling PF mailbox callback
- * @param pri_handle Master handle
- * @param vf_id Virtual function ID
- * @param cmd Command
- * @param buf_in Input buffer
- * @param in_size Input buffer size
- * @param buf_out Output buffer
- * @param out_size Output buffer size
+ * @brief 定义一个函数指针类型,用于处理PF邮箱的回调函数
+ * @param pri_handle 主句柄
+ * @param vf_id 虚拟函数ID
+ * @param cmd 命令
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
+ * @param buf_out 输出缓冲区
+ * @param out_size 输出缓冲区大小
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-typedef int (*hinic5_pf_mbox_cb)(void *pri_handle, u16 vf_id, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size);
+typedef int (*hinic5_pf_mbox_cb)(void *pri_handle, u16 vf_id, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size);
/**
- * @brief Define a function pointer type for handling PF to VF mailbox communication
- * @param pri_handle Device handle
- * @param pf_idx PF index
+ * @brief 定义一个函数指针类型,用于处理PF到VF的邮箱通信
+ * @param pri_handle 设备句柄
+ * @param pf_idx PF索引
* @param vf_id VF ID
- * @param cmd Command
- * @param buf_in Input buffer
- * @param in_size Input buffer size
- * @param buf_out Output buffer
- * @param out_size Output buffer size
+ * @param cmd 命令
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
+ * @param buf_out 输出缓冲区
+ * @param out_size 输出缓冲区大小
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-typedef int (*hinic5_ppf_mbox_cb)(void *pri_handle, u16 pf_idx, u16 vf_id, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size);
+typedef int (*hinic5_ppf_mbox_cb)(void *pri_handle, u16 pf_idx, u16 vf_id,
+ u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
/**
- * @brief Define a function pointer type for receiving messages from PPF mailbox
- * @param pri_handle Private handle
- * @param cmd Command
- * @param buf_in Input buffer
- * @param in_size Input buffer size
- * @param buf_out Output buffer
- * @param out_size Output buffer size
+ * @brief 定义一个函数指针类型,用于接收来自PPF邮箱的消息
+ * @param pri_handle 私有句柄
+ * @param cmd 命令
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
+ * @param buf_out 输出缓冲区
+ * @param out_size 输出缓冲区大小
*
- * @return Return value
+ * @return 返回值
*/
-typedef int (*hinic5_pf_recv_from_ppf_mbox_cb)(void *pri_handle, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size);
+typedef int (*hinic5_pf_recv_from_ppf_mbox_cb)(void *pri_handle, u16 cmd,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
/**
- * @brief Define a function pointer type for handling management messages
- * @param pri_handle Private handle passed to callback function
- * @param cmd Command code representing the operation to be performed
- * @param buf_in Input buffer for passing input parameters
- * @param in_size Input buffer size for limiting input parameter length
- * @param buf_out Output buffer for passing output results
- * @param out_size Output buffer size for limiting output result length
+ * @brief 定义一个函数指针类型,用于处理管理消息
+ * @param pri_handle 私有句柄,用于传递给回调函数
+ * @param cmd 命令码,表示需要执行的操作
+ * @param buf_in 输入缓冲区,用于传递输入参数
+ * @param in_size 输入缓冲区大小,用于限制输入参数的长度
+ * @param buf_out 输出缓冲区,用于传递输出结果
+ * @param out_size 输出缓冲区大小,用于限制输出结果的长度
*
- * @return None
+ * @return 无
*/
-typedef void (*hinic5_mgmt_msg_cb)(void *pri_handle, u16 cmd, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
+typedef void (*hinic5_mgmt_msg_cb)(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
u8 hinic5_nic_sw_aeqe_stats(void *hwdev, u8 event, u8 *data);
/**
- * @brief Register handler for stateless aeqe generated by microcode
+ * @brief 注册微码产生的无状态aeqe的handler
*
- * @param hwdev Device object pointer (struct hinic5_hwdev *)
- * @param pri_handle Callback function private data
- * @param stateless_aeq_swe_cb Callback function
+ * @param hwdev 设备对象指针(struct hinic5_hwdev *)
+ * @param pri_handle 回调函数私有数据
+ * @param stateless_aeq_swe_cb 回调函数
*
* @details NA
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval 0 Registration success
- * @retval non-zero Registration failure
+ * @return: 描述函数返回值.
+ * @retval 0 注册成功
+ * @retval 非0 注册失败
*/
-int hinic5_register_stateless_aeqs(void *hwdev, void *pri_handle, hinic5_aeq_swe_cb stateless_aeq_swe_cb);
+int hinic5_register_stateless_aeqs(void *hwdev, void *pri_handle,
+ hinic5_aeq_swe_cb stateless_aeq_swe_cb);
/**
- * @brief Unregister handler for stateless aeqe generated by microcode
+ * @brief 注销处理微码产生的无状态aeqe的handler
*
- * @param hwdev Device object pointer (struct hinic5_hwdev *)
+ * @param hwdev 设备对象指针(struct hinic5_hwdev *)
*
* @details NA
*
@@ -278,7 +278,8 @@ void hinic5_unregister_stateless_aeqs(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_ceq_register_cb(void *hwdev, void *pri_handle, enum hinic5_ceq_event event,
+int hinic5_ceq_register_cb(void *hwdev, void *pri_handle,
+ enum hinic5_ceq_event event,
hinic5_ceq_event_cb callback);
/**
* @brief hinic5_ceq_unregister_cb - unregister ceq callback
@@ -288,67 +289,67 @@ int hinic5_ceq_register_cb(void *hwdev, void *pri_handle, enum hinic5_ceq_event
void hinic5_ceq_unregister_cb(void *hwdev, enum hinic5_ceq_event event);
/**
- * @brief Register handler for PPF mailbox messages
+ * @brief 为PPF注册处理mailbox消息的handler
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
- * @param pri_handle Callback private data
- * @param callback Callback function
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
+ * @param pri_handle 回调私有数据
+ * @param callback 回调
*
* @details NA
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_register_ppf_mbox_cb(void *hwdev, u8 mod, void *pri_handle,
hinic5_ppf_mbox_cb callback);
/**
- * @brief Register handler for PF mailbox messages
+ * @brief 为PF注册处理mailbox消息的handler
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
- * @param pri_handle Callback private data
- * @param callback Callback function
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
+ * @param pri_handle 回调私有数据
+ * @param callback 回调
*
* @details NA
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_register_pf_mbox_cb(void *hwdev, u8 mod, void *pri_handle,
hinic5_pf_mbox_cb callback);
/**
- * @brief Register handler for VF mailbox messages
+ * @brief 为VF注册处理mailbox消息的handler
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
- * @param pri_handle Callback private data
- * @param callback Callback function
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
+ * @param pri_handle 回调私有数据
+ * @param callback 回调
*
* @details NA
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_register_vf_mbox_cb(void *hwdev, u8 mod, void *pri_handle,
hinic5_vf_mbox_cb callback);
/**
- * @brief Unregister PPF mailbox callback
+ * @brief 注销PPF的处理mailbox的回调
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
*
* @details NA
*
@@ -359,10 +360,10 @@ int hinic5_register_vf_mbox_cb(void *hwdev, u8 mod, void *pri_handle,
void hinic5_unregister_ppf_mbox_cb(void *hwdev, u8 mod);
/**
- * @brief Unregister PF mailbox callback
+ * @brief 注销PF的处理mailbox的回调
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
*
* @details NA
*
@@ -373,10 +374,10 @@ void hinic5_unregister_ppf_mbox_cb(void *hwdev, u8 mod);
void hinic5_unregister_pf_mbox_cb(void *hwdev, u8 mod);
/**
- * @brief Unregister VF mailbox callback
+ * @brief 注销VF的处理mailbox的回调
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
*
* @details NA
*
@@ -387,12 +388,12 @@ void hinic5_unregister_pf_mbox_cb(void *hwdev, u8 mod);
void hinic5_unregister_vf_mbox_cb(void *hwdev, u8 mod);
/**
- * @brief Unregister PF mailbox callback
+ * @brief 注销PF的处理mailbox的回调
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
*
- * @details source is PPF
+ * @details source是PPF
*
* @attention: NA
*
@@ -401,31 +402,31 @@ void hinic5_unregister_vf_mbox_cb(void *hwdev, u8 mod);
void hinic5_unregister_ppf_to_pf_mbox_cb(void *hwdev, u8 mod);
/**
- * @brief Register handler for function mailbox messages
+ * @brief 为function注册处理mailbox消息的handler
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
- * @param pri_handle Callback private data
- * @param callback Callback function
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
+ * @param pri_handle 回调私有数据
+ * @param callback 回调
*
- * @details source is MPU
+ * @details source为MPU
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_register_mgmt_msg_cb(void *hwdev, u8 mod, void *pri_handle,
hinic5_mgmt_msg_cb callback);
/**
- * @brief Unregister function mailbox callback
+ * @brief 注销function的处理mailbox的回调
*
- * @param hwdev Device object pointer
- * @param mod Service module, value is HINIC5_MOD_XXX macro definition
+ * @param hwdev 设备对象指针
+ * @param mod 业务模块 值为HINIC5_MOD_XXX宏定义
*
- * @details source is MPU
+ * @details source是MPU
*
* @attention: NA
*
@@ -540,8 +541,8 @@ void hinic5_free_db_phy_addr(void *hwdev, u64 db_base, u64 dwqe_base);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth,
- u16 rx_buf_sz, u16 channel);
+int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz,
+ u16 channel);
/**
* @brief hinic5_clean_root_ctxt - clean root context
@@ -562,7 +563,7 @@ int hinic5_clean_root_ctxt(void *hwdev, u16 channel);
* @retval non-zero: success
* @retval null: failure
* @note
- * Allocated memory does not support default zeroing, caller should zero according to needs
+ * 申请到的内存不支持默认清零, 调用者根据需求进行清零
*/
struct hinic5_cmd_buf *hinic5_alloc_cmd_buf(void *hwdev);
@@ -574,16 +575,17 @@ struct hinic5_cmd_buf *hinic5_alloc_cmd_buf(void *hwdev);
void hinic5_free_cmd_buf(void *hwdev, struct hinic5_cmd_buf *cmd_buf);
/**
- * @brief Read 16-bit counter value
- * @param hwdev Hardware device context
- * @param node Node number
- * @param instance Instance number
- * @param ctr_id Counter ID
- * @param value Pointer to store the read counter value
+ * @brief 读取16位计数器的值
+ * @param hwdev 硬件设备上下文
+ * @param node 节点号
+ * @param instance 实例号
+ * @param ctr_id 计数器ID
+ * @param value 存储读取到的计数器值的指针
*
- * @return 0 on success, other values indicate failure
+ * @return 0 成功,其他值表示失败
*/
-int hinic5_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+int hinic5_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value);
/**
* @brief hinic5_sm_ctr_rd32 - small single 32 counter read
@@ -611,8 +613,8 @@ int hinic5_sm_ctr_rd32(void *hwdev, u8 node, u8 instance, u32 ctr_id,
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u32 *value);
+int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u32 *value);
/**
* @brief hinic5_sm_ctr_rd64_pair - big pair 128 counter read
@@ -627,22 +629,22 @@ int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance,
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u64 *value1, u64 *value2);
+int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u64 *value1, u64 *value2);
/**
- * @brief Read and clear 64-bit counter pair value
- * @param hwdev Hardware device context
- * @param node Node number
- * @param instance Instance number
- * @param ctr_id Counter ID
- * @param value1 Pointer to store the first value of the 64-bit counter pair
- * @param value2 Pointer to store the second value of the 64-bit counter pair
+ * @brief 读取并清除64位计数器对的值
+ * @param hwdev 硬件设备上下文
+ * @param node 节点号
+ * @param instance 实例号
+ * @param ctr_id 计数器ID
+ * @param value1 存储读取到的64位计数器对的第一个值的指针
+ * @param value2 存储读取到的64位计数器对的第二个值的指针
*
- * @return 0 on success, other values indicate failure
+ * @return 0 成功,其他值 失败
*/
-int hinic5_sm_ctr_rd64_pair_clear(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u64 *value1, u64 *value2);
+int hinic5_sm_ctr_rd64_pair_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u64 *value1, u64 *value2);
/**
* @brief hinic5_sm_ctr_rd64 - big counter 64 read
@@ -660,17 +662,17 @@ int hinic5_sm_ctr_rd64(void *hwdev, u8 node, u8 instance, u32 ctr_id,
u64 *value);
/**
- * @brief Clear 64-bit counter value
- * @param hwdev Hardware device handle
- * @param node Node number
- * @param instance Instance number
- * @param ctr_id Counter ID
- * @param value Pointer to store the read counter value
+ * @brief 清除64位计数器的值
+ * @param hwdev 硬件设备的句柄
+ * @param node 节点号
+ * @param instance 实例号
+ * @param ctr_id 计数器ID
+ * @param value 存储读取到的计数器值的指针
*
- * @return 0 on success, other values indicate failure
+ * @return 0 成功,其他值表示失败
*/
-int hinic5_sm_ctr_rd64_clear(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u64 *value);
+int hinic5_sm_ctr_rd64_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u64 *value);
/**
* @brief hinic5_api_csr_rd32 - read 32 byte csr
@@ -721,7 +723,8 @@ int hinic5_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats, const u32 *out_size);
+int hinic5_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats,
+ const u32 *out_size);
/**
* @brief hinic5_dbg_clear_hw_stats - clear hardware stats
@@ -786,7 +789,7 @@ int hinic5_msg_to_mgmt_async(void *hwdev, u8 mod, u16 cmd, const void *buf_in,
* @param channel: channel id
*
* @details The function will sleep inside, and it is not allowed to be used in interrupt context
- * @return Whether send is successful
+ * @return 发送是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -794,14 +797,14 @@ int hinic5_msg_to_mgmt_no_ack(void *hwdev, u8 mod, u16 cmd, void *buf_in,
u16 in_size, u16 channel);
/**
- * @brief Send async message to management processing chain
- * @param hwdev Hardware device context
- * @param mod Message module
- * @param cmd Message command
- * @param buf_in Input buffer
- * @param in_size Input buffer size
+ * @brief 向管理处理链发送异步消息
+ * @param hwdev 硬件设备上下文
+ * @param mod 消息模块
+ * @param cmd 消息命令
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
*
- * @return Whether send is successful
+ * @return 发送是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -824,13 +827,12 @@ int hinic5_msg_to_mgmt_api_chain_sync(void *hwdev, u8 mod, u16 cmd,
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size,
- u32 timeout, u16 channel);
+int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size, u32 timeout, u16 channel);
/**
* @brief hinic5_mbox_to_vf - mbox message to vf
@@ -845,7 +847,7 @@ int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in,
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -863,12 +865,12 @@ int hinic5_mbox_to_vf(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in,
* @param in_size: in buffer size
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_mbox_to_vf_without_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
- void *buf_in, u16 in_size, u16 channel);
+ void *buf_in, u16 in_size, u16 channel);
/**
* @brief hinic5_mbox_to_vf_no_ack - mbox message to vf no ack
@@ -882,12 +884,13 @@ int hinic5_mbox_to_vf_without_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
* @param out_size: out buffer size
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_mbox_to_vf_no_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size, u16 channel);
+int hinic5_mbox_to_vf_no_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u16 channel);
int hinic5_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in,
u16 in_size, void *buf_out, u16 *out_size);
@@ -899,11 +902,12 @@ int hinic5_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in,
* @param buf_in: message buffer in
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic5_cmd_buf *buf_in, u16 channel);
+int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in, u16 channel);
/**
* @brief hinic5_cmdq_direct_resp - cmdq direct message response
@@ -915,13 +919,13 @@ int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic5_cmd_buf *buf_in
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_cmdq_direct_resp(void *hwdev, u8 mod, u8 cmd,
- struct hinic5_cmd_buf *buf_in,
- u64 *out_param, u32 timeout, u16 channel);
+ struct hinic5_cmd_buf *buf_in, u64 *out_param,
+ u32 timeout, u16 channel);
/**
* @brief hinic5_cmdq_detail_resp - cmdq detail message response
@@ -934,14 +938,14 @@ int hinic5_cmdq_direct_resp(void *hwdev, u8 mod, u8 cmd,
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_cmdq_detail_resp(void *hwdev, u8 mod, u8 cmd,
struct hinic5_cmd_buf *buf_in,
- struct hinic5_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel);
+ struct hinic5_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel);
/**
* @brief hinic5_cmdq_inline_data - cmdq with inline data
@@ -950,11 +954,12 @@ int hinic5_cmdq_detail_resp(void *hwdev, u8 mod, u8 cmd,
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_cmdq_inline_data(void *hwdev, struct hinic5_cmdq_cmd_param *cmd_param,
+int hinic5_cmdq_inline_data(void *hwdev,
+ struct hinic5_cmdq_cmd_param *cmd_param,
u32 timeout, u16 channel);
/**
@@ -969,20 +974,20 @@ int hinic5_cmdq_inline_data(void *hwdev, struct hinic5_cmdq_cmd_param *cmd_param
* @param timeout: timeout
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_cos_id_detail_resp(void *hwdev, u8 mod, u8 cmd, u8 cos_id,
struct hinic5_cmd_buf *buf_in,
- struct hinic5_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel);
+ struct hinic5_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel);
/**
* @brief hinic5_ppf_tmr_start - start ppf timer
* @param hwdev: device pointer to hwdev
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -992,7 +997,7 @@ int hinic5_ppf_tmr_start(void *hwdev);
* @brief hinic5_ppf_tmr_stop - stop ppf timer
* @param hwdev: device pointer to hwdev
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1004,7 +1009,7 @@ int hinic5_ppf_tmr_stop(void *hwdev);
* @param func_id: global function index
* @param enable: 0-disable, 1-enable
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1015,7 +1020,7 @@ int hinic5_func_tmr_bitmap_set(void *hwdev, u16 func_id, bool en);
* @param hwdev: device pointer to hwdev
* @param en: 0-disable, 1-enable
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1027,7 +1032,7 @@ int hinic5_func_vio_en(void *hwdev, bool en);
* @param info: board info
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1041,7 +1046,7 @@ int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info,
* @param page_size: page size
* @param channel: channel id
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1063,8 +1068,8 @@ void hinic5_event_callback(void *hwdev, struct hinic5_event_info *event);
* @param lt_index: liner table index id
* @param data: data
*/
-int hinic5_dbg_lt_rd_16byte(void *hwdev, u8 dest, u8 instance,
- u32 lt_index, u8 *data);
+int hinic5_dbg_lt_rd_16byte(void *hwdev, u8 dest, u8 instance, u32 lt_index,
+ u8 *data);
/**
* @brief hinic5_dbg_lt_wr_16byte_mask - liner table write
@@ -1111,66 +1116,67 @@ int hinic5_get_hw_pf_infos(void *hwdev, struct hinic5_hw_pf_infos *infos,
int hinic5_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel);
/**
- * @brief Get PPF (Physical Function) timer configuration
- * @param hwdev Hardware device context
+ * @brief 获取PPF(Physical Function,物理功能)定时器配置
+ * @param hwdev 硬件设备上下文
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_get_ppf_timer_cfg(void *hwdev);
/**
- * @brief Set PCI device BDF (Bus, Device, Function) information
- * @param hwdev Hardware device context
- * @param bus PCI bus number
- * @param device PCI device number
- * @param function PCI function number
+ * @brief 设置PCI设备的BDF(总线、设备、功能)信息
+ * @param hwdev 硬件设备上下文
+ * @param bus PCI总线号
+ * @param device PCI设备号
+ * @param function PCI功能号
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_set_bdf_ctxt(void *hwdev, u8 bus, u8 device, u8 function);
/**
- * @brief Initialize function mailbox message channel
- * @param hwdev Hardware device
- * @param num_func Number of functions
+ * @brief 初始化函数邮箱消息通道
+ * @param hwdev 硬件设备
+ * @param num_func 函数数量
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_init_func_mbox_msg_channel(void *hwdev, u16 num_func);
/**
- * @brief Get SML table information
- * @param hwdev Hardware device info
- * @param tbl_id Table ID
- * @param node_id Node ID
- * @param instance_id Instance ID
+ * @brief 获取SML表信息
+ * @param hwdev 硬件设备信息
+ * @param tbl_id 表ID
+ * @param node_id 节点ID
+ * @param instance_id 实例ID
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_get_sml_table_info(void *hwdev, u32 tbl_id, u8 *node_id, u8 *instance_id);
+int hinic5_get_sml_table_info(void *hwdev, u32 tbl_id, u8 *node_id,
+ u8 *instance_id);
/**
- * @brief Send mailbox message from PPF to host
- * @param hwdev Hardware device
- * @param mod Message module
- * @param cmd Message command
- * @param host_id Host ID
- * @param buf_in Input buffer
- * @param in_size Input buffer size
- * @param buf_out Output buffer
- * @param out_size Output buffer size
- * @param timeout Timeout
- * @param channel Channel
+ * @brief 从PPF发送邮箱消息到主机
+ * @param hwdev 硬件设备
+ * @param mod 消息模块
+ * @param cmd 消息命令
+ * @param host_id 主机ID
+ * @param buf_in 输入缓冲区
+ * @param in_size 输入缓冲区大小
+ * @param buf_out 输出缓冲区
+ * @param out_size 输出缓冲区大小
+ * @param timeout 超时时间
+ * @param channel 通道
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1179,46 +1185,47 @@ int hinic5_mbox_ppf_to_host(void *hwdev, u8 mod, u16 cmd, u8 host_id,
u16 *out_size, u32 timeout, u16 channel);
/**
- * @brief Force complete all operations
- * @param dev Device pointer
+ * @brief 强制完成所有的操作
+ * @param dev 设备指针
*
- * @return None
+ * @return 无
*/
void hinic5_force_complete_all(void *dev);
/**
- * @brief Get CEQ page physical address
- * @param hwdev Hardware device context
- * @param q_id Queue ID
- * @param page_idx Page index
- * @param page_phy_addr Page physical address
+ * @brief 获取CEQ页面的物理地址
+ * @param hwdev 硬件设备上下文
+ * @param q_id 队列ID
+ * @param page_idx 页面索引
+ * @param page_phy_addr 页面物理地址
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_get_ceq_page_phy_addr(void *hwdev, u16 q_id,
- u16 page_idx, u64 *page_phy_addr);
- /**
- * @brief Disable interrupt request
- * @param hwdev Hardware device
- * @param q_id Queue ID
+int hinic5_get_ceq_page_phy_addr(void *hwdev, u16 q_id, u16 page_idx,
+ u64 *page_phy_addr);
+/**
+ * @brief 禁用中断请求
+ * @param hwdev 硬件设备
+ * @param q_id 队列ID
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_set_ceq_irq_disable(void *hwdev, u16 q_id);
/**
- * @brief Get CEQ information
- * @param hwdev Hardware device info
- * @param q_id Queue ID
- * @param ceq_info CEQ information
+ * @brief 获取ceq信息
+ * @param hwdev 硬件设备信息
+ * @param q_id 队列ID
+ * @param ceq_info ceq信息
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_get_ceq_info(void *hwdev, u16 q_id, struct hinic5_ceq_info *ceq_info);
+int hinic5_get_ceq_info(void *hwdev, u16 q_id,
+ struct hinic5_ceq_info *ceq_info);
/**
* @brief hinic5_init_single_ceq_status
@@ -1228,29 +1235,29 @@ int hinic5_get_ceq_info(void *hwdev, u16 q_id, struct hinic5_ceq_info *ceq_info)
int hinic5_init_single_ceq_status(void *hwdev, u16 q_id);
/**
- * @brief Set API stop
- * @param hwdev Hardware device pointer
+ * @brief 设置API停止
+ * @param hwdev 硬件设备指针
*
- * @return None
+ * @return 无
*/
void hinic5_set_api_stop(void *hwdev);
/**
- * @brief Activate firmware
- * @param hwdev Hardware device
- * @param cfg_index Configuration index
+ * @brief 激活固件
+ * @param hwdev 硬件设备
+ * @param cfg_index 配置索引
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_activate_firmware(void *hwdev, u8 cfg_index);
/**
- * @brief hinic5_switch_config function main purpose is to switch firmware version
- * @param hwdev Device handle
- * @param cfg_index Configuration index
+ * @brief hinic5_switch_config函数的主要功能是切换固件版本
+ * @param hwdev 设备句柄
+ * @param cfg_index 配置索引
*
- * @return Whether successful
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -1265,20 +1272,20 @@ enum hinic5_hw_type {
};
/**
- * @brief Get device hardware type
+ * @brief 获取设备硬件类型
*
- * @param hwdev Device object pointer
+ * @param hwdev 设备对象指针
*
* @details NA
*
* @attention: NA
*
- * @return: Function return value description.
- * @retval HINIC5_HW_TYPE_FPGA fpga type
- * @retval HINIC5_HW_TYPE_ASIC asic type
- * @retval HINIC5_HW_TYPE_EMU emu type
- * @retval HINIC5_HW_TYPE_EDA eda type
- * @retval HINIC5_HW_TYPE_INVALID invalid type
+ * @return: 描述函数返回值.
+ * @retval HINIC5_HW_TYPE_FPGA fpga类型
+ * @retval HINIC5_HW_TYPE_ASIC asic类型
+ * @retval HINIC5_HW_TYPE_EMU emu类型
+ * @retval HINIC5_HW_TYPE_EDA eda类型
+ * @retval HINIC5_HW_TYPE_INVALID 无效类型
*/
u8 hinic5_get_hw_type(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_lld.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_lld.h
index 055de5188..97c12e1dd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_lld.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_lld.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_lld.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_LLD_H
#define HINIC5_LLD_H
@@ -14,18 +7,8 @@
#include <linux/pci.h>
#include "hinic5_crm.h"
-/**
- * @brief function device bus type
- * @details NA
- */
-enum hinic5_dev_type {
- HINIC5_DEVICE_T_PCI, /**< Device connected via pci bus */
- HINIC5_DEVICE_T_UB, /**< Device connected via ub bus */
- HINIC5_DEVICE_T_MAX, /**< Number of supported bus types */
-};
-
-#define HINIC5_CARD_ID_OFFSET 16
-#define HINIC5_CARD_ID_MASK 0xffffffffffff
+#define HINIC5_CARD_ID_OFFSET 16
+#define HINIC5_CARD_ID_MASK 0xffffffffffff
#define HINIC5_GUID_LEN (16)
/**
* @brief guid
@@ -36,41 +19,47 @@ struct hinic5_guid {
};
/**
- * @brief Device information for each function
+ * @brief 每个function的设备信息
* @details NA
*/
struct hinic5_device_info {
- u64 id; /* DPU unique identifier */
+ u64 id; /* DPU唯一性标识编号 */
struct hinic5_guid guid;
};
/**
- * @brief struct hinic5_lld_dev - Device object exposed to uld
- * @details Device object used by uld, contains device type and hardware device pointer
+ * @brief struct hinic5_lld_dev - 暴露给uld的设备对象
+ * @details uld使用的设备对象,包含设备类型、硬件设备指针
*/
struct hinic5_lld_dev {
- void *hwdev; /**< Hardware device pointer inside sdk driver */
- struct device *dev; /**< Associated struct device */
- enum hinic5_dev_type dev_type; /**< device bus type */
+ void *hwdev; /**< sdk驱动内部的硬件设备指针 */
+ struct device *dev; /**< 关联的struct device */
+ enum hinic5_dev_type dev_type; /**< device bus type */
};
/**
* @brief struct hinic5_uld_info
- * @details Defines a structure for storing user-level driver (uld) information
+ * @details 定义了一个结构体,用于存储用户层驱动(uld)的信息
*/
struct hinic5_uld_info {
/* When the function does not need to initialize the corresponding uld,
* @probe needs to return 0 and uld_dev is set to NULL;
* if uld_dev is NULL, @remove will not be called when uninstalling
*/
- int (*probe)(struct hinic5_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name); /**< Initialize user-level driver function */
- void (*remove)(struct hinic5_lld_dev *lld_dev, void *uld_dev); /**< Remove user-level driver function */
- int (*suspend)(struct hinic5_lld_dev *lld_dev, void *uld_dev, pm_message_t state); /**< Suspend user-level driver function */
- int (*resume)(struct hinic5_lld_dev *lld_dev, void *uld_dev); /**< Resume user-level driver function */
- void (*event)(struct hinic5_lld_dev *lld_dev, void *uld_dev, /**< Event handling function */
+ int (*probe)(struct hinic5_lld_dev *lld_dev, void **uld_dev,
+ char *uld_dev_name); /**< 初始化用户层驱动的函数 */
+ void (*remove)(struct hinic5_lld_dev *lld_dev,
+ void *uld_dev); /**< 移除用户层驱动的函数 */
+ int (*suspend)(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ pm_message_t state); /**< 挂起用户层驱动的函数 */
+ int (*resume)(struct hinic5_lld_dev *lld_dev,
+ void *uld_dev); /**< 恢复用户层驱动的函数 */
+ void (*event)(struct hinic5_lld_dev *lld_dev,
+ void *uld_dev, /**< 处理事件的函数 */
struct hinic5_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size, /**< Execute ioctl operation function */
+ int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in,
+ u32 in_size, /**< 执行ioctl操作的函数 */
void *buf_out, u32 *out_size);
};
@@ -85,47 +74,49 @@ struct hinic5_uld_info {
* @retval non-zero: failure
*/
-int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev, u32 *dev_cnt, void *array[]);
+int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev,
+ uint32_t *dev_cnt, void *array[]);
/**
- * @brief Register user-level driver
- * @param type Service type
- * @param uld_info User-level driver information
+ * @brief 注册用户层驱动
+ * @param type 服务类型
+ * @param uld_info 用户层驱动信息
*
- * @details This function is used to register user-level driver based on the provided service type and user-level driver information
+ * @details 此函数用于注册用户层驱动,根据提供的服务类型和用户层驱动信息进行注册
*
* @return
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_register_uld(enum hinic5_service_type type, struct hinic5_uld_info *uld_info);
+int hinic5_register_uld(enum hinic5_service_type type,
+ struct hinic5_uld_info *uld_info);
/**
- * @brief Unregister user-defined upper driver module
- * @param type Service type enumeration
+ * @brief 注销用户定义的上层驱动模块
+ * @param type 服务类型枚举
*
- * @details This function is used to unregister user-defined upper driver module
+ * @details 此函数用于注销用户定义的上层驱动模块
*
- * @return None
+ * @return 无
*/
void hinic5_unregister_uld(enum hinic5_service_type type);
/**
- * @brief Wait for LLD device node change to complete
+ * @brief 等待LLD设备节点的改变完成
*
- * @details Before calling this function, ensure no device node is being changed
+ * @details 在调用此函数前,需要确保没有任何设备节点正在改变
*
- * @return None
+ * @return 无
*/
-void hinic5_lld_hold(void);
+void lld_hold(void);
/**
- * @brief This function is used to release the global lock
+ * @brief 此函数用于释放全局锁
*
- * @details Decrements device reference count through atomic operation. If reference count is 0, it means no device is using the lock and can be released
+ * @details 通过原子操作递减设备引用计数,如果引用计数为0,则表示没有设备在使用该锁,可以进行释放
*
- * @return None
+ * @return 无
*/
-void hinic5_lld_put(void);
+void lld_put(void);
/**
* @brief hinic5_get_lld_dev_by_chip_name - get lld device by chip name
@@ -134,7 +125,7 @@ void hinic5_lld_put(void);
* @details The value of lld_dev reference increases when lld_dev is obtained. The caller needs
* to release the reference by calling hinic5_lld_dev_put.
*
- * @return lld device
+ * @return 返回lld设备
*/
struct hinic5_lld_dev *hinic5_get_lld_dev_by_chip_name(const char *chip_name);
@@ -162,10 +153,11 @@ void hinic5_lld_dev_put(struct hinic5_lld_dev *dev);
* @details The value of lld_dev reference increases when lld_dev is obtained. The caller needs
* to release the reference by calling hinic5_lld_dev_put.
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic5_service_type type);
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_dev_name(const char *dev_name,
+ enum hinic5_service_type type);
/**
* @brief hinic5_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
@@ -178,27 +170,30 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name(const char *dev_name,
* The caller must ensure that lld_dev will not be freed during the remove process
* when using lld_dev.
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic5_service_type type);
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
+ enum hinic5_service_type type);
/**
* @brief hinic5_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
* @param chip_name: chip name
* @param port_id: port id
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
/**
* @brief hinic5_get_lld_dev_with_l3i_enabled - get lld device which enables BAT L3I
* @param chip_name: chip name
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
-struct hinic5_lld_dev *hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name);
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name);
/**
* @brief hinic5_get_ppf_lld_dev - get ppf lld device by current function's lld device
@@ -207,7 +202,7 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name
* @details The value of lld_dev reference increases when lld_dev is obtained. The caller needs
* to release the reference by calling hinic5_lld_dev_put.
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
struct hinic5_lld_dev *hinic5_get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev);
@@ -220,9 +215,10 @@ struct hinic5_lld_dev *hinic5_get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev);
* The caller must ensure that ppf's lld_dev will not be freed during the remove process
* when using ppf lld_dev.
*
- * @return Returns LLD device on success, otherwise returns NULL
+ * @return 如果成功,返回LLD设备,否则返回NULL
*/
-struct hinic5_lld_dev *hinic5_get_ppf_lld_dev_unsafe(struct hinic5_lld_dev *lld_dev);
+struct hinic5_lld_dev *
+hinic5_get_ppf_lld_dev_unsafe(struct hinic5_lld_dev *lld_dev);
/**
* @brief hinic5_get_ppf_hw_dev_unsafe - get any ppf hw device in current host by current function's hw device
@@ -234,22 +230,24 @@ struct hinic5_lld_dev *hinic5_get_ppf_lld_dev_unsafe(struct hinic5_lld_dev *lld_
void *hinic5_get_ppf_hw_dev_unsafe(void *hwdev);
/**
- * @brief hinic5_uld_dev_hold - get reference to uld_dev
+ * @brief uld5_dev_hold - get reference to uld_dev
* @param lld_dev: lld device
* @param type: uld service type
*
* @details Hold reference to uld device to keep it from being freed
*/
-void hinic5_uld_dev_hold(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+void uld5_dev_hold(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
- * @brief hinic5_uld_dev_put - release reference to lld_dev
+ * @brief uld5_dev_put - release reference to lld_dev
* @param dev: lld device
* @param type: uld service type
*
* @details Release reference to uld device to allow it to be freed
*/
-void hinic5_uld_dev_put(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+void uld5_dev_put(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
* @brief hinic5_get_uld_dev - get uld device by lld device
@@ -257,9 +255,10 @@ void hinic5_uld_dev_put(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type
* @param type: uld service type
*
* @details The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling hinic5_uld_dev_put.
+ * to release the reference by calling uld5_dev_put.
*/
-void *hinic5_get_uld_dev(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+void *hinic5_get_uld_dev(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
* @brief hinic5_get_uld_dev_unsafe - get uld device by lld device
@@ -270,7 +269,8 @@ void *hinic5_get_uld_dev(struct hinic5_lld_dev *lld_dev, enum hinic5_service_typ
* The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
* The caller must ensure that uld_dev will not be freed during the remove process when using uld_dev.
*/
-void *hinic5_get_uld_dev_unsafe(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+void *hinic5_get_uld_dev_unsafe(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
* @brief hinic5_get_chip_name - get chip name by lld device
@@ -278,129 +278,137 @@ void *hinic5_get_uld_dev_unsafe(struct hinic5_lld_dev *lld_dev, enum hinic5_serv
* @param chip_name: String for storing the chip name
* @param max_len: Maximum number of characters to be copied for chip_name
*
- * @return 0 on success, other values on failure
+ * @attention 此接口即将日落, 有需求请优先使用hinic5_get_chip_node_id_by_hwdev接口
+ *
+ * @return 0 成功,其他值 失败
*/
-int hinic5_get_chip_name(struct hinic5_lld_dev *lld_dev, char *chip_name, u16 max_len);
+int hinic5_get_chip_name(struct hinic5_lld_dev *lld_dev, char *chip_name,
+ u16 max_len);
/**
- * @brief Get SDK hardware device
- * @param lld_dev Low-level driver device
+ * @brief 获取SDK硬件设备
+ * @param lld_dev 低层驱动设备
*
- * @return Returns SDK hardware device
+ * @return 返回SDK硬件设备
*/
void *hinic5_get_sdk_hwdev_by_lld(struct hinic5_lld_dev *lld_dev);
/**
- * @brief Set VF service enable switch, only PF calls
- * @param lld_dev Device structure pointer
- * @param service Service type
- * @param vf_srv_load Whether to enable virtual function service load
+ * @brief 设置VF业务(service)的使能开关,仅PF调用
+ * @param lld_dev 设备结构体指针
+ * @param service 服务类型
+ * @param vf_srv_load 是否启用虚拟函数服务负载
*
- * @return Returns 0 on success, otherwise returns error code
+ * @return 返回0表示成功,否则返回错误码
*/
int hinic5_set_vf_service_load(struct hinic5_lld_dev *lld_dev, u16 service,
bool vf_srv_load);
/**
- * @brief Set VF load enable flag for this service
- * @param lld_dev Physical device
- * @param vf_func_id Virtual function ID
- * @param service Service type
- * @param en Whether to enable
+ * @brief 设置该服务的VF加载使能标志位
+ * @param lld_dev 物理设备
+ * @param vf_func_id 虚拟函数ID
+ * @param service 服务类型
+ * @param en 是否启用
*
- * @return Returns 0 on success, otherwise returns error code
+ * @return 返回0表示成功,否则返回错误码
*/
int hinic5_set_vf_service_state(struct hinic5_lld_dev *lld_dev, u16 vf_func_id,
u16 service, bool en);
/**
- * @brief Set VF load enable flag
- * @param lld_dev Device structure pointer
- * @param vf_load_state Virtual function load state
+ * @brief 设置VF的加载使能标志
+ * @param lld_dev 设备结构体指针
+ * @param vf_load_state 虚拟函数加载状态
*
- * @return Returns 0 on success, otherwise returns error code
+ * @return 返回0表示成功,否则返回错误码
*/
-int hinic5_set_vf_load_state(struct hinic5_lld_dev *lld_dev, bool vf_load_state);
+int hinic5_set_vf_load_state(struct hinic5_lld_dev *lld_dev,
+ bool vf_load_state);
/**
- * @brief Attach NIC device
- * @param lld_dev Low-level device structure pointer
+ * @brief 绑定NIC设备
+ * @param lld_dev 低层设备结构体指针
*
- * @return Returns 0 on success, otherwise returns error code
+ * @return 返回0表示成功,否则返回错误码
*/
int hinic5_attach_nic(struct hinic5_lld_dev *lld_dev);
/**
- * @brief Detach NIC
- * @param lld_dev Device low-level driver information
+ * @brief 解除网卡
+ * @param lld_dev 设备的底层驱动信息
*
- * @return None
+ * @return 无
*/
void hinic5_detach_nic(const struct hinic5_lld_dev *lld_dev);
/**
- * @brief Attach specified service type to device
- * @param lld_dev Device low-level driver information
- * @param type Service type
+ * @brief 将指定的服务类型附加到设备上
+ * @param lld_dev 设备的底层驱动信息
+ * @param type 服务类型
*
- * @return Returns 0 on success, otherwise returns error code
+ * @return 成功返回0,失败返回错误码
*/
-int hinic5_attach_service(const struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+int hinic5_attach_service(const struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
- * @brief hinic5_detach_service function is used to detach service
- * @param lld_dev Device low-level driver information
- * @param type Service type
+ * @brief hinic5_detach_service 函数的作用是解除服务
+ * @param lld_dev 设备的底层驱动信息
+ * @param type 服务类型
*
- * @return None
+ * @return 无
*/
-void hinic5_detach_service(const struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type);
+void hinic5_detach_service(const struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type);
/**
- * @brief Called before unregistering uld, executes cleanup callback
+ * @brief 注销uld前调用,执行cleanup回调
*
- * @param type ULD service type
- * @param cleanup Callback
+ * @param type ULD服务类型
+ * @param cleanup 回调
*
- * @details All functions with ULD loaded, call cleanup callback in order
+ * @details 加载了ULD的所有function,按顺序调用cleanup回调
*
* @attention: NA
*
* @return: NA
*/
-void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type, void (*cleanup)(void *));
+void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type,
+ void (*cleanup)(void *));
/**
- * @brief hinic5_get_vf_num function is used to get the number of enabled VFs for pci/ub device
- * @param lld_dev Device low-level driver information
+ * @brief hinic5_get_vf_num 函数的作用是获取pci/ub设备使能的vf数
+ * @param lld_dev 设备的底层驱动信息
*
- * @return Number of enabled VFs
+ * @return 使能的vf数
*/
int hinic5_get_vf_num(struct hinic5_lld_dev *lld_dev);
/**
- * @brief hinic5_get_chip_node_id function is used to get the chip_node id to which pci/ub device belongs
- * @param lld_dev Device low-level driver information
+ * @brief hinic5_get_chip_node_id 函数的作用是获取pci/ub设备归属的chip_node id
+ * @param lld_dev 设备的底层驱动信息
+ *
+ * @attention 此接口即将日落, 有需求请使用hinic5_get_chip_node_id_by_hwdev接口
*
* @return chip_node id
*/
int hinic5_get_chip_node_id(struct hinic5_lld_dev *lld_dev, u64 *chip_node_id);
/**
- * @brief Get device information
+ * @brief 获取设备信息
*
- * @param[in] lld_dev Device
- * @param[out] info Return device information
+ * @param[in] lld_dev 设备
+ * @param[out] info 返回设备信息
*
* @details NULL
*
* @attention: NULL
*
- * @return: Describes function return value.
- * @retval 0 Success
- * @retval non-zero Error code
+ * @return: 描述函数返回值.
+ * @retval 0 成功
+ * @retval 非0 错误码
*/
-int hinic5_get_device_info(struct hinic5_lld_dev *lld_dev, struct hinic5_device_info *info);
-int hinic5_lld_init(void);
-void hinic5_lld_exit(void);
+int hinic5_get_device_info(struct hinic5_lld_dev *lld_dev,
+ struct hinic5_device_info *info);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_mt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_mt.h
index c7ecad6f9..271cec2a1 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_mt.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_mt.h
@@ -1,24 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_MT_H
#define HINIC5_MT_H
#include <linux/types.h>
-#ifdef __HIFC__ /**< If __HIFC__ macro is defined */
-#define HINIC5_DRV_NAME "hifc3" /**< Define driver name as hifc3 */
-#define HINIC5_CHIP_NAME "hifc" /**< Define chip name as hifc */
-#else /**< If __HIFC__ macro is not defined */
-#define HINIC5_DRV_NAME "hisdk5" /**< Define driver name as hisdk5 */
-#define HINIC5_CHIP_NAME "hinic" /**< Define chip name as hinic */
+#ifdef __HIFC__ /**< 如果定义了__HIFC__宏 */
+#define HINIC5_DRV_NAME "hifc5" /**< 定义驱动名为 hifc5 */
+#define HINIC5_CHIP_NAME "hifc" /**< 定义芯片名为 hifc */
+#else /**< 如果没有定义__HIFC__宏 */
+#define HINIC5_DRV_NAME "hisdk5" /**< 定义驱动名为 hisdk5 */
+#define HINIC5_CHIP_NAME "hinic" /**< 定义芯片名为 hinic */
#endif
/* Interrupt at most records, interrupt will be recorded in the FFM */
@@ -26,40 +19,40 @@
/**
* @brief struct api_cmd_rd
- * @details Structure for receiving API commands
+ * @details 用于接收API命令的结构体
*/
struct api_cmd_rd {
- u32 pf_id; /**< pf id */
- u8 dest; /**< node id */
- u8 *cmd; /**< Pointer to API command */
- u16 size; /**< Command size */
- void *ack; /**< Pointer to command acknowledgment information */
- u16 ack_size; /**< Acknowledgment information size */
+ u32 pf_id; /**< pf id */
+ u8 dest; /**< node id */
+ u8 *cmd; /**< 指向API命令的指针 */
+ u16 size; /**< 表示命令的大小 */
+ void *ack; /**< 指向命令的确认信息的指针 */
+ u16 ack_size; /**< 表示确认信息的大小 */
};
/**
* @brief struct api_cmd_wr
- * @details Structure for API command write operation
+ * @details 用于API命令写操作的结构体
*/
struct api_cmd_wr {
- u32 pf_id; /**< pf id */
- u8 dest; /**< node id */
- u8 *cmd; /**< Pointer to API command */
- u16 size; /**< Command size */
+ u32 pf_id; /**< pf id */
+ u8 dest; /**< node id */
+ u8 *cmd; /**< 指向API命令的指针 */
+ u16 size; /**< 表示命令的大小 */
};
-#define PF_DEV_INFO_NUM 32
+#define PF_DEV_INFO_NUM 32
/**
* @brief struct pf_dev_info
- * @details Structure for storing PCI device information
+ * @details 存储PCI设备的信息的结构体
*/
struct pf_dev_info {
- u64 bar0_size; /**< bar0 size */
- u8 bus; /**< PCI device bus number */
- u8 slot; /**< PCI device slot number */
- u8 func; /**< PCI device function number */
- u64 phy_addr; /**< PCI device physical address */
+ u64 bar0_size; /**< bar0的大小 */
+ u8 bus; /**< PCI设备的总线号 */
+ u8 slot; /**< PCI设备的插槽号 */
+ u8 func; /**< PCI设备的功能号 */
+ u64 phy_addr; /**< PCI设备的物理地址 */
};
/**
@@ -70,93 +63,94 @@ struct pf_dev_info {
/**
* @brief struct ffm_intr_info
- * @details Structure for storing interrupt information
+ * @details 存储中断信息的结构体
*/
struct ffm_intr_info {
- u8 node_id; /**< Interrupt source node ID */
- u8 err_level; /**< Interrupt source error level */
- u16 err_type; /**< Interrupt source error type */
- u32 err_csr_addr; /**< Interrupt source address */
- u32 err_csr_value; /**< Interrupt source value */
+ u8 node_id; /**< 中断源的节点ID */
+ u8 err_level; /**< 中断源的错误级别 */
+ u16 err_type; /**< 中断源的错误类型 */
+ u32 err_csr_addr; /**< 中断源的地址 */
+ u32 err_csr_value; /**< 中断源的值 */
};
/**
* @brief struct ffm_intr_tm_info
- * @details Structure for storing interrupt and time information
+ * @details 存储中断信息和时间信息的结构体
*/
struct ffm_intr_tm_info {
- struct ffm_intr_info intr_info; /**< Interrupt information */
- u8 times; /**< Time */
- u8 sec; /**< Second */
- u8 min; /**< Minute */
- u8 hour; /**< Hour */
- u8 mday; /**< Day of month */
- u8 mon; /**< Month */
- u16 year; /**< Year */
+ struct ffm_intr_info intr_info; /**< 中断信息 */
+ u8 times; /**< 时间 */
+ u8 sec; /**< 秒 */
+ u8 min; /**< 分钟 */
+ u8 hour; /**< 小时 */
+ u8 mday; /**< 日期 */
+ u8 mon; /**< 月份 */
+ u16 year; /**< 年份 */
};
/**
* @brief struct ffm_record_info
- * @details Structure for storing FFM record information
+ * @details 用于存储FFM记录信息的结构体
*/
struct ffm_record_info {
- u32 ffm_num; /**< FFM number */
- u32 last_err_csr_addr; /**< Last error CSR address */
- u32 last_err_csr_value; /**< Last error CSR value */
- struct ffm_intr_tm_info ffm[FFM_RECORD_NUM_MAX]; /**< FFM interrupt time information array */
+ u32 ffm_num; /**< FFM编号 */
+ u32 last_err_csr_addr; /**< 最后一次错误的CSR地址 */
+ u32 last_err_csr_value; /**< 最后一次错误的CSR值 */
+ struct ffm_intr_tm_info
+ ffm[FFM_RECORD_NUM_MAX]; /**< FFM中断时间信息数组 */
};
/**
* @brief struct dbgtool_k_glb_info
- * @details Structure for storing debug tool global information
+ * @details 存储调试工具的全局信息的结构体
*/
struct dbgtool_k_glb_info {
- struct semaphore dbgtool_sem; /**< Semaphore for synchronizing debug tool threads */
- struct ffm_record_info *ffm; /**< FFM record information */
+ struct semaphore dbgtool_sem; /**< 信号量,用于同步调试工具的线程 */
+ struct ffm_record_info *ffm; /**< 存储ffm记录信息 */
};
/**
* @brief struct msg_2_up
- * @details Structure for storing uplink message related information
+ * @details 存储上行消息的相关信息的结构体
*/
struct msg_2_up {
- u8 pf_id; /**< Protocol ID */
- u8 mod; /**< Module ID */
- u8 cmd; /**< Command ID */
- void *buf_in; /**< Input buffer pointer */
- u16 in_size; /**< Input buffer size */
- void *buf_out; /**< Output buffer pointer */
- u16 *out_size; /**< Output buffer size pointer */
+ u8 pf_id; /**< 协议ID */
+ u8 mod; /**< 模块ID */
+ u8 cmd; /**< 命令ID */
+ void *buf_in; /**< 输入缓冲区指针 */
+ u16 in_size; /**< 输入缓冲区大小 */
+ void *buf_out; /**< 输出缓冲区指针 */
+ u16 *out_size; /**< 输出缓冲区大小指针 */
};
/**
* @brief struct dbgtool_param
- * @details Debug tool parameter structure
+ * @details 调试工具参数结构体
*/
struct dbgtool_param {
union {
- struct api_cmd_rd api_rd; /**< Read command */
- struct api_cmd_wr api_wr; /**< Write command */
- struct pf_dev_info *dev_info; /**< Device information */
- struct ffm_record_info *ffm_rd; /**< FFM record information */
- struct msg_2_up msg2up; /**< Uplink message */
+ struct api_cmd_rd api_rd; /**< 读取命令 */
+ struct api_cmd_wr api_wr; /**< 写入命令 */
+ struct pf_dev_info *dev_info; /**< 设备信息 */
+ struct ffm_record_info *ffm_rd; /**< FFM记录信息 */
+ struct msg_2_up msg2up; /**< 上行消息 */
} param;
- char chip_name[16]; /**< Chip name */
+ char chip_name[16]; /**< 芯片名称 */
};
/**
* @brief typedef enum
- * @details Represents debug tool command types
+ * @details 表示调试工具的命令类型
*/
typedef enum {
- DBGTOOL_CMD_API_RD = 0, /**< Read API command */
- DBGTOOL_CMD_API_WR, /**< Write API command */
- DBGTOOL_CMD_FFM_RD, /**< Read FFM command */
- DBGTOOL_CMD_FFM_CLR, /**< Clear FFM command */
- DBGTOOL_CMD_PF_DEV_INFO_GET, /**< Get PF device info command */
- DBGTOOL_CMD_MSG_2_UP, /**< Send message to upper layer command */
- DBGTOOL_CMD_FREE_MEM, /**< Free memory command */
- DBGTOOL_CMD_NUM /**< Number of command types */
+ DBGTOOL_CMD_API_RD = 0, /**< 读取API命令 */
+ DBGTOOL_CMD_API_WR, /**< 写入API命令 */
+ DBGTOOL_CMD_FFM_RD, /**< 读取FFM命令 */
+ DBGTOOL_CMD_FFM_CLR, /**< 清除FFM命令 */
+ DBGTOOL_CMD_PF_DEV_INFO_GET, /**< 获取PF设备信息命令 */
+ DBGTOOL_CMD_MSG_2_UP, /**< 将消息发送到上层命令 */
+ DBGTOOL_CMD_FREE_MEM, /**< 释放内存命令 */
+ DBGTOOL_CMD_NUM /**< 命令类型数量 */
} dbgtool_cmd;
#define PF_MAX_SIZE (16)
@@ -165,305 +159,313 @@ typedef enum {
/**
* @brief enum module_name
- * @details Represents different module names
+ * @details 表示不同的模块名称
*/
enum module_name {
- SEND_TO_NPU = 1, /**< Send to NPU module */
- SEND_TO_MPU, /**< Send to MPU module */
- SEND_TO_SM, /**< Send to SM module */
- SEND_TO_HW_DRIVER, /**< Send to hardware driver */
+ SEND_TO_NPU = 1, /**< 发送到NPU模块 */
+ SEND_TO_MPU, /**< 发送到MPU模块 */
+ SEND_TO_SM, /**< 发送到SM模块 */
+ SEND_TO_HW_DRIVER, /**< 发送到硬件驱动 */
#define SEND_TO_SRV_DRV_BASE (SEND_TO_HW_DRIVER + 1)
- SEND_TO_NIC_DRIVER = SEND_TO_SRV_DRV_BASE, /**< Send to network interface controller driver */
- SEND_TO_OVS_DRIVER, /**< Send to Open vSwitch driver */
- SEND_TO_ROCE_DRIVER, /**< Send to RDMA over Converged Ethernet driver */
- SEND_TO_TOE_DRIVER, /**< Send to TCP offload driver */
- SEND_TO_IOE_DRIVER, /**< Send to I/O acceleration driver */
- SEND_TO_FC_DRIVER, /**< Send to Fibre Channel driver */
- SEND_TO_VBS_DRIVER, /**< Send to virtual block storage driver */
- SEND_TO_IPSEC_DRIVER, /**< Send to IPsec driver */
- SEND_TO_VIRTIO_DRIVER, /**< Send to Virtio driver */
- SEND_TO_MIGRATE_DRIVER, /**< Send to migration driver */
- SEND_TO_PPA_DRIVER, /**< Send to PPA driver */
- SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11, /**< Send to custom driver */
- SEND_TO_VROCE_DRIVER, /**< Send to vRDMA over Converged Ethernet driver */
- SEND_TO_UB_DRIVER, /**< Send to UB driver */
- SEND_TO_JBOF_DRIVER, /**< Send to Jumbo Frame offload driver */
- SEND_TO_MACSEC_DRIVER, /**< Send to MACsec driver */
+ SEND_TO_NIC_DRIVER =
+ SEND_TO_SRV_DRV_BASE, /**< 发送到网络接口控制器驱动 */
+ SEND_TO_OVS_DRIVER, /**< 发送到Open vSwitch驱动 */
+ SEND_TO_ROCE_DRIVER, /**< 发送到RDMA over Converged Ethernet驱动 */
+ SEND_TO_TOE_DRIVER, /**< 发送到TCP offload驱动 */
+ SEND_TO_IOE_DRIVER, /**< 发送到I/O加速驱动 */
+ SEND_TO_FC_DRIVER, /**< 发送到光纤通道驱动 */
+ SEND_TO_VBS_DRIVER, /**< 发送到虚拟阻塞存储驱动 */
+ SEND_TO_IPSEC_DRIVER, /**< 发送到IPsec驱动 */
+ SEND_TO_VIRTIO_DRIVER, /**< 发送到Virtio驱动 */
+ SEND_TO_MIGRATE_DRIVER, /**< 发送到迁移驱动 */
+ SEND_TO_PPA_DRIVER, /**< 发送到PPA驱动 */
+ SEND_TO_CUSTOM_DRIVER =
+ SEND_TO_SRV_DRV_BASE + 11, /**< 发送到自定义驱动 */
+ SEND_TO_VROCE_DRIVER, /**< 发送到vRDMA over Converged Ethernet驱动 */
+ SEND_TO_UB_DRIVER, /**< 发送到UB驱动 */
+ SEND_TO_JBOF_DRIVER, /**< 发送到Jumbo Frame offload驱动 */
+ SEND_TO_MACSEC_DRIVER, /**< 发送到MACsec驱动 */
SEND_TO_BIFUR_DRIVER = SEND_TO_MACSEC_DRIVER + 3,
- SEND_TO_HIHTR_DRIVER, /**< Send to Hihtr driver */
+ SEND_TO_HIHTR_DRIVER, /**< 发送到Hihtr驱动 */
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 20, /* reserved */
};
/**
* @brief enum driver_cmd_type
- * @details Defines driver command type enumeration
+ * @details 定义驱动命令类型枚举
*/
enum driver_cmd_type {
- TX_INFO = 0x1, /**< Transmit information */
- Q_NUM = 0x2, /**< Queue number */
- TX_WQE_INFO = 0x3, /**< Transmit work queue information */
- TX_MAPPING = 0x4, /**< Transmit mapping */
- RX_INFO = 0x5, /**< Receive information */
- RX_WQE_INFO = 0x6, /**< Receive work queue information */
- RX_CQE_INFO = 0x7, /**< Receive completion queue information */
- UPRINT_FUNC_EN = 0x8, /**< Print function enable */
- UPRINT_FUNC_RESET = 0x9, /**< Print function reset */
- UPRINT_SET_PATH = 0xa, /**< Set print path */
- UPRINT_GET_STATISTICS = 0xb, /**< Get print statistics */
- FUNC_TYPE = 0xc, /**< Function type */
- GET_FUNC_IDX = 0xd, /**< Get function index */
- GET_INTER_NUM = 0xe, /**< Get internal number */
- CLOSE_TX_STREAM = 0xf, /**< Close transmit stream */
- GET_DRV_VERSION = 0x10, /**< Get driver version */
- CLEAR_FUNC_STASTIC = 0x11, /**< Clear function statistics */
- GET_HW_STATS = 0x12, /**< Get hardware statistics */
- CLEAR_HW_STATS = 0x13, /**< Clear hardware statistics */
- GET_SELF_TEST_RES = 0x14, /**< Get self test result */
- GET_CHIP_FAULT_STATS = 0x15, /**< Get chip fault statistics */
+ TX_INFO = 0x1, /**< 发送信息 */
+ Q_NUM = 0x2, /**< 队列数量 */
+ TX_WQE_INFO = 0x3, /**< 发送工作队列信息 */
+ TX_MAPPING = 0x4, /**< 发送映射 */
+ RX_INFO = 0x5, /**< 接收信息 */
+ RX_WQE_INFO = 0x6, /**< 接收工作队列信息 */
+ RX_CQE_INFO = 0x7, /**< 接收完成队列信息 */
+ UPRINT_FUNC_EN = 0x8, /**< 打印功能启用 */
+ UPRINT_FUNC_RESET = 0x9, /**< 打印功能重置 */
+ UPRINT_SET_PATH = 0xa, /**< 设置打印路径 */
+ UPRINT_GET_STATISTICS = 0xb, /**< 获取打印统计信息 */
+ FUNC_TYPE = 0xc, /**< 功能类型 */
+ GET_FUNC_IDX = 0xd, /**< 获取功能索引 */
+ GET_INTER_NUM = 0xe, /**< 获取内部数量 */
+ CLOSE_TX_STREAM = 0xf, /**< 关闭发送流 */
+ GET_DRV_VERSION = 0x10, /**< 获取驱动版本 */
+ CLEAR_FUNC_STASTIC = 0x11, /**< 清除功能统计信息 */
+ GET_HW_STATS = 0x12, /**< 获取硬件统计信息 */
+ CLEAR_HW_STATS = 0x13, /**< 清除硬件统计信息 */
+ GET_SELF_TEST_RES = 0x14, /**< 获取自我测试结果 */
+ GET_CHIP_FAULT_STATS = 0x15, /**< 获取芯片故障统计信息 */
NIC_RSVD1 = 0x16,
NIC_RSVD2 = 0x17,
NIC_RSVD3 = 0x18,
- GET_CHIP_ID = 0x19, /**< Get chip ID */
- GET_SINGLE_CARD_INFO = 0x1a, /**< Get single card information */
- GET_FIRMWARE_ACTIVE_STATUS = 0x1b, /**< Get firmware active status */
- ROCE_DFX_FUNC = 0x1c, /**< RoCE debug function */
- GET_DEVICE_ID = 0x1d, /**< Get device ID */
- GET_PF_DEV_INFO = 0x1e, /**< Get PF device information */
- CMD_FREE_MEM = 0x1f, /**< Free memory */
- GET_LOOPBACK_MODE = 0x20, /**< Get loopback mode */
- SET_LOOPBACK_MODE = 0x21, /**< Set loopback mode */
- SET_LINK_MODE = 0x22, /**< Set link mode */
- SET_PF_BW_LIMIT = 0x23, /**< Set PF bandwidth limit */
- GET_PF_BW_LIMIT = 0x24, /**< Get PF bandwidth limit */
- ROCE_CMD = 0x25, /**< RoCE command */
- GET_POLL_WEIGHT = 0x26, /**< Get poll weight */
- SET_POLL_WEIGHT = 0x27, /**< Set poll weight */
- GET_HOMOLOGUE = 0x28, /**< Get peer information */
- SET_HOMOLOGUE = 0x29, /**< Set peer information */
- GET_SSET_COUNT = 0x2a, /**< Get statistics count */
- GET_SSET_ITEMS = 0x2b, /**< Get statistics items */
- IS_DRV_IN_VM = 0x2c, /**< Check if in VM */
- LRO_ADPT_MGMT = 0x2d, /**< Manage LRO adapter */
- SET_INTER_COAL_PARAM = 0x2e, /**< Set interrupt coalescing parameters */
- GET_INTER_COAL_PARAM = 0x2f, /**< Get interrupt coalescing parameters */
- GET_CHIP_INFO = 0x30, /**< Get chip information */
- GET_NIC_STATS_LEN = 0x31, /**< Get NIC statistics length */
- GET_NIC_STATS_STRING = 0x32, /**< Get NIC statistics string */
- GET_NIC_STATS_INFO = 0x33, /**< Get NIC statistics information */
- GET_PF_ID = 0x34, /**< Get PF ID */
- GET_MBOX_CNT = 0x35, /**< Get mailbox count */
+ GET_CHIP_ID = 0x19, /**< 获取芯片ID */
+ GET_SINGLE_CARD_INFO = 0x1a, /**< 获取单卡信息 */
+ GET_FIRMWARE_ACTIVE_STATUS = 0x1b, /**< 获取固件活动状态 */
+ ROCE_DFX_FUNC = 0x1c, /**< RoCE调试功能 */
+ GET_DEVICE_ID = 0x1d, /**< 获取设备ID */
+ GET_PF_DEV_INFO = 0x1e, /**< 获取PF设备信息 */
+ CMD_FREE_MEM = 0x1f, /**< 释放内存 */
+ GET_LOOPBACK_MODE = 0x20, /**< 获取环回模式 */
+ SET_LOOPBACK_MODE = 0x21, /**< 设置环回模式 */
+ SET_LINK_MODE = 0x22, /**< 设置链接模式 */
+ SET_PF_BW_LIMIT = 0x23, /**< 设置PF带宽限制 */
+ GET_PF_BW_LIMIT = 0x24, /**< 获取PF带宽限制 */
+ ROCE_CMD = 0x25, /**< RoCE命令 */
+ GET_POLL_WEIGHT = 0x26, /**< 获取轮询权重 */
+ SET_POLL_WEIGHT = 0x27, /**< 设置轮询权重 */
+ GET_HOMOLOGUE = 0x28, /**< 获取对端信息 */
+ SET_HOMOLOGUE = 0x29, /**< 设置对端信息 */
+ GET_SSET_COUNT = 0x2a, /**< 获取统计信息数量 */
+ GET_SSET_ITEMS = 0x2b, /**< 获取统计信息项 */
+ IS_DRV_IN_VM = 0x2c, /**< 判断是否在虚拟机中 */
+ LRO_ADPT_MGMT = 0x2d, /**< 管理LRO适配器 */
+ SET_INTER_COAL_PARAM = 0x2e, /**< 设置中断合并参数 */
+ GET_INTER_COAL_PARAM = 0x2f, /**< 获取中断合并参数 */
+ GET_CHIP_INFO = 0x30, /**< 获取芯片信息 */
+ GET_NIC_STATS_LEN = 0x31, /**< 获取NIC统计信息长度 */
+ GET_NIC_STATS_STRING = 0x32, /**< 获取NIC统计信息字符串 */
+ GET_NIC_STATS_INFO = 0x33, /**< 获取NIC统计信息 */
+ GET_PF_ID = 0x34, /**< 获取PF ID */
+ GET_MBOX_CNT = 0x35, /**< 获取mailbox数量 */
NIC_RSVD5 = 0x36,
- DCB_QOS_INFO = 0x37, /**< DCB QoS information */
- DCB_PFC_STATE = 0x38, /**< DCB PFC state */
- DCB_ETS_STATE = 0x39, /**< DCB ETS state */
- DCB_STATE = 0x3a, /**< DCB state */
- QOS_DEV = 0x3b, /**< QOS device */
- GET_QOS_COS = 0x3c, /**< Get QOS priority */
- GET_ULD_DEV_NAME = 0x3d, /**< Get ULD device name */
- GET_TX_TIMEOUT = 0x3e, /**< Get transmit timeout */
- SET_TX_TIMEOUT = 0x3f, /**< Set transmit timeout */
-
- RSS_CFG = 0x40, /**< RSS configuration */
- RSS_INDIR = 0x41, /**< RSS indirect table */
- PORT_ID = 0x42, /**< Port ID */
- BOND_DFX_OPS = 0x43, /**< BOND DFX operations */
-
- GET_FUNC_CAP = 0x50, /**< Get function capability */
- GET_XSFP_PRESENT = 0x51, /**< Get XSFP presence status */
- GET_XSFP_INFO = 0x52, /**< Get XSFP information */
- DEV_NAME_TEST = 0x53, /**< Device name test */
- GET_XSFP_INFO_COMP_CMIS = 0x54, /**< Get XSFP information (CMIS supported) */
+ DCB_QOS_INFO = 0x37, /**< DCB QoS信息 */
+ DCB_PFC_STATE = 0x38, /**< DCB PFC状态 */
+ DCB_ETS_STATE = 0x39, /**< DCB ETS状态 */
+ DCB_STATE = 0x3a, /**< DCB状态 */
+ QOS_DEV = 0x3b, /**< QOS设备 */
+ GET_QOS_COS = 0x3c, /**< 获取QOS优先级 */
+ GET_ULD_DEV_NAME = 0x3d, /**< 获取ULD设备名称 */
+ GET_TX_TIMEOUT = 0x3e, /**< 获取发送超时 */
+ SET_TX_TIMEOUT = 0x3f, /**< 设置发送超时 */
+
+ RSS_CFG = 0x40, /**< RSS配置 */
+ RSS_INDIR = 0x41, /**< RSS间接表 */
+ PORT_ID = 0x42, /**< 端口ID */
+ BOND_DFX_OPS = 0x43, /**< BOND DFX操作 */
+
+ GET_FUNC_CAP = 0x50, /**< 获取功能能力 */
+ GET_XSFP_PRESENT = 0x51, /**< 获取XSFP存在状态 */
+ GET_XSFP_INFO = 0x52, /**< 获取XSFP信息 */
+ DEV_NAME_TEST = 0x53, /**< 设备名称测试 */
+ GET_XSFP_INFO_COMP_CMIS = 0x54, /**< 获取XSFP信息(支持CMIS) */
CMD_GET_PROFILE_ID = 0x55,
CMD_SET_PROFILE_ID = 0x56,
CMD_MOVE_TCAM_TABLE = 0x57,
- GET_WIN_STAT = 0x60, /**< Get window status */
- WIN_CSR_READ = 0x61, /**< Read window CSR */
- WIN_CSR_WRITE = 0x62, /**< Write window CSR */
- WIN_API_CMD_RD = 0x63, /**< Read window API command */
-
- ROCE_CMD_SET_LDCP_PARAM = 0x70, /**< RoCE command set LDCP parameter */
-
- ROCE_CMD_GET_QPC_FROM_CACHE = 0x80, /**< Get QPC from cache */
- ROCE_CMD_GET_QPC_FROM_HOST = 0x81, /**< Get QPC from host */
- ROCE_CMD_GET_CQC_FROM_CACHE = 0x82, /**< Get CQC from cache */
- ROCE_CMD_GET_CQC_FROM_HOST = 0x83, /**< Get CQC from host */
- ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84, /**< Get SRQC from cache */
- ROCE_CMD_GET_SRQC_FROM_HOST = 0x85, /**< Get SRQC from host */
- ROCE_CMD_GET_MPT_FROM_CACHE = 0x86, /**< Get MPT from cache */
- ROCE_CMD_GET_MPT_FROM_HOST = 0x87, /**< Get MPT from host */
- ROCE_CMD_GET_GID_FROM_CACHE = 0x88, /**< Get GID from cache */
- ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89, /**< Get QPC, CQC, PI, CI */
- ROCE_CMD_GET_QP_COUNT = 0x8a, /**< Get QP count */
- ROCE_CMD_GET_DEV_ALGO = 0x8b, /**< Get device algorithm */
- ROCE_CMD_GET_DEV_TYPE = 0x8c, /**< Get device type */
- ROCE_CMD_GET_HW_COUNT = 0x8d, /**< Get hardware count */
- ROCE_CMD_GET_SPECIFICATIONS = 0x8e, /**< Get device specifications from cache */
-
- ROCE_CMD_START_CAP_PACKET = 0x90, /**< Start packet capture */
- ROCE_CMD_STOP_CAP_PACKET = 0x91, /**< Stop packet capture */
- ROCE_CMD_QUERY_CAP_INFO = 0x92, /**< Query capture information */
- ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93, /**< Enable QP packet capture */
- ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94, /**< Disable QP packet capture */
- ROCE_CMD_QUERY_QP_CAP_INFO = 0x95, /**< Query QP capture information */
- ROCE_CMD_SET_BYPASS = 0x96, /**< Set bypass */
- ROCE_CMD_QUERY_BYPASS = 0x97, /**< Query bypass */
- ROCE_CMD_GET_AEQC_FROM_CACHE = 0x98, /**< Get AEQC from cache */
- ROCE_CMD_GET_AEQC_FROM_HOST = 0x99, /**< Get AEQC from host */
-
- ROCE_CMD_ENABLE_BW_CTRL = 0xa0, /**< Enable bandwidth control */
- ROCE_CMD_DISABLE_BW_CTRL = 0xa1, /**< Disable bandwidth control */
- ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2, /**< Change bandwidth control parameter */
- ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3, /**< Query bandwidth control parameter */
- ROCE_CMD_SET_BW_WATERLINE = 0xa4, /**< Set bandwidth watermark */
- ROCE_CMD_GET_BW_WATERLINE = 0xa5, /**< Get bandwidth watermark */
- ROCE_CMD_SET_VNIC_WATERLINE = 0xa6, /**< Set VNIC watermark */
- ROCE_CMD_GET_VNIC_WATERLINE = 0xa7, /**< Get VNIC watermark */
- ROCE_CMD_ROCE_SET = 0xa8, /**< Set ROCE related configuration */
- ROCE_CMD_DFX_LATCH_QUERY = 0xa9, /**< ROCE latch query */
-
- ROCE_CMD_TIMEOUT_ALARM = 0xb0, /**< Timeout alarm */
- ROCE_CMD_PORT_TRAFFIC = 0Xb1, /**< Port traffic */
- ROCE_CMD_DFX_ATTACK = 0Xb2, /**< ROCE host side attack prevention */
- ROCE_CMD_ULD_IOCTL_EXTEND = 0xb3, /**< User ioctl to driver entry */
-
- MIG_QUERY_DFX = 0xc0, /**< Query migration DFX */
-
- DRV_CMD_TYPE_RSV = 0xd0, /**< Reserved, cannot use */
-
- NIC_CMD_ANTI_ATTACK = 0xd6, /**< Anti-attack verification */
-
- VM_COMPAT_TEST = 0xFF, /**< VM compatibility test */
-
- SERVICE_DRV_BASE_CMD = 0x120, /**< Service commands start from 0x120, commands before 0x120 are reserved for future product use */
+ GET_WIN_STAT = 0x60, /**< 获取窗口状态 */
+ WIN_CSR_READ = 0x61, /**< 读取窗口CSR */
+ WIN_CSR_WRITE = 0x62, /**< 写入窗口CSR */
+ WIN_API_CMD_RD = 0x63, /**< 读取窗口API命令 */
+
+ ROCE_CMD_SET_LDCP_PARAM = 0x70, /**< RoCE命令设置LDCP参数 */
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80, /**< 从缓存获取QPC */
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81, /**< 从主机获取QPC */
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82, /**< 从缓存获取CQC */
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83, /**< 从主机获取CQC */
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84, /**< 从缓存获取SRQC */
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85, /**< 从主机获取SRQC */
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86, /**< 从缓存获取MPT */
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87, /**< 从主机获取MPT */
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88, /**< 从缓存获取GID */
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89, /**< 获取QPC、CQC、PI、CI */
+ ROCE_CMD_GET_QP_COUNT = 0x8a, /**< 获取QP数量 */
+ ROCE_CMD_GET_DEV_ALGO = 0x8b, /**< 获取设备算法 */
+ ROCE_CMD_GET_DEV_TYPE = 0x8c, /**< 获取设备类型 */
+ ROCE_CMD_GET_HW_COUNT = 0x8d, /**< 获取硬件计数 */
+ ROCE_CMD_GET_SPECIFICATIONS = 0x8e, /**< 从缓存获取设备的功能规格 */
+
+ ROCE_CMD_START_CAP_PACKET = 0x90, /**< 开始捕获数据包 */
+ ROCE_CMD_STOP_CAP_PACKET = 0x91, /**< 停止捕获数据包 */
+ ROCE_CMD_QUERY_CAP_INFO = 0x92, /**< 查询捕获信息 */
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93, /**< 启用QP捕获数据包 */
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94, /**< 禁用QP捕获数据包 */
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95, /**< 查询QP捕获信息 */
+ ROCE_CMD_SET_BYPASS = 0x96, /**< 设置bypass */
+ ROCE_CMD_QUERY_BYPASS = 0x97, /**< 查询bypass */
+ ROCE_CMD_GET_AEQC_FROM_CACHE = 0x98, /**< 从缓存获取AEQC */
+ ROCE_CMD_GET_AEQC_FROM_HOST = 0x99, /**< 从主机获取AEQC */
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0, /**< 启用带宽控制 */
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1, /**< 禁用带宽控制 */
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2, /**< 更改带宽控制参数 */
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3, /**< 查询带宽控制参数 */
+ ROCE_CMD_RSVD1 = 0xa4,
+ ROCE_CMD_RSVD2 = 0xa5,
+ ROCE_CMD_SET_VNIC_WATERLINE = 0xa6, /**< 设置VNIC水线值 */
+ ROCE_CMD_GET_VNIC_WATERLINE = 0xa7, /**< 获取VNIC水线值 */
+ ROCE_CMD_ROCE_SET = 0xa8, /**< 设置ROCE相关配置 */
+ ROCE_CMD_DFX_LATCH_QUERY = 0xa9, /**< ROCE锁存查询 */
+ ROCE_CMD_ROCE_SET_DEBUG = 0xaa, /**< DEBUG版本设置ROCE相关配置 */
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0, /**< 超时警告 */
+ ROCE_CMD_PORT_TRAFFIC = 0xb1, /**< 端口流量 */
+ ROCE_CMD_DFX_ATTACK = 0xb2, /**< ROCE主机侧防攻击 */
+ ROCE_CMD_ULD_IOCTL_EXTEND = 0xb3, /**< 用户ioctl到驱动的总入口 */
+
+ MIG_QUERY_DFX = 0xc0, /**< 查询迁移DFX */
+
+ DRV_CMD_TYPE_RSV = 0xd0, /**< 预留,不可使用 */
+
+ NIC_CMD_ANTI_ATTACK = 0xd6, /**< 防攻击验证 */
+
+ VM_COMPAT_TEST = 0xFF, /**< VM兼容性测试 */
+
+ SERVICE_DRV_BASE_CMD =
+ 0x120, /**< 业务命令字从0x120开始,0x120前面的预留给产品后续使用 */
};
/**
* @brief enum api_chain_cmd_type
- * @details Defines API chain command type enumeration
+ * @details 定义API链命令类型枚举
*/
enum api_chain_cmd_type {
- API_CSR_READ, /**< Read CSR (Control and Status Register) */
- API_CSR_WRITE /**< Write CSR (Control and Status Register) */
+ API_CSR_READ, /**< 读取CSR(控制和状态寄存器) */
+ API_CSR_WRITE /**< 写入CSR(控制和状态寄存器) */
};
/**
* @brief sm_cmd_type
- * @details Used to represent different command types
+ * @details 用于表示不同的命令类型
*/
enum sm_cmd_type {
- SM_CTR_RD16 = 1, /**< Command to read 16-bit data */
- SM_CTR_RD32, /**< Command to read 32-bit data */
- SM_CTR_RD64_PAIR, /**< Command to read 64-bit data pair */
- SM_CTR_RD64, /**< Command to read 64-bit data */
- SM_CTR_RD32_CLEAR, /**< Command to clear 32-bit data */
- SM_CTR_RD64_PAIR_CLEAR, /**< Command to clear 64-bit data pair */
- SM_CTR_RD64_CLEAR /**< Command to clear 64-bit data */
-};
-
-#define HINIC5_CQM_AEQ_CALLBACK_CNT_MAX 128 /* Consistent with HINIC5_CQM_AEQ_BASE_T_MAX */
-
-/**
- * @brief struct hinic5_cqm_stats
- * @details Statistics of various operations in HINIC5_CQM module
- */
-struct hinic5_cqm_stats {
- atomic_t hinic5_cqm_cmd_alloc_cnt; /**< Statistics of HINIC5_CQM command allocation count */
- atomic_t hinic5_cqm_cmd_free_cnt; /**< Statistics of HINIC5_CQM command free count */
- atomic_t hinic5_cqm_send_cmd_box_cnt; /**< Statistics of HINIC5_CQM send command box count */
- atomic_t hinic5_cqm_send_cmd_imm_cnt; /**< Statistics of HINIC5_CQM send command count */
- atomic_t hinic5_cqm_db_addr_alloc_cnt; /**< Statistics of HINIC5_CQM database address allocation count */
- atomic_t hinic5_cqm_db_addr_free_cnt; /**< Statistics of HINIC5_CQM database address free count */
- atomic_t hinic5_cqm_fc_srq_create_cnt; /**< Statistics of HINIC5_CQM FC SRQ creation count */
- atomic_t hinic5_cqm_srq_create_cnt; /**< Statistics of HINIC5_CQM SRQ creation count */
- atomic_t hinic5_cqm_rq_create_cnt; /**< Statistics of HINIC5_CQM RQ creation count */
- atomic_t hinic5_cqm_qpc_mpt_create_cnt; /**< Statistics of HINIC5_CQM QPC and MPT creation count */
- atomic_t hinic5_cqm_nonrdma_queue_create_cnt; /**< Statistics of HINIC5_CQM non-RDMA queue creation count */
- atomic_t hinic5_cqm_rdma_queue_create_cnt; /**< Statistics of HINIC5_CQM RDMA queue creation count */
- atomic_t hinic5_cqm_rdma_table_create_cnt; /**< Statistics of HINIC5_CQM RDMA table creation count */
- atomic_t hinic5_cqm_qpc_mpt_delete_cnt; /**< Statistics of HINIC5_CQM QPC and MPT deletion count */
- atomic_t hinic5_cqm_nonrdma_queue_delete_cnt; /**< Statistics of HINIC5_CQM non-RDMA queue deletion count */
- atomic_t hinic5_cqm_rdma_queue_delete_cnt; /**< Statistics of HINIC5_CQM RDMA queue deletion count */
- atomic_t hinic5_cqm_rdma_table_delete_cnt; /**< Statistics of HINIC5_CQM RDMA table deletion count */
- atomic_t hinic5_cqm_func_timer_clear_cnt; /**< Statistics of HINIC5_CQM function timer clear count */
- atomic_t hinic5_cqm_func_hash_buf_clear_cnt; /**< Statistics of HINIC5_CQM function hash buffer clear count */
- atomic_t hinic5_cqm_scq_callback_cnt; /**< Statistics of HINIC5_CQM SCQ callback count */
- atomic_t hinic5_cqm_ecq_callback_cnt; /**< Statistics of HINIC5_CQM ECQ callback count */
- atomic_t hinic5_cqm_nocq_callback_cnt; /**< Statistics of HINIC5_CQM NOCQ callback count */
- atomic_t hinic5_cqm_aeq_callback_cnt[HINIC5_CQM_AEQ_CALLBACK_CNT_MAX]; /**< Statistics of HINIC5_CQM AEQ callback count */
+ SM_CTR_RD16 = 1, /**< 读取16位数据的命令 */
+ SM_CTR_RD32, /**< 读取32位数据的命令 */
+ SM_CTR_RD64_PAIR, /**< 读取64位数据对的命令 */
+ SM_CTR_RD64, /**< 读取64位数据的命令 */
+ SM_CTR_RD32_CLEAR, /**< 清除32位数据的命令 */
+ SM_CTR_RD64_PAIR_CLEAR, /**< 清除64位数据对的命令 */
+ SM_CTR_RD64_CLEAR /**< 清除64位数据的命令 */
+};
+
+#define CQM_AEQ_CALLBACK_CNT_MAX 128 /* 与CQM_AEQ_BASE_T_MAX保持一致 */
+
+/**
+ * @brief struct cqm_stats
+ * @details 统计CQM模块的各种操作数量
+ */
+struct cqm_stats {
+ atomic_t cqm5_cmd_alloc_cnt; /**< 统计CQM命令分配的次数 */
+ atomic_t cqm5_cmd_free_cnt; /**< 统计CQM命令释放的次数 */
+ atomic_t cqm5_send_cmd_box_cnt; /**< 统计CQM发送命令盒子的次数 */
+ atomic_t cqm5_send_cmd_imm_cnt; /**< 统计CQM发送命令的次数 */
+ atomic_t cqm5_db_addr_alloc_cnt; /**< 统计CQM数据库地址分配的次数 */
+ atomic_t cqm5_db_addr_free_cnt; /**< 统计CQM数据库地址释放的次数 */
+ atomic_t cqm_fc_srq_create_cnt; /**< 统计CQM创建FC SRQ的次数 */
+ atomic_t cqm_srq_create_cnt; /**< 统计CQM创建SRQ的次数 */
+ atomic_t cqm_rq_create_cnt; /**< 统计CQM创建RQ的次数 */
+ atomic_t cqm_qpc_mpt_create_cnt; /**< 统计CQM创建QPC和MPT的次数 */
+ atomic_t cqm_nonrdma_queue_create_cnt; /**< 统计CQM创建非RDMA队列的次数 */
+ atomic_t cqm_rdma_queue_create_cnt; /**< 统计CQM创建RDMA队列的次数 */
+ atomic_t cqm_rdma_table_create_cnt; /**< 统计CQM创建RDMA表的次数 */
+ atomic_t cqm_qpc_mpt_delete_cnt; /**< 统计CQM删除QPC和MPT的次数 */
+ atomic_t cqm_nonrdma_queue_delete_cnt; /**< 统计CQM删除非RDMA队列的次数 */
+ atomic_t cqm_rdma_queue_delete_cnt; /**< 统计CQM删除RDMA队列的次数 */
+ atomic_t cqm_rdma_table_delete_cnt; /**< 统计CQM删除RDMA表的次数 */
+ atomic_t cqm_func_timer_clear_cnt; /**< 统计CQM清除函数计时器的次数 */
+ atomic_t cqm_func_hash_buf_clear_cnt; /**< 统计CQM清除函数哈希缓冲区的次数 */
+ atomic_t cqm_scq_callback_cnt; /**< 统计CQM SCQ回调的次数 */
+ atomic_t cqm_ecq_callback_cnt; /**< 统计CQM ECQ回调的次数 */
+ atomic_t cqm_nocq_callback_cnt; /**< 统计CQM NOCQ回调的次数 */
+ atomic_t cqm_aeq_callback_cnt
+ [CQM_AEQ_CALLBACK_CNT_MAX]; /**< 统计CQM AEQ回调的次数 */
};
/**
* @brief struct link_event_stats
- * @details Used to count the number of link events
+ * @details 用于统计链路事件的数量
*/
struct link_event_stats {
- atomic_t link_down_stats; /**< Number of events indicating link has been disconnected */
- atomic_t link_up_stats; /**< Number of events indicating link has been connected */
+ atomic_t link_down_stats; /**< 表示链路已经断开的事件数量 */
+ atomic_t link_up_stats; /**< 表示链路已经连接的事件数量 */
};
/**
* @brief enum hinic5_fault_err_level
- * @details Error level enumeration type
+ * @details 错误级别枚举类型
*/
enum hinic5_fault_err_level {
- FAULT_LEVEL_FATAL, /**< Fatal error */
- FAULT_LEVEL_SERIOUS_RESET, /**< Serious error, requires reset */
- FAULT_LEVEL_HOST, /**< Host error */
- FAULT_LEVEL_SERIOUS_FLR, /**< Serious error, requires FLR (Function Level Reset) */
- FAULT_LEVEL_GENERAL, /**< General error */
- FAULT_LEVEL_SUGGESTION, /**< Suggestion error */
- FAULT_LEVEL_MAX, /**< Maximum error level value */
+ FAULT_LEVEL_FATAL, /**< 致命错误 */
+ FAULT_LEVEL_SERIOUS_RESET, /**< 严重错误,需要重置 */
+ FAULT_LEVEL_HOST, /**< 主机错误 */
+ FAULT_LEVEL_SERIOUS_FLR, /**< 严重错误,需要FLR(函数级复位) */
+ FAULT_LEVEL_GENERAL, /**< 一般错误 */
+ FAULT_LEVEL_SUGGESTION, /**< 建议错误 */
+ FAULT_LEVEL_MAX, /**< 错误级别最大值 */
};
/**
* @brief enum hinic5_fault_type
- * @details Defines possible fault types
+ * @details 定义了可能出现的故障类型
*/
enum hinic5_fault_type {
- FAULT_TYPE_CHIP, /**< Chip fault */
- FAULT_TYPE_UCODE, /**< Microcode fault */
- FAULT_TYPE_MEM_RD_TIMEOUT, /**< Memory read timeout fault */
- FAULT_TYPE_MEM_WR_TIMEOUT, /**< Memory write timeout fault */
- FAULT_TYPE_REG_RD_TIMEOUT, /**< Register read timeout fault */
- FAULT_TYPE_REG_WR_TIMEOUT, /**< Register write timeout fault */
- FAULT_TYPE_PHY_FAULT, /**< Physical fault */
- FAULT_TYPE_TSENSOR_FAULT, /**< Temperature sensor fault */
- FAULT_TYPE_MAX, /**< Maximum fault type value */
+ FAULT_TYPE_CHIP, /**< 芯片故障 */
+ FAULT_TYPE_UCODE, /**< 微码故障 */
+ FAULT_TYPE_MEM_RD_TIMEOUT, /**< 读取内存超时故障 */
+ FAULT_TYPE_MEM_WR_TIMEOUT, /**< 写入内存超时故障 */
+ FAULT_TYPE_REG_RD_TIMEOUT, /**< 读取寄存器超时故障 */
+ FAULT_TYPE_REG_WR_TIMEOUT, /**< 写入寄存器超时故障 */
+ FAULT_TYPE_PHY_FAULT, /**< 物理故障 */
+ FAULT_TYPE_TSENSOR_FAULT, /**< 温度传感器故障 */
+ FAULT_TYPE_HEARTBEAT_LOST, /**< 心跳丢失故障 */
+ FAULT_TYPE_MAX, /**< 故障类型最大值 */
};
/**
* @brief struct fault_event_stats
- * @details Fault event statistics structure
+ * @details 故障事件统计结构体
*/
struct fault_event_stats {
/* HINIC_NODE_ID_MAX: temp use the value of 1822(22) */
- atomic_t chip_fault_stats[22][FAULT_LEVEL_MAX]; /**< Fault level statistics for each chip */
- atomic_t fault_type_stat[FAULT_TYPE_MAX]; /**< Statistics for each fault type */
- atomic_t pcie_fault_stats; /**< PCIE fault statistics */
+ atomic_t chip_fault_stats[22]
+ [FAULT_LEVEL_MAX]; /**< 各个芯片的故障等级统计 */
+ atomic_t fault_type_stat[FAULT_TYPE_MAX]; /**< 各种故障类型的统计 */
+ atomic_t pcie_fault_stats; /**< PCIE故障的统计 */
};
/**
* @brief enum hinic5_ucode_event_type
- * @details Enumeration of Ucode event types
+ * @details 定义了Ucode事件类型的枚举类型
*/
enum hinic5_ucode_event_type {
- HINIC5_INTERNAL_OTHER_FATAL_ERROR = 0x0, /**< Internal other fatal error */
- HINIC5_HTN_PTP_EVENT = 0x1, /**< HTN PTP event */
- HINIC5_CHANNEL_BUSY = 0x7, /**< Channel busy */
- HINIC5_NIC_FATAL_ERROR_MAX = 0x8, /**< Maximum NIC fatal error value */
+ HINIC5_INTERNAL_OTHER_FATAL_ERROR = 0x0, /**< 内部其他致命错误 */
+ HINIC5_HTN_PTP_EVENT = 0x1, /**< HTN PTP事件 */
+ HINIC5_CHANNEL_BUSY = 0x7, /**< 通道忙 */
+ HINIC5_NIC_FATAL_ERROR_MAX = 0x8, /**< NIC致命错误的最大值 */
};
/**
* @brief struct hinic5_hw_stats
- * @details Hardware statistics structure
+ * @details 硬件统计结构体
*/
struct hinic5_hw_stats {
- atomic_t heart_lost_stats; /**< Heartbeat lost statistics */
- struct hinic5_cqm_stats hinic5_cqm_stats; /**< HINIC5_CQM statistics */
- struct link_event_stats link_event_stats; /**< Link event statistics */
- struct fault_event_stats fault_event_stats; /**< Fault event statistics */
- atomic_t nic_ucode_event_stats[HINIC5_NIC_FATAL_ERROR_MAX]; /**< NIC microcode event statistics */
+ atomic_t heart_lost_stats; /**< 心跳丢失统计 */
+ struct cqm_stats cqm_stats; /**< CQM统计 */
+ struct link_event_stats link_event_stats; /**< 链路事件统计 */
+ struct fault_event_stats fault_event_stats; /**< 故障事件统计 */
+ atomic_t nic_ucode_event_stats
+ [HINIC5_NIC_FATAL_ERROR_MAX]; /**< NIC微码事件统计 */
};
#ifndef IFNAMSIZ
@@ -472,24 +474,24 @@ struct hinic5_hw_stats {
/**
* @brief struct pf_info
- * @details Structure for storing network interface information
+ * @details 用于存储网络接口的信息
*/
struct pf_info {
- char name[IFNAMSIZ]; /**< Network interface name */
- char bus_info[BUSINFO_LEN]; /**< Network interface bus information */
- u32 pf_type; /**< Network interface type */
+ char name[IFNAMSIZ]; /**< 网络接口的名称 */
+ char bus_info[BUSINFO_LEN]; /**< 网络接口的总线信息 */
+ u32 pf_type; /**< 网络接口的类型 */
};
/**
* @brief struct card_info
- * @details Structure for storing card information
+ * @details 用于存储卡片信息
* @param pf_num
- * in_param: Accumulated pf num obtained (integer multiple of PF_MAX_SIZE)
- * out_param: Number of pf_info obtained and sum of pf num to be obtained
+ * in_param: 累计已获取的pf num(PF_MAX_SIZE的整数倍)
+ * out_param: 当前获取的pf_info的数量及待获取pf_info的pf num总和
*/
struct card_info {
- struct pf_info pf[PF_MAX_SIZE]; /**< Structure for storing card information */
- u32 pf_num; /**< Number of cards */
+ struct pf_info pf[PF_MAX_SIZE]; /**< 用于存储卡片的各种信息 */
+ u32 pf_num; /**< 用于存储卡片的数量 */
};
struct func_mbox_cnt_info {
@@ -505,20 +507,20 @@ struct card_mbox_cnt_info {
/**
* @brief struct hinic5_nic_loop_mode
- * @details Structure for loop mode
+ * @details 用于循环模式的结构体
*/
struct hinic5_nic_loop_mode {
- u32 loop_mode; /**< Loop mode identifier */
- u32 loop_ctrl; /**< Loop control identifier */
+ u32 loop_mode; /**< 循环模式的标识符 */
+ u32 loop_ctrl; /**< 循环控制的标识符 */
};
/**
* @brief struct hinic5_pf_info
- * @details Structure for storing PF information
+ * @details 用于存储PF的信息
*/
struct hinic5_pf_info {
- u32 isvalid; /**< Flag indicating whether PF information is valid */
- u32 pf_id; /**< PF unique identifier */
+ u32 isvalid; /**< 表示PF信息是否有效的标志位 */
+ u32 pf_id; /**< PF的唯一标识符 */
};
#define HINIC5_CHIP_FAULT_SIZE (110 * 1024)
@@ -526,145 +528,145 @@ struct hinic5_pf_info {
/**
* @brief struct nic_cmd_chip_fault_stats
- * @details Network interface command chip fault statistics structure
+ * @details 网络接口命令芯片故障统计信息结构体
*/
struct nic_cmd_chip_fault_stats {
- u32 offset; /**< Offset */
- u8 chip_fault_stats[MAX_DRV_BUF_SIZE]; /**< Chip fault statistics array */
+ u32 offset; /**< 偏移量 */
+ u8 chip_fault_stats[MAX_DRV_BUF_SIZE]; /**< 芯片故障统计信息数组 */
};
-#define NIC_TOOL_MAGIC 'x' /**< NIC tool magic number */
+#define NIC_TOOL_MAGIC 'x' /**< 表示NIC工具的魔数 */
#ifdef STORAGE_PANGEA
-#define CARD_MAX_SIZE (16) /**< Maximum card size is 16 */
+#define CARD_MAX_SIZE (16) /**< 定义卡片的最大大小为16 */
#else
-#define CARD_MAX_SIZE (64) /**< Maximum card size is 64 */
+#define CARD_MAX_SIZE (64) /**< 卡片的最大大小为64 */
#endif
/**
* @brief struct nic_card_id
- * @details Structure for storing NIC ID and count
+ * @details 用于存储网卡的ID和数量
*/
struct nic_card_id {
- u32 id[CARD_MAX_SIZE]; /**< NIC ID array, maximum length is CARD_MAX_SIZE */
- u32 num; /**< NIC count */
+ u32 id[CARD_MAX_SIZE]; /**< 网卡ID数组,最大长度为CARD_MAX_SIZE */
+ u32 num; /**< 网卡数量 */
};
/**
* @brief struct func_dev_info
- * @details Structure for storing function-related dev information
+ * @details 用于存储函数相关的dev信息
*/
struct func_dev_info {
- u64 bar0_phy_addr; /**< bar0 physical address */
- u64 bar0_size; /**< bar0 size */
- u64 bar1_phy_addr; /**< bar1 physical address */
- u64 bar1_size; /**< bar1 size */
- u64 bar3_phy_addr; /**< bar3 physical address */
- u64 bar3_size; /**< bar3 size */
+ u64 bar0_phy_addr; /**< bar0的物理地址 */
+ u64 bar0_size; /**< bar0的大小 */
+ u64 bar1_phy_addr; /**< bar1的物理地址 */
+ u64 bar1_size; /**< bar1的大小 */
+ u64 bar3_phy_addr; /**< bar3的物理地址 */
+ u64 bar3_size; /**< bar3的大小 */
u64 rsvd1[4];
};
/**
* @brief struct hinic5_card_func_info
- * @details Structure for storing card function information
+ * @details 用于存储卡片功能信息
*/
struct hinic5_card_func_info {
- u32 num_pf; /**< Number of physical functions */
+ u32 num_pf; /**< 物理函数数量 */
u32 rsvd0;
- u64 usr_api_phy_addr; /**< User API physical address */
- struct func_dev_info dev_info[CARD_MAX_SIZE]; /**< Function dev information array */
+ u64 usr_api_phy_addr; /**< 用户API物理地址 */
+ struct func_dev_info dev_info[CARD_MAX_SIZE]; /**< 函数dev信息数组 */
};
-#define MAX_VER_INFO_LEN 128 /**< Maximum version information length constant */
+#define MAX_VER_INFO_LEN 128 /**< 定义最大版本信息长度常量 */
/**
* @brief struct drv_version_info
- * @details Driver version information structure definition
+ * @details 定义驱动版本信息结构体
*/
struct drv_version_info {
- char ver[MAX_VER_INFO_LEN]; /**< Version information character array, length is MAX_VER_INFO_LEN */
+ char ver[MAX_VER_INFO_LEN]; /**< 定义版本信息字符数组,长度为MAX_VER_INFO_LEN */
};
-#define MT_EPERM 1 /**< Operation not permitted */
-#define MT_EIO 2 /**< I/O error */
-#define MT_EINVAL 3 /**< Invalid argument */
-#define MT_EBUSY 4 /**< Device or resource busy */
-#define MT_EOPNOTSUPP 0xFF /**< Operation not supported */
+#define MT_EPERM 1 /**< 不允许操作 */
+#define MT_EIO 2 /**< I/O错误 */
+#define MT_EINVAL 3 /**< 无效参数 */
+#define MT_EBUSY 4 /**< 设备或资源忙 */
+#define MT_EOPNOTSUPP 0xFF /**< 不支持操作 */
/**
* @brief struct mt_msg_head
- * @details Structure for storing message header
+ * @details 用于存储消息头的结构体
*/
struct mt_msg_head {
- u8 status; /**< Status */
- u8 rsvd1[3]; /**< Reserved field */
+ u8 status; /**< 状态 */
+ u8 rsvd1[3]; /**< 保留字段 */
};
/**
* @brief enum mt_api_type
- * @details Enumeration for different API types
+ * @details 用于表示不同的API类型
*/
enum mt_api_type {
- API_TYPE_MBOX = 1, /**< MBOX API type */
- API_TYPE_API_CHAIN_BYPASS, /**< API chain bypass API type */
- API_TYPE_API_CHAIN_TO_MPU, /**< API chain to MPU API type */
- API_TYPE_CLP, /**< CLP API type */
+ API_TYPE_MBOX = 1, /**< MBOX API类型 */
+ API_TYPE_API_CHAIN_BYPASS, /**< API链式调用绕过API类型 */
+ API_TYPE_API_CHAIN_TO_MPU, /**< API链式调用到MPU的API类型 */
+ API_TYPE_CLP, /**< CLP API类型 */
};
/**
* @brief struct npu_cmd_st
- * @details Structure for describing NPU command
+ * @details 用于描述NPU命令的结构体
*/
struct npu_cmd_st {
- u32 mod : 8; /**< Module ID, occupies 8 bits of 32 bits */
- u32 cmd : 8; /**< Command ID, occupies 8 bits of 32 bits */
- u32 ack_type : 3; /**< Acknowledgment type, occupies 3 bits of 32 bits */
- u32 direct_resp : 1; /**< Direct response flag, occupies 1 bit of 32 bits */
- u32 len : 12; /**< Length, occupies 12 bits of 32 bits */
+ u32 mod : 8; /**< 模块ID,占用32位中的8位 */
+ u32 cmd : 8; /**< 命令ID,占用32位中的8位 */
+ u32 ack_type : 3; /**< 确认类型,占用32位中的3位 */
+ u32 direct_resp : 1; /**< 直接响应标志,占用32位中的1位 */
+ u32 len : 12; /**< 长度,占用32位中的12位 */
};
/**
* @brief struct mpu_cmd_st
- * @details Structure for storing MPU command
+ * @details 用于存储MPU命令的结构体
*/
struct mpu_cmd_st {
- u32 api_type : 8; /**< Defines a 32-bit unsigned integer for storing API type, occupies 8 bits */
- u32 mod : 8; /**< Defines a 32-bit unsigned integer for storing module, occupies 8 bits */
- u32 cmd : 16; /**< Defines a 32-bit unsigned integer for storing command, occupies 16 bits */
+ u32 api_type : 8; /**< 定义了一个32位的无符号整数,用于存储API类型,占用8位 */
+ u32 mod : 8; /**< 定义了一个32位的无符号整数,用于存储模块,占用8位 */
+ u32 cmd : 16; /**< 定义了一个32位的无符号整数,用于存储命令,占用16位 */
};
/**
* @brief struct msg_module
- * @details Message module structure for storing device name, module information, command format, timeout, function index, input/output buffer size, buffer pointer, bus number, Port ID and other information
+ * @details 消息模块结构体,用于存储设备名、模块信息、命令格式、超时时间、函数索引、输入输出缓冲区大小、缓冲区指针、总线号、端口ID等信息
*/
struct msg_module {
- char device_name[IFNAMSIZ]; /**< Device name, stores device name */
- u32 module; /**< Module information, stores module related information */
+ char device_name[IFNAMSIZ]; /**< 设备名,存储设备的名称 */
+ u32 module; /**< 模块信息,存储模块的相关信息 */
/**
- * @brief Message format storage
- */
+ * @brief 存储消息的格式
+ */
union {
u32 msg_formate;
struct npu_cmd_st npu_cmd;
struct mpu_cmd_st mpu_cmd;
};
- u32 timeout; /**< Timeout, stores operation timeout */
- u32 func_idx; /**< Function index, stores function index information */
- u32 buf_in_size; /**< Input buffer size, stores input buffer size */
- u32 buf_out_size; /**< Output buffer size, stores output buffer size */
- void *in_buf; /**< Input buffer pointer, stores input buffer pointer */
- void *out_buf; /**< Output buffer pointer, stores output buffer pointer */
- int bus_num; /**< Bus number, stores bus number information */
- u8 port_id; /**< Port ID, stores port ID information */
- u8 use_func_idx; /**< Indicates whether func_idx is used to send commands to device, used together with func_idx */
+ u32 timeout; /**< 超时时间,存储操作的超时时间 */
+ u32 func_idx; /**< 函数索引,存储函数的索引信息 */
+ u32 buf_in_size; /**< 输入缓冲区大小,存储输入缓冲区的大小 */
+ u32 buf_out_size; /**< 输出缓冲区大小,存储输出缓冲区的大小 */
+ void *in_buf; /**< 输入缓冲区指针,存储输入缓冲区的指针 */
+ void *out_buf; /**< 输出缓冲区指针,存储输出缓冲区的指针 */
+ int bus_num; /**< 总线编号,存储总线的编号信息 */
+ u8 port_id; /**< 端口ID,存储端口的ID信息 */
+ u8 use_func_idx; /**< 表示使用func_idx对设备下发命令, 配合func_idx使用 */
u8 rsvd1[2];
u32 rsvd2[4];
};
-#define MQM_FLOW_NUM 2
-#define MQM_XID_NUM 32768
-#define MQM_COS_VLD 1
-#define MQM_COS_INVLD 0
-#define MQM_COS_NUM 8
+#define MQM_FLOW_NUM 2
+#define MQM_XID_NUM 32768
+#define MQM_COS_VLD 1
+#define MQM_COS_INVLD 0
+#define MQM_COS_NUM 8
typedef struct hinic5_mqm_send_db_cmd_s {
u32 service_type;
@@ -685,15 +687,15 @@ typedef struct hinic5_mqm_send_db_cmd_s {
} mqm_send_db_cmd_s;
struct hinic5_mqm_db_num_len {
- u32 db_info;
- u32 pi_hi;
+ u32 db_info;
+ u32 pi_hi;
};
typedef union {
struct {
- u32 num : 8;
- u32 length : 18;
- u32 mode : 2;
- u32 rsvd : 4;
+ u32 num : 8;
+ u32 length : 18;
+ u32 mode : 2;
+ u32 rsvd : 4;
} bs;
u32 value;
} u_hinic5_mqm_db_num_len;
@@ -707,21 +709,21 @@ struct hinic5_mt_msg {
/**
* @brief struct hinic5_non_ptp_info
- * @details Structure for storing non PTP time information
+ * @details 定义一个结构体,用于存储non ptp 时间信息
*/
struct hinic5_non_ptp_info {
- char name[IFNAMSIZ]; /**< Chip device name corresponding to time */
- u64 non_ptp_time_diff_enable; /**< Non-PTP time difference enable */
- s64 non_ptp_time_diff; /**< Non-PTP time difference */
- atomic_t ref_cnt; /**< Reference count for using this non PTP info */
+ char name[IFNAMSIZ]; /**< 存储时间对应的chip设备名 */
+ u64 non_ptp_time_diff_enable; /**< 非PTP时间差使能 */
+ s64 non_ptp_time_diff; /**< 非PTP时间差 */
+ atomic_t ref_cnt; /**< 使用该non ptp info的引用计数 */
};
/**
* @brief hinic5_set_freq_reduce_ratio
* @param dev: device pointer
- * @param ratio: non PTP chip time frequency reduction ratio, must be greater than 0
+ * @param ratio: non ptp chip time 降频比, 需要大于0
*
- * @return Success or failure
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
@@ -730,28 +732,30 @@ int hinic5_set_freq_reduce_ratio(void *dev, u32 ratio);
/**
* @brief hinic5_set_non_ptp_time_diff_en
* @param dev: device pointer
- * @param enable: non PTP chip time enable flag, 0 disable, 1 enable
+ * @param enable: non ptp chip time 使能标记, 0 disable, 1 enable
*
- * @return Success or failure
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_set_non_ptp_time_diff_en(void *dev, bool enable);
/**
- * @brief SDK driver command hook function
+ * @brief SDK驱动命令钩子函数
*
* @param lld_dev device pointer to hinic5_lld_dev
- * @param cmd Command word
- * @param nt_msg Command content
- * @param support Whether the command is supported, product needs to determine whether to support based on command word
+ * @param cmd 命令字
+ * @param nt_msg 命令内容
+ * @param support 是否支持该命令, 产品需要根据命令字判断是否支持
*
- * @details Overloaded by product
+ * @details 由产品重载
*
- * @return: Command execution result.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_nictool_cmd_extend_handle(void *lld_dev, u32 cmd, struct hinic5_mt_msg *mt_msg, bool *support);
+int hinic5_nictool_cmd_extend_handle(void *lld_dev, u32 cmd,
+ struct hinic5_mt_msg *mt_msg,
+ bool *support);
-#endif /* _HINIC5_MT_H_ */
+#endif /* HINIC5_MT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_profile.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_profile.h
index 6968985e0..06495515f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_profile.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_profile.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_profile.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_PROFILE_H
#define HINIC5_PROFILE_H
@@ -39,8 +32,8 @@ typedef void (*hinic5_deinit_prof_attr)(void *porf_attr);
* @brief Profile adapter types
*/
enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID, /**< Invalid adapter type */
- PROF_ADAP_TYPE_PANGEA = 1, /**< PANGEA */
+ PROF_ADAP_TYPE_INVALID, /**< Invalid adapter type */
+ PROF_ADAP_TYPE_PANGEA = 1, /**< PANGEA */
/* Add prof adapter type before default */
PROF_ADAP_TYPE_DEFAULT,
@@ -57,17 +50,17 @@ enum prof_adapter_type {
* remove. Implemented in the source file of the custom scene
*/
struct hinic5_prof_adapter {
- enum prof_adapter_type type;
- hinic5_is_match_prof match;
- hinic5_init_prof_attr init;
- hinic5_deinit_prof_attr deinit;
+ enum prof_adapter_type type;
+ hinic5_is_match_prof match;
+ hinic5_init_prof_attr init;
+ hinic5_deinit_prof_attr deinit;
};
struct hinic5_prof_ops {
- void (*fault_recover)(void *data, u16 src, u16 level);
- int (*get_work_cpu_affinity)(void *data, u32 work_type);
- void (*probe_success)(void *data);
- void (*remove_pre_handle)(void *hwdev);
+ void (*fault_recover)(void *data, u16 src, u16 level);
+ int (*get_work_cpu_affinity)(void *data, u32 work_type);
+ void (*probe_success)(void *data);
+ void (*remove_pre_handle)(void *hwdev);
};
struct hinic5_prof_attr {
@@ -92,14 +85,15 @@ const struct hinic5_prof_adapter *hinic5_get_prof_adapter(void *hwdev);
* @param adapter Adapter pointer
* @return True if the adapter is valid
*/
-static inline bool hinic5_verify_prof_adapter(const struct hinic5_prof_adapter *adapter)
+static inline bool
+hinic5_verify_prof_adapter(const struct hinic5_prof_adapter *adapter)
{
bool has_init, has_deinit;
if (!adapter)
return true;
- has_init = adapter->init != NULL;
+ has_init = adapter->init != NULL;
has_deinit = adapter->deinit != NULL;
if (has_init != has_deinit)
return false;
@@ -116,9 +110,9 @@ static inline bool hinic5_verify_prof_adapter(const struct hinic5_prof_adapter *
*
* @return Nullable, the adapter for the device
*/
-static inline struct hinic5_prof_adapter *hinic5_prof_init(void *device,
- struct hinic5_prof_adapter *adap_objs,
- int num_adap, void **prof_attr)
+static inline struct hinic5_prof_adapter *
+hinic5_prof_init(void *device, struct hinic5_prof_adapter *adap_objs,
+ int num_adap, void **prof_attr)
{
struct hinic5_prof_adapter *prof_obj = NULL;
int i;
@@ -137,13 +131,14 @@ static inline struct hinic5_prof_adapter *hinic5_prof_init(void *device,
}
/**
- * @brief Deinitialize a hinic5 profile object
- * @param prof_obj Profile object
- * @param prof_attr Profile attributes
+ * @brief 反初始化一个 hinic5 的 profile 对象
+ * @param prof_obj 参数说明
+ * @param prof_attr 参数说明
*
- * @return None
+ * @return 无
*/
-static inline void hinic5_prof_deinit(const struct hinic5_prof_adapter *prof_obj, void *prof_attr)
+static inline void
+hinic5_prof_deinit(const struct hinic5_prof_adapter *prof_obj, void *prof_attr)
{
if (!prof_obj)
return;
@@ -158,28 +153,30 @@ static inline void hinic5_prof_deinit(const struct hinic5_prof_adapter *prof_obj
* @brief model-level interface
*/
struct hinic5_module_ops {
- int (*module_prof_pre_init)(void); /**< Pre-initialize module profile config file, returns 0 on success, otherwise returns error code */
- int (*module_prof_post_init)(void); /**< Post-initialize module profile config file, returns 0 on success, otherwise returns error code */
- void (*module_prof_pre_exit)(void); /**< Pre-exit module profile config file */
- void (*module_prof_post_exit)(void); /**< Post-exit module profile config file */
- void (*probe_fault_process)(void *pdev, u16 level); /**< Handle probe fault */
- int (*probe_pre_process)(void *pdev); /**< Pre-process probe */
- void (*probe_pre_unprocess)(void *pdev); /**< Pre-process probe cancel */
+ int (*module_prof_pre_init)(
+ void); /**< pre初始化模块的配置文件,成功返回0,否则返回错误码 */
+ int (*module_prof_post_init)(
+ void); /**< post初始化模块的配置文件,成功返回0,否则返回错误码 */
+ void (*module_prof_pre_exit)(void); /**< pre退出模块的配置文件 */
+ void (*module_prof_post_exit)(void); /**< post退出模块的配置文件 */
+ void (*probe_fault_process)(void *pdev, u16 level); /**< 处理探测故障 */
+ int (*probe_pre_process)(void *pdev); /**< 预处理探测 */
+ void (*probe_pre_unprocess)(void *pdev); /**< 预处理探测取消 */
};
/**
- * @brief Get module performance operations function
+ * @brief 获取模块性能操作的函数
*
- * @return Returns a pointer to hinic5_module_ops structure
+ * @return 返回一个指向hinic5_module_ops结构体的指针
*/
struct hinic5_module_ops *hinic5_get_module_prof_ops(void);
/**
- * @brief Handle device probe error
- * @param pdev Device pointer
- * @param level Error level
+ * @brief 用于处理设备的探测错误
+ * @param pdev 设备指针
+ * @param level 错误级别
*
- * @return None
+ * @return 无
*/
static inline void hinic5_probe_fault_process(void *pdev, u16 level)
{
@@ -190,9 +187,9 @@ static inline void hinic5_probe_fault_process(void *pdev, u16 level)
}
/**
- * @brief Module pre-initialization function
+ * @brief 模块预初始化函数
*
- * @return Returns 0 on success, other values indicate failure
+ * @return 返回0表示成功,返回其他值表示失败
*/
static inline int hinic5_module_pre_init(void)
{
@@ -205,9 +202,9 @@ static inline int hinic5_module_pre_init(void)
}
/**
- * @brief Module post-exit processing function
+ * @brief 模块退出后的处理函数
*
- * @return void No return value
+ * @return void 无返回值
*/
static inline void hinic5_module_post_exit(void)
{
@@ -218,10 +215,10 @@ static inline void hinic5_module_post_exit(void)
}
/**
- * @brief Pre-process before device probe in driver
- * @param pdev Device pointer
+ * @brief 在驱动程序中进行设备探测前的预处理
+ * @param pdev 设备指针
*
- * @return Returns 0 on success, -EINVAL on failure
+ * @return 成功返回0,失败返回-EINVAL
*/
static inline int hinic5_probe_pre_process(void *pdev)
{
@@ -234,10 +231,10 @@ static inline int hinic5_probe_pre_process(void *pdev)
}
/**
- * @brief Handle device removal or load failure, matches hinic5_probe_pre_process
- * @param pdev Device pointer
+ * @brief 设备移除或者加载失败后处理,和hinic5_probe_pre_process匹配
+ * @param pdev 设备指针
*
- * @return None
+ * @return 无
*/
static inline void hinic5_probe_pre_unprocess(void *pdev)
{
@@ -248,9 +245,9 @@ static inline void hinic5_probe_pre_unprocess(void *pdev)
}
/**
- * @brief Module post-initialization function
+ * @brief 模块后初始化函数
*
- * @return Returns 0 on success, other values indicate failure
+ * @return 返回0表示成功,返回其他值表示失败
*/
static inline int hinic5_module_post_init(void)
{
@@ -263,9 +260,9 @@ static inline int hinic5_module_post_init(void)
}
/**
- * @brief Module pre-exit processing function
+ * @brief 模块退出前的处理函数
*
- * @return void No return value
+ * @return void 无返回值
*/
static inline void hinic5_module_pre_exit(void)
{
@@ -278,14 +275,13 @@ static inline void hinic5_module_pre_exit(void)
#else
/**
- * @brief Function description for hinic5_probe_fault_process
- * @param pdev Device pointer for device operation
- * @param level Error level
+ * @brief hinic5_probe_fault_process 函数的作用
+ * @param pdev 设备指针,用于操作设备
+ * @param level 错误级别
*
- * @return None
+ * @return 无
*/
-static inline void hinic5_probe_fault_process(void *pdev, u16 level) { };
-
+static inline void hinic5_probe_fault_process(void *pdev, u16 level){};
/**
* @brief module pre initial
@@ -301,11 +297,11 @@ static inline int hinic5_module_pre_init(void)
}
/**
- * @brief Module post-exit processing function
+ * @brief 模块退出后的处理函数
*
- * @return None
+ * @return 无
*/
-static inline void hinic5_module_post_exit(void) { };
+static inline void hinic5_module_post_exit(void){};
/**
* @brief module pre process
@@ -329,12 +325,12 @@ static inline int hinic5_probe_pre_process(void *pdev)
* @retval zero: success
* @retval non-zero: failure
*/
-static inline void hinic5_probe_pre_unprocess(void *pdev) { };
+static inline void hinic5_probe_pre_unprocess(void *pdev){};
/**
- * @brief Module post-initialization function
+ * @brief 模块后初始化函数
*
- * @return Returns 0 on success, other values indicate failure
+ * @return 返回0表示成功,返回其他值表示失败
*/
static inline int hinic5_module_post_init(void)
{
@@ -342,22 +338,22 @@ static inline int hinic5_module_post_init(void)
}
/**
- * @brief Module pre-exit processing function
+ * @brief 模块退出前的处理函数
*
- * @return void No return value
+ * @return void 无返回值
*/
-static inline void hinic5_module_pre_exit(void) { };
+static inline void hinic5_module_pre_exit(void){};
#endif
/**
- * @brief Get struct hinic5_prof_attr pointer
+ * @brief 获取struct hinic5_prof_attr指针
*
- * @param hwdev SDK driver internal hardware device pointer
+ * @param hwdev sdk驱动内部的硬件设备指针
*
- * @return: Command execution result.
- * @retval NULL Get failed
- * @retval non-NULL Get successful
+ * @return: 命令执行结果.
+ * @retval NULL 获取失败
+ * @retval 非NULL 获取成功
*/
struct hinic5_prof_attr *hinic5_get_prof_attr(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_wq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_wq.h
index b4005d762..2854dba5d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_wq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/hisdk/hinic5_wq.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_wq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_WQ_H
#define HINIC5_WQ_H
@@ -14,87 +7,89 @@
#include <linux/types.h>
#include "hinic5_common.h"
+#if !defined(__UEFI__) && !defined(__WIN__)
+#include "securec.h"
+#endif
/**
* @brief struct hinic5_wq
- * @details Structure for describing work queue information; modifications need to be synchronized to user-space struct sdk_cmdq_info
+ * @details 用于描述一个工作队列的相关信息; 修改需同步到用户态的struct sdk_cmdq_info
*/
struct hinic5_wq {
- u16 cons_idx; /**< Consumer index */
- u16 prod_idx; /**< Producer index */
+ u16 cons_idx; /**< 消费者索引 */
+ u16 prod_idx; /**< 生产者索引 */
- u32 q_depth; /**< Queue depth */
- u16 idx_mask; /**< Queue index mask */
- u16 wqebb_size_shift; /**< WQEBB shift */
+ u32 q_depth; /**< 队列深度 */
+ u16 idx_mask; /**< 队列索引掩码 */
+ u16 wqebb_size_shift; /**< wqebb的位移 */
u16 rsvd1;
- u16 num_wq_pages; /**< Number of wq pages */
- u32 wqebbs_per_page; /**< Number of wqes per page */
+ u16 num_wq_pages; /**< wq页面的数量 */
+ u32 wqebbs_per_page; /**< 每页的wqe数量 */
u16 wqebbs_per_page_shift;
u16 wqebbs_per_page_mask;
- struct hinic5_dma_addr_align *wq_pages; /* Pointer to DMA address alignment structure,
- * used to describe wq page information
- */
+ struct hinic5_dma_addr_align *
+ wq_pages; /**< 指向DMA地址对齐结构体的指针,用于描述wq页面的相关信息 */
- dma_addr_t wq_block_paddr; /**< WQ block physical address */
- u64 *wq_block_vaddr; /**< WQ block virtual address */
+ dma_addr_t wq_block_paddr; /**< wq块的物理地址 */
+ u64 *wq_block_vaddr; /**< wq块的虚拟地址 */
- void *dev_hdl; /**< Pointer to pcidev->dev or Handler */
- u32 wq_page_size; /**< WQ page size */
- u16 wqebb_size; /**< WQEBB size */
+ void *dev_hdl; /**< 指向pcidev->dev或Handler的指针 */
+ u32 wq_page_size; /**< wq页面大小 */
+ u16 wqebb_size; /**< wqebb大小 */
} ____cacheline_aligned;
-
/**
- * @brief Define a macro for calculating mask value of specific index in given queue
- * @param wq Queue object
- * @param idx Index value
+ * @brief 定义一个宏,用于计算给定队列中特定索引的掩码值
+ * @param wq 队列对象
+ * @param idx 索引值
*
- * @return Returns calculated mask value
+ * @return 返回计算后的掩码值
*/
#define WQ_MASK_IDX(wq, idx) (((u16)(idx)) & (wq)->idx_mask)
/**
- * @brief Calculate masked page based on work queue and page index
- * @param wq Work queue
- * @param pg_idx Page index
+ * @brief 根据工作队列和页索引计算掩码页
+ * @param wq 工作队列
+ * @param pg_idx 页索引
*
- * @return Returns page index if page index is less than work queue page count, otherwise returns 0
+ * @return 如果页索引小于工作队列的页数,则返回页索引,否则返回0
*/
-#define WQ_MASK_PAGE(wq, pg_idx) (((pg_idx) < (wq)->num_wq_pages) ? (pg_idx) : 0)
+#define WQ_MASK_PAGE(wq, pg_idx) \
+ (((pg_idx) < (wq)->num_wq_pages) ? (pg_idx) : 0)
/**
- * @brief Calculate page index
- * @param wq Wait queue
- * @param idx Index
+ * @brief 计算页面索引
+ * @param wq 等待队列
+ * @param idx 索引
*
- * @return Returns calculated page index
+ * @return 返回计算后的页面索引
*/
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
/**
- * @brief Calculate element offset in queue
- * @param wq Queue pointer
- * @param idx Element index
+ * @brief 计算队列中元素的偏移量
+ * @param wq 队列指针
+ * @param idx 元素索引
*
- * @return Returns element offset in page
+ * @return 返回元素在页面中的偏移量
*/
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
/**
- * @brief Get WQEBB address
- * @param wq Work queue
- * @param pg_idx Page index
- * @param idx_in_pg Index within page
+ * @brief 获取WQEBB地址
+ * @param wq 工作队列
+ * @param pg_idx 页索引
+ * @param idx_in_pg 页内索引
*
- * @return u8* Returns WQEBB address
+ * @return u8* 返回WQEBB地址
*/
-#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
+#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
((u8 *)(wq)->wq_pages[(pg_idx)].align_vaddr + \
(((u64)(idx_in_pg)) << (wq)->wqebb_size_shift))
/**
- * @brief Check if queue is level 0
- * @param wq Queue pointer
+ * @brief 判断队列是否为0级别
+ * @param wq 队列指针
*
* @return
- * @retval true If queue is level 0
- * @retval false If queue is not level 0
+ * @retval true 如果队列是0级别
+ * @retval false 如果队列不是0级别
*/
#define WQ_IS_0_LEVEL_CLA(wq) ((wq)->num_wq_pages == 1)
@@ -106,9 +101,10 @@ struct hinic5_wq {
*/
static inline u16 hinic5_wq_free_wqebbs(struct hinic5_wq *wq)
{
- return (u16)(wq->q_depth
- - ((wq->q_depth + wq->prod_idx - wq->cons_idx) & wq->idx_mask)
- - 1);
+ return (u16)(wq->q_depth -
+ ((wq->q_depth + wq->prod_idx - wq->cons_idx) &
+ wq->idx_mask) -
+ 1);
}
/**
@@ -130,12 +126,14 @@ static inline bool hinic5_wq_is_empty(const struct hinic5_wq *wq)
*
* @return first wqebb address
**/
-static inline void *hinic5_wq_get_wqebbs(struct hinic5_wq *wq, u16 wqebb_cnt, u16 *pi)
+static inline void *hinic5_wq_get_wqebbs(struct hinic5_wq *wq, u16 wqebb_cnt,
+ u16 *pi)
{
*pi = WQ_MASK_IDX(wq, wq->prod_idx);
wq->prod_idx += wqebb_cnt;
- return WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, *pi), WQ_OFFSET_IN_PAGE(wq, *pi));
+ return WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, *pi),
+ WQ_OFFSET_IN_PAGE(wq, *pi));
}
/**
@@ -158,8 +156,9 @@ static inline void *hinic5_wq_get_one_wqebb(struct hinic5_wq *wq, u16 *pi)
*
* @return wqebbs address
*/
-static inline void *hinic5_wq_get_multi_wqebbs(struct hinic5_wq *wq, u16 num_wqebbs,
- u16 *prod_idx, void **second_part_wqebbs_addr,
+static inline void *hinic5_wq_get_multi_wqebbs(struct hinic5_wq *wq,
+ u16 num_wqebbs, u16 *prod_idx,
+ void **second_part_wqebbs_addr,
u16 *first_part_wqebbs_num)
{
u32 pg_idx, off_in_page;
@@ -172,8 +171,10 @@ static inline void *hinic5_wq_get_multi_wqebbs(struct hinic5_wq *wq, u16 num_wqe
if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
- *second_part_wqebbs_addr = WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
- *first_part_wqebbs_num = (u16)(wq->wqebbs_per_page - off_in_page);
+ *second_part_wqebbs_addr =
+ WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
+ *first_part_wqebbs_num =
+ (u16)(wq->wqebbs_per_page - off_in_page);
} else {
*second_part_wqebbs_addr = NULL;
*first_part_wqebbs_num = num_wqebbs;
@@ -201,7 +202,8 @@ static inline void hinic5_wq_put_wqebbs(struct hinic5_wq *wq, u16 num_wqebbs)
static inline void *hinic5_wq_wqebb_addr(struct hinic5_wq *wq, u16 idx)
{
- return WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, idx), WQ_OFFSET_IN_PAGE(wq, idx));
+ return WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, idx),
+ WQ_OFFSET_IN_PAGE(wq, idx));
}
/**
@@ -211,7 +213,8 @@ static inline void *hinic5_wq_wqebb_addr(struct hinic5_wq *wq, u16 idx)
*
* @return wqe page address
*/
-static inline void *hinic5_wq_read_one_wqebb(struct hinic5_wq *wq, u16 *cons_idx)
+static inline void *hinic5_wq_read_one_wqebb(struct hinic5_wq *wq,
+ u16 *cons_idx)
{
*cons_idx = WQ_MASK_IDX(wq, wq->cons_idx);
@@ -241,11 +244,12 @@ static inline void hinic5_wq_reset(struct hinic5_wq *wq)
wq->prod_idx = 0;
for (pg_idx = 0; pg_idx < wq->num_wq_pages; pg_idx++)
- memset(wq->wq_pages[pg_idx].align_vaddr, 0, wq->wq_page_size);
+ (void)memset_s(wq->wq_pages[pg_idx].align_vaddr,
+ wq->wq_page_size, 0, wq->wq_page_size);
}
/**
- * @brief Initialize wq struct and allocate wq page
+ * @brief initial wq struct and alloc wq page
* @param udkdev: device pointer to udkdev
* @param wq: pointer of wq control struct
* @param q_depth: wq depth
@@ -258,7 +262,7 @@ int hinic5_wq_create(void *hwdev, struct hinic5_wq *wq, u32 q_depth,
u16 wqebb_size);
/**
- * @brief Release wqe pages
+ * @brief release wqe pages
* @param udkdev: device pointer to udkdev
* @param wq: pointer of wq control struct
*/
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h
index 474203969..549f5b09b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/nic_kcompat.h
@@ -1,69 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_kcompat.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+/**
+ * @copyright Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * @file nic_kcompat.h
+ * @brief Temporary file - The actual nic_kcompat.h is generated during build.
+ * @version Initial
+ * @date 2025/11/1
*/
+#ifndef _NIC_KCOMPAT_H_
+#define _NIC_KCOMPAT_H_
-#ifndef NIC_KCOMPAT_H
-#define NIC_KCOMPAT_H
-#define HAVE_NETIF_NAPI_NO_WEIGHT 1
-#define HAVE_NETIF_NAPI_ADD_WEIGHT 1
-#define HAVE_NDO_TX_TIMEOUT_TXQ 1
-#define HAVE_NDO_BPF 1
-#define HAVE_NDO_GET_STATS64 1
-#define HAVE_NDO_ETH_IOCTL 1
-#define HAVE_VOID_NDO_GET_STATS64 1
-#define HAVE_NDO_SET_FEATURES 1
-#define HAVE_NAPI_GRO_FLUSH_OLD 1
-#define HAVE_VF_SPOOFCHK_CONFIGURE 1
-#define HAVE_NDO_SET_VF_TRUST 1
-#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE 1
-#define HAVE_NETDEVICE_MIN_MAX_MTU 1
-#define HAVE_NETDEV_STATS_IN_NETDEV 1
-#define HAVE_NETDEVICE_MACSEC_OPS 1
-#define HAVE_NDO_SET_VF_LINK_STATE 1
-#define HAVE_NDO_SELECT_QUEUE_SB_DEV 1
-#define HAVE_NETDEV_CHANGEUPPER 1
-#define HAVE_ETHTOOL_COALESCE_EXTACK 1
-#define HAVE_ETHTOOL_EXTENDED_RINGPARAMS 1
-#define HAVE_RXFH_HASHFUNC 1
-#define HAVE_ETHTOOL_GET_RXFH_INDIR_SIZE 1
-#define HAVE_ETHTOOL_GET_MODULE_EEPROM_BY_PAGE 1
-#define SUPPORTED_COALESCE_PARAMS 1
-#define HAVE_ETHTOOL_SET_PHYS_ID 1
-#define NEED_DEFINE_SPEED_20000 1
-#define NEED_DEFINE_SPEED_25000 1
-#define NEED_DEFINE_SPEED_40000 1
-#define NEED_DEFINE_SPEED_100000 1
-#define HAVE_ETHTOOL_GLINKSETTINGS 1
-#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY 1
-#define HAVE_NETDEV_PROG_XDP_WARN_ACTION 1
-#define HAVE_XDP_DO_FLUSH_MAP 1
-#define HAVE_SK_BUFF_ENCAPSULATION 1
-#define HAVE_TYPEDEF_SKB_FRAG_T_BIOVEC 1
-#define HAVE_SKBUFF_CSUM_LEVEL 1
-#define HAVE_ETH_GET_HEADLEN_NET_DEVICE_ARG 1
-#define HAVE_ETH_HW_ADDR_SET 1
-#define HAVE_ETH_GET_HEADLEN_FUNC 1
-#define NEED_ETH_P_8021AD 1
-#define HAVE_VM_FLAGS_SET 1
-#define NEED_PDE_DATA 1
-#define HAVE_PDE_DATA_LOWERCASE 1
-#define HAVE_NETIF_F_RXHASH 1
-#define HAVE_SOCK_CREATE_KERN_NET 1
-#define HAVE_UDP_TUNNEL_NIC_INFO 1
-#define NEED_DEFINE_FIELD_SIZEOF 1
-#define HAVE_XDP_SUPPORT 1
-#define HAVE_XDP_DATA_META 1
-#define HAVE_XDP_RXQ_INFO_REG_NAPI_ID 1
-#define HAVE_NETDEV_XDP_ACT_NDO_XMIT 1
-#define HAVE_PAGE_POOL_SUPPORT 1
-#define HAVE_PAGE_POOL_NEW 1
-#define HAVE_PP_FLAG_PAGE_FRAG 1
-#define HAVE_FLOW_ACTION_PRIORITY 1
-#define HAVE_KOBJ_TYPE_DEFAULT_GROUPS 1
-#endif /* NIC_KCOMPAT_H */
+// nic_kcompat.h是中间产物头文件
+
+#endif /* _NIC_KCOMPAT_H_ */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl.h
index 53299b06d..04a095484 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : ossl_knl.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef OSSL_KNL_H
#define OSSL_KNL_H
@@ -22,29 +15,32 @@
#include "ossl_knl_nic_win.h"
#endif
#endif
+#ifdef __UEFI__
+#include "ossl_knl_uefi.h"
+#endif
#ifdef __VMWARE__
#include "ossl_knl_vmware.h"
#endif
#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 0x4321
+#define BIG_ENDIAN 0x4321
#endif
#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 0x1234
+#define LITTLE_ENDIAN 0x1234
#endif
#ifdef BYTE_ORDER
#undef BYTE_ORDER
#endif
/* X86 */
-#define BYTE_ORDER LITTLE_ENDIAN
-#define USEC_PER_MSEC 1000L
-#define MSEC_PER_SEC 1000L
+#define BYTE_ORDER LITTLE_ENDIAN
+#define USEC_PER_MSEC 1000L
+#define MSEC_PER_SEC 1000L
#ifndef UINT16_MAX
-#define UINT16_MAX ((u16)(~((u16)0))) /* 0xFFFF */
+#define UINT16_MAX (u16)(~((u16)0)) /* 0xFFFF */
#endif /* UINT16_MAX */
#ifndef __LINUX__
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux.h
index 48c0f36b7..9d91d6d8e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : ossl_knl_linux.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
@@ -32,6 +25,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include "securec.h"
#include "sdk_kcompat.h"
#include "ossl_knl_linux_nic.h"
#ifdef HAVE_XDP_SUPPORT
@@ -54,8 +48,8 @@
#define ossl_get_free_pages __get_free_pages
#ifndef high_16_bits
-#define low_16_bits(x) ((x) & 0xFFFF)
-#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
+#define low_16_bits(x) ((x)&0xFFFF)
+#define high_16_bits(x) (((x)&0xFFFF0000) >> 16)
#endif
#ifndef U8_MAX
@@ -73,11 +67,14 @@
#define AX_RELEASE_CODE 0
#endif
-#if (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 0))
+#if (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && \
+ AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 0))
#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5, 0)
-#elif (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 1))
+#elif (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && \
+ AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 1))
#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5, 1)
-#elif (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 2))
+#elif (defined(AX_RELEASE_CODE) && AX_RELEASE_CODE && \
+ AX_RELEASE_CODE == AX_RELEASE_VERSION(3, 2))
#define RHEL_RELEASE_CODE RHEL_RELEASE_VERSION(5, 3)
#endif
@@ -90,7 +87,8 @@
* create_singlethread_workqueue.
* If/when RH corrects this we will want to tighten up the version check.
*/
-#if (defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 0))
+#if (defined(RHEL_RELEASE_CODE) && RHEL_RELEASE_CODE && \
+ RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7, 0))
#undef create_singlethread_workqueue
#define create_singlethread_workqueue(name) \
alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, name)
@@ -197,10 +195,10 @@
* updates 3.12.xx-60.yy where xx={51..}
*/
#define SLE_VERSION_CODE SLE_VERSION(12, 1, 0)
-#elif ((KERNEL_VERSION(4, 4, 21) <= LINUX_VERSION_CODE && \
+#elif ((KERNEL_VERSION(4, 4, 21) <= LINUX_VERSION_CODE && \
(KERNEL_VERSION(4, 4, 59) >= LINUX_VERSION_CODE)) || \
- (KERNEL_VERSION(4, 4, 74) <= LINUX_VERSION_CODE && \
- KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE && \
+ (KERNEL_VERSION(4, 4, 74) <= LINUX_VERSION_CODE && \
+ KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE && \
KERNEL_VERSION(92, 0, 0) <= SLE_LOCALVERSION_CODE && \
KERNEL_VERSION(93, 0, 0) > SLE_LOCALVERSION_CODE))
/*
@@ -210,15 +208,15 @@
* but they all use a SLE_LOCALVERSION_CODE matching 92.nn.y
*/
#define SLE_VERSION_CODE SLE_VERSION(12, 2, 0)
-#elif ((KERNEL_VERSION(4, 4, 73) == LINUX_VERSION_CODE || \
- KERNEL_VERSION(4, 4, 82) == LINUX_VERSION_CODE || \
- KERNEL_VERSION(4, 4, 92)) == LINUX_VERSION_CODE || \
- (KERNEL_VERSION(4, 4, 103) == LINUX_VERSION_CODE && \
- (KERNEL_VERSION(6, 33, 0) == LINUX_VERSION_CODE || \
- KERNEL_VERSION(6, 38, 0) == SLE_LOCALVERSION_CODE)) || \
- (KERNEL_VERSION(4, 4, 114) <= LINUX_VERSION_CODE && \
- KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE && \
- KERNEL_VERSION(94, 0, 0) <= SLE_LOCALVERSION_CODE && \
+#elif ((KERNEL_VERSION(4, 4, 73) == LINUX_VERSION_CODE || \
+ KERNEL_VERSION(4, 4, 82) == LINUX_VERSION_CODE || \
+ KERNEL_VERSION(4, 4, 92)) == LINUX_VERSION_CODE || \
+ (KERNEL_VERSION(4, 4, 103) == LINUX_VERSION_CODE && \
+ (KERNEL_VERSION(6, 33, 0) == LINUX_VERSION_CODE || \
+ KERNEL_VERSION(6, 38, 0) == SLE_LOCALVERSION_CODE)) || \
+ (KERNEL_VERSION(4, 4, 114) <= LINUX_VERSION_CODE && \
+ KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE && \
+ KERNEL_VERSION(94, 0, 0) <= SLE_LOCALVERSION_CODE && \
KERNEL_VERSION(95, 0, 0) > SLE_LOCALVERSION_CODE))
/* SLES12 SP3 GM is 4.4.73-5 and update kernels are 4.4.82-6.3.
* SLES12 SP3 updates not conflicting with SP2 are: 4.4.{82,92}
@@ -252,16 +250,16 @@
#define SUSE_PRODUCT_CODE 0
#endif /* SUSE_PRODUCT_CODE */
#ifndef SUSE_PRODUCT
-#define SUSE_PRODUCT(product, version, patchlevel, auxrelease) \
- (((product) << 24) + ((version) << 16) + \
- ((patchlevel) << 8) + (auxrelease))
+#define SUSE_PRODUCT(product, version, patchlevel, auxrelease) \
+ (((product) << 24) + ((version) << 16) + ((patchlevel) << 8) + \
+ (auxrelease))
#endif /* SUSE_PRODUCT */
#ifndef ALIGN_DOWN
#ifndef __ALIGN_KERNEL
-#define __ALIGN_KERNEL(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_KERNEL(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
#endif
-#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a))
+#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a)-1), (a))
#endif
/* ************************************************************************ */
/* mm buddy */
@@ -282,8 +280,7 @@
#define skb_network_header(skb) ((skb)->nh.raw)
#define skb_tail_pointer(skb) ((skb)->tail)
#define skb_reset_tail_pointer(skb) ((skb)->tail = (skb)->data)
-#define skb_set_tail_pointer(skb, offset) \
- ((skb)->tail = (skb)->data + (offset))
+#define skb_set_tail_pointer(skb, offset) ((skb)->tail = (skb)->data + (offset))
#define skb_copy_to_linear_data(skb, from, len) memcpy(skb->data, from, len)
#define pci_register_driver pci_module_init
@@ -337,9 +334,9 @@ static inline struct udphdr *_udp_hdr(const struct sk_buff *skb)
#define PORT_NONE PORT_OTHER
#endif
-#if ((RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_VERSION(6, 3) <= RHEL_RELEASE_CODE) && \
- (RHEL_RELEASE_VERSION(7, 0) > RHEL_RELEASE_CODE)))
+#if ((RHEL_RELEASE_CODE && \
+ (RHEL_RELEASE_VERSION(6, 3) <= RHEL_RELEASE_CODE) && \
+ (RHEL_RELEASE_VERSION(7, 0) > RHEL_RELEASE_CODE)))
#if !defined(CONFIG_X86_32) && !defined(CONFIG_NEED_DMA_MAP_STATE)
#undef DEFINE_DMA_UNMAP_ADDR
#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME
@@ -359,7 +356,7 @@ static inline struct udphdr *_udp_hdr(const struct sk_buff *skb)
#if (!(RHEL_RELEASE_CODE && (RHEL_RELEASE_VERSION(6, 2) <= RHEL_RELEASE_CODE)))
#define sk_tx_queue_get(_sk) (-1)
#define sk_tx_queue_set(_sk, _tx_queue) \
- do { \
+ do { \
} while (0)
#endif /* !(RHEL >= 6.2) */
#endif /* < 2.6.33 */
@@ -444,19 +441,19 @@ static inline const char *_kc_netdev_name(const struct net_device *dev)
dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \
netdev_name(__dev), ##args)
#else /* DEBUG */
-#define netdev_dbg(__dev, format, args...) \
- ({ \
- if (0) \
+#define netdev_dbg(__dev, format, args...) \
+ ({ \
+ if (0) \
netdev_printk(KERN_DEBUG, __dev, format, ##args); \
- 0; \
+ 0; \
})
#endif /* DEBUG */
#undef netif_printk
-#define netif_printk(priv, type, level, dev, fmt, args...) \
- do { \
- if (netif_msg_##type(priv) != 0) \
- netdev_printk(level, (dev), fmt, ##args); \
+#define netif_printk(priv, type, level, dev, fmt, args...) \
+ do { \
+ if (netif_msg_##type(priv) != 0) \
+ netdev_printk(level, (dev), fmt, ##args); \
} while (0)
#undef netif_emerg
@@ -485,9 +482,9 @@ static inline const char *_kc_netdev_name(const struct net_device *dev)
netif_level(dbg, priv, type, dev, fmt, ##args)
#ifndef for_each_set_bit
-#define for_each_set_bit(bit, addr, size) \
- for ((bit) = find_first_bit((addr), (size)); \
- (bit) < (size); (bit) = find_next_bit((addr), (size), (bit) + 1))
+#define for_each_set_bit(bit, addr, size) \
+ for ((bit) = find_first_bit((addr), (size)); (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
#endif /* for_each_set_bit */
#ifndef DEFINE_DMA_UNMAP_ADDR
@@ -553,8 +550,8 @@ unsigned int _work_busy(struct work_struct *work);
#define NET_SKB_PAD 32
#endif
-static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *dev,
- unsigned int length)
+static inline struct sk_buff *
+_kc_netdev_alloc_skb_ip_align(struct net_device *dev, unsigned int length)
{
struct sk_buff *skb;
@@ -576,9 +573,9 @@ static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *d
#undef netif_level
#define netif_level(level, priv, type, dev, fmt, args...) \
- do { \
- if (netif_msg_##type(priv) != 0) \
- netdev_##level(dev, fmt, ##args); \
+ do { \
+ if (netif_msg_##type(priv) != 0) \
+ netdev_##level(dev, fmt, ##args); \
} while (0)
#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 3)))
@@ -587,17 +584,17 @@ static inline struct sk_buff *_kc_netdev_alloc_skb_ip_align(struct net_device *d
#endif
#define u64_stats_update_begin(a) \
- do { \
+ do { \
} while (0)
#define u64_stats_update_end(a) \
- do { \
+ do { \
} while (0)
#define u64_stats_fetch_retry(a, b) (0)
#define u64_stats_fetch_begin(a) (0)
#define u64_stats_fetch_retry_bh(a, b) (0)
#define u64_stats_fetch_begin_bh(a) (0)
struct u64_stats_sync_empty {
- int:0;
+ int : 0;
};
#if (RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 1))
@@ -607,13 +604,14 @@ struct u64_stats_sync_empty {
/* RHEL6.4 and SLES11sp2 backported skb_tx_timestamp */
/* RHEL6.4 and SLES11sp2 backported skb_tx_timestamp */
#if (!(RHEL_RELEASE_VERSION(6, 4) <= RHEL_RELEASE_CODE) && \
- !(SLE_VERSION(11, 2, 0) <= SLE_VERSION_CODE))
-static inline void skb_tx_timestamp(struct sk_buff __always_unused *skb) {}
+ !(SLE_VERSION(11, 2, 0) <= SLE_VERSION_CODE))
+static inline void skb_tx_timestamp(struct sk_buff __always_unused *skb)
+{
+}
#endif
#else /* < 2.6.36 */
-
#endif /* < 2.6.36 */
/* ************************************************************************ */
@@ -647,8 +645,8 @@ static inline void *_kc_vzalloc(unsigned long size)
#ifndef skb_queue_reverse_walk_safe
#define skb_queue_reverse_walk_safe(queue, skb, tmp) \
- for (skb = (queue)->prev, tmp = skb->prev; \
- skb != (struct sk_buff *)(queue); skb = tmp, tmp = skb->prev)
+ for (skb = (queue)->prev, tmp = skb->prev; \
+ skb != (struct sk_buff *)(queue); skb = tmp, tmp = skb->prev)
#endif
#if (!(RHEL_RELEASE_CODE && RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6, 0)))
@@ -658,10 +656,10 @@ int _kc_netdev_set_num_tc(struct net_device *dev, u8 num_tc);
#define netdev_set_num_tc(dev, tc) _kc_netdev_set_num_tc((dev), (tc))
#define netdev_reset_tc(dev) _kc_netdev_set_num_tc((dev), 0)
#define netdev_set_tc_queue(dev, tc, cnt, off) \
- do { \
+ do { \
} while (0)
#define netdev_set_prio_tc_map(dev, up, tc) \
- do { \
+ do { \
} while (0)
#else /* RHEL6.1 or greater */
#ifndef HAVE_MQPRIO
@@ -723,7 +721,7 @@ static inline void *_kc_dma_zalloc_coherent(struct device *dev, size_t size,
#endif
#ifndef skb_frag_size
-#define skb_frag_size(frag) kc_skb_frag_size(frag)
+#define skb_frag_size(frag) kc_skb_frag_size(frag)
static inline unsigned int kc_skb_frag_size(const skb_frag_t *frag)
{
return frag->size;
@@ -731,7 +729,7 @@ static inline unsigned int kc_skb_frag_size(const skb_frag_t *frag)
#endif /* skb_frag_size */
#ifndef skb_frag_size_sub
-#define skb_frag_size_sub(frag, delta) kc_skb_frag_size_sub(frag, delta)
+#define skb_frag_size_sub(frag, delta) kc_skb_frag_size_sub(frag, delta)
static inline void kc_skb_frag_size_sub(skb_frag_t *frag, int delta)
{
frag->size -= delta;
@@ -747,7 +745,7 @@ static inline struct page *_kc_skb_frag_page(const skb_frag_t *frag)
#endif /* skb_frag_page */
#ifndef skb_frag_address
-#define skb_frag_address(frag) kc_skb_frag_address(frag)
+#define skb_frag_address(frag) kc_skb_frag_address(frag)
static inline void *kc_skb_frag_address(const skb_frag_t *frag)
{
return page_address(skb_frag_page(frag)) + frag->page_offset;
@@ -761,7 +759,8 @@ static inline void *kc_skb_frag_address(const skb_frag_t *frag)
#define skb_frag_dma_map(dev, frag, offset, size, dir) \
_kc_skb_frag_dma_map(dev, frag, offset, size, dir)
-static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev, const skb_frag_t *frag,
+static inline dma_addr_t _kc_skb_frag_dma_map(struct device *dev,
+ const skb_frag_t *frag,
size_t offset, size_t size,
enum dma_data_direction dir)
{
@@ -785,7 +784,7 @@ static inline void __kc_skb_frag_unref(skb_frag_t *frag)
#define DUPLEX_UNKNOWN 0xff
#endif
#if ((RHEL_RELEASE_VERSION(6, 3) <= RHEL_RELEASE_CODE) || \
- (SLE_VERSION_CODE && SLE_VERSION(11, 3, 0) <= SLE_VERSION_CODE))
+ (SLE_VERSION_CODE && SLE_VERSION(11, 3, 0) <= SLE_VERSION_CODE))
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#endif
@@ -806,8 +805,8 @@ static inline void __kc_skb_frag_unref(skb_frag_t *frag)
#define STR_IDX 3
#define FIRST_TO_CHECK 4
static inline struct workqueue_struct *__printf(STR_IDX, FIRST_TO_CHECK)
-_kc_alloc_workqueue(__maybe_unused int flags, __maybe_unused int max_active,
- const char *fmt, ...)
+ _kc_alloc_workqueue(__maybe_unused int flags,
+ __maybe_unused int max_active, const char *fmt, ...)
{
struct workqueue_struct *wq;
va_list args, temp;
@@ -851,22 +850,22 @@ typedef u32 netdev_features_t;
#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
#ifndef CONFIG_BQL
#define netdev_tx_completed_queue(_q, _p, _b) \
- do { \
+ do { \
} while (0)
#define netdev_completed_queue(_n, _p, _b) \
- do { \
+ do { \
} while (0)
#define netdev_tx_sent_queue(_q, _b) \
- do { \
+ do { \
} while (0)
#define netdev_sent_queue(_n, _b) \
- do { \
+ do { \
} while (0)
#define netdev_tx_reset_queue(_q) \
- do { \
+ do { \
} while (0)
#define netdev_reset_queue(_n) \
- do { \
+ do { \
} while (0)
#endif
#if (SLE_VERSION_CODE && SLE_VERSION_CODE >= SLE_VERSION(11, 3, 0))
@@ -907,11 +906,12 @@ static inline int kc_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
#ifndef skb_add_rx_frag
#define skb_add_rx_frag _kc_skb_add_rx_frag
void _kc_skb_add_rx_frag(struct sk_buff *param0, int param1,
- struct page *param2, int param3, int param4, unsigned int param5);
+ struct page *param2, int param3, int param4,
+ unsigned int param5);
#endif
#ifdef NET_ADDR_RANDOM
-#define eth_hw_addr_random(N) \
- do { \
+#define eth_hw_addr_random(N) \
+ do { \
eth_random_addr(N->dev_addr); \
N->addr_assign_type |= NET_ADDR_RANDOM; \
} while (0)
@@ -920,9 +920,9 @@ void _kc_skb_add_rx_frag(struct sk_buff *param0, int param1,
#endif /* NET_ADDR_RANDOM */
#ifndef for_each_set_bit_from
-#define for_each_set_bit_from(bit, addr, size) \
- for ((bit) = find_next_bit((addr), (size), (bit)); \
- (bit) < (size); (bit) = find_next_bit((addr), (size), (bit) + 1))
+#define for_each_set_bit_from(bit, addr, size) \
+ for ((bit) = find_next_bit((addr), (size), (bit)); (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
#endif /* for_each_set_bit_from */
#if (RHEL_RELEASE_VERSION(7, 0) > RHEL_RELEASE_CODE)
@@ -963,7 +963,8 @@ static inline int of_get_phy_mode(struct device_node __always_unused *np)
return -ENODEV;
}
-static inline const void *of_get_mac_address(struct device_node __always_unused *np)
+static inline const void *
+of_get_mac_address(struct device_node __always_unused *np)
{
return NULL;
}
@@ -1016,7 +1017,7 @@ static inline int kc_pci_vfs_assigned(struct pci_dev __always_unused *dev)
#endif /* NEED_DEFINE_LIST_FIRST_ENTRY_OR_NULL */
#ifndef VLAN_TX_COOKIE_MAGIC
static inline struct sk_buff *kc_vlan_hwaccel_put_tag(struct sk_buff *skb,
- u16 vlan_tci)
+ u16 vlan_tci)
{
#ifdef VLAN_TAG_PRESENT
vlan_tci |= VLAN_TAG_PRESENT;
@@ -1045,6 +1046,7 @@ static inline struct sk_buff *kc_vlan_hwaccel_put_tag(struct sk_buff *skb,
#endif
#if (KERNEL_VERSION(6, 3, 0) > LINUX_VERSION_CODE)
+#ifndef HAVE_VM_FLAGS_SET
static inline void vm_flags_set(struct vm_area_struct *vma, vm_flags_t flags)
{
vma->vm_flags |= flags;
@@ -1054,6 +1056,7 @@ static inline void vm_flags_clear(struct vm_area_struct *vma, vm_flags_t flags)
{
vma->vm_flags &= ~flags;
}
+#endif /* have vm flags set */
#endif /* < 6.3.0 */
/* ************************************************************************ */
@@ -1062,7 +1065,7 @@ static inline void vm_flags_clear(struct vm_area_struct *vma, vm_flags_t flags)
int kc_dma_set_mask_and_coherent(struct device *dev, u64 mask);
#ifndef u64_stats_init
#define u64_stats_init(a) \
- do { \
+ do { \
} while (0)
#endif
#ifndef BIT_ULL
@@ -1087,7 +1090,7 @@ int kc_dma_set_mask_and_coherent(struct device *dev, u64 mask);
#else /* >= 3.13.0 */
#define HAVE_VXLAN_CHECKS
#if (defined(UBUNTU_VERSION_CODE) && UBUNTU_VERSION_CODE && \
- UBUNTU_VERSION(3, 13, 0, 24) <= UBUNTU_VERSION_CODE)
+ UBUNTU_VERSION(3, 13, 0, 24) <= UBUNTU_VERSION_CODE)
#else
#define HAVE_NDO_SELECT_QUEUE_ACCEL
#endif
@@ -1097,9 +1100,9 @@ int kc_dma_set_mask_and_coherent(struct device *dev, u64 mask);
/* ************************************************************************ */
#if (KERNEL_VERSION(3, 14, 0) > LINUX_VERSION_CODE)
-#if (!(RHEL_RELEASE_CODE && \
- RHEL_RELEASE_VERSION(7, 0) <= RHEL_RELEASE_CODE) && \
- !(SLE_VERSION_CODE && SLE_VERSION(12, 0, 0) <= SLE_VERSION_CODE))
+#if (!(RHEL_RELEASE_CODE && \
+ RHEL_RELEASE_VERSION(7, 0) <= RHEL_RELEASE_CODE) && \
+ !(SLE_VERSION_CODE && SLE_VERSION(12, 0, 0) <= SLE_VERSION_CODE))
/* it isn't expected that this would be a #define unless we made it so */
#ifndef NEED_SKB_SET_HASH
@@ -1118,9 +1121,9 @@ enum _kc_pkt_hash_types {
#define pkt_hash_types _kc_pkt_hash_types
#define skb_set_hash __kc_skb_set_hash
-static inline void
-__kc_skb_set_hash(struct sk_buff __maybe_unused *skb,
- u32 __maybe_unused hash, int __maybe_unused type)
+static inline void __kc_skb_set_hash(struct sk_buff __maybe_unused *skb,
+ u32 __maybe_unused hash,
+ int __maybe_unused type)
{
#ifdef HAVE_SKB_L4_RXHASH
skb->l4_rxhash = (type == PKT_HASH_TYPE_L4);
@@ -1181,11 +1184,11 @@ int kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
/* ************************************************************************ */
#if (KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE)
#define HAVE_STRUCT_CURRENT
-#if (SLE_VERSION_CODE && (SLE_VERSION(12, 3, 0) <= SLE_VERSION_CODE)) || \
- (RHEL_RELEASE_CODE && \
- RHEL_RELEASE_VERSION(7, 5) <= RHEL_RELEASE_CODE) || \
- (DEEPIN_VERSION_CODE && \
- (DEEPIN_PRODUCT_VERSION(15, 2, 0) == DEEPIN_VERSION_CODE))
+#if (SLE_VERSION_CODE && (SLE_VERSION(12, 3, 0) <= SLE_VERSION_CODE)) || \
+ (RHEL_RELEASE_CODE && \
+ RHEL_RELEASE_VERSION(7, 5) <= RHEL_RELEASE_CODE) || \
+ (DEEPIN_VERSION_CODE && \
+ (DEEPIN_PRODUCT_VERSION(15, 2, 0) == DEEPIN_VERSION_CODE))
#endif
#ifdef CONFIG_NET_RX_BUSY_POLL
@@ -1209,7 +1212,7 @@ int kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
/* ************************************************************************ */
#if (KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE)
#if ((KERNEL_VERSION(3, 10, 0) == LINUX_VERSION_CODE) && RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_VERSION(7, 6) == RHEL_RELEASE_CODE))
+ (RHEL_RELEASE_VERSION(7, 6) == RHEL_RELEASE_CODE))
#else
#define TC_SETUP_QDISC_MQPRIO TC_SETUP_MQPRIO
#endif
@@ -1247,7 +1250,7 @@ int kc_pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
#if (SLE_VERSION_CODE && (SLE_VERSION(15, 0, 0) > SLE_VERSION_CODE))
#ifndef kmalloc_array
-#define SIZE_MAX (~(size_t)0)
+#define SIZE_MAX (~(size_t)0)
static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
{
@@ -1259,13 +1262,14 @@ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
#endif
#define bitmap_zalloc(nbits, flags) _hinic5_bitmap_zalloc(nbits, flags)
-static inline unsigned long *_hinic5_bitmap_zalloc(unsigned int nbits, gfp_t flags)
+static inline unsigned long *_hinic5_bitmap_zalloc(unsigned int nbits,
+ gfp_t flags)
{
- return kmalloc_array(BITS_TO_LONGS(nbits),
- sizeof(unsigned long), flags | __GFP_ZERO);
+ return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long),
+ flags | __GFP_ZERO);
}
-#define bitmap_free(bitmap) _hinic5_bitmap_free(bitmap)
+#define bitmap_free(bitmap) _hinic5_bitmap_free(bitmap)
static inline void _hinic5_bitmap_free(unsigned long *bitmap)
{
kfree(bitmap);
@@ -1283,15 +1287,14 @@ static inline void _hinic5_bitmap_free(unsigned long *bitmap)
#else /* >= 5.0.0 */
#define dev_open(x) dev_open(x, NULL)
-
#ifndef get_ds
-#define get_ds() (KERNEL_DS)
+#define get_ds() (KERNEL_DS)
#endif
#ifndef dma_zalloc_coherent
#define dma_zalloc_coherent(d, s, h, f) _hinic5_dma_zalloc_coherent(d, s, h, f)
-static inline void *_hinic5_dma_zalloc_coherent(struct device *dev,
- size_t size, dma_addr_t *dma_handle,
+static inline void *_hinic5_dma_zalloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle,
gfp_t gfp)
{
/* Above kernel 5.0, fixed up all remaining architectures
@@ -1306,8 +1309,8 @@ static inline void *_hinic5_dma_zalloc_coherent(struct device *dev,
#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
- __kernel_old_time_t tv_sec; /* seconds */
- __kernel_suseconds_t tv_usec; /* microseconds */
+ __kernel_old_time_t tv_sec; /* seconds */
+ __kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
#endif
@@ -1370,15 +1373,14 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define HAVE_XDP_FRAME_SZ
#endif /* 5.9.0 */
-
#ifdef NEED_DEFINE_PCI_DMA_COMPAT
#include <linux/dma-mapping.h>
/* This defines the direction arg to the DMA mapping routines. */
-#define PCI_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
-#define PCI_DMA_TODEVICE DMA_TO_DEVICE
-#define PCI_DMA_FROMDEVICE DMA_FROM_DEVICE
-#define PCI_DMA_NONE DMA_NONE
+#define PCI_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
+#define PCI_DMA_TODEVICE DMA_TO_DEVICE
+#define PCI_DMA_FROMDEVICE DMA_FROM_DEVICE
+#define PCI_DMA_NONE DMA_NONE
static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
dma_addr_t *dma_handle)
@@ -1457,8 +1459,8 @@ static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev,
}
static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev,
- struct scatterlist *sg,
- int nelems, int direction)
+ struct scatterlist *sg, int nelems,
+ int direction)
{
dma_sync_sg_for_cpu(&pdev->dev, sg, nelems,
(enum dma_data_direction)direction);
@@ -1490,9 +1492,13 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
}
#else
static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{ return -EIO; }
+{
+ return -EIO;
+}
static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{ return -EIO; }
+{
+ return -EIO;
+}
#endif
#endif /* > NEED_DEFINE_PCI_DMA_COMPAT */
@@ -1502,56 +1508,56 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
#include <linux/dmapool.h>
-#define pci_pool dma_pool
+#define pci_pool dma_pool
#define pci_pool_create(name, pdev, size, align, allocation) \
- dma_pool_create(name, &pdev->dev, size, align, allocation)
-#define pci_pool_destroy(pool) dma_pool_destroy(pool)
-#define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
-#define pci_pool_zalloc(pool, flags, handle) \
- dma_pool_zalloc(pool, flags, handle)
-#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
+ dma_pool_create(name, &pdev->dev, size, align, allocation)
+#define pci_pool_destroy(pool) dma_pool_destroy(pool)
+#define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
+#define pci_pool_zalloc(pool, flags, handle) \
+ dma_pool_zalloc(pool, flags, handle)
+#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
#endif /* > 5.15.0 */
/* PCI AER */
#ifdef NEED_PCI_DISABLE_PCIE_ERROR_REPORTING
-#define pci_disable_pcie_error_reporting(pdev) ((void)pdev)
+#define pci_disable_pcie_error_reporting(pdev) ((void)pdev)
#endif
#ifdef NEED_PCI_ENABLE_PCIE_ERROR_REPORTING
-#define pci_enable_pcie_error_reporting(pdev) ((void)pdev)
+#define pci_enable_pcie_error_reporting(pdev) ((void)pdev)
#endif
/* ************************************************************************ */
/* device class */
#ifndef HAVE_CLASS_CREATE_OWNER
-#define class_create(owner, dev_class) class_create(dev_class)
+#define class_create(owner, dev_class) class_create(dev_class)
#endif
#ifdef NEED_GET_FS
-#define get_fs() 0
+#define get_fs() 0
#endif
#ifdef NEED_SET_FS
-#define set_fs(fs) ((void)fs)
+#define set_fs(fs) ((void)fs)
#endif
#ifdef NEED_FORCE_UACCESS_BEGIN
-#define force_uaccess_begin() 0
+#define force_uaccess_begin() 0
#endif
#ifdef NEED_FORCE_UACCESS_END
-#define force_uaccess_end(oldfs) ((void)oldfs)
+#define force_uaccess_end(oldfs) ((void)oldfs)
#endif
/* ************************************************************************ */
/* kallsyms */
#ifndef kallsyms_lookup_name
-#define kallsyms_lookup_name(name) __symbol_get(name)
+#define kallsyms_lookup_name(name) __symbol_get(name)
#endif
#ifndef kallsyms_lookup_name_wrap
-#define kallsyms_lookup_name_wrap(name) __symbol_get(name)
+#define kallsyms_lookup_name_wrap(name) __symbol_get(name)
#endif
/* ********************* net/devlink.h start ************ */
@@ -1562,12 +1568,13 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
/*****************************************************************************/
#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
#else /* >= 5.5.0 */
-#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS // TODO, legacy, devlink feature macro switch
+#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS // TODO, 历史遗留, devlink 功能性宏开关
#endif /* 5.5.0 */
/* devlink_alloc */
#if (defined(HAVE_DEVLINK_ALLOC) && defined(HAVE_DEVLINK_ALLOC_SET_DEV))
-#define ossl_devlink_alloc(ops, priv_size, dev) devlink_alloc(ops, priv_size, dev)
+#define ossl_devlink_alloc(ops, priv_size, dev) \
+ devlink_alloc(ops, priv_size, dev)
#else
#define ossl_devlink_alloc(ops, priv_size, dev) devlink_alloc(ops, priv_size)
#endif
@@ -1575,7 +1582,11 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
/* devlink_register */
#ifdef HAVE_DEVLINK_REGISTER
#ifndef HAVE_DEVLINK_REGISTER_HAVE_RET
-#define ossl_devlink_register(devlink, dev) ({ devlink_register(devlink); 0; })
+#define ossl_devlink_register(devlink, dev) \
+ ({ \
+ devlink_register(devlink); \
+ 0; \
+ })
#else
#ifndef HAVE_DEVLINK_REGISTER_SET_DEV
#define ossl_devlink_register(devlink, dev) devlink_register(devlink)
@@ -1587,11 +1598,11 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
/* devlink_params_* */
#ifndef HAVE_DEVLINK_PARAMS_PUBLISH
-#define devlink_params_publish(devlink) ((void)(devlink))
+#define devlink_params_publish(devlink) ((void)(devlink))
#endif
#ifndef HAVE_DEVLINK_PARAMS_UNPUBLISH
-#define devlink_params_unpublish(devlink) ((void)(devlink))
+#define devlink_params_unpublish(devlink) ((void)(devlink))
#endif
/* ********************* net/devlink.h end ************ */
@@ -1599,10 +1610,10 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
* skb->inner_transport_header is wrong
*/
#if (defined(SLE_VERSION_CODE) && defined(SLE_VERSION) && SLE_VERSION_CODE && \
- ((SLE_VERSION(12, 1, 0) == SLE_VERSION_CODE) || \
- (SLE_VERSION(12, 0, 0) == SLE_VERSION_CODE))) || \
- (RHEL_RELEASE_CODE && \
- (RHEL_RELEASE_VERSION(7, 0) == RHEL_RELEASE_CODE))
+ ((SLE_VERSION(12, 1, 0) == SLE_VERSION_CODE) || \
+ (SLE_VERSION(12, 0, 0) == SLE_VERSION_CODE))) || \
+ (RHEL_RELEASE_CODE && \
+ (RHEL_RELEASE_VERSION(7, 0) == RHEL_RELEASE_CODE))
#define HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
#endif
@@ -1623,22 +1634,22 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev);
unsigned int cpumask_local_spread(unsigned int i, int node);
#endif
-#define spin_lock_deinit(lock) ((void)(lock))
+#define spin_lock_deinit(lock) ((void)(lock))
-struct file *hinic5_file_creat(const char *file_name);
+struct file *file_creat(const char *file_name);
-struct file *hinic5_file_open(const char *file_name);
+struct file *file_open(const char *file_name);
-void hinic5_file_close(struct file *file_handle);
+void file_close(struct file *file_handle);
-u32 hinic5_get_file_size(struct file *file_handle);
+u32 get_file_size(struct file *file_handle);
-void hinic5_set_file_position(struct file *file_handle, u32 position);
+void set_file_position(struct file *file_handle, u32 position);
-int hinic5_file_read(struct file *file_handle, char *log_buffer, u32 rd_length,
+int file_read(struct file *file_handle, char *log_buffer, u32 rd_length,
u32 *file_pos);
-u32 hinic5_file_write(struct file *file_handle, const char *log_buffer, u32 wr_length);
+u32 file_write(struct file *file_handle, const char *log_buffer, u32 wr_length);
struct sdk_thread_info {
struct task_struct *thread_obj;
@@ -1648,23 +1659,23 @@ struct sdk_thread_info {
void *data;
};
-int hinic5_creat_thread(struct sdk_thread_info *thread_info);
+int creat_thread(struct sdk_thread_info *thread_info);
-void hinic5_stop_thread(struct sdk_thread_info *thread_info);
+void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-void hinic5_utctime_to_localtime(u64 utctime, u64 *localtime);
+void utctime_to_localtime(u64 utctime, u64 *localtime);
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-void hinic5_add_to_timer(struct timer_list *timer, u64 period);
-void hinic5_stop_timer(struct timer_list *timer);
-void hinic5_delete_timer(struct timer_list *timer);
-u64 hinic5_ossl_get_real_time(void);
+void add_to_timer(struct timer_list *timer, u64 period);
+void stop_timer(struct timer_list *timer);
+void delete_timer(struct timer_list *timer);
+u64 ossl_get_real_time(void);
-/* Does not exist in linux kernel, defined as empty */
+/* linux 内核中不存在, 定义为空 */
#define destroy_completion(completion)
#define sema_deinit(lock)
#define mutex_deinit(lock)
@@ -1673,7 +1684,7 @@ u64 hinic5_ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#ifdef NEED_MATH64_MUL_U64_U64_DIV_U64
-u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c);
+u64 mul5_u64_u64_div_u64(u64 a, u64 b, u64 c);
#else
#define HAVE_PTP_INFO_GETTIMEX64
#endif
@@ -1689,7 +1700,8 @@ static inline bool diff_by_scaled_ppm(u64 base, long scaled_ppm, u64 *diff)
scaled_ppm_val = -scaled_ppm;
}
/* scaled_ppm(x.y) low 16bit -> y, high 16bit -> x */
- *diff = mul_u64_u64_div_u64(base, (u64)scaled_ppm_val, 1000000ULL << 16);
+ *diff = mul5_u64_u64_div_u64(base, (u64)scaled_ppm_val,
+ 1000000ULL << 16);
return negative;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux_nic.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux_nic.h
index 00a0a0770..3000c1b3c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux_nic.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/ossl_knl_linux_nic.h
@@ -1,14 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : ossl_knl_linux_nic.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Kernel compatibility layer for the NIC module across different OS kernels.
+/**
+ * @copyright Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * @file ossl_knl_linux_nic.h
+ * @brief Kernel compatibility layer for the NIC module across different OS kernels.
+ * @version Initial
+ * @date 2025/11/1
*/
-
#ifndef OSSL_KNL_LINUX_NIC_H
#define OSSL_KNL_LINUX_NIC_H
@@ -27,7 +24,7 @@
#include "base_type.h"
#include "nic_kcompat.h"
-#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
#ifndef __GFP_COLD
#define __GFP_COLD 0
@@ -48,22 +45,22 @@
#ifndef ETHTOOL_GLINKSETTINGS
/* adapt to SUPPORTED_** and ADVERTISED_**, only 32 bits */
enum ethtool_link_mode_bit_indices {
- ETHTOOL_LINK_MODE_1000baseT_Full_BIT = 5,
- ETHTOOL_LINK_MODE_Autoneg_BIT = 6,
- ETHTOOL_LINK_MODE_TP_BIT = 7,
- ETHTOOL_LINK_MODE_FIBRE_BIT = 10,
- ETHTOOL_LINK_MODE_Pause_BIT = 13,
- ETHTOOL_LINK_MODE_Asym_Pause_BIT = 14,
- ETHTOOL_LINK_MODE_Backplane_BIT = 16,
- ETHTOOL_LINK_MODE_10000baseT_Full_BIT = 12,
- ETHTOOL_LINK_MODE_1000baseKX_Full_BIT = 17,
- ETHTOOL_LINK_MODE_10000baseKR_Full_BIT = 19,
- ETHTOOL_LINK_MODE_10000baseR_FEC_BIT = 20,
- ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT = 23,
- ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT = 24,
- ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT = 25,
- ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT = 26,
- ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31,
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT = 5,
+ ETHTOOL_LINK_MODE_Autoneg_BIT = 6,
+ ETHTOOL_LINK_MODE_TP_BIT = 7,
+ ETHTOOL_LINK_MODE_FIBRE_BIT = 10,
+ ETHTOOL_LINK_MODE_Pause_BIT = 13,
+ ETHTOOL_LINK_MODE_Asym_Pause_BIT = 14,
+ ETHTOOL_LINK_MODE_Backplane_BIT = 16,
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT = 12,
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT = 17,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT = 19,
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT = 20,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT = 23,
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT = 24,
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT = 25,
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT = 26,
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 31,
};
#ifndef __ETHTOOL_LINK_MODE_MASK_NBITS
@@ -72,7 +69,7 @@ enum ethtool_link_mode_bit_indices {
#endif
#ifndef __ETHTOOL_DECLARE_LINK_MODE_MASK
-#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
+#define __ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
DECLARE_BITMAP(name, __ETHTOOL_LINK_MODE_MASK_NBITS)
#endif
@@ -149,11 +146,11 @@ enum ethtool_link_mode_bit_indices {
#endif
#ifndef SPEED_50000
-#define SPEED_50000 50000
+#define SPEED_50000 50000
#endif
#ifndef SPEED_200000
-#define SPEED_200000 200000
+#define SPEED_200000 200000
#endif
#ifndef SPEED_400000
@@ -215,7 +212,7 @@ enum ethtool_link_mode_bit_indices {
#endif /* NEED_DEFINE_DMA_RMB */
#ifdef NEED_ETH_P_8021AD
-#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
+#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#endif /* NEED_ETH_P_8021AD */
#ifdef NEED___vlan_get_protocol
@@ -230,7 +227,6 @@ __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, int *next_depth);
#define NETDEV_RSS_KEY_LEN (13 * 4)
#endif /* NEED_DEFINE_NETDEV_RSS_KEY_LEN */
-
#ifdef NEED_NAPI_SCHEDULE_IRQOFF
#define napi_schedule_irqoff napi_schedule
#endif /* NEED_NAPI_SCHEDULE_IRQOFF */
@@ -287,11 +283,12 @@ __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, int *next_depth);
#define HAVE_XDP_QUERY_PROG
#endif /* HAVE_XDP_QUERY_PROG */
-#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) && !defined(HAVE_NDO_SELECT_QUEUE_FALLBACK)
+#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) && \
+ !defined(HAVE_NDO_SELECT_QUEUE_FALLBACK)
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
-#elif defined(HAVE_NDO_SELECT_QUEUE_FALLBACK) && \
+#elif defined(HAVE_NDO_SELECT_QUEUE_FALLBACK) && \
(defined(HAVE_NDO_SELECT_QUEUE_SB_DEV) || \
- defined(HAVE_NDO_SELECT_QUEUE_ACCEL))
+ defined(HAVE_NDO_SELECT_QUEUE_ACCEL))
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
#endif /* HAVE_NDO_SELECT_QUEUE_ACCEL */
@@ -300,18 +297,20 @@ __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type, int *next_depth);
#define netif_napi_add(dev, napi, napi_struct, weight) \
netif_napi_add_weight(dev, napi, napi_struct, weight)
#elif defined(HAVE_NETIF_NAPI_NO_WEIGHT)
-#define netif_napi_add(dev, napi, napi_struct, weight) netif_napi_add(dev, napi, napi_struct)
+#define netif_napi_add(dev, napi, napi_struct, weight) \
+ netif_napi_add(dev, napi, napi_struct)
#endif
/* skb_recv_datagram absent noblock param int new kernel version */
#ifndef HAVE_SKB_RECV_DATAGRAM_NOBLOCK
-#define skb_recv_datagram(sk, flags, noblock, err) \
- skb_recv_datagram(sk, (flags) | ((noblock) != 0 ? MSG_DONTWAIT : 0), err)
+#define skb_recv_datagram(sk, flags, noblock, err) \
+ skb_recv_datagram(sk, (flags) | ((noblock) != 0 ? MSG_DONTWAIT : 0), \
+ err)
#endif
/* bpf_warn_invalid_xdp_action absent net_dev and prog param in old kernel version */
#ifndef HAVE_NETDEV_PROG_XDP_WARN_ACTION
-#define bpf_warn_invalid_xdp_action(net_dev, prog, act) \
+#define bpf_warn_invalid_xdp_action(net_dev, prog, act) \
bpf_warn_invalid_xdp_action(act)
#endif
@@ -352,7 +351,8 @@ static inline void __kc_ether_addr_copy(u8 *dst, const u8 *src)
#endif
/* eth_hw_addr_set was introduced in kernel version 5.15 */
-static inline void hinic5_eth_hw_addr_set(struct net_device *dev, const u8 *addr)
+static inline void hinic5_eth_hw_addr_set(struct net_device *dev,
+ const u8 *addr)
{
#if defined(HAVE_ETH_HW_ADDR_SET)
eth_hw_addr_set(dev, addr);
@@ -370,7 +370,6 @@ static inline void hinic5_eth_hw_addr_set(struct net_device *dev, const u8 *addr
#endif
#endif /* HAVE_PAGE_POOL_SUPPORT */
-
#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
#define HAVE_ENCAPSULATION_TSO
#endif
@@ -379,4 +378,4 @@ static inline void hinic5_eth_hw_addr_set(struct net_device *dev, const u8 *addr
#define HAVE_ENCAPSULATION_CSUM
#endif
-#endif /* OSSL_KNL_LINUX_NIC_H */
\ No newline at end of file
+#endif /* OSSL_KNL_LINUX_NIC_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h
index b3cd253d1..7745485a3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_sdk_intf/ossl/sdk_kcompat.h
@@ -1,29 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : sdk_kcompat.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+/**
+ * @copyright Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * @file sdk_kcompat.h
+ * @brief Temporary file - The actual sdk_kcompat.h is generated during build.
+ * @version Initial
+ * @date 2025/11/1
*/
+#ifndef _SDK_KCOMPAT_H_
+#define _SDK_KCOMPAT_H_
-#ifndef SDK_KCOMPAT_H
-#define SDK_KCOMPAT_H
-#define HAVE_PCIE_RESET_DONE 1
-#define HAVE_TIMER_SETUP 1
-#define HAVE_DEVLINK_H 1
-#define HAVE_DEVLINK_FLASH_UPDATE_METHOD 1
-#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW 1
-#define HAVE_DEVLINK_OPS_FLASH_UPDATE_HAVE_PARAMS 1
-#define HAVE_DEVLINK_ALLOC_SET_DEV 1
-#define HAVE_DEVLINK_ALLOC 1
-#define HAVE_DEVLINK_REGISTER 1
-#define NEED_FORCE_UACCESS_BEGIN 1
-#define NEED_FORCE_UACCESS_END 1
-#define NEED_GET_FS 1
-#define NEED_SET_FS 1
-#define NEED_PCI_ENABLE_PCIE_ERROR_REPORTING 1
-#define NEED_PCI_DISABLE_PCIE_ERROR_REPORTING 1
-#define HAVE_DEVNODE_CONST_DEV 1
-#endif /* SDK_KCOMPAT_H */
+// sdk_kcompat.h是中间产物头文件
+
+#endif /* _SDK_KCOMPAT_H_ */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/drv_bond_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/drv_bond_api.h
index bc6c43973..bc4a1ff8c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/drv_bond_api.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/drv_bond_api.h
@@ -1,15 +1,14 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : drv_bond_api.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : NIC driver half-offload bond interface definition
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description : nic驱动提供的半卸载bond接口定义
+ * Author : /
+ * Create : 2025/9/9
+ * Notes :
+ * History : Init
*/
-#ifndef DRV_BOND_API
-#define DRV_BOND_API
+#ifndef DRV_BOND_API_H
+#define DRV_BOND_API_H
#include <net/bonding.h>
#include <linux/netdevice.h>
@@ -18,177 +17,183 @@
/**
* @brief struct hinic5_bond_info_s
- * @details Bond information structure obtained by user
+ * @details 用户获取的bond信息结构体
*/
struct hinic5_bond_info_s {
- u8 slaves; /**< bond port slave bitmap */
- u8 cnt; /**< Number of bond slaves */
+ u8 slaves; /**< bond port slave bitmap */
+ u8 cnt; /**< bond slave 的数量 */
u8 rsvd[2];
- char slaves_name[BOND_PORT_MAX_NUM][BOND_NAME_MAX_LEN]; /**< Slave device name */
+ char slaves_name[BOND_PORT_MAX_NUM]
+ [BOND_NAME_MAX_LEN]; /**< slave设备名 */
};
/**
* @brief struct netdev_lower_state_info
- * @details Ndev status information
+ * @details ndev状态信息
*/
struct netdev_lower_state_info {
- u8 link_up : 1; /**< Slave device link up status */
- u8 tx_enabled : 1; /**< Slave device available for transmitting data */
+ u8 link_up : 1; /**< slave设备 link up状态 */
+ u8 tx_enabled : 1; /**< 可用于发送数据的slave设备 */
u8 rsvd : 6;
} __attribute__((__packed__));
/**
* @brief struct bond_tracker
- * @details Bond device information structure
+ * @details bond设备信息结构体
*/
struct bond_tracker {
- struct netdev_lower_state_info netdev_state[BOND_PORT_MAX_NUM]; /**< Bond slave device information */
- struct net_device *ndev[BOND_PORT_MAX_NUM]; /**< Bond slave device pointer */
- u8 cnt; /**< Number of bond slave devices */
- bool is_bonded; /**< Whether bond can be sent to mpu to create and activate bond */
+ struct netdev_lower_state_info
+ netdev_state[BOND_PORT_MAX_NUM]; /**< bond slave设备信息 */
+ struct net_device *ndev[BOND_PORT_MAX_NUM]; /**< bond slave设备指针 */
+ u8 cnt; /**< bond slave 设备数量 */
+ bool is_bonded; /**< bond是否可以发送至mpu创建并激活bond */
};
/**
* @brief struct bond_attr
- * @details Bond basic attributes
+ * @details bond基础属性
*/
struct bond_attr {
- u16 bond_mode; /**< Bond mode */
- u16 bond_id; /**< bond id */
- u16 up_delay; /**< Delay time before bond starts working when up */
- u16 down_delay; /**< Delay time before bond is unavailable when down */
- u8 active_slaves; /**< Active available slave bitmap */
- u8 slaves; /**< Original slave bitmap when creating bond */
- u8 lacp_collect_slaves; /**< Slave bitmap configured for LACP protocol */
- u8 xmit_hash_policy; /**< Hash policy for bond routing */
- u32 first_roce_func; /**< First func in bond, used only by RoCE */
- u32 bond_pf_bitmap; /**< Func for creating bond */
- u32 user_bitmap; /**< Current user bitmap using bond */
+ u16 bond_mode; /**< bond模式 */
+ u16 bond_id; /**< bond id */
+ u16 up_delay; /**< bond up时开始工作的延迟时间 */
+ u16 down_delay; /**< bond donw时不可用的延迟时间 */
+ u8 active_slaves; /**< 激活可用的slave bitmap */
+ u8 slaves; /**< 组bond时原始的slave bitmap */
+ u8 lacp_collect_slaves; /**< lacp协议配置的slave bitmap */
+ u8 xmit_hash_policy; /**< bond选路的hash策略 */
+ u32 first_roce_func; /**< bond中的第一个func,仅roce使用 */
+ u32 bond_pf_bitmap; /**< 组bond的func */
+ u32 user_bitmap; /**< 当前使用bond的用户bitmap */
};
/**
- * @brief User-registered bond binding processing interface
- * @param[in] bond: Pointer to bonding structure in kernel protocol
- * @details After user registers this interface, when protocol stack bond triggers bond events (adding/removing slaves, etc.),
- * this interface will be called to determine if binding is possible. If yes, bond driver will try to bind bond for user.
+ * @brief 用户注册的bond绑定处理接口
+ * @param[in] bond: 内核协议中bonding结构体指针
+ * @details 当用户注册此接口后,协议栈bond触发bond事件(增删slave等)会调用此接口进行
+ * 是否可以绑定bond的判断,如果判断可以则bond驱动会为用户尝试绑定bond
* @attention N/A
- * @return If returns true, bond can be bound; if returns false, bond cannot be bound
+ * @return 如果返回true,代表可以绑定bond,如果返回false代表不可绑定bond
**/
typedef bool (*attach_func)(struct bonding *bond);
/**
- * @brief User-registered bond event processing interface
- * @param[in] bond_name: Bond name
- * @param[in] attr: Bond attributes
- * @param[in] err: Processing result after bond activation/modification/deactivation, 0 for success, non-0 for failure
- * @details User registers this interface, and bond driver will call it for service's own processing before/after bond creation/deletion/update
+ * @brief 用户注册的bond事件处理接口
+ * @param[in] bond_name: bond名
+ * @param[in] attr: bond属性
+ * @param[in] err: bond激活后/修改后/去激活后的处理结果,0为成功,非0失败
+ * @details 用户注册此接口,当bond的创建/删除/更新前后,bond驱动会调用做业务自身的处理
* @attention N/A
* @return void
**/
-typedef void (*event_func)(const char *bond_name, struct bond_attr *attr, int err);
+typedef void (*event_func)(const char *bond_name, struct bond_attr *attr,
+ int err);
/**
* @brief struct bond_srv_func
- * @details Service-registered bond processing interface collection
+ * @details 业务注册的bond处理接口集合
*/
struct bond_srv_func {
- event_func before_active; /**< Srv processing before bond activation */
- event_func after_active; /**< Srv processing after bond activation */
- event_func before_modify; /**< Srv processing before bond modification */
- event_func after_modify; /**< Srv processing after bond modification */
- event_func before_deactive; /**< Srv processing before bond deactivation */
- event_func after_deactive; /**< Srv processing after bond deactivation */
- attach_func can_attach; /**< Register this interface to indicate that when protocol stack bond updates CFM, it will bind bond for srv */
+ event_func before_active; /**< bond激活前srv处理 */
+ event_func after_active; /**< bond激活后srv处理 */
+ event_func before_modify; /**< bond修改前srv处理 */
+ event_func after_modify; /**< bond修改后srv处理 */
+ event_func before_deactive; /**< bond去激活前srv处理 */
+ event_func after_deactive; /**< bond去激活后srv处理 */
+ attach_func
+ can_attach; /**< 注册此接口代表当协议栈bond更新CFM会为srv绑定bond */
};
/**
- * @brief User binds protocol stack bonding
- * @param[in] name Bond device name
- * @param[in] user User to bind
- * @param[out] bond_id Bound bond id
- * @details After user creates protocol stack bonding, they can issue this interface to bind bond with corresponding bond name,
- * and it returns the bond id managed internally by chip
- * @attention N/A
- * @return Returns binding result, 0 for success, non-0 for failure
+ * @brief 用户绑定协议栈bonding
+ * @param[in] name bond设备名
+ * @param[in] user 绑定的用户
+ * @param[out] bond_id 绑定的bondid
+ * @details 用户在协议栈bonding创建完成后,可以下发此接口绑定对应bond名的bond,返回芯片内部管理的bondid
+ * @attention 异步起work场景不能调用该接口
+ * @return 返回绑定结果,0为成功,非0失败
**/
-int hinic5_bond_attach(const char *name, enum hinic5_bond_user user, u16 *bond_id);
+int hinic5_bond_attach(const char *name, enum hinic5_bond_user user,
+ u16 *bond_id);
/**
- * @brief User unbinds protocol stack bonding
- * @param[in] bond_id Bond id
- * @param[in] user User to unbind
- * @details User unbinds protocol stack bonding. If there is no user using it, bond device in nic driver will be destroyed
- * @attention N/A
- * @return Returns unbinding result, 0 for success, non-0 for failure
+ * @brief 用户解绑协议栈bonding
+ * @param[in] bond_id bond id
+ * @param[in] user 绑定的用户
+ * @details 用户解绑协议栈bonding,如果无使用的用户则会销毁nic驱动中的bond设备
+ * @attention 异步起work场景不能调用该接口
+ * @return 返回解绑结果,0为成功,非0失败
**/
int hinic5_bond_detach(u16 bond_id, enum hinic5_bond_user user);
/**
- * @brief Unbind all bonds bound by this user
- * @param[in] user User
- * @details Unbind this user from all bond devices
+ * @brief 获取bond设备的BDF标识
+ * @param[in] bond_id bond id
+ * @param[out] uplink_id 返回的bdf id
+ * @details 获取bond设备的BDF标识,支持pci/ub设备
* @attention N/A
- * @return void
+ * @return 返回获取结果 0为成功,非0失败
**/
-void hinic5_bond_clean_user(enum hinic5_bond_user user);
+int hinic5_bond_get_uplink_id(u16 bond_id, u32 *uplink_id);
/**
- * @brief Get BDF identifier of bond device
- * @param[in] bond_id Bond id
- * @param[out] uplink_id Returned BDF id
- * @details Get BDF identifier of bond device, supports pci/ub devices
+ * @brief 上层用户服务注册回调函数及绑定bond
+ * @param[in] user 上层业务类型
+ * @param[in] func 用户拟注册的回调函数结集合,包含事件处理和绑定处理
* @attention N/A
- * @return Returns get result, 0 for success, non-0 for failure
+ * @return 返回注册结果0为成功,非0为绑定用户服务函数失败
**/
-int hinic5_bond_get_uplink_id(u16 bond_id, u32 *uplink_id);
+int hinic5_bond_register(enum hinic5_bond_user user,
+ struct bond_srv_func *func);
/**
- * @brief Bond user registers processing interface
- * @param[in] user User
- * @param[in] func Processing interface collection, including event processing and binding processing
- * @details User registers processing interface, see interface definition in bond_srv_func structure
+ * @brief 上层用户服务解绑bond及解注册回调函数
+ * @param[in] user 上层业务类型
* @attention N/A
- * @return Returns registration result, 0 for success, non-0 for failure
+ * @return 返回解注册结果0为成功,非0为解绑bond失败
**/
-int hinic5_bond_register_service_func(enum hinic5_bond_user user, struct bond_srv_func *func);
+int hinic5_bond_unregister(enum hinic5_bond_user user);
/**
- * @brief Bond user unregisters processing interface
- * @param[in] user User
- * @details User unregisters processing interface, see interface definition in bond_srv_func structure
+ * @brief 获取bond slave信息
+ * @param[in] bond_id bond id
+ * @param[in] info bond slave信息,详见hinic5_bond_info_s
+ * @details 获取bond slave信息
* @attention N/A
- * @return Returns unregistration result, 0 for success, non-0 for failure
+ * @return 返回获取结果 0为成功,非0失败
**/
-int hinic5_bond_unregister_service_func(enum hinic5_bond_user user);
+int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info);
/**
- * @brief Get bond slave information
- * @param[in] bond_id Bond id
- * @param[in] info Bond slave information, see hinic5_bond_info_s for details
- * @details Get bond slave information
+ * @brief 获取bond slave的ndev设备
+ * @param[in] bond_name bond名
+ * @param[in] port_id port id
+ * @details 获取bond中对应portid的ndev设备指针
* @attention N/A
- * @return Returns get result, 0 for success, non-0 for failure
+ * @return 返回ndev指针,返回非NULL获取成功,返回NULL获取失败
**/
-int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info);
+struct net_device *hinic5_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id);
/**
- * @brief Get bond slave's ndev device
- * @param[in] bond_name Bond name
- * @param[in] port_id Port id
- * @details Get ndev device pointer corresponding to portid in bond
+ * @brief 获取bond slave的设备信息
+ * @param[in] bond_name bond名
+ * @param[out] tracker bond设备信息,见bond_tracker
+ * @details 获取bond中所有slave设备的设备信息
* @attention N/A
- * @return Returns ndev pointer, returns non-NULL on success, returns NULL on failure
+ * @return 返回获取结果 0为成功,非0失败
**/
-struct net_device *hinic5_bond_get_netdev_by_portid(const char *bond_name, u8 port_id);
+int hinic5_bond_get_tracker_by_name(const char *name,
+ struct bond_tracker *tracker);
/**
- * @brief Get bond slave's device information
- * @param[in] name Bond name
- * @param[out] tracker Bond device information, see bond_tracker
- * @details Get device information of all slave devices in bond
+ * @brief 通过bond名获取bond id
+ * @param[in] bond_name bond名
+ * @param[out] bond_id 返回的bondid
+ * @details 返回的bondid为驱动侧维护的id
* @attention N/A
- * @return Returns get result, 0 for success, non-0 for failure
+ * @return 返回获取结果,0为找到,非0未找到
**/
-int hinic5_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker);
+int hinic5_bond_get_id_by_name(u8 *bond_name, u16 *bond_id);
-#endif
\ No newline at end of file
+#endif /* DRV_BOND_API_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/nic/drv_nic_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/nic/drv_nic_api.h
index e4614a0fd..fde621527 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/nic/drv_nic_api.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/drv_srvc_intf/nic/drv_nic_api.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : drv_nic_api.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef DRV_NIC_API_H
#define DRV_NIC_API_H
@@ -19,107 +9,122 @@
#endif
/**
- * @brief PF sets VF link state
+ * @brief PF设置VF link状态
*
* @param hwdev device pointer to hwdev
- * @param vf_link_forced VF forced link state, false--Link state follows PF, true--link state depends on link_state value
- * @param link_state link state, false--Link down, true--link up
- * @details PF sets link state for all VFs under this PF. PF saves VF's link state.
- * If not set, VF link state follows PF by default. After user setting, user's setting takes precedence.
+ * @param vf_link_forced VF 强制link状态,false--Link状态跟随PF,true--link状态根据link_state值
+ * @param link_state link状态,false--Link down,true--link up
+ * @details PF设置该PF下所有VF link状态,PF保存VF的link状态状态,
+ * 未设置场景下VF link状态默认跟随PF,用户设置后以用户设置为准
*
- * @attention: Only PF supports this
+ * @attention: 仅PF支持
*
- * @return: VF link state setting success or failure.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: VF link状态设置成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state);
+int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state);
/**
- * @brief Add device mac interface
+ * @brief 添加设备mac接口
*
* @param hwdev device pointer to hwdev
- * @param mac_addr MAC address
- * @param vlan_id VLAN id range [0~4095]
- * @param func_id Global function index
- * @param channel Channel id, channel id used for mailbox sending
+ * @param mac_addr mac地址
+ * @param vlan_id vlan id 范围[0~4095]
+ * @param func_id global function index
+ * @param channel channel id,mailbox发送使用的channel id
*
- * @details Add MAC address for corresponding function
+ * @details 添加对应function的mac地址
*
- * @attention: This function involves sending mailbox messages and may sleep. Do not call in interrupt context or other contexts that do not allow sleeping.
+ * @attention: 函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
*
- * @return: Add MAC returns success or failure.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 添加MAC返回成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id, u16 channel);
+int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
+ u16 channel);
#if !defined(__UEFI__) && !defined(__VMWARE__)
/**
- * @brief Get network device handle netdev structure pointer according to lld_dev
+ * @brief 根据lld_dev获取网络设备句柄netdev结构体指针
*
* @param lld_dev device pointer to lld_dev
*
- * @details Find nic uld device according to lld_dev to get netdev
+ * @details 根据lld_dev查找nic uld设备获取netdev
*
- * @attention: This interface returns without incrementing netdev reference count. If netdev is freed during use, it may lead to wild pointer access.
+ * @attention: 该接口返回不会对netdev引用计数++,使用过程中如果netdev被释放可能导致访问野指针
*
- * @return: Returns netdev structure pointer when successfully matching lld_dev, otherwise returns NULL
+ * @return: 成功匹配到lld_dev的netdev时返回netdev结构体指针,否则返回NULL
*/
struct net_device *hinic5_get_netdev_by_lld(struct hinic5_lld_dev *lld_dev);
/**
- * @brief Register device private data
+ * @brief 根据netdev获取hwdev指针
+ *
+ * @param netdev netdev结构体指针
+ *
+ * @details 根据netdev匹配查找查找hwdev
+ *
+ * @attention: 该接口返回不会对hwdev引用计数++,使用过程中如果hwdev被释放可能导致访问野指针
+ *
+ * @return: 成功匹配到netdev的hwdev时返回hwdev指针,否则返回NULL
+ */
+void *hinic5_get_hwdev_by_netdev(struct net_device *netdev);
+
+/**
+ * @brief 注册设备私有数据
*
* @param dev device pointer to net_device
- * @param priv Private data
+ * @param priv 私有数据
*
- * @details Register device private data through net_device
+ * @details 通过net_device注册设备私有数据
*
- * @return: Private data registration success or failure.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 私有数据注册成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_netdev_priv_set(const struct net_device *dev, void *priv);
/**
- * @brief Get device private data
+ * @brief 获取设备私有数据
*
* @param dev device pointer to net_device
*
- * @details Get device private data through net_device
+ * @details 通过net_device注册设备私有数据
*
- * @attention: Need to call hinic5_netdev_priv_set interface to register device private data first
+ * @attention: 需要先调用hinic5_netdev_priv_set接口注册设备私有数据
*
- * @return: Private data.
- * @retval NULL Failure
- * @retval non-NULL Success
+ * @return: 私有数据.
+ * @retval NULL 失败
+ * @retval 非NULL 成功
*/
void *hinic5_netdev_priv_get(const struct net_device *dev);
/**
- * @brief NIC driver load hook function
+ * @brief NIC驱动加载钩子函数
*
* @param netdev device pointer to net_device
*
- * @details Overloaded by product, can implement functions like registering filesystem files, modifying netdev name, etc.
+ * @details 由产品重载,可实现注册文件系统文件、修改netdev名称等功能
*
- * @return: Hook function execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 钩子函数运行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_probe_extend_hook(struct net_device *netdev);
/**
- * @brief NIC driver unload hook
+ * @brief NIC驱动卸载钩子
*
* @param netdev device pointer to net_device
*
- * @details Overloaded by product
+ * @details 由产品重载
*
- * @return: Hook function execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 钩子函数运行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
void hinic5_remove_extend_hook(struct net_device *netdev);
@@ -131,106 +136,120 @@ struct hinic5_nt_msg {
};
/**
- * @brief NIC driver command hook function
+ * @brief NIC驱动命令钩子函数
*
* @param netdev device pointer to net_device
- * @param cmd Command word
- * @param nt_msg Command content
- * @param support Whether the command is supported, product needs to determine support based on command word
+ * @param cmd 命令字
+ * @param nt_msg 命令内容
+ * @param support 是否支持该命令, 产品需要根据命令字判断是否支持
*
- * @details Overloaded by product
+ * @details 由产品重载
*
- * @return: Command execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_tool_cmd_extend_handle(struct net_device *netdev, u32 cmd,
struct hinic5_nt_msg *nt_msg, bool *support);
/**
- * @brief Product side interface to set user-space qps number
+ * @brief 产品侧设置用户态qps数的接口
*
* @param netdev device pointer to net_device
- * @param usr_qps_num Expected user-space qps number
- * @details Called by product
+ * @param usr_qps_num 期望的用户态qps数量
+ * @details 由产品调用
*
- * @return: Command execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_set_usr_qps_num(struct net_device *netdev, u16 usr_qps_num);
/**
- * @brief NIC related skip MAC setting function
+ * @brief 产品侧获取用户态qps数的接口
+ *
+ * @param netdev device pointer to net_device
+ * @details 获取用户态qps数的接口
+ *
+ * @return: 用户态qps数量
+ */
+u16 hinic5_get_usr_qps_num(struct net_device *netdev);
+
+/**
+ * @brief NIC相关跳过MAC设置函数
*
* @param dev device pointer to net_device
- * @param addr MAC address
+ * @param addr MAC地址
*
- * @details Overloaded by product, can implement skip related settings after user-space queue is enabled
+ * @details 由产品重载,可实现用户态队列开启后跳过相关设置的功能
*
- * @return: Hook function execution result.
- * @retval 0 Do not skip
- * @retval non-0 Skip
+ * @return: 钩子函数运行结果.
+ * @retval 0 不跳过
+ * @retval 非0 跳过
*/
int hinic5_set_mac_addr_pre_hook(struct net_device *netdev, void *addr);
/**
- * @brief NIC related skip MTU setting function
+ * @brief NIC相关跳过MTU设置函数
*
* @param netdev device pointer to net_device
- * @param new_mtu New MTU value
+ * @param new_mtu 新的mtu值
*
- * @details Overloaded by product, can implement skip related settings after user-space queue is enabled
+ * @details 由产品重载,可实现用户态队列开启后跳过相关设置的功能
*
- * @return: Hook function execution result.
- * @retval 0 Do not skip
- * @retval non-0 Skip
+ * @return: 钩子函数运行结果.
+ * @retval 0 不跳过
+ * @retval 非0 跳过
*/
int hinic5_change_mtu_pre_hook(struct net_device *netdev, int new_mtu);
/**
- * @brief NIC related skip ringparam setting function
+ * @brief NIC相关跳过MTU设置函数
*
* @param netdev device pointer to net_device
- * @param ring Queue depth related parameters
+ * @param ring 队列深度相关参数
*
- * @details Overloaded by product, can implement skip related settings after user-space queue is enabled
+ * @details 由产品重载,可实现用户态队列开启后跳过相关设置的功能
*
- * @return: Hook function execution result.
- * @retval 0 Do not skip
- * @retval non-0 Skip
+ * @return: 钩子函数运行结果.
+ * @retval 0 不跳过
+ * @retval 非0 跳过
*/
-int hinic5_set_ringparam_pre_hook(struct net_device *netdev, struct ethtool_ringparam *ring);
+int hinic5_set_ringparam_pre_hook(struct net_device *netdev,
+ struct ethtool_ringparam *ring);
/**
- * @brief Product side interface to set flow bifurcation enabled group number
+ * @brief 产品侧设置流分叉使能group数量的接口
*
* @param netdev device pointer to net_device
- * @param group_num Expected group number
- * @details Called by product, group_num range is 1~8. 1: disable flow bifurcation, other values: enable flow bifurcation.
- * @attention When flow bifurcation is enabled, the actual effective value of group_num will be rounded up to power of 2.
+ * @param group_num 期望的group数量
+ * @details 由产品调用,group_num范围为1~8。1:关闭流分叉,其他值:开启流分叉。
+ * @attention 开启流分叉时,group_num实际生效值会向上取整到2的幂次。
*
- * @return: Command execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_set_flow_bifurcation_group_num(struct net_device *netdev, u8 group_num);
+int hinic5_set_flow_bifurcation_group_num(struct net_device *netdev,
+ u8 group_num);
/**
- * @brief Product side query/set indirect table corresponding to groupId when flow bifurcation is enabled
+ * @brief 产品侧查询/设置流分叉功能启用时groupId对应的间接表
*
* @param netdev device pointer to net_device
- * @param op_code 0: query; 1: set
- * @param group_id Group id used by device
- * @param indir Indirect table
- * @param indir_length Indirect table length
- * @details Called by product
- *
- * @return: Command execution result.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @param op_code 0 查询;1 设置
+ * @param group_id 设备所使用的group id
+ * @param indir 间接表
+ * @param indir_length 间接表长度
+ * @details 由产品调用
+ *
+ * @return: 命令执行结果.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_cfg_flow_bifurcation_paras(struct net_device *netdev, u8 op_code,
- u8 group_id, u32 *indir, u16 indir_length);
+ u8 group_id, u32 *indir,
+ u16 indir_length);
+
#endif /* !defined(__UEFI__) && !defined(__VMWARE__) */
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_common_defs.h
index a4fe5c7fe..ef96ce34b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_common_defs.h
@@ -1,23 +1,22 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : bond_common_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
* Description : South Interface---ovs mpu bond interface between mpu and driver
+ * Author : /
+ * Create : 2019/1/1
+ * Notes : Attention--Use the doxygen comment style to generate interface document.
+ * History : None
*/
-
#ifndef BOND_COMMON_DEFS_H
#define BOND_COMMON_DEFS_H
-#define BOND_PORT_MAX_NUM 4
-#define BOND_NAME_MAX_LEN 16
-#define BOND_ID_INVALID 0xFFFF
-#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
-#define BOND_DEFAULT_ROCE_FUNC 0xFFFFFFFF
+#define BOND_PORT_MAX_NUM 4
+#define BOND_NAME_MAX_LEN 16
+#define BOND_ID_INVALID 0xFFFF
+#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
+#define BOND_DEFAULT_ROCE_FUNC 0xFFFFFFFF
-#define BOND_ID_IS_VALID(_id) (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
/**
@@ -32,7 +31,7 @@ enum bond_group_id {
/**
* @brief enum hinic5_bond_user
- * @details Bond user enumeration, for compatibility with version 23, not using common definition
+ * @details bond用户枚举,为了兼容23,不适用通用定义
*/
enum hinic5_bond_user {
HINIC5_BOND_USER_OVS,
@@ -45,45 +44,45 @@ enum hinic5_bond_user {
/**
* @brief enum tag_bond_mode
- * @details Bond mode enumeration type
+ * @details bond模式的枚举类型
*/
typedef enum tag_bond_mode {
- BOND_MODE_NONE = 0, /**< Disable network bonding */
- BOND_MODE_BACKUP = 1, /**< Active-backup mode, 1 indicates active-backup bonding */
- BOND_MODE_BALANCE = 2, /**< Load balancing mode, 2 indicates XOR load balancing bonding */
- BOND_MODE_LACP = 4, /**< LACP mode, 4 indicates 802.3ad bonding */
- BOND_MODE_MAX /**< Maximum value for network bonding mode */
+ BOND_MODE_NONE = 0, /**< 禁用网络绑定 */
+ BOND_MODE_BACKUP = 1, /**< 主备模式,1表示主备绑定 */
+ BOND_MODE_BALANCE = 2, /**< 负载均衡模式,2表示XOR负载均衡绑定 */
+ BOND_MODE_LACP = 4, /**< LACP模式,4表示802.3ad绑定 */
+ BOND_MODE_MAX /**< 网络绑定模式的最大值 */
} bond_mode_e;
/**
* @brief enum tag_bond_hash
- * @details Bond hash policy enumeration type
+ * @details bond hash策略的枚举类型
*/
typedef enum tag_bond_hash {
- BOND_HASH_L2 = 0, /**< Use L2 address for hashing */
- BOND_HASH_L23 = 1, /**< Use L2 and L3 addresses for hashing */
- BOND_HASH_L34 = 2, /**< Use L3 and L4 addresses for hashing */
- BOND_HASH_MAX = 3 /**< Maximum hash policy value */
+ BOND_HASH_L2 = 0, /**< 使用L2地址进行哈希 */
+ BOND_HASH_L23 = 1, /**< 使用L2和L3地址进行哈希 */
+ BOND_HASH_L34 = 2, /**< 使用L3和L4地址进行哈希 */
+ BOND_HASH_MAX = 3 /**< 最大的哈希策略值 */
} bond_hash_e;
/**
* ovs bond hash policy
*/
typedef enum ovs_bond_hash_policy {
- OVS_BOND_HASH_POLICY_L2 = 0, /**< 0 for layer 2 */
- OVS_BOND_HASH_POLICY_L34 = 1, /**< 1 for layer 3+4 */
- OVS_BOND_HASH_POLICY_L23 = 2, /**< 2 for layer 2+3 */
+ OVS_BOND_HASH_POLICY_L2 = 0, /**< 0 for layer 2 */
+ OVS_BOND_HASH_POLICY_L34 = 1, /**< 1 for layer 3+4 */
+ OVS_BOND_HASH_POLICY_L23 = 2, /**< 2 for layer 2+3 */
OVS_BOND_HASH_POLICY_VFID_SQN = 3, /**< 3 for vfid ^ sqn */
OVS_BOND_HASH_POLICY_MAX
} ovs_bond_hash_policy_e;
/**
* @brief enum bond_port_duplex_state
- * @details Port duplex state enumeration type
+ * @details 端口双工状态枚举类型
*/
enum bond_port_duplex_state {
- BOND_PORT_HALF_DUPLEX = 0, /**< Half duplex */
- BOND_PORT_FULL_DUPLEX, /**< Full duplex */
+ BOND_PORT_HALF_DUPLEX = 0, /**< 半双工 */
+ BOND_PORT_FULL_DUPLEX, /**< 全双工 */
};
#endif /* BOND_COMMON_DEFS_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_mpu_cmd_defs.h
index a5deceb1b..89567a3c0 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/bond/bond_mpu_cmd_defs.h
@@ -1,11 +1,10 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : bond_mpu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Driver and mpu interaction bond related definitions
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description : 驱动和mpu交互bond相关定义
+ * Author : /
+ * Create : 2025/9/8
+ * Notes : Attention--Use the doxygen comment style to generate interface document.
+ * History : None
*/
#ifndef BOND_MPU_CMD_DEFS_H
@@ -16,37 +15,35 @@
/**
* @brief enum bond_mpu_cmd
- * @details Inherited bond cmd enumeration type used in version 23, mbox message and OVS binding, see enum tag_ovs_mpu_cmd
+ * @details 继承的bond cmd枚举类型在23中使用,mbox消息和OVS绑定 见enum tag_ovs_mpu_cmd
*/
enum bond_mpu_cmd {
- MPU_CMD_BOND_CREATE = 17, /* Create bond, temporarily keep it to 17
- * @see struct tag_ovs_bond_cmd
- */
- MPU_CMD_BOND_DELETE = 18, /**< Delete bond @see struct tag_ovs_bond_cmd */
- MPU_CMD_BOND_SET_ATTR = 19, /**< Set bond attributes @see struct tag_ovs_bond_cmd */
- MPU_CMD_BOND_GET_ATTR = 20, /**< Get bond attributes, @see struct tag_bond_get */
+ MPU_CMD_BOND_CREATE =
+ 17, /**< Create bond, temporarily keep it to 17 @see struct tag_ovs_bond_cmd */
+ MPU_CMD_BOND_DELETE =
+ 18, /**< Delete bond @see struct tag_ovs_bond_cmd */
+ MPU_CMD_BOND_SET_ATTR =
+ 19, /**< Set bond attributes @see struct tag_ovs_bond_cmd */
+ MPU_CMD_BOND_GET_ATTR =
+ 20, /**< Get bond attributes, @see struct tag_bond_get */
};
/**
- * bond set attr: Variables before bond_name must be consistent with struct bond_attr definition
+ * bond set attr: bond_name之前变量定义要求与结构体struct bond_attr保持一致
*/
typedef struct tag_ovs_bond_cmd {
- u16 bond_mode; /* bond mode:1 for active-backup,
- * 2 for balance-xor,4 for 802.3ad
- */
- u16 bond_id; /**< bond id */
- u16 up_delay; /**< default:200ms */
- u16 down_delay; /**< default:200ms */
- u32 active_slaves : 8; /**< active port slaves(bitmaps) */
- u32 slaves : 8; /**< bond port id bitmaps */
- u32 lacp_collect_slaves : 8; /**< bond port id bitmaps */
- u32 xmit_hash_policy : 8; /* xmit hash:0 for layer 2 ,
- * 1 for layer 2+3 ,2 for layer 3+4
- */
- u32 first_roce_func; /**< RoCE used */
- u32 bond_pf_bitmap; /**< all PFs under the bond */
+ u16 bond_mode; /**< bond mode:1 for active-backup,2 for balance-xor,4 for 802.3ad */
+ u16 bond_id; /**< bond id */
+ u16 up_delay; /**< defualt:200ms */
+ u16 down_delay; /**< defualt:200ms */
+ u32 active_slaves : 8; /**< active port slaves(bitmaps) */
+ u32 slaves : 8; /**< bond port id bitmaps */
+ u32 lacp_collect_slaves : 8; /**< bond port id bitmaps */
+ u32 xmit_hash_policy : 8; /**< xmit hash:0 for layer 2 ,1 for layer 2+3 ,2 for layer 3+4 */
+ u32 first_roce_func; /**< RoCE used */
+ u32 bond_pf_bitmap; /**< all PFs under the bond */
u32 user_bitmap;
- u8 bond_name[BOND_NAME_MAX_LEN]; /**< bond name, length must be less than 16 */
+ u8 bond_name[BOND_NAME_MAX_LEN]; /**< bond name, length must be less than 16 */
} ovs_bond_cmd_s;
/**
@@ -92,31 +89,27 @@ typedef struct tag_bond_port_attr {
* @see OVS_MPU_CMD_BOND_GET_ATTR
*/
typedef struct tag_bond_get {
- u16 bond_id_vld; /* bond_id_vld=1: used bond_id get bond info;
- * bond_id_vld=0: used bond_name get bond info
- */
- u16 bond_id; /**< if bond_id_vld=1 input, else output */
- u8 bond_name[BOND_NAME_MAX_LEN]; /**< if bond_id_vld=0 input, else output */
+ u16 bond_id_vld; /**< bond_id_vld=1: used bond_id get bond info; bond_id_vld=0: used bond_name get bond info */
+ u16 bond_id; /**< if bond_id_vld=1 input, else output */
+ u8 bond_name[BOND_NAME_MAX_LEN]; /**< if bond_id_vld=0 input, else output */
- u16 bond_mode; /* bond mode:1 for active-backup,
- * 2 for balance-xor,4 for 802.3ad
- */
- u8 active_slaves; /**< active port slaves(bitmaps) */
- u8 slaves; /**< bond port id bitmaps */
+ u16 bond_mode; /**< bond mode:1 for active-backup,2 for balance-xor,4 for 802.3ad */
+ u8 active_slaves; /**< active port slaves(bitmaps) */
+ u8 slaves; /**< bond port id bitmaps */
- u8 lacp_collect_slaves; /**< bond port id bitmaps */
- u8 xmit_hash_policy; /**< xmit hash:0 for layer 2 ,1 for layer 2+3 ,2 for layer 3+4 */
- u16 rsvd0; /**< in order to 4B aligned */
+ u8 lacp_collect_slaves; /**< bond port id bitmaps */
+ u8 xmit_hash_policy; /**< xmit hash:0 for layer 2 ,1 for layer 2+3 ,2 for layer 3+4 */
+ u16 rsvd0; /**< in order to 4B alligned */
hinic5_bond_port_stat_s stat[BOND_PORT_MAX_NUM];
hinic5_bond_port_attr_s attr[BOND_PORT_MAX_NUM];
} hinic5_bond_get_s;
-/* BOND OPCODE operation type definition */
+/* BOND OPCODE操作类型定义 */
#define BOND_CFG_OPCODE_GET 0x0
#define BOND_CFG_OPCODE_SET 0x1
-/* BOND configuration BITMAP definition */
+/* BOND 配置的BITMAP定义 */
#define BOND_CFG_BITMAP_ARP_EN 0x1UL
#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd.h
index 2fa2c6f35..c4d49e33d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : cfg_mgmt_mpu_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef CFG_MGMT_MPU_CMD_H
#define CFG_MGMT_MPU_CMD_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index 0bc19bd8d..4d7947a11 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : cfg_mgmt_mpu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef CFG_MGMT_MPU_CMD_DEFS_H
#define CFG_MGMT_MPU_CMD_DEFS_H
@@ -19,123 +9,125 @@
#include "mpu_cmd_base_defs.h"
typedef enum {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9, // TBD to be replaced with SERVICE_BIT_ROCE_MIG
- SERVICE_BIT_CURRENET = 10, // TBD to be replaced with SERVICE_BIT_VIRTIO_MIG
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_VROCE = 13,
- SERVICE_BIT_DMMU = 14,
- SERVICE_BIT_UB = 15,
- SERVICE_BIT_ROCE_MIG = 16,
- SERVICE_BIT_JBOF = 17,
- SERVICE_BIT_RSV0 = 18,
- SERVICE_BIT_ADV_ROCE = 19,
- SERVICE_BIT_MACSEC = 20,
- SERVICE_BIT_PFE = 21,
- SERVICE_BIT_UBCNET = 22,
- SERVICE_BIT_CFM = 23,
- SERVICE_BIT_BIFUR = 24,
- SERVICE_BIT_HIHTR = 25,
+ SERVICE_BIT_NIC = 0,
+ SERVICE_BIT_ROCE = 1,
+ SERVICE_BIT_VBS = 2,
+ SERVICE_BIT_TOE = 3,
+ SERVICE_BIT_IPSEC = 4,
+ SERVICE_BIT_FC = 5,
+ SERVICE_BIT_VIRTIO = 6,
+ SERVICE_BIT_OVS = 7,
+ SERVICE_BIT_NVME = 8,
+ SERVICE_BIT_ROCEAA = 9,
+ SERVICE_BIT_VIRTIO_MIG = 10,
+ SERVICE_BIT_PPA = 11,
+ SERVICE_BIT_MIGRATE = 12,
+ SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
+ SERVICE_BIT_UB = 15,
+ SERVICE_BIT_ROCE_MIG = 16,
+ SERVICE_BIT_JBOF = 17,
+ SERVICE_BIT_RSV0 = 18,
+ SERVICE_BIT_ADV_ROCE = 19,
+ SERVICE_BIT_MACSEC = 20,
+ SERVICE_BIT_PFE = 21,
+ SERVICE_BIT_UBCNET = 22,
+ SERVICE_BIT_CFM = 23,
+ SERVICE_BIT_DMMU = 24,
+ SERVICE_BIT_HIHTR = 25,
SERVICE_BIT_MAX
} servic_bit_define_e;
typedef enum {
/* 0~31: reserved for servic_bit_define_e */
- EXT_CAP_BEGIN = 32,
- EXT_CAP_FAKE_VF = 32,
- EXT_CAP_FW_UPDATE = 33,
- EXT_CAP_COMM_INFO = 34,
+ EXT_CAP_BEGIN = 32,
+ EXT_CAP_FAKE_VF = 32,
+ EXT_CAP_FW_UPDATE = 33,
+ EXT_CAP_COMM_INFO = 34,
EXT_CAP_MAX,
} extend_cap_type_e;
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA) // TBD to be replaced with SERVICE_BIT_ROCE_MIG
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET) // TBD to be replaced with SERVICE_BIT_VIRTIO_MIG
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
-#define CFG_SERVICE_MASK_JBOF (0x1 << SERVICE_BIT_JBOF)
-#define CFG_SERVICE_MASK_DMMU (0x1 << SERVICE_BIT_DMMU)
-#define CFG_SERVICE_MASK_CFM (0x1 << SERVICE_BIT_CFM)
-#define CFG_SERVICE_MASK_UB (0x1 << SERVICE_BIT_UB)
-#define CFG_SERVICE_MASK_MACSEC (0x1 << SERVICE_BIT_MACSEC)
-#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
-#define CFG_SERVICE_MASK_HIHTR (0x1 << SERVICE_BIT_HIHTR)
+#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
+#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
+#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
+#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
+#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
+#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
+#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
+#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
+#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
+#define CFG_SERVICE_MASK_ROCEAA \
+ (0x1 << SERVICE_BIT_ROCEAA) // TBD 替换为SERVICE_BIT_ROCE_MIG
+#define CFG_SERVICE_MASK_CURRENET \
+ (0x1 << SERVICE_BIT_CURRENET) // TBD 替换为SERVICE_BIT_VIRTIO_MIG
+#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
+#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
+#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_JBOF (0x1 << SERVICE_BIT_JBOF)
+#define CFG_SERVICE_MASK_DMMU (0x1 << SERVICE_BIT_DMMU)
+#define CFG_SERVICE_MASK_CFM (0x1 << SERVICE_BIT_CFM)
+#define CFG_SERVICE_MASK_UB (0x1 << SERVICE_BIT_UB)
+#define CFG_SERVICE_MASK_MACSEC (0x1 << SERVICE_BIT_MACSEC)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
+#define CFG_SERVICE_MASK_HIHTR (0x1 << SERVICE_BIT_HIHTR)
#define FUNC_PARITY_GPA_SPU_EN 0
#define FUNC_GPA_SPU_DIS 1
#define FUNC_GPA_SPU_EN 2
typedef enum {
- PLATFORMS_ID_ASIC = 0,
- PLATFORMS_ID_FPGA = 1,
- PLATFORMS_ID_PG = 2,
- PLATFORMS_ID_STRG = 3,
+ PLATFORMS_ID_ASIC = 0,
+ PLATFORMS_ID_FPGA = 1,
+ PLATFORMS_ID_PG = 2,
+ PLATFORMS_ID_STRG = 3,
PLATFORMS_ID_MAX
} platform_id_e;
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
typedef enum {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
+ SCENES_ID_FPGA_ETH = 0,
+ SCENES_ID_FPGA_TIOE = 1, /* Discarded */
SCENES_ID_ASIC_STORAGE_ROCEAA_2X100 = 2,
- SCENES_ID_ASIC_STORAGE_ROCEAA_4X25 = 3,
- SCENES_ID_ASIC_CLOUD = 4,
- SCENES_ID_ASIC_FC = 5,
- SCENES_ID_ASIC_STORAGE_ROCE = 6,
- SCENES_ID_ASIC_COMPUTE_ROCE = 7,
- SCENES_ID_ASIC_STORAGE_TOE = 8,
- SCENES_ID_FPGA_UB = 9,
- SCENES_ID_FPGA_JBOF = 10,
- SCENES_ID_FPGA_CRYPT = 11,
- SCENES_ID_FPGA_VBS = 12,
- SCENES_ID_FPGA_FC = 13,
- SCENES_ID_FPGA_TOE = 14,
- SCENES_ID_FPGA_NIC = 15,
- SCENES_ID_PG_CLOUD = 16,
- SCENES_ID_PG_AT_TEST = 17,
- SCENES_ID_PG_JBOF = 18,
- SCENES_ID_ASIC_JBOF = 19,
- SCENES_ID_PG_TOE = 20,
- SCENES_ID_ASIC_SLT = 21,
- SCENES_ID_PG_FC = 22,
- SCENES_ID_STRG_NIC = 23,
- SCENES_ID_FPGA_OVS = 24,
- SCENES_ID_FPGA_ALL1 = 25,
- SCENES_ID_FPGA_ALL2 = 26,
- SCENES_ID_ASIC_ALL = 27,
+ SCENES_ID_ASIC_STORAGE_ROCEAA_4X25 = 3,
+ SCENES_ID_ASIC_CLOUD = 4,
+ SCENES_ID_ASIC_FC = 5,
+ SCENES_ID_ASIC_STORAGE_ROCE = 6,
+ SCENES_ID_ASIC_COMPUTE_ROCE = 7,
+ SCENES_ID_ASIC_STORAGE_TOE = 8,
+ SCENES_ID_FPGA_UB = 9,
+ SCENES_ID_FPGA_JBOF = 10,
+ SCENES_ID_FPGA_CRYPT = 11,
+ SCENES_ID_FPGA_VBS = 12,
+ SCENES_ID_FPGA_FC = 13,
+ SCENES_ID_FPGA_TOE = 14,
+ SCENES_ID_FPGA_NIC = 15,
+ SCENES_ID_PG_CLOUD = 16,
+ SCENES_ID_PG_AT_TEST = 17,
+ SCENES_ID_PG_JBOF = 18,
+ SCENES_ID_ASIC_JBOF = 19,
+ SCENES_ID_PG_TOE = 20,
+ SCENES_ID_ASIC_SLT = 21,
+ SCENES_ID_PG_FC = 22,
+ SCENES_ID_STRG_NIC = 23,
+ SCENES_ID_FPGA_OVS = 24,
+ SCENES_ID_FPGA_ALL1 = 25,
+ SCENES_ID_FPGA_ALL2 = 26,
+ SCENES_ID_ASIC_ALL = 27,
SCENES_ID_MAX
} scenes_id_define_e;
/* Definition of the scenario ID in the cfg_data of V100 */
typedef enum {
- SCENES_ID_V100_FPGA_ETH = 0,
- SCENES_ID_V100_COMPUTE_STANDARD = 1,
- SCENES_ID_V100_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_V100_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_V100_CLOUD = 4,
- SCENES_ID_V100_FC = 5,
- SCENES_ID_V100_STORAGE_ROCE = 6,
- SCENES_ID_V100_COMPUTE_ROCE = 7,
- SCENES_ID_V100_STORAGE_TOE = 8,
+ SCENES_ID_V100_FPGA_ETH = 0,
+ SCENES_ID_V100_COMPUTE_STANDARD = 1,
+ SCENES_ID_V100_STORAGE_ROCEAA_2x100 = 2,
+ SCENES_ID_V100_STORAGE_ROCEAA_4x25 = 3,
+ SCENES_ID_V100_CLOUD = 4,
+ SCENES_ID_V100_FC = 5,
+ SCENES_ID_V100_STORAGE_ROCE = 6,
+ SCENES_ID_V100_COMPUTE_ROCE = 7,
+ SCENES_ID_V100_STORAGE_TOE = 8,
SCENES_ID_V100_MAX
} scenes_id_v100_define_e;
@@ -152,7 +144,7 @@ enum {
struct timer_vf_info_fake {
u16 timer_normal_vf_num; /* Size from the first Non-Fake VF to the last Non-Fake VF */
u16 timer_fake_vf_id_start;
- u16 timer_fake_vf_num; /* Size from the first Fake VF to the last Fake VF */
+ u16 timer_fake_vf_num; /* Size from the first Fake VF to the last Fake VF */
u16 rsvd1;
u32 rsvd[5];
@@ -176,9 +168,9 @@ struct cfg_cmd_host_timer {
u8 host_id;
u8 rsvd1 : 6;
/*
- * Detailed info type about VF timer.
- * Only one can be set.
- */
+ * Detailed info type about VF timer.
+ * Only one can be set.
+ */
u8 timer_vf_info_mode_segs : 1; /* VF timer segments */
u8 timer_vf_info_mode_fake : 1; /* Fake VF timer info */
@@ -190,7 +182,7 @@ struct cfg_cmd_host_timer {
union {
struct timer_vf_info_fake fake;
- struct timer_vf_info_seg segs[TIMER_VF_SEGS_NUM];
+ struct timer_vf_info_seg segs[TIMER_VF_SEGS_NUM];
} timer_vf_info;
u32 rsvd3;
@@ -246,7 +238,7 @@ struct cfg_cmd_dev_cap {
u8 master_host_id;
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u16 vio_func_num; /* virtio + nvme function num, sharing the same cache */
+ u16 vio_func_num; /* virtio + nvme function num,共用同一片cache */
u16 nvme_qp_num;
u32 virtio_vq_num;
u32 rsvd_func4[3];
@@ -319,10 +311,10 @@ struct cfg_cmd_dev_cap {
/* VBS */
u16 vbs_max_volq;
- u8 vbs_main_pf_enable;
- u8 vbs_vsock_pf_enable;
- u8 vbs_fushion_queue_pf_enable;
- u8 rsvd0_vbs;
+ u8 vbs_main_pf_enable;
+ u8 vbs_vsock_pf_enable;
+ u8 vbs_fushion_queue_pf_enable;
+ u8 rsvd0_vbs;
u16 vbs_host_dma_data_cos : 3;
u16 vbs_vmio_cpy_data_cos : 3;
u16 vbs_volq_cos : 3;
@@ -419,7 +411,10 @@ struct cfg_fake_vf_ext_caps {
u8 qpc_fake_vf_ctx_size_order_en;
u16 fake_vf_parent_func_id; /* Parent function id of the fake vf group */
- u8 fake_vf_lazy_init;
+ u8 fake_vf_lazy_init : 1;
+ u8 fake_vf_bat_expanded : 1;
+ u8 rsvd2 : 6;
+
u8 rsvd1[0x3];
u32 rsvd[0x5];
@@ -430,12 +425,12 @@ struct comm_info_ext_cap {
u8 bat_cid_index_bit_width;
/* CFM - CCP */
- u16 ccp_child_ctx_sz; /* 12 bits */
- u32 ccp_max_child_ctx; /* 20 bits */
+ u16 ccp_child_ctx_sz; /* 12 bits */
+ u32 ccp_max_child_ctx; /* 20 bits */
/* SRIOV - ext cap */
- u32 vf_isolation : 1; /* The VF communicates directly with the Mgmt */
- u32 rsvd1 : 31;
+ u32 vf_isolation : 1; /* The VF communicates directly with the Mgmt */
+ u32 rsvd1 : 31;
u32 rsvd3[0x8];
};
@@ -471,7 +466,6 @@ typedef struct mpu_fw_update_ext_cap {
cfg_fw_update_ext_caps fw_update_caps;
} mpu_fw_update_ext_cap_s;
-
typedef struct mpu_dev_comm_info_ext_cap {
struct cfg_cmd_tlv_hdr mgmt;
struct comm_info_ext_cap comm_info;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/cfm_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/cfm_cmd.h
index d86c10cd3..31cc48d94 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/cfm_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/cfm_cmd.h
@@ -1,35 +1,29 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : cfm_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
* Description : cfm cmd define
+ * Author : /
+ * Create : 2025/08/07
+ * Notes :
+ * History : None
*/
-
#ifndef CFM_CMD_H
#define CFM_CMD_H
-#define HINIC5_BOND_MSG_TIMEOUT_MS (60000)
+#define HINIC5_BOND_MSG_TIMEOUT_MS (60000)
-/* TODO: bond ccp qos to be integrated into the same enum */
+/* TODO:bond ccp qos待整合在同一个枚举中 */
typedef enum tag_cfm_mpu_drv_cmd {
CFM_MPU_CMD_BOND_CREATE = 0,
CFM_MPU_CMD_BOND_DELETE = 1,
CFM_MPU_CMD_BOND_SET = 2,
CFM_MPU_CMD_BOND_GET = 3,
- CFM_MPU_CMD_BOND_CFG = 4, /* bond config and query */
+ CFM_MPU_CMD_BOND_CFG = 4, /* bond配置和查询 */
CFM_MPU_CMD_BOND_LINK_INFO_GET = 5,
- CFM_MPU_CMD_PASS_ARP_PKT = 6, /* send arp packet through mpu */
+ CFM_MPU_CMD_PASS_ARP_PKT = 6, /* 通过mpu发送arp报文 */
CFM_MPU_CMD_CCP_COMM_PARA_GET = 16,
CFM_MPU_CMD_CCP_ALGO_PARA_GET = 17,
- CFM_MPU_CMD_QOS_VPORT_MAPPING_SET = 32,
- CFM_MPU_CMD_QOS_VPORT_SHAPER_SET = 33,
- CFM_MPU_CMD_QOS_VPORT_SHAPER_CLR = 34,
- CFM_MPU_CMD_QOS_VPORT_SHAPER_GET = 35, /* qos_base config and query */
- CFM_MPU_CMD_QOS_CC_L2D_SET = 36, /* CFM QoS CC L2DMEM write operation */
- CFM_MPU_CMD_QOS_CC_L2D_GET = 37, /* CFM QoS CC L2DMEM read operation */
+ CFM_MPU_CMD_QOS_TH_SET = 36, /* CFM QoS TH L2DMEM写操作 */
+ CFM_MPU_CMD_QOS_TH_GET = 37, /* CFM QoS TH L2DMEM读操作 */
CFM_MPU_CMD_EXTEND_END = 64
} cfm_mpu_drv_cmd_e;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/fast_msg_common_define.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/fast_msg_common_define.h
index 8d36d5633..06aed2fb7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/fast_msg_common_define.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/cfm/fast_msg_common_define.h
@@ -1,14 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : fast_msg_common_define.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : fast msg common define, for driverµ_code usage, common struct defined
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2023. All rights reserved.
+ * Description : fast msg common define, for driverµ_code usage, common struct defined
+ * Version : 1.0
+ * Date : 2023/8/24
+ * Note : Auto generated, MUST NOT modify manually!
*/
-
#ifndef FAST_MSG_COMMON_DEFINE_H
#define FAST_MSG_COMMON_DEFINE_H
@@ -60,4 +57,4 @@ typedef struct hisdk5_fast_msg_buf {
u8 fast_msg_data[MAX_FAST_MSG_LEN];
} hisdk5_fast_msg_buf;
-#endif /* FAST_MSG_COMMON_DEFINE_H */
\ No newline at end of file
+#endif /* FAST_MSG_COMMON_DEFINE_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd.h
deleted file mode 100644
index 7af28eabb..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_npu_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : hinic5_cqm common command interface define.
- */
-#ifndef HINIC5_CQM_NPU_CMD_H
-#define HINIC5_CQM_NPU_CMD_H
-
-typedef enum {
- HINIC5_CQM_CMD_T_INVALID = 0,
- HINIC5_CQM_CMD_T_BAT_UPDATE = 1,
- HINIC5_CQM_CMD_T_CLA_UPDATE = 2,
- HINIC5_CQM_CMD_T_BLOOMFILTER_SET = 3,
- HINIC5_CQM_CMD_T_BLOOMFILTER_CLEAR = 4,
- HINIC5_CQM_CMD_T_COMPACT_SRQ_UPDATE = 5,
- HINIC5_CQM_CMD_T_CLA_CACHE_INVALID = 6,
- HINIC5_CQM_CMD_T_BLOOMFILTER_INIT = 7,
- HINIC5_CQM_CMD_T_CLA_RESET = 8, /* Reset VF's CLA */
- HINIC5_CQM_CMD_T_MAX
-} hinic5_cqm_cmd_type_e;
-
-#endif /* HINIC5_CQM_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd_defs.h
deleted file mode 100644
index d8b4ff39f..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm/hinic5_cqm_npu_cmd_defs.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_npu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : hinic5_cqm common command interface define.
- */
-#ifndef HINIC5_CQM_NPU_CMD_DEFS_H
-#define HINIC5_CQM_NPU_CMD_DEFS_H
-
-#if defined(__LINUX__) || defined(__VMWARE__)
-#include <linux/types.h>
-#else
-#include "typedef.h"
-#endif
-
-typedef struct tag_hinic5_cqm_cla_cache_invalid_cmd {
- u32 gpa_h;
- u32 gpa_l;
-
- u32 cache_size; /* CLA cache size=4096B */
-
- u32 smf_id;
- u32 func_id;
-} hinic5_cqm_cla_cache_invalid_cmd_s;
-
-typedef struct tag_hinic5_cqm_cla_update_cmd {
- /* Gpa address to be updated */
- u32 gpa_h; // byte addr
- u32 gpa_l; // byte addr
-
- /* Updated Value */
- u32 value_h;
- u32 value_l;
-
- u32 smf_id;
- u32 func_id;
-} hinic5_cqm_cla_update_cmd_s;
-
-typedef struct tag_hinic5_cqm_cla_reset_cmd {
- u32 func_id;
- u32 rsvd1;
-
- u32 rsvd[0x20]; /* Reserve 2 dwords for each BAT entries */
-} hinic5_cqm_cla_reset_cmd_s;
-
-typedef struct tag_hinic5_cqm_bloomfilter_cmd {
- u32 rsv1;
-
-#if (BYTE_ORDER == LITTLE_ENDIAN)
- u32 k_en : 4;
- u32 func_id : 16;
- u32 rsv2 : 12;
-#else
- u32 rsv2 : 12;
- u32 func_id : 16;
- u32 k_en : 4;
-#endif
-
- u32 index_h;
- u32 index_l;
-} hinic5_cqm_bloomfilter_cmd_s;
-
-#define HINIC5_CQM_BAT_MAX_SIZE 256
-typedef struct tag_hinic5_cqm_cmdq_bat_update {
- u32 offset; // byte offset,16Byte aligned
- u32 byte_len; // max size: 256byte
- u8 data[HINIC5_CQM_BAT_MAX_SIZE];
- u32 smf_id;
- u32 func_id;
-} hinic5_cqm_bat_update_cmd_s;
-
-
-typedef struct tag_hinic5_cqm_bloomfilter_init_cmd {
- u32 bloom_filter_len; // 16Byte aligned
- u32 bloom_filter_addr;
-} hinic5_cqm_bloomfilter_init_cmd_s;
-
-typedef struct tag_compact_srq_update_cmd {
- u32 srqid;
- u32 data[32];
-} compact_srq_update_cmd_s;
-
-#endif /* HINIC5_CQM_CMDQ_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd.h
index 7e3b0cd05..3204005d3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd.h
@@ -1,104 +1,100 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : macsec_mpu_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Filename : macsec_mpu_cmd.h
+ * Creation time : 2024/02/23
* Description : COMM Commands between host and MPU(macsec)
+ * Version : 1.0
*/
#ifndef MACSEC_MPU_CMD_H
#define MACSEC_MPU_CMD_H
-#include <linux/bits.h>
-
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
/**
* @brief macsec_mgmt_cmd_e - COMM Commands between hinicadm to MPU(macsec)
- * @details Operation codes for interaction between MACSEC and driver, including management of SC, SA, MIB and SERVICE
+ * @details MACSEC与驱动之间交互的操作码,涉及SC、SA、MIB以及SERVICE的管理
*/
typedef enum {
- MACSEC_CMD_SC_OP = 0, /* sc operation @see struct tag_macsec_cmd_sc_operation_s */
- MACSEC_CMD_SA_OP, /* sa operation @see struct tag_macsec_cmd_sa_operation_s */
- MACSEC_CMD_GET_PORT_MIB, /* get port mib @see struct tag_macsec_cmd_port_mib_operation_s */
- MACSEC_CMD_GET_SC_MIB, /* get sc mib @see struct tag_macsec_cmd_sc_mib_operation_s */
- MACSEC_CMD_GET_ERR_CNT, /* get error cnt @see struct tag_macsec_cmd_err_cnt_operation_s */
- MACSEC_CMD_SERVICE_OP, /* service op @see struct macsec_cmd_service_operation_s */
- MACSEC_CMD_FEATURE_NEGO_OP, /* macsec feature negotiate op
- * @see struct macsec_feature_nego_cmd_s
- */
- MACSEC_CMD_FLUSH_OP, /* macsec resource flush op @see struct tag_macsec_flush_cmd_s */
- MACSEC_CMD_WHITELIST_OP, /* macsec whitelist op @see struct macsec_whitelist_cmd_out */
+ MACSEC_CMD_SC_OP =
+ 0, /**< sc operation @see struct tag_macsec_cmd_sc_operation_s */
+ MACSEC_CMD_SA_OP, /**< sa operation @see struct tag_macsec_cmd_sa_operation_s */
+ MACSEC_CMD_GET_PORT_MIB, /**< get port mib @see struct tag_macsec_cmd_port_mib_operation_s */
+ MACSEC_CMD_GET_SC_MIB, /**< get sc mib @see struct tag_macsec_cmd_sc_mib_operation_s */
+ MACSEC_CMD_GET_ERR_CNT, /**< get error cnt @see struct tag_macsec_cmd_err_cnt_operation_s */
+ MACSEC_CMD_SERVICE_OP, /**< service op @see struct macsec_cmd_service_operation_s */
+ MACSEC_CMD_FEATURE_NEGO_OP, /**< macsec feature negotiate op @see struct macsec_feature_nego_cmd_s */
+ MACSEC_CMD_FLUSH_OP, /**< macsec resource flush op @see struct tag_macsec_flush_cmd_s */
+ MACSEC_CMD_WHITELIST_OP, /**< macsec whitelist op @see struct macsec_whitelist_cmd_out */
} macsec_mgmt_cmd_e;
/**
* @brief macsec_mbox_sc_op_cmd_e - opcode of mailbox sc opcode
- * @details Operation codes for SC encryption/decryption side, including create, delete and update operations
+ * @details SC加解密侧的操作码,涉及创建、删除和更新等操作
*/
typedef enum {
- MACSEC_CMD_ENC_SC_CREATE = 0, /* enc sc create */
- MACSEC_CMD_ENC_SC_DELETE, /* enc sc delete */
- MACSEC_CMD_ENC_SC_UPDATE, /* enc sc update */
- MACSEC_CMD_ENC_SC_GET_INFO, /* get enc sc */
- MACSEC_CMD_DEC_SC_CREATE, /* dec sc create */
- MACSEC_CMD_DEC_SC_DELETE, /* dec sc delete */
- MACSEC_CMD_DEC_SC_UPDATE, /* dec sc update */
- MACSEC_CMD_DEC_SC_GET_INFO, /* get dec sc */
+ MACSEC_CMD_ENC_SC_CREATE = 0, /**< enc sc create */
+ MACSEC_CMD_ENC_SC_DELETE, /**< enc sc delete */
+ MACSEC_CMD_ENC_SC_UPDATE, /**< enc sc update */
+ MACSEC_CMD_ENC_SC_GET_INFO, /**< get enc sc */
+ MACSEC_CMD_DEC_SC_CREATE, /**< dec sc create */
+ MACSEC_CMD_DEC_SC_DELETE, /**< dec sc delete */
+ MACSEC_CMD_DEC_SC_UPDATE, /**< dec sc update */
+ MACSEC_CMD_DEC_SC_GET_INFO, /**< get dec sc */
} macsec_mbox_sc_op_cmd_e;
/**
* @brief macsec_mbox_sa_op_cmd_e - opcode of mailbox sa opcode
- * @details Operation codes for SA encryption/decryption side, including create, delete and update operations
+ * @details SA加解密侧的操作码,涉及创建、删除和更新等操作
*/
typedef enum {
- MACSEC_CMD_ENC_SA_CREATE = 0, /* enc sa create */
- MACSEC_CMD_ENC_SA_DELETE, /* enc sa delete */
- MACSEC_CMD_ENC_SA_UPDATE, /* enc sa update */
- MACSEC_CMD_ENC_SA_GET_INFO, /* get enc sa */
- MACSEC_CMD_DEC_SA_CREATE, /* dec sa create */
- MACSEC_CMD_DEC_SA_DELETE, /* dec sa delete */
- MACSEC_CMD_DEC_SA_UPDATE, /* dec sa update */
- MACSEC_CMD_DEC_SA_GET_INFO, /* get dec sa */
+ MACSEC_CMD_ENC_SA_CREATE = 0, /**< enc sa create */
+ MACSEC_CMD_ENC_SA_DELETE, /**< enc sa delete */
+ MACSEC_CMD_ENC_SA_UPDATE, /**< enc sa update */
+ MACSEC_CMD_ENC_SA_GET_INFO, /**< get enc sa */
+ MACSEC_CMD_DEC_SA_CREATE, /**< dec sa create */
+ MACSEC_CMD_DEC_SA_DELETE, /**< dec sa delete */
+ MACSEC_CMD_DEC_SA_UPDATE, /**< dec sa update */
+ MACSEC_CMD_DEC_SA_GET_INFO, /**< get dec sa */
} macsec_mbox_sa_op_cmd_e;
/**
* @brief macsec_mbox_service_op_cmd_e - opcode of mailbox service opcode
- * @details MACSEC service related operations, such as enabling MACSEC when driver loads and disabling MACSEC when driver unloads
+ * @details MACSEC服务相关操作,如驱动加载时的使能MACSEC功能,驱动卸载时的关闭MACSEC功能
*/
typedef enum {
- MACSEC_CMD_SERVICE_OP_MACSEC_DISABLE = 0, /* macsec disable */
- MACSEC_CMD_SERVICE_OP_MACSEC_ENABLE, /* macsec enable */
+ MACSEC_CMD_SERVICE_OP_MACSEC_DISABLE = 0, /**< macsec disable */
+ MACSEC_CMD_SERVICE_OP_MACSEC_ENABLE, /**< macsec enable */
} macsec_mbox_service_op_cmd_e;
/**
* @brief macsec_mbox_feature_nego_op_cmd_e - opcode of mailbox feature negotiate opcode
- * @details MACSEC feature negotiation related operations, querying or setting features
+ * @details MACSEC特性协商相关操作,对特性进行查询或者设置
*/
typedef enum {
- MACSEC_FEATURE_NEGO_OPCODE_GET = 0, /* feature negotiation get */
- MACSEC_FEATURE_NEGO_OPCODE_SET = 1, /* feature negotiation set (reserve for using) */
+ MACSEC_FEATURE_NEGO_OPCODE_GET = 0, /**< feature negotiation get */
+ MACSEC_FEATURE_NEGO_OPCODE_SET =
+ 1, /**< feature negotiation set (reserve for using) */
} macsec_mbox_feature_nego_op_cmd_e;
/**
* @brief macsec_mbox_feature_cap_e - list of features supported by macsec
- * @details MACSEC supported feature list
+ * @details MACSEC支持特性列表
*/
typedef enum {
- MACSEC_F_HARDEN_PATH = BIT(0), /* macsec does not have NPU */
- MACSEC_F_SUPPORT_SM4 = BIT(1), /* macsec support using sm4 */
+ MACSEC_F_HARDEN_PATH = BIT(0), /**< macsec does not have NPU */
+ MACSEC_F_SUPPORT_SM4 = BIT(1), /**< macsec support using sm4 */
} macsec_mbox_feature_cap_e;
/**
* @brief macsec_mbox_flush_op_cmd_e - opcode of mailbox macsec flush opcode
- * @details MACSEC resource cleanup related operations
+ * @details MACSEC资源清理相关操作
*/
typedef enum {
- MACSEC_CMD_FLUSH_SC_OP = 0, /* flush sc and sa resource */
- MACSEC_CMD_FLUSH_SA_OP, /* flush sa resource */
+ MACSEC_CMD_FLUSH_SC_OP = 0, /**< flush sc and sa resource */
+ MACSEC_CMD_FLUSH_SA_OP, /**< flush sa resource */
} macsec_mbox_flush_op_cmd_e;
#endif /* MACSEC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd_defs.h
index 88c5458ea..aa8af5ba0 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/macsec/macsec_mpu_cmd_defs.h
@@ -1,11 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : macsec_mpu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Filename : macsec_mpu_cmd_defs.h
+ * Creation time : 2024/02/23
* Description : COMM Commands between host and MPU(macsec)
+ * Version : 1.0
*/
#ifndef MACSEC_MPU_CMD_DEFS_H
@@ -13,316 +11,285 @@
#include "mpu_cmd_base_defs.h"
-#define MACSEC_PORT_NUM 4 /* macsec max port number */
-#define MACSEC_SC_NUM 32 /* macsec max SC number */
-#define MACSEC_SA_NUM 64 /* macsec max SA number */
-#define MACSEC_MAX_FEATURE_QWORD 4 /* macsec max feature number */
-#define MACSEC_WHITELIST_DMAC_ID_MAX 16 /* macsec dmac id max template count */
+#define MACSEC_PORT_NUM 4 /**< macsec最大的端口规格 */
+#define MACSEC_SC_NUM 32 /**< macsec最大的SC规格 */
+#define MACSEC_SA_NUM 64 /**< macsec最大的SA规格 */
+#define MACSEC_MAX_FEATURE_QWORD 4 /**< macsec最大特性规格 */
+#define MACSEC_WHITELIST_DMAC_ID_MAX 16 /**< macsec dmac id最大模板数量 */
#define MACSEC_WHITELIST_TOOL_IN_BUF_MAX 1024
#define MACSEC_WHITELIST_TOOL_OUT_BUF_MAX 4096
-#define MACSEC_WHITELIST_DMAC_ENABLE 1 /* macsec dmac enable */
-#define MACSEC_WHITELIST_DMAC_DISABLE 0 /* macsec dmac disable */
-#define MACSEC_WHITELIST_SERVICE_ENABLE 1 /* macsec enable */
-#define MACSEC_WHITELIST_SERVICE_DISABLE 0 /* macsec disable */
+#define MACSEC_WHITELIST_DMAC_ENABLE 1 /**< macsec dmac使能 */
+#define MACSEC_WHITELIST_DMAC_DISABLE 0 /**< macsec dmac不使能 */
+#define MACSEC_WHITELIST_SERVICE_ENABLE 1 /**< macsec 使能 */
+#define MACSEC_WHITELIST_SERVICE_DISABLE 0 /**< macsec 不使能 */
#define WHITELIST_FUNC_ENABLE 0x1
#define WHITELIST_FUNC_DISABLE 0x0
-#define MACSEC_DMAC_TEMPLATE_NUM 16 /* macsec dmac max template number */
-#define MACSEC_ETYPE_TEMPLATE_NUM 16 /* macsec etype max template number */
-#define MACSEC_VLANID_MAX 4094 /* macsec vlanid max value */
-#define MACSEC_VLANID_MIN 1 /* macsec vlanid min value */
-#define MACSEC_RXVLANID_MASK_MAX 0xFFF /* macsec rxvlan mask max value */
-#define MACSEC_DMAC_VALUE_MAX 0xFFFFFFFFFFFF /* macsec dmac max value */
-#define MACSEC_DMAC_MASK_MAX 0xFF /* macsec dmac mask max value */
+#define MACSEC_DMAC_TEMPLATE_NUM 16 /**< macsec dmac最大模板数量 */
+#define MACSEC_ETYPE_TEMPLATE_NUM 16 /**< macsec etype最大模板数量 */
+#define MACSEC_VLANID_MAX 4094 /**< macsec vlanid最大值 */
+#define MACSEC_VLANID_MIN 1 /**< macsec vlanid最小值 */
+#define MACSEC_RXVLANID_MASK_MAX 0xFFF /**< macsec rxvlan mask最大值 */
+#define MACSEC_DMAC_VALUE_MAX 0xFFFFFFFFFFFF /**< macsec dmac最大值 */
+#define MACSEC_DMAC_MASK_MAX 0xFF /**< macsec dmac mask最大值 */
/**
- * @brief macsec_sa_info_s - SA structure
- * @details SA management through this structure
+ * @brief macsec_sa_info_s - SA结构体
+ * @details 通过该结构体进行SA的管理
*/
typedef struct tag_macsec_sa_info_s {
// encryption
- u64 pn_th; /* The threshold of PN */
- u64 next_pn; /* NEXTPN number */
- u8 enable_transmit; /* Indicates if the transmit SA can be used to receive frames */
- u8 rsvd0[7]; /* for expanding */
+ u64 pn_th; /**< The threshold of PN */
+ u64 next_pn; /**< NEXTPN number */
+ u8 enable_transmit; /**< Indicates if the transmit SA can be used to receive frames */
+ u8 rsvd0[7]; /**< for expanding */
// decryption
- u8 replay_protect; /* Enable or disable replay protection function */
- u8 enable_receive; /* Indicates if the transmit SA can be used to receive frames */
+ u8 replay_protect; /**< Enable or disable replay protection function */
+ u8 enable_receive; /**< Indicates if the transmit SA can be used to receive frames */
u8 rsvd1[2];
- u32 replay_window; /* Indicates the replay protection window size */
- u64 lowest_pn; /* LOWESTPN number */
+ u32 replay_window; /**< Indicates the replay protection window size */
+ u64 lowest_pn; /**< LOWESTPN number */
// common
- u8 an; /* an value used by sa */
- /* The confidentaility protection offset options of the cipher suite */
- u8 confidentiality_offset;
- u8 current_key_length; /* Indicate the key length the SA is currently using */
- /* Indicates to enable the extended packet number while receiving MACsec frames */
- u8 extended_pn_enable;
- /* Indicates the crypto algorithm which the SA is currently using */
- u8 current_crypto_algo;
- u8 rsvd2[7]; /* for expanding */
- u32 ssci; /* If extended_pn_enable is 1, use SSCI to compose IV */
- u32 salt[3]; /* Used to generate IV in extended Packet Number mode, 96bit */
- u32 sak_crc; /* sak key crc val */
- u64 sci; /* 64-bit SCI value used to identify an SC */
- u32 sak[8]; /* cipher suite key,max 256bit */
+ u8 an; /**< an value used by sa */
+ u8 confidentiality_offset; /**< The confidentaility protection offset options of the cipher suite */
+ u8 current_key_length; /**< Indicate the key length the SA is currently using */
+ u8 extended_pn_enable; /**< Indicates to enable the extended packet number while receiving MACsec frames */
+ u8 current_crypto_algo; /**< Indicates the crypto algorithm which the SA is currently using */
+ u8 rsvd2[7]; /**< for expanding */
+ u32 ssci; /**< If extended_pn_enable is 1, use SSCI to compose IV */
+ u32 salt[3]; /**< Used to generate IV in extended Packet Number mode, 96bit */
+ u32 sak_crc; /**< sak key crc val */
+ u64 sci; /**< 64-bit SCI value used to identify an SC */
+ u32 sak[8]; /**< cipher suite key,max 256bit */
} macsec_sa_info_s;
/**
- * @brief macsec_sc_info_s - SC structure
- * @details SC management through this structure
+ * @brief macsec_sc_info_s - SC结构体
+ * @details 通过该结构体进行SC的管理
*/
typedef struct tag_macsec_sc_info_s {
// encryption
- u8 protect_frames; /* Protect function for frames */
- u8 protection_mode; /* Protection options of the Cipher Suite */
- u8 include_sci_enable; /* Indicates to include the SCI information in SecTAG field */
- u8 use_es_enable; /* Indicates to enable the ES bit in SecTAG */
- u8 use_scb_enable; /* Indicates to enable the SCB bit in SecTAG field */
- u8 encoding_sa; /* The current transmitting SA in use */
- u8 rsvd0[2]; /* for expanding */
+ u8 protect_frames; /**< Protect function for frames */
+ u8 protection_mode; /**< Protection options of the Cipher Suite */
+ u8 include_sci_enable; /**< Indicates to include the SCI information in SecTAG field */
+ u8 use_es_enable; /**< Indicates to enable the ES bit in SecTAG */
+ u8 use_scb_enable; /**< Indicates to enable the SCB bit in SecTAG field */
+ u8 encoding_sa; /**< The current transmitting SA in use */
+ u8 rsvd0[2]; /**< for expanding */
// decryption
- u8 validate_frames; /* Uses to control the validation function for frames per SC */
- u8 rsvd1[3]; /* for expanding */
+ u8 validate_frames; /**< Uses to control the validation function for frames per SC */
+ u8 rsvd1[3]; /**< for expanding */
// common
- u8 sa_an[4]; /* AN number used by SA, 4 refer to max num */
- u64 sci; /* 64-bit SCI value used to identify an SC */
-} macsec_sc_info_s; /* Common head info */
+ u8 sa_an[4]; /**< AN number used by SA, 4 refer to max num */
+ u64 sci; /**< 64-bit SCI value used to identify an SC */
+} macsec_sc_info_s; /**< Common head info */
/**
- * @brief macsec_cmd_sc_operation_s - SC management information with host driver
- * @details Through the transmission of this information, SC is created, deleted and updated, each SC is independent.
+ * @brief macsec_cmd_sc_operation_s - 与主机驱动之间的SC管理信息
+ * @details 通过该信息的传递,进行SC的创建、删除和更新,各SC之间独立。
*/
typedef struct tag_macsec_cmd_sc_operation_s {
- struct mgmt_msg_head head; /* Common head info */
- u8 op_code; /* Operation code, 0: enc get/1: enc set/2: enc update
- * 3: dec get/4: dec set/5: dec update
- */
- u8 rsvd[3]; /* reserved for expanding */
- macsec_sc_info_s sc_info; /* sc information transmitted with host driver */
+ struct mgmt_msg_head head; /**< Common head info */
+ u8 op_code; /**< Operation code, 0: enc get/1: enc set/2: enc update/3: dec get/4: dec set/5: dec update */
+ u8 rsvd[3]; /**< reserved for expanding */
+ macsec_sc_info_s sc_info; /**< 与主机驱动之间传递的sc信息 */
} macsec_cmd_sc_operation_s;
/**
- * @brief macsec_cmd_sa_operation_s - SA management information with host driver
- * @details Used for SA creation, deletion and update, including key management, replay management and PN value information
+ * @brief macsec_cmd_sa_operation_s - 与主机驱动之间的SA管理信息
+ * @details 用作SA的创建、删除和更新,其中包括密钥管理、重放管理以及PN值等信息
*/
typedef struct tag_macsec_cmd_sa_operation_s {
- struct mgmt_msg_head head; /* Common head info */
- u8 op_code; /* Operation code, 0: enc get/1: enc set/2: enc update
- *3: dec get/4: dec set/5: dec update
- */
- u8 rsvd[3]; /* reserved for expanding */
- macsec_sa_info_s sa_info; /* sa information transmitted with host driver */
+ struct mgmt_msg_head head; /**< Common head info */
+ u8 op_code; /**< Operation code, 0: enc get/1: enc set/2: enc update/3: dec get/4: dec set/5: dec update */
+ u8 rsvd[3]; /**< reserved for expanding */
+ macsec_sa_info_s sa_info; /**< 与主机驱动之间传递的sa信息 */
} macsec_cmd_sa_operation_s;
/**
- * @brief macsec_port_mib_info_s - PORT MIB specific content
- * @details Includes SecTAG exception, integrity protection and encryption protection statistics at PORT level
+ * @brief macsec_port_mib_info_s - PORT MIB具体内容
+ * @details 包括PORT级别的SecTAG异常、完整性保护和加密保护的统计值
*/
typedef struct {
- u64 macsec_mib_txpkts_untagged; /* Number of transmitted untagged packets */
- /* Number of bytes transmitted with integrity protection only, no encryption */
- u64 macsec_mib_txoctets_protected;
- /* Number of bytes transmitted with both integrity protection and encryption */
- u64 macsec_mib_txoctets_encrypted;
- /* Number of received untagged packets not strict mode */
- u64 macsec_mib_rxpkts_untagged;
- u64 macsec_mib_rxpkts_notag; /* Number of received untagged packets strict mode */
- /* Number of received packets with invalid SecTAG or ICV, V, SC, SL errors */
- u64 macsec_mib_rxpkts_badtag;
- /* Number of received packets with unknown SCI or unused SA not validateEnable&C&strict mode */
- u64 macsec_mib_rxpkts_nosa;
- /* Number of received packets with unknown SCI or unused SA validateEnable&C&strict mode */
- u64 macsec_mib_rxpkts_nosaerror;
- /* Number of received bytes with integrity protection only, no encryption */
- u64 macsec_mib_rxoctets_validated;
- /* Number of received bytes with both integrity protection and encryption */
- u64 macsec_mib_rxoctets_decrypted;
+ u64 macsec_mib_txpkts_untagged; /**< 传输的不带SecTAG的报文数 */
+ u64 macsec_mib_txoctets_protected; /**< 传输的只做完整性保护不做加密的字节数 */
+ u64 macsec_mib_txoctets_encrypted; /**< 传输的即做完整性保护也做加密的字节数 */
+ u64 macsec_mib_rxpkts_untagged; /**< 接收不带SecTAG的报文数 not strict mode */
+ u64 macsec_mib_rxpkts_notag; /**< 接收不带SecTAG的报文数 strict mode */
+ u64 macsec_mib_rxpkts_badtag; /**< 接收的无效SecTAG或ICV无效的报文数,V、SC、SL出现错误 */
+ u64 macsec_mib_rxpkts_nosa; /**< 接收的未知SCI或未使用的SA的报文数 未设置validateEnable&C&strict mode */
+ u64 macsec_mib_rxpkts_nosaerror; /**< 接收的未知SCI或未使用的SA的报文数 设置validateEnable&C&strict mode */
+ u64 macsec_mib_rxoctets_validated; /**< 接收到的只做完整性保护不做加密的字节数 */
+ u64 macsec_mib_rxoctets_decrypted; /**< 接收到的即做完整性保护也做加密的字节数 */
} macsec_port_mib_info_s;
/**
- * @brief macsec_sc_mib_info_s - SC MIB specific content
- * @details Includes integrity protection and encryption protection statistics, replay and security check statistics at SC level
+ * @brief macsec_sc_mib_info_s - SC MIB具体内容
+ * @details 包括SC级别的完整性保护和加密保护的统计值、重放以及安全校验相关的统计值
*/
typedef struct {
- /* Number of transmitted packets with integrity protection only, no encryption */
- u64 macsec_mib_txscpkts_protected;
- /* Number of transmitted packets with both integrity protection and encryption */
- u64 macsec_mib_txscpkts_encrypted;
- u64 macsec_mib_rxscpkts_ok; /* Number of packets received that passed validation and are within replay window */
- u64 macsec_mib_rxscpkts_delayed; /* Number of packets with PN less than minimum acceptable PN */
- /* Number of packets with ReplayProtect true and PN less than replay check lower limit */
- u64 macsec_mib_rxscpkts_late;
- /* validateFrames disable, C bit in SecTAG not set,
- * and the packet is not a replay packet
- */
- u64 macsec_mib_rxscpkts_unchecked;
- /* ICV verification failed but discarded due to validateFrames strict
- * or data already encrypted
- */
- u64 macsec_mib_rxscpkts_notvalid;
- /* validateFrames check flag set,
- * but data not encrypted (original frame may be recovered) packet count
- */
- u64 macsec_mib_rxscpkts_invalid;
+ u64 macsec_mib_txscpkts_protected; /**< 传输的只做完整性保护不做加密的报文数 */
+ u64 macsec_mib_txscpkts_encrypted; /**< 传输的即做完整性保护也做加密的报文数 */
+ u64 macsec_mib_rxscpkts_ok; /**< 成功验证且在重放窗口内接收的报文数 */
+ u64 macsec_mib_rxscpkts_delayed; /**< 报文的PN小于可接受的最小PN的报文数 */
+ u64 macsec_mib_rxscpkts_late; /**< ReplayProtect为true,且报文的PN小于重放检查PN的下限的报文数 */
+ u64 macsec_mib_rxscpkts_unchecked; /**< validateFrames disable,SecTAG中的C位没有设置,且该数据包不是重放数据包 */
+ u64 macsec_mib_rxscpkts_notvalid; /**< ICV验证失败,但由于validateFrames为strtic或数据已加密而被丢弃的报文数 */
+ u64 macsec_mib_rxscpkts_invalid; /**< validateFrames标识check,但是数据没有加密(原始帧可能是recovered)的报文数 */
} macsec_sc_mib_info_s;
/**
- * @brief macsec_cmd_port_mib_operation_s - PORT MIB management information
- * @details Following macsec standard protocol, get MIB information for specified port
+ * @brief macsec_cmd_port_mib_operation_s - PORT MIB管理信息
+ * @details 遵循macsec标准协议,获取指定端口的MIB信息
*/
typedef struct tag_macsec_cmd_port_mib_operation_s {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- macsec_port_mib_info_s port_mib; /* port mib info */
- u64 reserved; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ macsec_port_mib_info_s port_mib; /**< port mib info */
+ u64 reserved; /**< reserved for expanding */
} macsec_cmd_port_mib_operation_s;
/**
- * @brief macsec_cmd_sc_mib_operation_s - SC MIB management information
- * @details Following macsec standard protocol, get MIB information for single SC
+ * @brief macsec_cmd_sc_mib_operation_s - SC MIB管理信息
+ * @details 遵循macsec标准协议,获取单个SC的MIB信息
*/
typedef struct tag_macsec_cmd_sc_mib_operation_s {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- macsec_sc_mib_info_s sc_mib; /* sc mib info */
- u64 sci; /* 64-bit SCI value used to identify an SC */
- u8 reserved[8]; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ macsec_sc_mib_info_s sc_mib; /**< sc mib info */
+ u64 sci; /**< 64-bit SCI value used to identify an SC */
+ u8 reserved[8]; /**< reserved for expanding */
} macsec_cmd_sc_mib_operation_s;
/**
- * @brief macsec_enc_cnt_u - MACSEC encryption side DFX statistics
- * @details Includes correctable and uncorrectable exceptions on encryption side, sop and eop exceptions on data path, and statistics for different processing based on profile id
+ * @brief macsec_enc_cnt_u - MACSEC加密侧的DFX统计值
+ * @details 包括加密侧可纠和不可纠异常、数据路径的sop和eop异常以及根据profile id进行不同处理的统计值等
*/
typedef union {
struct {
- u32 macsec_enc_msop_cnt; /* MSOP interrupt count */
- u32 macsec_enc_meop_cnt; /* MEOP interrupt count */
- u32 macsec_enc_iadp_ierr_c_cnt; /* IADP interrupt correctable error count */
- u32 macsec_enc_iadp_ierr_u_cnt; /* IADP interrupt uncorrectable error count */
- u32 macsec_enc_oadp_ierr_c_cnt; /* OADP interrupt correctable error count */
- u32 macsec_enc_oadp_ierr_u_cnt; /* OADP interrupt uncorrectable error count */
- u32 macsec_enc_cs_ierr_c_cnt; /* CS interrupt correctable error count */
- u32 macsec_enc_cs_ierr_u_cnt; /* CS interrupt uncorrectable error count */
- u32 macsec_enc_mib_ierr_c_cnt; /* MIB interrupt correctable error count */
- u32 macsec_enc_mib_ierr_u_cnt; /* MIB interrupt uncorrectable error count */
- u32 macsec_enc_dpp_ierr_c_cnt; /* DPP interrupt correctable error count */
- u32 macsec_enc_dpp_ierr_u_cnt; /* DPP interrupt uncorrectable error count */
- u32 macsec_enc_dpp_wrongsa_cnt; /* DPP wrong SA count */
- u32 macsec_enc_dpp_illegal_pkt_cnt; /* Illegal packet count */
- /* profile id 0 bypass packet count */
- u64 macsec_enc_dpp_profile_id_0_bypass_pkt_cnt;
- /* profile id not 0 but profile info is 0 bypass packet count */
- u32 macsec_enc_dpp_profile_read_all0_bypass_pkt_cnt;
- u32 macsec_enc_dpp_profile_id_1_cnt; /* profile id 1 packet count */
- u32 macsec_enc_dpp_profile_id_2_cnt; /* profile id 2 packet count */
- u32 macsec_enc_dpp_profile_id_3_cnt; /* profile id 3 packet count */
- u64 macsec_enc_white_list_plaintext_pkt_cnt; /* Whitelist pass packet count */
- u64 macsec_enc_in_sop_cnt; /* Encryption engine input port SOP count */
- u64 macsec_enc_in_eop_cnt; /* Encryption engine input port EOP count */
- u64 macsec_enc_in_abort_cnt; /* Encryption engine input port abort count */
- u64 macsec_enc_out_sop_cnt; /* Encryption engine output port SOP count */
- u64 macsec_enc_out_eop_cnt; /* Encryption engine output port EOP count */
- u64 macsec_enc_out_abort_cnt; /* Encryption engine output port abort count */
- u32 macsec_enc_drop_pkt_cnt; /* External port drop packet count */
- u32 macsec_enc_oadp_out_msop_cnt; /* output sop count */
- u32 macsec_enc_oadp_out_meop_cnt; /* output eop count */
+ u32 macsec_enc_msop_cnt; /**< MSOP中断产生的次数 */
+ u32 macsec_enc_meop_cnt; /**< MEOP中断产生的次数 */
+ u32 macsec_enc_iadp_ierr_c_cnt; /**< IADP中断可纠错误统计 */
+ u32 macsec_enc_iadp_ierr_u_cnt; /**< IADP中断不可纠错误统计 */
+ u32 macsec_enc_oadp_ierr_c_cnt; /**< OADP中断可纠错误统计 */
+ u32 macsec_enc_oadp_ierr_u_cnt; /**< OADP中断不可纠错误统计 */
+ u32 macsec_enc_cs_ierr_c_cnt; /**< CS中断可纠错误统计 */
+ u32 macsec_enc_cs_ierr_u_cnt; /**< CS中断不可纠错误统计 */
+ u32 macsec_enc_mib_ierr_c_cnt; /**< MIB中断可纠错误统计 */
+ u32 macsec_enc_mib_ierr_u_cnt; /**< MIB中断不可纠错误统计 */
+ u32 macsec_enc_dpp_ierr_c_cnt; /**< DPP中断可纠错误统计 */
+ u32 macsec_enc_dpp_ierr_u_cnt; /**< DPP中断不可纠错误统计 */
+ u32 macsec_enc_dpp_wrongsa_cnt; /**< DPP错误SA统计 */
+ u32 macsec_enc_dpp_illegal_pkt_cnt; /**< 非法报文统计 */
+ u64 macsec_enc_dpp_profile_id_0_bypass_pkt_cnt; /**< profile id为0的bypass报文统计 */
+ u32 macsec_enc_dpp_profile_read_all0_bypass_pkt_cnt; /**< porfile id非0但profile信息为0被bypass报文统计 */
+ u32 macsec_enc_dpp_profile_id_1_cnt; /**< profile id为1的报文统计 */
+ u32 macsec_enc_dpp_profile_id_2_cnt; /**< profile id为2的报文统计 */
+ u32 macsec_enc_dpp_profile_id_3_cnt; /**< profile id为3的报文统计 */
+ u64 macsec_enc_white_list_plaintext_pkt_cnt; /**< 白名单放通报文统计 */
+ u64 macsec_enc_in_sop_cnt; /**< 加密引擎入端口产生SOP次数 */
+ u64 macsec_enc_in_eop_cnt; /**< 加密引擎入端口产生EOP次数 */
+ u64 macsec_enc_in_abort_cnt; /**< 加密引擎入端口丢弃的次数 */
+ u64 macsec_enc_out_sop_cnt; /**< 加密引擎出端口产生SOP次数 */
+ u64 macsec_enc_out_eop_cnt; /**< 加密引擎出端口产生EOP次数 */
+ u64 macsec_enc_out_abort_cnt; /**< 加密引擎出端口丢弃的次数 */
+ u32 macsec_enc_drop_pkt_cnt; /**< 外部端口丢包的数量 */
+ u32 macsec_enc_oadp_out_msop_cnt; /**< output sop 统计次数 */
+ u32 macsec_enc_oadp_out_meop_cnt; /**< output eop 统计次数 */
} enc_cnt_s;
u32 cnt_info[0];
} macsec_enc_cnt_u;
/**
- * @brief macsec_dec_cnt_u - MACSEC decryption side DFX statistics
- * @details Includes correctable and uncorrectable exceptions on decryption side, sop and eop exceptions on data path, and statistics for different processing based on profile id
+ * @brief macsec_dec_cnt_u - MACSEC解密侧的DFX统计值
+ * @details 包括解密侧可纠和不可纠异常、数据路径的sop和eop异常以及根据profile id进行不同处理的统计值等
*/
typedef union {
struct {
- u32 macsec_dec_msop_cnt; /* MSOP interrupt count */
- u32 macsec_dec_meop_cnt; /* MEOP interrupt count */
- u32 macsec_dec_iadp_ierr_c_cnt; /* IADP interrupt correctable error count */
- u32 macsec_dec_iadp_ierr_u_cnt; /* IADP interrupt uncorrectable error count */
- u32 macsec_dec_oadp_ierr_c_cnt; /* OADP interrupt correctable error count */
- u32 macsec_dec_oadp_ierr_u_cnt; /* OADP interrupt uncorrectable error count */
- u32 macsec_dec_pa_ierr_c_cnt; /* PA interrupt correctable error count */
- u32 macsec_dec_pa_ierr_u_cnt; /* PA interrupt uncorrectable error count */
- u32 macsec_dec_pg_ierr_c_cnt; /* PG interrupt correctable error count */
- u32 macsec_dec_pg_ierr_u_cnt; /* PG interrupt uncorrectable error count */
- u32 macsec_dec_mib_ierr_c_cnt; /* MIB interrupt correctable error count */
- u32 macsec_dec_mib_ierr_u_cnt; /* MIB interrupt uncorrectable error count */
- u32 macsec_dec_dpp_ierr_u_cnt; /* DPP interrupt correctable error count */
- u32 macsec_dec_dpp_ierr_c_cnt; /* DPP interrupt uncorrectable error count */
- u32 macsec_dec_dpp_ec01_pkt_cnt; /* E=0 and C=1 statistics */
- u32 macsec_dec_dpp_ec10_pkt_cnt; /* E=1 and C=0 statistics */
- u32 macsec_dec_dpp_unknownsci_bypass_pkt_cnt; /* Unknown SCI bypass packet count */
- u32 macsec_dec_dpp_illegal_pad_pkt_cnt; /* Illegal padding packet count */
- u64 macsec_dec_dpp_white_list_plaintext_pkt_cnt; /* Whitelist pass packet count */
- /* profile id 0 pass packet count */
- u64 macsec_dec_dpp_profile_id_0_bypass_pkt_cnt;
- /* profile id not 0 but profile info is 0 bypass packet count */
- u32 macsec_dec_dpp_profile_read_all0_bypass_pkt_cnt;
- u32 macsec_dec_dpp_profile_id_1_pkt_cnt; /* profile id 1 packet count */
- u32 macsec_dec_dpp_profile_id_2_pkt_cnt; /* profile id 2 packet count */
- u32 macsec_dec_dpp_profile_id_3_pkt_cnt; /* profile id 3 packet count */
- u32 macsec_dec_dpp_profile_id_4_pkt_cnt; /* profile id 4 packet count */
- u32 macsec_dec_dpp_illegal_pkt_cnt; /* Illegal packet count */
- u64 macsec_dec_intf_in_sop_cnt; /* DEC_INTF input port sop count */
- u64 macsec_dec_intf_in_eop_cnt; /* DEC_INTF input port eop count */
- u64 macsec_dec_intf_in_abort_cnt; /* DEC_INTF input port abort count */
- u64 macsec_dec_out_sop_cnt; /* DEC_INTF output port sop count */
- u64 macsec_dec_out_eop_cnt; /* DEC_INTF output port eop count */
- u64 macsec_dec_out_abort_cnt; /* DEC_INTF output port abort count */
- u32 macsec_dec_intf_drop_pkt_cnt; /* Port disable drop packet count */
- u32 macsec_dec_oadp_out_msop_cnt; /* out msop count */
- u32 macsec_dec_oadp_out_meop_cnt; /* out meop count */
+ u32 macsec_dec_msop_cnt; /**< MSOP中断产生的次数 */
+ u32 macsec_dec_meop_cnt; /**< MEOP中断产生的次数 */
+ u32 macsec_dec_iadp_ierr_c_cnt; /**< IADP中断可纠错误统计 */
+ u32 macsec_dec_iadp_ierr_u_cnt; /**< IADP中断不可纠错误统计 */
+ u32 macsec_dec_oadp_ierr_c_cnt; /**< OADP中断可纠错误统计 */
+ u32 macsec_dec_oadp_ierr_u_cnt; /**< OADP中断不可纠错误统计 */
+ u32 macsec_dec_pa_ierr_c_cnt; /**< PA中断可纠错误统计 */
+ u32 macsec_dec_pa_ierr_u_cnt; /**< PA中断不可纠错误统计 */
+ u32 macsec_dec_pg_ierr_c_cnt; /**< PG中断可纠错误统计 */
+ u32 macsec_dec_pg_ierr_u_cnt; /**< PG中断不可纠错误统计 */
+ u32 macsec_dec_mib_ierr_c_cnt; /**< MIB中断可纠错误统计 */
+ u32 macsec_dec_mib_ierr_u_cnt; /**< MIB中断不可纠错误统计 */
+ u32 macsec_dec_dpp_ierr_u_cnt; /**< DPP中断可纠错误统计 */
+ u32 macsec_dec_dpp_ierr_c_cnt; /**< DPP中断不可纠错误统计 */
+ u32 macsec_dec_dpp_ec01_pkt_cnt; /**< E=0且C=1统计 */
+ u32 macsec_dec_dpp_ec10_pkt_cnt; /**< E=1且C=0统计 */
+ u32 macsec_dec_dpp_unknownsci_bypass_pkt_cnt; /**< 未知SCI bypass报文统计 */
+ u32 macsec_dec_dpp_illegal_pad_pkt_cnt; /**< 非法的padding报文统计 */
+ u64 macsec_dec_dpp_white_list_plaintext_pkt_cnt; /**< 白名单放通报文统计 */
+ u64 macsec_dec_dpp_profile_id_0_bypass_pkt_cnt; /**< profile id为0的放通报文统计 */
+ u32 macsec_dec_dpp_profile_read_all0_bypass_pkt_cnt; /**< porfile id非0但profile信息为0被bypass报文统计 */
+ u32 macsec_dec_dpp_profile_id_1_pkt_cnt; /**< profile id为1的报文统计 */
+ u32 macsec_dec_dpp_profile_id_2_pkt_cnt; /**< profile id为2的报文统计 */
+ u32 macsec_dec_dpp_profile_id_3_pkt_cnt; /**< profile id为3的报文统计 */
+ u32 macsec_dec_dpp_profile_id_4_pkt_cnt; /**< profile id为4的报文统计 */
+ u32 macsec_dec_dpp_illegal_pkt_cnt; /**< 非法报文统计 */
+ u64 macsec_dec_intf_in_sop_cnt; /**< DEC_INTF入端口sop的统计 */
+ u64 macsec_dec_intf_in_eop_cnt; /**< DEC_INTF入端口eop的统计 */
+ u64 macsec_dec_intf_in_abort_cnt; /**< DEC_INTF入端口丢弃的统计 */
+ u64 macsec_dec_out_sop_cnt; /**< DEC_INTF出端口sop的统计 */
+ u64 macsec_dec_out_eop_cnt; /**< DEC_INTF出端口eop的统计 */
+ u64 macsec_dec_out_abort_cnt; /**< DEC_INTF出端口丢弃的统计 */
+ u32 macsec_dec_intf_drop_pkt_cnt; /**< 端口disable丢弃包统计 */
+ u32 macsec_dec_oadp_out_msop_cnt; /**< out msop计数统计 */
+ u32 macsec_dec_oadp_out_meop_cnt; /**< out meop计数统计 */
} dec_cnt_s;
u32 cnt_info[0];
} macsec_dec_cnt_u;
/**
- * @brief macsec_cmd_err_cnt_operation_s - macsec internal dfx cnt information retrieval
- * @details Includes statistics for encryption and decryption sides, for problem diagnosis
+ * @brief macsec_cmd_err_cnt_operation_s - macsec内部的dfx cnt信息获取
+ * @details 包括加密和解密侧的统计信息,用于问题定位
*/
typedef struct tag_macsec_cmd_err_cnt_operation_s {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- macsec_enc_cnt_u enc_module_cnt; /* enc cnt info */
- macsec_dec_cnt_u dec_module_cnt; /* dec cnt info */
- u8 reserved[4]; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ macsec_enc_cnt_u enc_module_cnt; /**< enc cnt info */
+ macsec_dec_cnt_u dec_module_cnt; /**< dec cnt info */
+ u8 reserved[4]; /**< reserved for expanding */
} macsec_cmd_err_cnt_operation_s;
/**
- * @brief macsec_cmd_service_operation_s - macsec service management operation
- * @details Includes macsec handling when driver loads and unloads
+ * @brief macsec_cmd_service_operation_s - macsec服务管理操作
+ * @details 包括驱动加卸载时对macsec的处理
*/
typedef struct tag_macsec_cmd_service_operation_s {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- u8 op_code; /* Operation code, 0: disable macsec/1: enable macsec */
- u8 reserved[7]; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ u8 op_code; /**< Operation code, 0: disable macsec/1: enable macsec */
+ u8 reserved[7]; /**< reserved for expanding */
} macsec_cmd_service_operation_s;
/**
* @brief macsec_feature_nego_cmd_s - feature negotiation command struct defination
- * @details Includes macsec feature negotiation handling when driver loads
+ * @details 包括驱动加载时对macsec特性协商的处理
*/
typedef struct tag_macsec_feature_nego_cmd {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- u64 s_feature[MACSEC_MAX_FEATURE_QWORD]; /* macsec features */
- u8 op_code; /* Operation code, 0: get macsec feature/1: set macsec feature */
- u8 rsvd[7]; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ u64 s_feature[MACSEC_MAX_FEATURE_QWORD]; /**< macsec features */
+ u8 op_code; /**< Operation code, 0: get macsec feature/1: set macsec feature */
+ u8 rsvd[7]; /**< reserved for expanding */
} macsec_feature_nego_cmd_s;
/**
* @brief tag_macsec_flush_cmd_s - MACSEC resource actively cleans up parameters
- * @details Parameters included when flush command is issued
+ * @details 下发flush命令时包括的参数
*/
typedef struct tag_macsec_flush_cmd {
- struct mgmt_msg_head head; /* Management msg header info, 8B */
- u64 sci; /* 64-bit SCI value used to identify an SC */
- u8 op_code; /* Operation code, 0: flush sc and sa, 1: flush sa */
- u8 reserved[7]; /* reserved for expanding */
+ struct mgmt_msg_head head; /**< Management msg header info, 8B */
+ u64 sci; /**< 64-bit SCI value used to identify an SC */
+ u8 op_code; /**< Operation code, 0: flush sc and sa, 1: flush sa */
+ u8 reserved[7]; /**< reserved for expanding */
} tag_macsec_flush_cmd_s;
-/* macsec whitelist tool supported operation types */
+// macsec 白名单工具支持的操作类型
typedef enum macsec_whitelist_tool_op {
MACSEC_WHITELIST_TOOL_OP_ENABLE = 0,
MACSEC_WHITELIST_TOOL_OP_SET,
@@ -330,7 +297,7 @@ typedef enum macsec_whitelist_tool_op {
MACSEC_WHITELIST_TOOL_OP_MAX
} macsec_whitelist_tool_op_e;
-/* macsec whitelist configuration scenarios */
+// macsec 白名单的配置场景
typedef enum macsec_whitelist_tool_mode {
MACSEC_WHITELIST_TOOL_MODE_DMAC = 0,
MACSEC_WHITELIST_TOOL_MODE_TXVLAN,
@@ -339,16 +306,16 @@ typedef enum macsec_whitelist_tool_mode {
MACSEC_WHITELIST_TOOL_MODE_MAX
} macsec_whitelist_tool_mode_e;
-// inbuf contains a hdr
+// inbuf 包含一个hdr
typedef struct macsec_whitelist_cmd_hdr {
macsec_whitelist_tool_op_e cmd_type;
macsec_whitelist_tool_mode_e mode_type;
} macsec_whitelist_cmd_hdr_t;
-// inbuf definition
+// inbuf 定义
typedef struct macsec_whitelist_info {
- u64 dmac;/* dmac value */
- u32 vlanid;/* vlanid value */
+ u64 dmac; /**< dmac value */
+ u32 vlanid; /**< vlanid value */
u32 mask;
u32 dmac_id;
u32 port;
@@ -371,7 +338,7 @@ typedef struct macsec_whitelist_cmd_in {
macsec_whitelist_info_t buf;
} macsec_whitelist_cmd_in_t;
-// outbuf definition
+// outbuf 定义
typedef struct macsec_whitelist_cmd_out {
struct mgmt_msg_head head;
u64 dmac_list[MACSEC_DMAC_TEMPLATE_NUM];
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd.h
index 17f8b1b5f..1cba1c1c7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd.h
@@ -1,23 +1,20 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mag_mpu_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : serdesmag cmd definition between driver and mpu
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ * Description: serdes/mag cmd definition between driver and mpu
+ * Author: ETH group
+ * Create: 2021-07-30
*/
#ifndef MAG_MPU_CMD_H
#define MAG_MPU_CMD_H
-/* serdes/mag message command code definition */
+/* serdes/mag消息命令字定义 */
enum mag_cmd {
- /* serdes command code, unified encapsulation of all serdes commands */
+ /* serdes命令字,统一封装所有serdes命令 */
SERDES_CMD_PROCESS = 0,
- /* mag command code, divided by function */
- /* port configuration related 0-29 */
+ /* mag命令字,按功能划分 */
+ /* 端口配置相关 0-29 */
MAG_CMD_SET_PORT_CFG = 1,
MAG_CMD_SET_PORT_ADAPT = 2,
MAG_CMD_CFG_LOOPBACK_MODE = 3,
@@ -33,34 +30,36 @@ enum mag_cmd {
MAG_CMD_CFG_LINK_TIME = 13,
MAG_CMD_SET_PANGEA_ADAPT = 15,
- MAG_CMD_HILINK_MODE = 16, /* set port hilink debug mode @see struct mag_cmd_hilink_mode */
+ MAG_CMD_HILINK_MODE =
+ 16, /* set port hilink debug mode @see struct mag_cmd_hilink_mode */
- /* bios link configuration related 30-49 */
+ /* bios link配置相关 30-49 */
MAG_CMD_CFG_BIOS_LINK_CFG = 31,
MAG_CMD_RESTORE_LINK_CFG = 32,
MAG_CMD_ACTIVATE_BIOS_LINK_CFG = 33,
- /* optical module, LED, PHY and other peripheral configuration management 50-99 */
+ /* 光模块、LED、PHY等外设配置管理 50-99 */
/* LED */
MAG_CMD_SET_LED_CFG = 50,
/* PHY */
MAG_CMD_GET_PHY_INIT_STATUS = 55, /* reserved for future use */
- /* optical module */
+ /* 光模块 */
MAG_CMD_GET_XSFP_INFO = 60,
MAG_CMD_SET_XSFP_ENABLE = 61,
MAG_CMD_GET_XSFP_PRESENT = 62,
- MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, for equipment test */
+ MAG_CMD_SET_XSFP_RW =
+ 63, /* sfp/qsfp single byte read/write, for equipment test */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64,
MAG_CMD_SET_XSFP_TLV_INFO = 65,
MAG_CMD_GET_XSFP_TLV_INFO = 66,
- /* event report 100-149 */
+ /* 事件上报 100-149 */
MAG_CMD_WIRE_EVENT = 100,
MAG_CMD_LINK_ERR_EVENT = 101,
- /* DFX, Counter related */
+ /* DFX、Counter相关 */
MAG_CMD_EVENT_PORT_INFO = 150,
MAG_CMD_GET_PORT_STAT = 151,
MAG_CMD_CLR_PORT_STAT = 152,
@@ -75,7 +74,7 @@ enum mag_cmd {
MAG_CMD_SET_HIMAC_PRBS = 161,
MAG_CMD_GET_HIMAC_PRBS = 162,
- /* patch reserved cmd */
+ /* patch预留cmd */
MAG_CMD_PATCH_RSVD_0 = 200,
MAG_CMD_PATCH_RSVD_1 = 201,
MAG_CMD_PATCH_RSVD_2 = 202,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd_defs.h
index a78351be7..f02995c71 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mag/mag_mpu_cmd_defs.h
@@ -1,11 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mag_mpu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : serdesmag cmd definition between driver and mpu
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
+ * Description: serdes/mag cmd definition between driver and mpu
+ * Author: ETH group
+ * Create: 2021-07-30
*/
#ifndef MAG_MPU_CMD_DEFS_H
@@ -20,7 +17,7 @@
#endif
#include "mpu_cmd_base_defs.h"
-/* serdes cmd struct definition */
+/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
#define RX_RSFEC_PHY_DFX_STA_TBL_SIZE 25
@@ -139,10 +136,7 @@ enum mag_cmd_port_lanes {
PORT_LANES_X8 = 8 /* reserved for future use */
};
-enum mag_cmd_port_duplex {
- PORT_DUPLEX_HALF = 0,
- PORT_DUPLEX_FULL = 1
-};
+enum mag_cmd_port_duplex { PORT_DUPLEX_HALF = 0, PORT_DUPLEX_FULL = 1 };
enum mag_cmd_wire_node {
WIRE_NODE_UNDEF = 0,
@@ -165,33 +159,38 @@ enum mag_cmd_wire_node {
WIRE_NODE_NUM
};
-#define CABLE_10G_SPEED (1 << PORT_SPEED_10GB)
-#define CABLE_25G_SPEED ((1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
-#define CABLE_40G_SPEED ((1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_10GB))
-#define CABLE_50G_SPEED ((1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_25GB) | \
- (1 << PORT_SPEED_10GB))
-#define CABLE_100G_SPEED ((1 << PORT_SPEED_100GB) | (1 << PORT_SPEED_50GB) | \
- (1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_25GB) | \
- (1 << PORT_SPEED_10GB))
-#define CABLE_200G_SPEED ((1 << PORT_SPEED_200GB) | (1 << PORT_SPEED_100GB) | \
- (1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_40GB) | \
- (1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
-#define CABLE_400G_SPEED ((1 << PORT_SPEED_400GB) | (1 << PORT_SPEED_200GB) | \
- (1 << PORT_SPEED_100GB) | (1 << PORT_SPEED_50GB) | \
- (1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_25GB) | \
- (1 << PORT_SPEED_10GB))
-#define CABLE_800G_SPEED ((1 << PORT_SPEED_800GB) | (1 << PORT_SPEED_400GB) | \
- (1 << PORT_SPEED_200GB) | (1 << PORT_SPEED_100GB) | \
- (1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_40GB) | \
- (1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
-#define FIBER_10G_SPEED (1 << PORT_SPEED_10GB)
-#define FIBER_25G_SPEED (1 << PORT_SPEED_25GB)
-#define FIBER_40G_SPEED (1 << PORT_SPEED_40GB)
-#define FIBER_50G_SPEED (1 << PORT_SPEED_50GB)
-#define FIBER_100G_SPEED (1 << PORT_SPEED_100GB)
-#define FIBER_200G_SPEED (1 << PORT_SPEED_200GB)
-#define FIBER_400G_SPEED (1 << PORT_SPEED_400GB)
-#define FIBER_800G_SPEED (1 << PORT_SPEED_800GB)
+#define CABLE_10G_SPEED (1 << PORT_SPEED_10GB)
+#define CABLE_25G_SPEED ((1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
+#define CABLE_40G_SPEED ((1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_10GB))
+#define CABLE_50G_SPEED \
+ ((1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_25GB) | \
+ (1 << PORT_SPEED_10GB))
+#define CABLE_100G_SPEED \
+ ((1 << PORT_SPEED_100GB) | (1 << PORT_SPEED_50GB) | \
+ (1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_25GB) | \
+ (1 << PORT_SPEED_10GB))
+#define CABLE_200G_SPEED \
+ ((1 << PORT_SPEED_200GB) | (1 << PORT_SPEED_100GB) | \
+ (1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_40GB) | \
+ (1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
+#define CABLE_400G_SPEED \
+ ((1 << PORT_SPEED_400GB) | (1 << PORT_SPEED_200GB) | \
+ (1 << PORT_SPEED_100GB) | (1 << PORT_SPEED_50GB) | \
+ (1 << PORT_SPEED_40GB) | (1 << PORT_SPEED_25GB) | \
+ (1 << PORT_SPEED_10GB))
+#define CABLE_800G_SPEED \
+ ((1 << PORT_SPEED_800GB) | (1 << PORT_SPEED_400GB) | \
+ (1 << PORT_SPEED_200GB) | (1 << PORT_SPEED_100GB) | \
+ (1 << PORT_SPEED_50GB) | (1 << PORT_SPEED_40GB) | \
+ (1 << PORT_SPEED_25GB) | (1 << PORT_SPEED_10GB))
+#define FIBER_10G_SPEED (1 << PORT_SPEED_10GB)
+#define FIBER_25G_SPEED (1 << PORT_SPEED_25GB)
+#define FIBER_40G_SPEED (1 << PORT_SPEED_40GB)
+#define FIBER_50G_SPEED (1 << PORT_SPEED_50GB)
+#define FIBER_100G_SPEED (1 << PORT_SPEED_100GB)
+#define FIBER_200G_SPEED (1 << PORT_SPEED_200GB)
+#define FIBER_400G_SPEED (1 << PORT_SPEED_400GB)
+#define FIBER_800G_SPEED (1 << PORT_SPEED_800GB)
enum mag_cmd_cnt_type {
MAG_RX_RSFEC_DEC_CW_CNT = 0,
@@ -222,7 +221,7 @@ struct mag_cmd_set_port_cfg {
u8 fec;
u8 lanes;
u8 rsvd1[19];
- u8 adapt_en; /* Cross-DIE addition, tool has not enabled this capability yet */
+ u8 adapt_en; /* 跨DIE增加,工具暂未使能该能力 */
};
/* mag supported/advertised link mode bitmap */
@@ -274,25 +273,35 @@ enum mag_cmd_himac_prbs_type {
#define LINK_MODE_800GE_BASE_R8_BIT 0x4000u
#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
-#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_25GE_BASE_R_BIT \
+ (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
-#define CABLE_50GE_BASE_R_BIT (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
- LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_50GE_BASE_R_BIT \
+ (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
+ LINK_MODE_10GE_BASE_R_BIT)
#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
-#define CABLE_100GE_BASE_R_BIT (LINK_MODE_100GE_BASE_R_BIT | LINK_MODE_50GE_BASE_R_BIT | \
- LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
-#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
-#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
-#define CABLE_200GE_BASE_R2_BIT (LINK_MODE_200GE_BASE_R2_BIT | LINK_MODE_100GE_BASE_R2_BIT | \
- LINK_MODE_50GE_BASE_R2_BIT)
-#define CABLE_200GE_BASE_R4_BIT (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
- LINK_MODE_40GE_BASE_R4_BIT)
+#define CABLE_100GE_BASE_R_BIT \
+ (LINK_MODE_100GE_BASE_R_BIT | LINK_MODE_50GE_BASE_R_BIT | \
+ LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_100GE_BASE_R2_BIT \
+ (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
+#define CABLE_100GE_BASE_R4_BIT \
+ (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
+#define CABLE_200GE_BASE_R2_BIT \
+ (LINK_MODE_200GE_BASE_R2_BIT | LINK_MODE_100GE_BASE_R2_BIT | \
+ LINK_MODE_50GE_BASE_R2_BIT)
+#define CABLE_200GE_BASE_R4_BIT \
+ (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
+ LINK_MODE_40GE_BASE_R4_BIT)
#define CABLE_200GE_BASE_R8_BIT LINK_MODE_200GE_BASE_R8_BIT
-#define CABLE_400GE_BASE_R4_BIT (LINK_MODE_400GE_BASE_R4_BIT | LINK_MODE_200GE_BASE_R4_BIT | \
- LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
-#define CABLE_400GE_BASE_R8_BIT (LINK_MODE_400GE_BASE_R8_BIT | LINK_MODE_200GE_BASE_R8_BIT)
-#define CABLE_800GE_BASE_R8_BIT (LINK_MODE_800GE_BASE_R8_BIT | LINK_MODE_400GE_BASE_R8_BIT | \
- LINK_MODE_200GE_BASE_R8_BIT)
+#define CABLE_400GE_BASE_R4_BIT \
+ (LINK_MODE_400GE_BASE_R4_BIT | LINK_MODE_200GE_BASE_R4_BIT | \
+ LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
+#define CABLE_400GE_BASE_R8_BIT \
+ (LINK_MODE_400GE_BASE_R8_BIT | LINK_MODE_200GE_BASE_R8_BIT)
+#define CABLE_800GE_BASE_R8_BIT \
+ (LINK_MODE_800GE_BASE_R8_BIT | LINK_MODE_400GE_BASE_R8_BIT | \
+ LINK_MODE_200GE_BASE_R8_BIT)
struct mag_cmd_ber_cor_cnt {
u32 corr_lane_sym_cnt;
@@ -416,9 +425,7 @@ struct mag_cmd_cfg_loopback_mode {
struct mag_cmd_set_port_enable {
struct mgmt_msg_head head;
- u16 function_id; /* function_id should not more than
- * the max support pf_id(32)
- */
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
u16 rsvd0;
u8 state; /* bitmap bit0:tx_en bit1:rx_en */
@@ -437,15 +444,11 @@ struct mag_cmd_get_port_enable {
#define PMA_FOLLOW_ENABLE 0x1
#define PMA_FOLLOW_DISABLE 0x2
#define PMA_FOLLOW_GET 0x4
-/* the physical port disable link follow only when
- * all pf of the port are set to follow disable
- */
+/* the physical port disable link follow only when all pf of the port are set to follow disable */
struct mag_cmd_set_link_follow {
struct mgmt_msg_head head;
- u16 function_id; /* function_id should not more than
- * the max support pf_id(32)
- */
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
u16 rsvd0;
u8 follow;
@@ -464,9 +467,7 @@ struct mag_cmd_get_link_status {
struct mag_cmd_set_pma_enable {
struct mgmt_msg_head head;
- u16 function_id; /* function_id should not more than
- * the max support pf_id(32)
- */
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
u16 enable;
};
@@ -501,64 +502,64 @@ struct mag_cmd_cfg_fec_mode {
};
/* speed */
-#define PANGEA_ADAPT_10G_BITMAP 0xd
-#define PANGEA_ADAPT_25G_BITMAP 0x72
-#define PANGEA_ADAPT_40G_BITMAP 0x680
-#define PANGEA_ADAPT_100G_BITMAP 0x1900
-#define PANGEA_ADAPT_200G_BITMAP 0x1c000
+#define PANGEA_ADAPT_10G_BITMAP 0xd
+#define PANGEA_ADAPT_25G_BITMAP 0x72
+#define PANGEA_ADAPT_40G_BITMAP 0x680
+#define PANGEA_ADAPT_100G_BITMAP 0x1900
+#define PANGEA_ADAPT_200G_BITMAP 0x1c000
/* speed and fec */
-#define PANGEA_10G_NO_BITMAP 0x8
-#define PANGEA_10G_BASE_BITMAP 0x4
-#define PANGEA_25G_NO_BITMAP 0x10
-#define PANGEA_25G_BASE_BITMAP 0x20
-#define PANGEA_25G_RS_BITMAP 0x40
-#define PANGEA_40G_NO_BITMAP 0x400
-#define PANGEA_40G_BASE_BITMAP 0x200
-#define PANGEA_100G_NO_BITMAP 0x800
-#define PANGEA_100G_RS_BITMAP 0x1000
-#define PANGEA_200G_RS_BITMAP 0x8000
-#define PANGEA_200G_LLRS_BITMAP 0x10000
+#define PANGEA_10G_NO_BITMAP 0x8
+#define PANGEA_10G_BASE_BITMAP 0x4
+#define PANGEA_25G_NO_BITMAP 0x10
+#define PANGEA_25G_BASE_BITMAP 0x20
+#define PANGEA_25G_RS_BITMAP 0x40
+#define PANGEA_40G_NO_BITMAP 0x400
+#define PANGEA_40G_BASE_BITMAP 0x200
+#define PANGEA_100G_NO_BITMAP 0x800
+#define PANGEA_100G_RS_BITMAP 0x1000
+#define PANGEA_200G_RS_BITMAP 0x8000
+#define PANGEA_200G_LLRS_BITMAP 0x10000
/* adapt or fec */
-#define PANGEA_ADAPT_ADAPT_BITMAP 0x4183
-#define PANGEA_ADAPT_NO_BITMAP 0xc18
-#define PANGEA_ADAPT_BASE_BITMAP 0x224
-#define PANGEA_ADAPT_RS_BITMAP 0x9040
-#define PANGEA_ADAPT_LLRS_BITMAP 0x10000
+#define PANGEA_ADAPT_ADAPT_BITMAP 0x4183
+#define PANGEA_ADAPT_NO_BITMAP 0xc18
+#define PANGEA_ADAPT_BASE_BITMAP 0x224
+#define PANGEA_ADAPT_RS_BITMAP 0x9040
+#define PANGEA_ADAPT_LLRS_BITMAP 0x10000
/* default cfg */
-#define PANGEA_ADAPT_CFG_10G_CR 0x200d
-#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
-#define PANGEA_ADAPT_CFG_25G_CR 0x207f
-#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
-#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
-#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
-#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
+#define PANGEA_ADAPT_CFG_10G_CR 0x200d
+#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
+#define PANGEA_ADAPT_CFG_25G_CR 0x207f
+#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
+#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
+#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
+#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
-#define PANGEA_ADAPT_CFG_200G_CR4 0x1ff80
+#define PANGEA_ADAPT_CFG_200G_CR4 0x1ff80
#define PANGEA_ADAPT_CFG_200G_SRLR4 0x1c000
typedef union {
struct {
- u32 adapt_10g : 1; /* [0] adapt_10g */
- u32 adapt_25g : 1; /* [1] adapt_25g */
- u32 base_10g : 1; /* [2] base_10g */
- u32 no_10g : 1; /* [3] no_10g */
- u32 no_25g : 1; /* [4] no_25g */
- u32 base_25g : 1; /* [5] base_25g */
- u32 rs_25g : 1; /* [6] rs_25g */
- u32 adapt_40g : 1; /* [7] adapt_40g */
+ u32 adapt_10g : 1; /* [0] adapt_10g */
+ u32 adapt_25g : 1; /* [1] adapt_25g */
+ u32 base_10g : 1; /* [2] base_10g */
+ u32 no_10g : 1; /* [3] no_10g */
+ u32 no_25g : 1; /* [4] no_25g */
+ u32 base_25g : 1; /* [5] base_25g */
+ u32 rs_25g : 1; /* [6] rs_25g */
+ u32 adapt_40g : 1; /* [7] adapt_40g */
u32 adapt_100g : 1; /* [8] adapt_100g */
- u32 base_40g : 1; /* [9] base_40g */
- u32 no_40g : 1; /* [10] no_40g */
- u32 no_100g : 1; /* [11] no_100g */
- u32 rs_100g : 1; /* [12] rs_100g */
- u32 auto_neg : 1; /* [13] auto_neg */
+ u32 base_40g : 1; /* [9] base_40g */
+ u32 no_40g : 1; /* [10] no_40g */
+ u32 no_100g : 1; /* [11] no_100g */
+ u32 rs_100g : 1; /* [12] rs_100g */
+ u32 auto_neg : 1; /* [13] auto_neg */
u32 adapt_200g : 1; /* [14] adapt_200g */
- u32 rs_200g : 1; /* [15] rs_200g */
- u32 llrs_200g : 1; /* [16] llrs_200g */
- u32 rsvd0 : 15; /* [31:17] reserved */
+ u32 rs_200g : 1; /* [15] rs_200g */
+ u32 llrs_200g : 1; /* [16] llrs_200g */
+ u32 rsvd0 : 15; /* [31:17] reserved */
} bits;
u32 value;
@@ -696,12 +697,12 @@ struct mag_cmd_set_xsfp_rw {
u8 rsvd0;
u32 devaddr;
u32 offset;
- u8 misc; /* bit [0:1]: means cmis bank_id, bit [2:7]: reserved */
+ u8 misc; /* bit [0:1]: means cmis bank_id, bit [2:7]: reserved */
/*
- * for qsfp and cmis, means upper page id.
- * for qsfp, if not specified, read the upper page specified last time.
- * for cmis, page_id must be specified.
- */
+ for qsfp and cmis, means upper page id.
+ for qsfp, if not specified, read the upper page specified last time.
+ for cmis, page_id must be specified.
+ */
u8 page_id;
u16 rsvd1;
};
@@ -815,47 +816,47 @@ struct mag_port_param_info {
#define XSFP_VENDOR_SN_LEN 16
struct mag_cmd_event_port_info {
- /* Message header common info 8+4=12B */
+ /* 消息头公共信息 8+4=12B */
struct mgmt_msg_head head;
u8 port_id;
u8 event_type;
u8 rsvd0[2];
- /* Optical module related 16+4*3+4+16+8=56B */
+ /* 光模块相关 16+4*3+4+16+8=56B */
u8 vendor_name[XSFP_VENDOR_NAME_LEN];
- u32 port_type; /* fiber / copper */
- u32 port_sub_type; /* sr / lr */
- u32 cable_length; /* 1/3/5m */
- u8 cable_temp; /* Temperature */
- u8 max_speed; /* Optical module max speed */
- u8 sfp_type; /* sfp/qsfp */
+ u32 port_type; /* fiber / copper */
+ u32 port_sub_type; /* sr / lr */
+ u32 cable_length; /* 1/3/5m */
+ u8 cable_temp; /* 温度 */
+ u8 max_speed; /* 光模块最大速率 */
+ u8 sfp_type; /* sfp/qsfp */
u8 rsvd1;
- u32 power[4]; /* Optical power */
+ u32 power[4]; /* 光功率 */
u8 an_state;
u8 fec;
u16 speed;
- u8 gpio_insert; /* 0:present 1:absent */
+ u8 gpio_insert; /* 0:present 1:absent */
u8 alos;
- u8 rx_los; /* gpio get */
- u8 pma_ctrl; /* eth_ctrl.pma_ctrl.bits.rf_en; */
-
- /* himac related info 4*5+4=32B */
- u32 pma_fifo_reg; /* himac pma fifo status */
- u32 pma_signal_ok_reg; /* himac pma signal ok status */
- u32 pcs_64_66b_reg; /* himac V600 has no this register */
- u32 rf_lf; /* himac rxmac lf rf status */
- u8 pcs_link; /* himac pcs link status */
- u8 pcs_mac_link; /* link state after thread judgment */
- u8 tx_enable; /* himac txmac enable status */
- u8 rx_enable; /* himac rxmac enable status */
- u32 pcs_err_cnt; /* himac pcs ber err cnt */
+ u8 rx_los; /* gpio获取 */
+ u8 pma_ctrl; /* eth_ctrl.pma_ctrl.bits.rf_en; */
+
+ /* himac相关信息 4*5+4=32B */
+ u32 pma_fifo_reg; /* himac pma fifo status */
+ u32 pma_signal_ok_reg; /* himac pma signal ok status */
+ u32 pcs_64_66b_reg; /* himac V600 无该寄存器 */
+ u32 rf_lf; /* himac rxmac lf rf status */
+ u8 pcs_link; /* himac pcs link status */
+ u8 pcs_mac_link; /* link 线程判断后的 link_state */
+ u8 tx_enable; /* himac txmac enable status */
+ u8 rx_enable; /* himac rxmac enable status */
+ u32 pcs_err_cnt; /* himac pcs ber err cnt */
u8 eq_data[38];
u8 rsvd2[2];
- /* link thread related dfx 4+4+128+128+4=268 */
+ /* link线程相关dfx 4+4+128+128+4=268 */
u32 his_link_machine_state;
u32 cur_link_machine_state;
u8 his_machine_state_data[128];
@@ -863,24 +864,24 @@ struct mag_cmd_event_port_info {
u8 his_machine_state_length;
u8 cur_machine_state_length;
- /* an/adapt/link thread configuration info 4+4*24+16+36= */
+ /* an/adapt/link线程配置信息 4+4*24+16+36= */
struct mag_port_param_info param_info;
- /* Auto-negotiation(an) and auto-adapt(adapt) related info 4+8=12B */
- u32 speed_ability; /* supported_mode & advertised_mode */
- u32 fec_ability; /* supported FEC modes */
+ /* 自协商(an)和自适应(adapt)相关信息 4+8=12B */
+ u32 speed_ability; /* supported_mode & advertised_mode */
+ u32 fec_ability; /* supported FEC modes */
u8 duplex;
- /* Cable SN ASCII representation 16B */
+ /* 线缆SN ASIIC表示 16B */
u8 vendor_sn[XSFP_VENDOR_SN_LEN];
- u32 osfp_power[4]; /* 4-channel optical power */
+ u32 osfp_power[4]; /* 4通道光功率 */
- /* serdes txrx key parameters */
+ /* serdes txrx 关键参数 */
u8 sds_txrx_para[8][10];
u8 ds_mask;
- /* Ensure compatibility */
- u8 rsvd3[238]; /* Reserved 238 bytes */
+ /* 确保兼容性 */
+ u8 rsvd3[238]; /* 预留238byte */
};
struct mag_cmd_port_stats {
@@ -1024,46 +1025,46 @@ struct mag_cmd_dump_antrain_info {
};
#define MAG_SFP_PORT_NUM 24
-/* Chip optical module temperature structure definition */
+/* 芯片光模块温度结构体定义 */
struct mag_cmd_sfp_temp_in_info {
struct mgmt_msg_head head; /* 8B */
- u8 opt_type; /* 0:read operation 1:cfg operation */
+ u8 opt_type; /* 0:read operation 1:cfg operation */
u8 rsv[3];
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ s32 max_temp; /* 芯片光模块阈值 */
+ s32 min_temp; /* 芯片光模块阈值 */
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Read temperature */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* 读出的温度 */
+ s32 max_temp; /* 芯片光模块阈值 */
+ s32 min_temp; /* 芯片光模块阈值 */
};
#define XSFP_CMIS_INFO_MAX_SIZE 1536
-#define QSFP_CMIS_PAGE_SIZE 128
-
-#define QSFP_CMIS_PAGE_00H 0x00 /* Lower: Control and Essentials, Upper: \
- * Administrative Information \
- */
-#define QSFP_CMIS_PAGE_01H 0x01 /* Advertising */
-#define QSFP_CMIS_PAGE_02H 0x02 /* Module and lane Thresholds */
-#define QSFP_CMIS_PAGE_03H 0x03 /* User EEPROM */
-#define QSFP_CMIS_PAGE_04H 0x04 /* Laser Capabilities Advertising \
- * (Page 04h, Optional) \
- */
-#define QSFP_CMIS_PAGE_05H 0x05
-#define QSFP_CMIS_PAGE_10H 0x10 /* Lane and Data Path Control */
-#define QSFP_CMIS_PAGE_11H 0x11 /* Lane Status */
-#define QSFP_CMIS_PAGE_12H 0x12
-#define QSFP_CMIS_PAGE_13H 0x13
-#define QSFP_CMIS_PAGE_14H 0x14
-#define QSFP_CMIS_PAGE_9FH 0x9f
-#define QSFP_CMIS_PAGE_B7H 0xb7
-#define QSFP_CMIS_PAGE_B8H 0xb8
-
-/* In ethtool, both lower page 00h and high page 00h have page id 0, with the latter offset being 128,
-but due to MPU defining high page 00h page id = 1, special handling is required */
+#define QSFP_CMIS_PAGE_SIZE 128
+
+#define QSFP_CMIS_PAGE_00H \
+ 0x00 /* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_01H 0x01 /* Advertising */
+#define QSFP_CMIS_PAGE_02H 0x02 /* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_03H 0x03 /* User EEPROM */
+#define QSFP_CMIS_PAGE_04H \
+ 0x04 /* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_05H 0x05
+#define QSFP_CMIS_PAGE_06H 0x06
+#define QSFP_CMIS_PAGE_07H 0x07
+#define QSFP_CMIS_PAGE_10H 0x10 /* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_11H 0x11 /* Lane Status */
+#define QSFP_CMIS_PAGE_12H 0x12
+#define QSFP_CMIS_PAGE_13H 0x13
+#define QSFP_CMIS_PAGE_14H 0x14
+#define QSFP_CMIS_PAGE_9FH 0x9f
+#define QSFP_CMIS_PAGE_B7H 0xb7
+#define QSFP_CMIS_PAGE_B8H 0xb8
+
+/* ETHTOOL中 lower page 00h和high page 00h的page id都为0,后者offset为128,
+但是由于MPU定义high page 00h的page id = 1,特殊处理 */
#define HINIC5_PAGE_L00_H00_OFFSET 0
#define HINIC5_PAGE_H01_OFFSET 1
#define HINIC5_PAGE_H02_OFFSET 2
@@ -1071,60 +1072,55 @@ but due to MPU defining high page 00h page id = 1, special handling is required
#define HINIC5_PAGE_H11_OFFSET 4
#define HINIC5_PAGE_INVALID_OFFSET 0xff
-/* Maximum page id 0x11 supported by ethtool 6.6 for parsing */
+/* ethtool 6.6支持解析的最大page id为0x11 */
#ifndef CMIS_MAX_PAGES
#define CMIS_MAX_PAGES 18
#endif
-#define MGMT_TLV_U8_SIZE 1
-#define MGMT_TLV_U16_SIZE 2
-#define MGMT_TLV_U32_SIZE 4
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
-#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
-#define MGMT_TLV_SET_U8(addr, value) \
- ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) ((*((u8 *)(void *)(addr))) = ((u8)(value)))
-#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
#define MGMT_TLV_SET_U16(addr, value) \
- ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
-#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
#define MGMT_TLV_SET_U32(addr, value) \
- ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
-#define MGMT_TLV_TYPE_END 0xFFFF
+#define MGMT_TLV_TYPE_END 0xFFFF
enum mag_xsfp_type {
- /* Skip 0x00, reason for defining Type starting from 0x01: to distinguish from memset data */
- MAG_XSFP_TYPE_PAGE = 0x01,
+ /* 跳过0x00,从0x01开始定义Type的原因:便于和memset的数据做区别 */
+ MAG_XSFP_TYPE_PAGE = 0x01,
MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
- MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
};
struct mgmt_tlv_info {
u16 type;
u16 length;
- u8 value[0]; // When value is page content, data composition:
- // page_id(4byte) + page_context(128byte)
+ u8 value[0]; // value为page页内容时数据组成:page_id(4byte) + page_context(128byte)
};
typedef struct tag_mag_cmd_set_xsfp_tlv_req {
struct mgmt_msg_head head;
/*
- * Parse according to struct mgmt_tlv_info format.
- * +---------------------------------------------+
- * | TYPE | LEN | VALUE |
- * +--------------------+-------+----------------+
- * | MAG_XSFP_TYPE_PAGE | 4 | Page Number |
- * +---------------------------------------------+
- *
- * Description:
- * 1、Page number definition: lower page 00h number is:
- * 0, upper page 00h number is 1, and so on.
- * 2、Specification: Currently supports max 10 Pages, among which:
- * lower page 00h, upper page 00h/01h/02h/10h/11h are required,
- * Remaining 4 for extension reservation.
- */
+ * 按结构体struct mgmt_tlv_info格式解析。
+ * +---------------------------------------------+
+ * | TYPE | LEN | VALUE |
+ * +--------------------+-------+----------------+
+ * | MAG_XSFP_TYPE_PAGE | 4 | Page Number |
+ * +---------------------------------------------+
+ *
+ * 说明:
+ * 1、Page编号定义:lower page 00h编号为:0,upper page 00h编号为:1,依此类推。
+ * 2、规格:当前最大支持10个Page,其中:lower page 00h, upper page 00h/01h/02h/10h/11h为必选项,剩余4个为扩展预留。
+ */
u8 tlv_buf[0];
} mag_cmd_set_xsfp_tlv_req;
@@ -1137,7 +1133,7 @@ typedef struct tag_mag_cmd_get_xsfp_tlv_req {
u8 port_id;
u8 rsvd;
- u16 rsp_buf_len; /* In response: buffer space length for storing TLV format data */
+ u16 rsp_buf_len; /* 响应里面:用于存放TLV格式数据的Buffer空间长度 */
} mag_cmd_get_xsfp_tlv_req;
typedef struct tag_mag_cmd_get_xsfp_tlv_rsp {
@@ -1147,23 +1143,23 @@ typedef struct tag_mag_cmd_get_xsfp_tlv_rsp {
u8 rsvd[3];
/*
- * Assemble according to struct mgmt_tlv_info format.
- * +----------------------------------------------------------------------+
- * | TYPE | LEN | VALUE |
- * +-------------------------+--------------+-----------------------------+
- * | MAG_XSFP_TYPE_WIRE_TYPE | 4 | Wire Type |
- * +-------------------------+--------------+-----------------------------+
- * | MAG_XSFP_TYPE_PAGE | 4 + Page Len | Page Number + Page Content |
- * +----------------------------------------------------------------------+
- *
- * Description:
- * 1、Page number definition: lower page 00h number is: 0, upper page 00h number is: 1, and so on.
- * 2、Caller needs to apply for enough space (including space for end Type and end Length).
- */
+ * 按结构体struct mgmt_tlv_info格式组装。
+ * +----------------------------------------------------------------------+
+ * | TYPE | LEN | VALUE |
+ * +-------------------------+--------------+-----------------------------+
+ * | MAG_XSFP_TYPE_WIRE_TYPE | 4 | Wire Type |
+ * +-------------------------+--------------+-----------------------------+
+ * | MAG_XSFP_TYPE_PAGE | 4 + Page Len | Page Number + Page Content |
+ * +----------------------------------------------------------------------+
+ *
+ * 说明:
+ * 1、Page编号定义:lower page 00h编号为:0,upper page 00h编号为:1,依此类推。
+ * 2、调用者需要申请足够的空间(包括存放结束Type和结束Length的空间)。
+ */
u8 tlv_buf[0];
} mag_cmd_get_xsfp_tlv_rsp;
-#define XSFP_CMIS_PARSE_PAGE_NUM 10
+#define XSFP_CMIS_PARSE_PAGE_NUM 10
typedef struct mag_parse_tlv_info {
u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
@@ -1183,246 +1179,211 @@ typedef struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
} drv_mag_cmd_get_xsfp_tlv_rsp;
typedef struct {
- u8 resv0[14]; /* Reg 0-13: Lower Memory: Page 00h */
- u8 temperature_msb; /* Reg 14: Module Monitor 1: Temperature1 MSB */
- u8 temperature_lsb; /* Reg 15: Module Monitor 1: Temperature1 LSB */
- u8 volt_supply[2]; /*
- * Reg 16-17: Internally measured 3.3 volt
- * input supply voltage: in 100 µV increments.
- */
- u8 resv1[67]; /* Reg 18-84 */
- u8 media_type; /* Reg 85: Table 8-12 Byte 85 Module Media Type Encodings */
-
- u8 electrical_interface_id; /* Reg 86: ID from SFF-8024 IDs for
- * Host Electrical Interfaces
- */
- u8 media_interface_id; /* Reg 87: ID from table selected by Byte 85
- * (see Table 8-12)
- */
- u8 lane_count; /*
- * Reg 88: Lane Count, ApSel Code: 0001b.
- * bit 7-4: Host Lane Count.
- * bit 3-0: Media Lane Count.
- */
- u8 lane_assignment_options; /*
- * Reg 89: Bits 0-7 form a bit map corresponding
- * to Host Lanes 1-8.
- * A set bit indicates that the Application
- * may begin on the corresponding host lane.
- */
- u8 resv2[38]; /* Reg 90-127 */
+ u8 resv0[3]; /* Reg 0-2: Lower Memory: Page 00h */
+ u8 module_state; /* Reg 3: module_state: bit1-bit3 */
+ u8 resv1[10]; /* Reg 4-13: Lower Memory: Page 00h */
+ u8 temperature_msb; /* Reg 14: Module Monitor 1: Temperature1 MSB */
+ u8 temperature_lsb; /* Reg 15: Module Monitor 1: Temperature1 LSB */
+ u8 volt_supply[2]; /*
+ * Reg 16-17: Internally measured 3.3 volt
+ * input supply voltage: in 100 µV increments.
+ */
+ u8 resv2[67]; /* Reg 18-84 */
+ u8 media_type; /* Reg 85: Table 8-12 Byte 85 Module Media Type Encodings */
+
+ u8 electrical_interface_id; /* Reg 86: ID from SFF-8024 IDs for Host Electrical Interfaces */
+ u8 media_interface_id; /* Reg 87: ID from table selected by Byte 85 (see Table 8-12) */
+ u8 lane_count; /*
+ * Reg 88: Lane Count, ApSel Code: 0001b.
+ * bit 7-4: Host Lane Count.
+ * bit 3-0: Media Lane Count.
+ */
+ u8 lane_assignment_options; /*
+ * Reg 89: Bits 0-7 form a bit map corresponding to Host Lanes 1-8.
+ * A set bit indicates that the Application may begin on the corresponding
+ * host lane.
+ */
+ u8 resv3[38]; /* Reg 90-127 */
} qsfp_cmis_lower_page_00_s;
typedef struct {
- u8 identifier; /* Reg 128: Type of Serial Module - See SFF-8024. */
- u8 vendor_name[16]; /* Reg 129-144: Vendor name (ASCII) */
- u8 vendor_oui[3]; /* Reg 145-147: Vendor IEEE company ID */
- u8 vendor_pn[16]; /* Reg 148-163: Part number provided by vendor (ASCII) */
- u8 vendor_rev[2]; /* Reg 164-165: Revision level for part number provided
- * by vendor (ASCII)
- */
- u8 vendor_sn[16]; /* Reg 166-181: Vendor Serial Number (ASCII) */
- u8 date_code[8]; /* Reg 182-189: Vendor's manufacturing date code */
- u8 clei_code[10]; /* Reg 190-199: Common Language Equipment
- * Identification code */
- u8 power_character[2]; /* Reg 200-201: Module power characteristics */
- u8 cable_len; /*
- * Reg 202: bit 7-6: Length multiplier field
- * (Copper or active cable).
- * Reg 202: bit 5-0: Link length base value in meters.
- * To calculate actual link length use multiplier
- * in bits 7-6.
- */
- u8 connector; /* Reg 203: Type of connector present in the module.
- * See SFF-8024 for codes
- */
+ u8 identifier; /* Reg 128: Type of Serial Module - See SFF-8024. */
+ u8 vendor_name[16]; /* Reg 129-144: Vendor name (ASCII) */
+ u8 vendor_oui[3]; /* Reg 145-147: Vendor IEEE company ID */
+ u8 vendor_pn[16]; /* Reg 148-163: Part number provided by vendor (ASCII) */
+ u8 vendor_rev[2]; /* Reg 164-165: Revision level for part number provided by vendor (ASCII) */
+ u8 vendor_sn[16]; /* Reg 166-181: Vendor Serial Number (ASCII) */
+ u8 date_code[8]; /* Reg 182-189: Vendor's manufacturing date code */
+ u8 clei_code[10]; /* Reg 190-199: Common Language Equipment Identification code */
+ u8 power_character[2]; /* Reg 200-201: Module power characteristics */
+ u8 cable_len; /*
+ * Reg 202: bit 7-6: Length multiplier field (Copper or active cable).
+ * Reg 202: bit 5-0: Link length base value in meters.
+ * To calculate actual link length use multiplier in bits 7-6.
+ */
+ u8 connector; /* Reg 203: Type of connector present in the module. See SFF-8024 for codes */
u8 copper_cable_attenuation[6]; /* Reg 204-209: Copper Cable Attenuation */
- u8 near_end_implementation; /* Reg 210: Cable Assembly Lane Information,
- * Near end implementation
- */
- u8 far_end_config; /* Reg 211: Cable Assembly Lane Information:
- * Far End Configuration
- */
- u8 media_technology; /* Reg 212: Media Interface Technology encodings */
- u8 resv0[43]; /* Reg 213-255 */
+ u8 near_end_implementation; /* Reg 210: Cable Assembly Lane Information, Near end implementation */
+ u8 far_end_config; /* Reg 211: Cable Assembly Lane Information: Far End Configuration */
+ u8 media_technology; /* Reg 212: Media Interface Technology encodings */
+ u8 resv0[43]; /* Reg 213-255 */
} qsfp_cmis_upper_page_00_s;
typedef struct {
- u8 firmware_rev[2]; /* Reg 128-129: Numeric representation of
- * inactive module firmware revision
- */
- u8 hardware_rev[2]; /* Reg 130-131: Numeric representation of
- * module hardware revision
- */
- u8 smf_len_km; /*
- * Reg 132: bit 7-6: Link length multiplier for SMF fiber.
- * 00 = 0.1 (1 t0 6.3 km)
- * 01 = 1 (1 to 63 km)
- * 10, 11 = reserved
- * Reg 132: bit 5-0: Base link length for SMF fiber.
- * Must be multiplied by value in bits 7-6
- * to calculate actual link length in km.
- */
- u8 om5_len; /* Reg 133: Link length supported for OM5 fiber,
- * units of 2 m
- */
- u8 om4_len; /* Reg 134: Link length supported for OM4 fiber,
- * units of 2 m
- */
- u8 om3_len; /* Reg 135: Link length supported for EBW 50/125
- * µm fiber (OM3), units of 2m
- */
- u8 om2_len; /* Reg 136: Link length supported for 50/125
- * µm fiber (OM2), units of 1m
- */
- u8 resv0; /* Reg 137: Reserved */
- u8 wavelength[2]; /* Reg 138-139: Nominal laser wavelength
- * (Wavelength = value / 20 in nm)
- */
- u8 wavelength_tolerance[2]; /*
- * Reg 140-141: Guaranteed range of laser
- * wavelength (+/- value) from Nominal wavelength.
- * (Wavelength Tol. = value/200 in nm).
- */
- u8 pages_implement; /* Reg 142: Implemented pages advertising */
- u8 resv1[16]; /* Reg 143-158 */
- u8 monitor_implement[2]; /*
- * Reg 159-160: Implemented Monitors Advertisement.
- * Reg 159: bit 7-6: Reserved.
- * bit 5: Custom monitor implemented
- * bit 4-2: Aux3 ~ Aux1 monitor implemented
- * bit 1: Internal 3.3 Volts monitor implemented
- * bit 0: Temperature monitor implemented
- * Reg 160: bit 7-5: Reserved.
- * bit 4-3: Tx Bias current measurement
- * and threshold multiplier.
- * 00b = multiply x1
- * 01b = multiply x2
- * 10b = multiply x4
- * 11b = reserved
- * bit 2: Rx Optical Input Power monitor implemented
- * bit 1: Tx Output Optical Power monitor implemented
- * bit 0: Tx Bias monitor implemented
- */
- u8 resv2[95]; /* Reg 161-255 */
+ u8 firmware_rev
+ [2]; /* Reg 128-129: Numeric representation of inactive module firmware revision */
+ u8 hardware_rev
+ [2]; /* Reg 130-131: Numeric representation of module hardware revision */
+ u8 smf_len_km; /*
+ * Reg 132: bit 7-6: Link length multiplier for SMF fiber.
+ * 00 = 0.1 (1 t0 6.3 km)
+ * 01 = 1 (1 to 63 km)
+ * 10, 11 = reserved
+ * Reg 132: bit 5-0: Base link length for SMF fiber.
+ * Must be multiplied by value in bits 7-6 to calculate actual link length in km.
+ */
+ u8 om5_len; /* Reg 133: Link length supported for OM5 fiber, units of 2 m */
+ u8 om4_len; /* Reg 134: Link length supported for OM4 fiber, units of 2 m */
+ u8 om3_len; /* Reg 135: Link length supported for EBW 50/125 µm fiber (OM3), units of 2m */
+ u8 om2_len; /* Reg 136: Link length supported for 50/125 µm fiber (OM2), units of 1m */
+ u8 resv0; /* Reg 137: Reserved */
+ u8 wavelength[2]; /* Reg 138-139: Nominal laser wavelength (Wavelength = value / 20 in nm) */
+ u8 wavelength_tolerance[2]; /*
+ * Reg 140-141: Guaranteed range of laser wavelength (+/- value)
+ * from Nominal wavelength.(Wavelength Tol. = value/200 in nm).
+ */
+ u8 pages_implement; /* Reg 142: Implemented pages advertising */
+ u8 resv1[16]; /* Reg 143-158 */
+ u8 monitor_implement[2]; /*
+ * Reg 159-160: Implemented Monitors Advertisement.
+ * Reg 159: bit 7-6: Reserved.
+ * bit 5: Custom monitor implemented
+ * bit 4-2: Aux3 ~ Aux1 monitor implemented
+ * bit 1: Internal 3.3 Volts monitor implemented
+ * bit 0: Temperature monitor implemented
+ * Reg 160: bit 7-5: Reserved.
+ * bit 4-3: Tx Bias current measurement and threshold multiplier.
+ * 00b = multiply x1
+ * 01b = multiply x2
+ * 10b = multiply x4
+ * 11b = reserved
+ * bit 2: Rx Optical Input Power monitor implemented
+ * bit 1: Tx Output Optical Power monitor implemented
+ * bit 0: Tx Bias monitor implemented
+ */
+ u8 resv2[95]; /* Reg 161-255 */
} qsfp_cmis_upper_page_01_s;
typedef struct {
- u8 temperature_high_alarm[2]; /* Reg 128-129: Threshold for internally
- * measured temperature monitor
- */
- u8 temperature_low_alarm[2]; /* Reg 130-131: Threshold for internally
- * measured temperature monitor
- */
- u8 temperature_high_warn[2]; /* Reg 132-133: Threshold for internally
- * measured temperature monitor
- */
- u8 temperature_low_warn[2]; /* Reg 134-135: Threshold for internally
- * measured temperature monitor
- */
- u8 volt_high_alarm[2]; /*
- * Reg 136-137: Thresholds for internally measured 3.3 volt
- * input supply voltage: in 100 µV increments.
- */
- u8 volt_low_alarm[2]; /*
- * Reg 138-139:Thresholds for internally measured 3.3 volt
- * input supply voltage: in 100 µV increments.
- */
- u8 volt_high_warn[2]; /*
- * Reg 140-141: Thresholds for internally measured 3.3 volt
- * input supply voltage: in 100 µV increments.
- */
- u8 volt_low_warn[2]; /*
- * Reg 142-143: Thresholds for internally measured 3.3 volt
- * input supply voltage: in 100 µV increments.
- */
- u8 resv0[32]; /* Reg 144-175: Upper Memory: Page 02H */
- u8 tx_power_high_alarm[2]; /* Reg 176-177: Threshold for Tx optical power monitor */
- u8 tx_power_low_alarm[2]; /* Reg 178-179: Threshold for Tx optical power monitor */
- u8 tx_power_high_warn[2]; /* Reg 180-181: Threshold for Tx optical power monitor */
- u8 tx_power_low_warn[2]; /* Reg 182-183: Threshold for Tx optical power monitor */
- u8 tx_bias_high_alarm[2]; /*
- * Reg 184-185: Threshold for Tx bias monitor:
- * unsigned inter in 2uA increments,
- * times the multiplier from Table 8-33.
- */
- u8 tx_bias_low_alarm[2]; /*
- * Reg 186-187: Threshold for Tx bias monitor:
- * unsigned inter in 2uA increments,
- * times the multiplier from Table 8-33.
- */
- u8 tx_bias_high_warn[2]; /*
- * Reg 188-189: Threshold for Tx bias monitor:
- * unsigned inter in 2uA increments,
- * times the multiplier from Table 8-33.
- */
- u8 tx_bias_low_warn[2]; /*
- * Reg 190-191: Threshold for Tx bias monitor:
- * unsigned inter in 2uA increments,
- * times the multiplier from Table 8-33.
- */
- u8 rx_power_high_alarm[2]; /* Reg 192-193: Threshold for Rx optical power monitor */
- u8 rx_power_low_alarm[2]; /* Reg 194-195: Threshold for Rx optical power monitor */
- u8 rx_power_high_warn[2]; /* Reg 196-197: Threshold for Rx optical power monitor */
- u8 rx_power_low_warn[2]; /* Reg 198-199: Threshold for Rx optical power monitor */
- u8 resv1[56]; /* Reg 200-255 */
+ u8 temperature_high_alarm
+ [2]; /* Reg 128-129: Threshold for internally measured temperature monitor */
+ u8 temperature_low_alarm
+ [2]; /* Reg 130-131: Threshold for internally measured temperature monitor */
+ u8 temperature_high_warn
+ [2]; /* Reg 132-133: Threshold for internally measured temperature monitor */
+ u8 temperature_low_warn
+ [2]; /* Reg 134-135: Threshold for internally measured temperature monitor */
+ u8 volt_high_alarm[2]; /*
+ * Reg 136-137: Thresholds for internally measured 3.3 volt
+ * input supply voltage: in 100 µV increments.
+ */
+ u8 volt_low_alarm[2]; /*
+ * Reg 138-139:Thresholds for internally measured 3.3 volt
+ * input supply voltage: in 100 µV increments.
+ */
+ u8 volt_high_warn[2]; /*
+ * Reg 140-141: Thresholds for internally measured 3.3 volt
+ * input supply voltage: in 100 µV increments.
+ */
+ u8 volt_low_warn[2]; /*
+ * Reg 142-143: Thresholds for internally measured 3.3 volt
+ * input supply voltage: in 100 µV increments.
+ */
+ u8 resv0[32]; /* Reg 144-175: Upper Memory: Page 02H */
+ u8 tx_power_high_alarm
+ [2]; /* Reg 176-177: Threshold for Tx optical power monitor */
+ u8 tx_power_low_alarm
+ [2]; /* Reg 178-179: Threshold for Tx optical power monitor */
+ u8 tx_power_high_warn
+ [2]; /* Reg 180-181: Threshold for Tx optical power monitor */
+ u8 tx_power_low_warn
+ [2]; /* Reg 182-183: Threshold for Tx optical power monitor */
+ u8 tx_bias_high_alarm[2]; /*
+ * Reg 184-185: Threshold for Tx bias monitor: unsigned inter in 2uA increments,
+ * times the multiplier from Table 8-33.
+ */
+ u8 tx_bias_low_alarm[2]; /*
+ * Reg 186-187: Threshold for Tx bias monitor: unsigned inter in 2uA increments,
+ * times the multiplier from Table 8-33.
+ */
+ u8 tx_bias_high_warn[2]; /*
+ * Reg 188-189: Threshold for Tx bias monitor: unsigned inter in 2uA increments,
+ * times the multiplier from Table 8-33.
+ */
+ u8 tx_bias_low_warn[2]; /*
+ * Reg 190-191: Threshold for Tx bias monitor: unsigned inter in 2uA increments,
+ * times the multiplier from Table 8-33.
+ */
+ u8 rx_power_high_alarm
+ [2]; /* Reg 192-193: Threshold for Rx optical power monitor */
+ u8 rx_power_low_alarm
+ [2]; /* Reg 194-195: Threshold for Rx optical power monitor */
+ u8 rx_power_high_warn
+ [2]; /* Reg 196-197: Threshold for Rx optical power monitor */
+ u8 rx_power_low_warn
+ [2]; /* Reg 198-199: Threshold for Rx optical power monitor */
+ u8 resv1[56]; /* Reg 200-255 */
} qsfp_cmis_upper_page_02_s;
typedef struct {
- u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
} qsfp_cmis_upper_page_03_s;
typedef struct {
- u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
- u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
- u8 resv1[125]; /* Reg 131-255 */
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
} qsfp_cmis_upper_page_10_s;
typedef struct {
- u8 resv0[7]; /* Reg 128-134: Upper Memory: Page 11H */
- u8 tx_fault; /* Reg 135: Latched Tx Fault flag, media lane 1 ~ 8 */
- u8 tx_los; /* Reg 136: Latched Tx LOS flag, lane 1 ~ 8 */
- u8 tx_cdr_lol; /* Reg 137: Latched Tx CDR LOL flag, lane 1 ~ 8 */
- u8 resv1[9]; /* Reg 138-146 */
- u8 rx_los; /* Reg 147: Latched Rx LOS flag, media lane 1 ~ 8. Clear on Read */
- u8 rx_cdr_lol; /* Reg 148: Latched Rx CDR LOL flag, media lane 1 ~ 8.
- * Clear on Read
- */
- u8 resv2[5]; /* Reg 149-153 */
- u8 tx_power[16]; /* Reg 154-169: Internally measured Tx output optical power */
- u8 tx_bias[16]; /* Reg 170-185: Internally measured Tx bias current monitor:
- * unsinged integer in 2uA increments,
- * times the multiplier from Table 8-33(Page 01H: Reg 160).
- */
- u8 rx_power[16]; /* Reg 186-201: Internally measured Rx input optical power */
- u8 resv3[54]; /* Reg 202-255 */
+ u8 resv0[7]; /* Reg 128-134: Upper Memory: Page 11H */
+ u8 tx_fault; /* Reg 135: Latched Tx Fault flag, media lane 1 ~ 8 */
+ u8 tx_los; /* Reg 136: Latched Tx LOS flag, lane 1 ~ 8 */
+ u8 tx_cdr_lol; /* Reg 137: Latched Tx CDR LOL flag, lane 1 ~ 8 */
+ u8 resv1[9]; /* Reg 138-146 */
+ u8 rx_los; /* Reg 147: Latched Rx LOS flag, media lane 1 ~ 8. Clear on Read */
+ u8 rx_cdr_lol; /* Reg 148: Latched Rx CDR LOL flag, media lane 1 ~ 8. Clear on Read */
+ u8 resv2[5]; /* Reg 149-153 */
+ u8 tx_power[16]; /* Reg 154-169: Internally measured Tx output optical power */
+ u8 tx_bias[16]; /*
+ * Reg 170-185: Internally measured Tx bias current monitor: unsinged integer
+ * in 2uA increments, times the multiplier from Table 8-33(Page 01H: Reg 160).
+ */
+ u8 rx_power[16]; /* Reg 186-201: Internally measured Rx input optical power */
+ u8 resv3[54]; /* Reg 202-255 */
} qsfp_cmis_upper_page_11_s;
typedef struct {
- u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 13H */
- u8 diagnostic_reporting_capabilities; /* Reg 130: The diagnostic reporting
- * capabilities of the module are advertised
- */
- u8 resv1[125]; /* Reg 131-255 */
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 13H */
+ u8 diagnostic_reporting_capabilities; /* Reg 130: The diagnostic reporting capabilities of the module are advertised */
+ u8 resv1[125]; /* Reg 131-255 */
} qsfp_cmis_upper_page_13_s;
-#define CMIS_LANE_NUM 8
+#define CMIS_LANE_NUM 8
typedef struct ber_lane_s {
u8 ber[CMIS_LANE_NUM][2];
} ber_lane;
typedef struct {
- u8 diagnostics_selector; /* Reg 128: This selects the content of the data
- * in bytes 192-255: Page 14H
- */
- u8 resv0; /* Reg 129 */
- u8 custom[2]; /* Reg 130-131 */
- u8 latched_diagnostics_flags[8]; /* Reg 132-139 */
- u8 resv1[52]; /* Reg 140-191 */
+ u8 diagnostics_selector; /* Reg 128: This selects the content of the data in bytes 192-255: Page 14H */
+ u8 resv0; /* Reg 129 */
+ u8 custom[2]; /* Reg 130-131 */
+ u8 latched_diagnostics_flags[8]; /* Reg 132-139 */
+ u8 resv1[52]; /* Reg 140-191 */
union {
u8 contents[64];
struct {
- u8 host_peak_detect_lane1[2]; /* Reg 192-193 */
+ u8 host_peak_detect_lane1[2]; /* Reg 192-193 */
u8 host_peak_detect_lane2[2];
u8 host_peak_detect_lane3[2];
u8 host_peak_detect_lane4[2];
@@ -1430,7 +1391,7 @@ typedef struct {
u8 host_peak_detect_lane6[2];
u8 host_peak_detect_lane7[2];
u8 host_peak_detect_lane8[2];
- u8 host_snr_lane1[2]; /* Reg 208-209 */
+ u8 host_snr_lane1[2]; /* Reg 208-209 */
u8 host_snr_lane2[2];
u8 host_snr_lane3[2];
u8 host_snr_lane4[2];
@@ -1438,7 +1399,7 @@ typedef struct {
u8 host_snr_lane6[2];
u8 host_snr_lane7[2];
u8 host_snr_lane8[2];
- u8 media_peak_detect_lane1[2]; /* Reg 224-225 */
+ u8 media_peak_detect_lane1[2]; /* Reg 224-225 */
u8 media_peak_detect_lane2[2];
u8 media_peak_detect_lane3[2];
u8 media_peak_detect_lane4[2];
@@ -1446,7 +1407,7 @@ typedef struct {
u8 media_peak_detect_lane6[2];
u8 media_peak_detect_lane7[2];
u8 media_peak_detect_lane8[2];
- u8 media_snr_lane1[2]; /* Reg 240-241 */
+ u8 media_snr_lane1[2]; /* Reg 240-241 */
u8 media_snr_lane2[2];
u8 media_snr_lane3[2];
u8 media_snr_lane4[2];
@@ -1457,202 +1418,185 @@ typedef struct {
} snr_and_peak_detect;
struct {
- ber_lane host_ber; /* Reg 192-193 */
- ber_lane media_ber; /* Reg 208-209 */
+ ber_lane host_ber; /* Reg 192-193 */
+ ber_lane media_ber; /* Reg 208-209 */
} host_and_media_ber;
- } err_info; /* Reg 192-255: Contents defined by Diagnostics Selector */
+ } err_info; /* Reg 192-255: Contents defined by Diagnostics Selector */
} qsfp_cmis_upper_page_14_s;
typedef struct {
- u8 resv0[16]; /* Reg 128-143: Upper Memory: Page B7H */
- u8 ret_loss_status[8]; /* Reg 144-151: Optical link return
- * loss detection status on lane 1~8
- */
- u8 ret_loss_overview; /* Reg 152: Optical link return loss detection overview */
- u8 resv1[103]; /* Reg 153-255 */
+ u8 resv0[16]; /* Reg 128-143: Upper Memory: Page B7H */
+ u8 ret_loss_status
+ [8]; /* Reg 144-151: Optical link return loss detection status on lane 1~8 */
+ u8 ret_loss_overview; /* Reg 152: Optical link return loss detection overview */
+ u8 resv1[103]; /* Reg 153-255 */
} qsfp_cmis_upper_page_b7_s;
typedef struct {
- u8 minimum_value[2]; /* LPL PM data 2 bytes – minimum value */
- u8 average_value[2]; /* LPL PM data 2 bytes – average (mean) value */
- u8 maximum_value[2]; /* LPL PM data 2 bytes – maximum value */
+ u8 minimum_value[2]; /* LPL PM data 2 bytes – minimum value */
+ u8 average_value[2]; /* LPL PM data 2 bytes – average (mean) value */
+ u8 maximum_value[2]; /* LPL PM data 2 bytes – maximum value */
} cdb_pam4_ltp_6bytes;
typedef struct {
- u8 minimum_value[2]; /* LPL PM data 2 bytes – minimum value */
- u8 average_value[2]; /* LPL PM data 2 bytes – average (mean) value */
- u8 maximum_value[2]; /* LPL PM data 2 bytes – maximum value */
- u8 current_value[2]; /* LPL PM data 2 bytes – an optional current value */
+ u8 minimum_value[2]; /* LPL PM data 2 bytes – minimum value */
+ u8 average_value[2]; /* LPL PM data 2 bytes – average (mean) value */
+ u8 maximum_value[2]; /* LPL PM data 2 bytes – maximum value */
+ u8 current_value[2]; /* LPL PM data 2 bytes – an optional current value */
} cdb_pam4_ltp_8bytes;
typedef struct {
- u8 rsv[2]; /* 136~137 reserved */
- u8 max_ref_pot; /* 138 Whether channel 1-8 max reflection intensity point has return loss alarm,
- * bit0-7: indicates channel 1-8,
- * 0: no alarm, 1: has alarm (recommend cleaning link)
- */
- u8 sec_ref_pot; /* 139 Whether channel 1-8 second max reflection intensity point has return loss alarm,
- * bit0-7: indicates channel 1-8,
- * 0: no alarm, 1: has alarm (recommend cleaning link)
- */
- u8 max_ref_val[8]; /* 140~147 Channel 1-8 max reflection intensity, unsigned data,
- * unit: -0.2 dB
- * for example: 0x0A means return loss intensity is -2db
- */
- u8 max_ref_pos[8][3]; /* 148~171 Channel 1-8 max reflection intensity point position, unsigned data,
- * unit: 0.1m,
- * report 0xFFFFFFh means invalid value (max reflection point not detected)
- */
- u8 sec_ref_val[8]; /* 172~179 Channel 1-8 second max reflection intensity, unsigned data,
- * unit: -0.2 dB
- * for example: 0x0A means return loss intensity is -2db
- */
- u8 sec_ref_pos[8][3]; /* 180~203 Channel 1-8 second max reflection intensity point position,
- * unsigned data, unit: 0.1m, report 0xFFFFFFh means invalid value
- * (max reflection point not detected)
- */
- u8 far_ref_val[8]; /* 204~211 Channel 1-8 farthest reflection intensity, unsigned data,
- * unit: -0.2 dB
- * for example: 0x0A means return loss intensity is -2db
- */
- u8 far_ref_pos[8][3]; /* 212~235 Channel 1-8 farthest reflection intensity point position,
- * unsigned data, unit: 0.1m,
- * report 0xFFFFFFh means invalid value (max reflection point not detected)
- */
- u8 peer_tx_alarm; /* 236 Whether peer TX optical port has alarm, bit0-7: TX optical port 1-8,
- * 0: no alarm, 1: has alarm (recommend cleaning link)
- */
- u8 peer_tx_val[8]; /* 237~244 Peer TX optical port 1-8 alarm level, unsigned data */
- u8 local_rx_alarm; /* 245 Whether local RX optical port has alarm, bit0-7: RX optical port 1-8,
- * 0: no alarm, 1: has alarm (recommend cleaning link)
- */
- u8 local_rx_val[8]; /* 246~253 Local RX optical port 1-8 alarm level, unsigned data */
- u8 rsv1[2]; /* 254~255 reserved */
+ u8 rsv[2]; /* 136~137 保留 */
+ u8 max_ref_pot; /* 138 通道1-8最大反射强度点是否有回损异常告警,bit0-7:标识通道1-8,0:无异常告警,1代表有告警(建议清理链路) */
+ u8 sec_ref_pot; /* 139 通道1-8第二大反射强度点是否有回损异常告警,bit0-7:标识通道1-8,0:无异常告警,1代表有告警(建议清理链路) */
+ u8 max_ref_val
+ [8]; /* 140~147 通道1-8最大反射强度,无符号数据,单位:-0.2 dB 例如:0x0A表示回损强度为-2db */
+ u8 max_ref_pos
+ [8]
+ [3]; /* 148~171 通道1-8最大反射强度点的位置,无符号数据,单位:0.1m,上报0xFFFFFFh表示无效值(未检测到最大反射点) */
+ u8 sec_ref_val
+ [8]; /* 172~179 通道1-8第二大反射强度,无符号数据,单位:-0.2 dB 例如:0x0A表示回损强度为-2db */
+ u8 sec_ref_pos
+ [8]
+ [3]; /* 180~203 通道1-8第二大反射强度点的位置,无符号数据,单位:0.1m,上报0xFFFFFFh表示无效值(未检测到最大反射点) */
+ u8 far_ref_val
+ [8]; /* 204~211 通道1-8最远反射强度,无符号数据,单位:-0.2 dB 例如:0x0A表示回损强度为-2db */
+ u8 far_ref_pos
+ [8]
+ [3]; /* 212~235 通道1-8最远反射强度点的位置,无符号数据,单位:0.1m,上报0xFFFFFFh表示无效值(未检测到最大反射点) */
+ u8 peer_tx_alarm; /* 236 对端TX光口是否有告警,bit0-7:TX光口1-8,0:无异常告警,1代表有告警(建议清理链路) */
+ u8 peer_tx_val[8]; /* 237~244 对端TX光口1-8告警程度,无符号数据 */
+ u8 local_rx_alarm; /* 245 本端RX光口是否有告警,bit0-7:RX光口1-8,0:无异常告警,1代表有告警(建议清理链路) */
+ u8 local_rx_val[8]; /* 246~253 本端RX光口1-8告警程度,无符号数据 */
+ u8 rsv1[2]; /* 254~255 保留 */
} cdb_dirt_detection;
typedef struct {
- u8 resv0[8]; /* Reg 128-135: Upper Memory: Page 9FH */
+ u8 resv0[8]; /* Reg 128-135: Upper Memory: Page 9FH */
union {
- u8 val[120]; /* Reg 136-255: LPL PM data 120 bytes */
- cdb_pam4_ltp_6bytes ltp6[8]; /* Reg 136-183: LPL PM data: lane1~8 PAM4 LTP,
- * Each LTP contains 6 bytes of data.
- */
- cdb_pam4_ltp_8bytes ltp8[8]; /* Reg 136-199: LPL PM data: lane1~8 PAM4 LTP,
- * Each LTP contains 8 bytes of data.
- */
- cdb_dirt_detection dirt0; /* Reg 136-255: Report max reflection,
- * second max reflection, farthest reflection and TX optical port detection info.
- */
+ u8 val[120]; /* Reg 136-255: LPL PM data 120 bytes */
+ cdb_pam4_ltp_6bytes ltp6
+ [8]; /* Reg 136-183: LPL PM data: lane1~8 PAM4 LTP, Each LTP contains 6 bytes of data. */
+ cdb_pam4_ltp_8bytes ltp8
+ [8]; /* Reg 136-199: LPL PM data: lane1~8 PAM4 LTP, Each LTP contains 8 bytes of data. */
+ cdb_dirt_detection
+ dirt0; /* Reg 136-255: 上报最大反射、第二大发射、最远反射以及TX光口检测信息. */
} lpl_pm_data;
} qsfp_cmis_upper_page_9f_s;
-/* The default byte order (storage order) for numeric data types is defined in section 8.1.3.5 (big-endian). In the case of non-default storage order (little-endian), non-default byte order must be explicitly specified. */
+/* 数值数据类型的默认字节序(存储顺序)在第8.1.3.5节中定义(大端序)。在非默认存储顺序(小端序)的情况下,必须明确指定非默认字节序。 */
typedef struct {
- qsfp_cmis_lower_page_00_s lower_page_00; /* QSFP-DD-CMIS lower page 00 128-byte data */
- qsfp_cmis_upper_page_00_s upper_page_00; /* QSFP-DD-CMIS upper page 00 128-byte data */
- qsfp_cmis_upper_page_01_s upper_page_01; /* QSFP-DD-CMIS upper page 01 128-byte data */
- qsfp_cmis_upper_page_02_s upper_page_02; /* QSFP-DD-CMIS upper page 02 128-byte data */
- qsfp_cmis_upper_page_10_s upper_page_10; /* QSFP-DD-CMIS upper page 10 128-byte data */
- qsfp_cmis_upper_page_11_s upper_page_11; /* QSFP-DD-CMIS upper page 11 128-byte data */
- qsfp_cmis_upper_page_13_s upper_page_13; /* QSFP-DD-CMIS upper page 13 128-byte data */
- qsfp_cmis_upper_page_14_s upper_page_14; /* QSFP-DD-CMIS upper page 14 128-byte data */
- qsfp_cmis_upper_page_9f_s upper_page_9f; /* QSFP-DD-CMIS upper page 9f 128-byte data */
- qsfp_cmis_upper_page_b7_s upper_page_b7; /* QSFP-DD-CMIS upper page b7 128-byte data */
+ qsfp_cmis_lower_page_00_s
+ lower_page_00; /* QSFP-DD-CMIS lower page 00 128-byte data */
+ qsfp_cmis_upper_page_00_s
+ upper_page_00; /* QSFP-DD-CMIS upper page 00 128-byte data */
+ qsfp_cmis_upper_page_01_s
+ upper_page_01; /* QSFP-DD-CMIS upper page 01 128-byte data */
+ qsfp_cmis_upper_page_02_s
+ upper_page_02; /* QSFP-DD-CMIS upper page 02 128-byte data */
+ qsfp_cmis_upper_page_10_s
+ upper_page_10; /* QSFP-DD-CMIS upper page 10 128-byte data */
+ qsfp_cmis_upper_page_11_s
+ upper_page_11; /* QSFP-DD-CMIS upper page 11 128-byte data */
+ qsfp_cmis_upper_page_13_s
+ upper_page_13; /* QSFP-DD-CMIS upper page 13 128-byte data */
+ qsfp_cmis_upper_page_14_s
+ upper_page_14; /* QSFP-DD-CMIS upper page 14 128-byte data */
} qsfp_cmis_info_s;
/* optical_speed */
-#define XSFP_MAC_SPEED_UNKNOWN 0 /* unknown */
-#define XSFP_MAC_SPEED_10M 10 /* 10 Mbps */
-#define XSFP_MAC_SPEED_100M 100 /* 100 Mbps */
-#define XSFP_MAC_SPEED_1G 1000 /* 1000 Mbps = 1 Gbps */
-#define XSFP_MAC_SPEED_10G 10000 /* 10000 Mbps = 10 Gbps */
-#define XSFP_MAC_SPEED_25G 25000 /* 25000 Mbps = 25 Gbps */
-#define XSFP_MAC_SPEED_40G 40000 /* 40000 Mbps = 40 Gbps */
-#define XSFP_MAC_SPEED_50G 50000 /* 50000 Mbps = 50 Gbps */
+#define XSFP_MAC_SPEED_UNKNOWN 0 /* unknown */
+#define XSFP_MAC_SPEED_10M 10 /* 10 Mbps */
+#define XSFP_MAC_SPEED_100M 100 /* 100 Mbps */
+#define XSFP_MAC_SPEED_1G 1000 /* 1000 Mbps = 1 Gbps */
+#define XSFP_MAC_SPEED_10G 10000 /* 10000 Mbps = 10 Gbps */
+#define XSFP_MAC_SPEED_25G 25000 /* 25000 Mbps = 25 Gbps */
+#define XSFP_MAC_SPEED_40G 40000 /* 40000 Mbps = 40 Gbps */
+#define XSFP_MAC_SPEED_50G 50000 /* 50000 Mbps = 50 Gbps */
#define XSFP_MAC_SPEED_100G 100000 /* 100000 Mbps = 100 Gbps */
#define XSFP_MAC_SPEED_200G 200000 /* 200000 Mbps = 200 Gbps */
#define XSFP_MAC_SPEED_400G 400000 /* 400000 Mbps = 400 Gbps */
#define XSFP_MAC_SPEED_800G 800000 /* 800000 Mbps = 800 Gbps */
struct mag_bios_cfg {
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-negotiation switch 0 - field invalid 1 - on 2 - off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, refer to enum mag_cmd_port_fec */
- u8 auto_adapt; /* Auto-adapt mode configuration 0 - invalid config 1 - on 2 - off */
+ u8 speed; /* enum of port speed */
+ u8 auto_neg; /* 自协商开关 0 - 字段无效 1 - 开2 - 关 */
+ u8 lanes; /* lane num */
+ u8 fec; /* FEC模式, 参考 enum mag_cmd_port_fec */
+ u8 auto_adapt; /* 自适应模式配置0 - 无效配置 1 - 开启 2 - 关闭 */
};
-#define VL_NUM 16
-#define LANE_NUM 8
+#define VL_NUM 16
+#define LANE_NUM 8
typedef struct {
u32 ubmac_nl_id;
u32 ubmac_port_id;
- u32 ubmac_port_info; // PORT_INFO
- u32 ubmac_port_link_sta; // PORT_LINK_STA
- u32 ubmac_phy_link_status_1; // PHY_LINK_STA_1
- u32 ubmac_phy_link_status_2; // PHY_LINK_STA_2
- u32 ubmac_phy_link_status_3; // PHY_LINK_STA_3
- u32 ubmac_phy_link_err_status; // PHY_LINK_ERR_STA
- u32 ubmac_fec_err_bit_num_low; // ST_MAC_FEC_ERR_BIT_NUM_LOW
- u32 ubmac_fec_err_bit_num_high; // ST_MAC_FEC_ERR_BIT_NUM_HIGH
- u32 ubmac_fec_decoding_fail_num_low; // ST_MAC_FEC_DECODING_FAIL_NUM_LOW
- u32 ubmac_fec_decoding_fail_num_high; // ST_MAC_FEC_DECODING_FAIL_NUM_HIGH
-
- u32 ubmac_dl_vl_enable; // CFG_LINK_CAP_11
- u32 ubmac_dl_rx_flit_cnt[VL_NUM]; // RX_FLIT_CNT_0 ~ 15
- u32 ubmac_dl_tx_flit_cnt[VL_NUM]; // TX_FLIT_CNT_0 ~ 15
- u32 ubmac_dl_crd_exist_cnt[VL_NUM]; // ST_CRD_0 ~ 15
- u32 ubmac_dl_crd_compensate_cnt[VL_NUM]; // ST_CRD_COMPENSATE_0 ~ 15
- u32 ubmac_dl_crd_vn_return_limit[VL_NUM]; // DATA_LINK_PFM_OPT_CFG_0 ~ 7
- u32 ubmac_dl_crd_vn_l1crd_limit[VL_NUM]; // DATA_LINK_PFM_OPT_CFG_8 ~ 15
-
- u32 ubmac_pfa_tx_fast_err_pkt_int_cnt; // PFA_TX_FAST_ERR_PKT_IN_CNT
- u32 ubmac_pfa_tx_fast_pkt_int_cnt; // PFA_TX_FAST_PKT_IN_CNT
- u32 ubmac_pfa_tx_norm_pkt_int_cnt; // PFA_TX_NORM_PKT_IN_CNT
- u32 ubmac_pfa_rx_pkt_int_cnt; // PFA_RX_PKT_IN_CNT
- u32 ubmac_pfa_tx_norm_err_pkt_int_cnt; // PFA_TX_NORM_ERR_PKT_IN_CNT
- u32 ubmac_pfa_rx_err_pkt_int_cnt; // PFA_RX_ERR_PKT_IN_CNT
- u32 ubmac_pfa_tx_fast_short_pkt_cnt; // PFA_TX_FAST_SHORT_PKT_CNT
- u32 ubmac_pfa_tx_fast_long_pkt_cnt; // PFA_TX_FAST_LONG_PKT_CNT
- u32 ubmac_pfa_tx_fast_mode_err_pkt_cnt; // PFA_TX_FAST_MODE_ERR_PKT_CNT
- u32 ubmac_pfa_tx_norm_short_pkt_cnt; // PFA_TX_NORM_SHORT_PKT_CNT
- u32 ubmac_pfa_tx_norm_long_pkt_cnt; // PFA_TX_NORM_LONG_PKT_CNT
- u32 ubmac_pfa_tx_norm_mode_err_pkt_cnt; // PFA_TX_NORM_MODE_ERR_PKT_CNT
- u32 ubmac_pfa_rx_short_pkt_cnt; // PFA_RX_SHORT_PKT_CNT
- u32 ubmac_pfa_rx_mode_err_pkt_cnt; // PFA_RX_MODE_ERR_PKT_CNT
- u32 ubmac_pfa_dfx_tx_pkt_len_chk_en; // PFA_DFX_TX_PKT_LEN_CHK_EN
- u32 ubmac_pfa_dfx_rx_pkt_len_chk_en; // PFA_DFX_RX_PKT_LEN_CHK_EN
- u32 ubmac_pfa_dfx_pkt_info_chk_en; // PFA_DFX_PKT_INFO_CHK_EN
- u32 ubmac_pfa_dfx_tx_fifo_state; // PFA_DFX_TX_FIFO_STATE
- u32 ubmac_pfa_dfx_rx_fifo_state; // PFA_DFX_RX_FIFO_STATE
- u32 ubmac_pfa_dfx_work_mode; // PFA_DFX_WORK_MODE
- u32 ubmac_pfa_dfx_tx_adp_fifo_state; // PFA_DFX_TX_ADP_FIFO_STATE
- u32 ubmac_pfa_tx_fast_lng_pkt_in_cnt; // PFA_TX_FAST_LNG_PKT_IN_CNT
- u32 ubmac_pfa_tx_fast_lng_err_pkt_in_cnt; // PFA_TX_FAST_LNG_ERR_PKT_IN_CNT
- u32 ubmac_pfa_tx_fast_lng_short_pkt_cnt; // PFA_TX_FAST_LNG_SHORT_PKT_CNT
- u32 ubmac_pfa_tx_fast_lng_long_pkt_cnt; // PFA_TX_FAST_LNG_LONG_PKT_CNT
- u32 ubmac_pfa_tx_fast_lng_mode_err_pkt_cnt; // PFA_TX_FAST_LNG_MODE_ERR_PKT_CNT
-
- u32 ubmac_pcs_lane_tsb_crc_cnt[LANE_NUM]; // ST_LANE0_TSB_CRC_CNT ~ 7
+ u32 ubmac_port_info; // PORT_INFO
+ u32 ubmac_port_link_sta; // PORT_LINK_STA
+ u32 ubmac_phy_link_status_1; // PHY_LINK_STA_1
+ u32 ubmac_phy_link_status_2; // PHY_LINK_STA_2
+ u32 ubmac_phy_link_status_3; // PHY_LINK_STA_3
+ u32 ubmac_phy_link_err_status; // PHY_LINK_ERR_STA
+ u32 ubmac_fec_err_bit_num_low; // ST_MAC_FEC_ERR_BIT_NUM_LOW
+ u32 ubmac_fec_err_bit_num_high; // ST_MAC_FEC_ERR_BIT_NUM_HIGH
+ u32 ubmac_fec_decoding_fail_num_low; // ST_MAC_FEC_DECODING_FAIL_NUM_LOW
+ u32 ubmac_fec_decoding_fail_num_high; // ST_MAC_FEC_DECODING_FAIL_NUM_HIGH
+
+ u32 ubmac_dl_vl_enable; // CFG_LINK_CAP_11
+ u32 ubmac_dl_rx_flit_cnt[VL_NUM]; // RX_FLIT_CNT_0 ~ 15
+ u32 ubmac_dl_tx_flit_cnt[VL_NUM]; // TX_FLIT_CNT_0 ~ 15
+ u32 ubmac_dl_crd_exist_cnt[VL_NUM]; // ST_CRD_0 ~ 15
+ u32 ubmac_dl_crd_compensate_cnt[VL_NUM]; // ST_CRD_COMPENSATE_0 ~ 15
+ u32 ubmac_dl_crd_vn_return_limit[VL_NUM]; // DATA_LINK_PFM_OPT_CFG_0 ~ 7
+ u32 ubmac_dl_crd_vn_l1crd_limit[VL_NUM]; // DATA_LINK_PFM_OPT_CFG_8 ~ 15
+
+ u32 ubmac_pfa_tx_fast_err_pkt_int_cnt; // PFA_TX_FAST_ERR_PKT_IN_CNT
+ u32 ubmac_pfa_tx_fast_pkt_int_cnt; // PFA_TX_FAST_PKT_IN_CNT
+ u32 ubmac_pfa_tx_norm_pkt_int_cnt; // PFA_TX_NORM_PKT_IN_CNT
+ u32 ubmac_pfa_rx_pkt_int_cnt; // PFA_RX_PKT_IN_CNT
+ u32 ubmac_pfa_tx_norm_err_pkt_int_cnt; // PFA_TX_NORM_ERR_PKT_IN_CNT
+ u32 ubmac_pfa_rx_err_pkt_int_cnt; // PFA_RX_ERR_PKT_IN_CNT
+ u32 ubmac_pfa_tx_fast_short_pkt_cnt; // PFA_TX_FAST_SHORT_PKT_CNT
+ u32 ubmac_pfa_tx_fast_long_pkt_cnt; // PFA_TX_FAST_LONG_PKT_CNT
+ u32 ubmac_pfa_tx_fast_mode_err_pkt_cnt; // PFA_TX_FAST_MODE_ERR_PKT_CNT
+ u32 ubmac_pfa_tx_norm_short_pkt_cnt; // PFA_TX_NORM_SHORT_PKT_CNT
+ u32 ubmac_pfa_tx_norm_long_pkt_cnt; // PFA_TX_NORM_LONG_PKT_CNT
+ u32 ubmac_pfa_tx_norm_mode_err_pkt_cnt; // PFA_TX_NORM_MODE_ERR_PKT_CNT
+ u32 ubmac_pfa_rx_short_pkt_cnt; // PFA_RX_SHORT_PKT_CNT
+ u32 ubmac_pfa_rx_mode_err_pkt_cnt; // PFA_RX_MODE_ERR_PKT_CNT
+ u32 ubmac_pfa_dfx_tx_pkt_len_chk_en; // PFA_DFX_TX_PKT_LEN_CHK_EN
+ u32 ubmac_pfa_dfx_rx_pkt_len_chk_en; // PFA_DFX_RX_PKT_LEN_CHK_EN
+ u32 ubmac_pfa_dfx_pkt_info_chk_en; // PFA_DFX_PKT_INFO_CHK_EN
+ u32 ubmac_pfa_dfx_tx_fifo_state; // PFA_DFX_TX_FIFO_STATE
+ u32 ubmac_pfa_dfx_rx_fifo_state; // PFA_DFX_RX_FIFO_STATE
+ u32 ubmac_pfa_dfx_work_mode; // PFA_DFX_WORK_MODE
+ u32 ubmac_pfa_dfx_tx_adp_fifo_state; // PFA_DFX_TX_ADP_FIFO_STATE
+ u32 ubmac_pfa_tx_fast_lng_pkt_in_cnt; // PFA_TX_FAST_LNG_PKT_IN_CNT
+ u32 ubmac_pfa_tx_fast_lng_err_pkt_in_cnt; // PFA_TX_FAST_LNG_ERR_PKT_IN_CNT
+ u32 ubmac_pfa_tx_fast_lng_short_pkt_cnt; // PFA_TX_FAST_LNG_SHORT_PKT_CNT
+ u32 ubmac_pfa_tx_fast_lng_long_pkt_cnt; // PFA_TX_FAST_LNG_LONG_PKT_CNT
+ u32 ubmac_pfa_tx_fast_lng_mode_err_pkt_cnt; // PFA_TX_FAST_LNG_MODE_ERR_PKT_CNT
+
+ u32 ubmac_pcs_lane_tsb_crc_cnt[LANE_NUM]; // ST_LANE0_TSB_CRC_CNT ~ 7
} ubmac_counter_info_s;
typedef struct {
- struct mgmt_msg_head head; /* 8B */
- u8 nl_id; /* nl id 0~2 */
- u8 port_id; /* port id 0~7 */
+ struct mgmt_msg_head head; /* 8B */
+ u8 nl_id; /* nl id 0~2 */
+ u8 port_id; /* port id 0~7 */
u8 rsvd;
} ubmac_counter_cmd_req;
typedef struct {
- struct mgmt_msg_head head; /* 8B */
+ struct mgmt_msg_head head; /* 8B */
ubmac_counter_info_s ubmac_cnt_info;
} ubmac_counter_cmd_resp;
-/* Because the firmware return rate field is u8 which cannot well carry data above 200Ge, data above 200Ge needs to be converted before display
- Refer to chip_attr_get_port_speed for conversion
- The above content refers to tool side modification
+/* 因为固件返回速率的字段为u8不能很好的承载200Ge以上数据,200Ge以上数据需要转换后显示
+ 可参考chip_attr_get_port_speed做转换
+ 上述内容参考工具侧修改
*/
typedef enum {
PORT_SPEED_MODE_START = 200,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_board_defs.h
index ee0a84755..6ae4bf1dc 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_board_defs.h
@@ -1,146 +1,159 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mpu_board_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : COMM board info between Driver and MPU
- */
+/* *****************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ ******************************************************************************
+ File Name : mpu_board_defs.h
+ Version : Initial Draft
+ Created : 2022/3/30
+ Last Modified :
+ Description : COMM board info between Driver and MPU
+ Function List :
+***************************************************************************** */
#ifndef COMM_BOARD_INFO_H
#define COMM_BOARD_INFO_H
-#define BOARD_TYPE_TEST_RANGE_START 1 /* Test board range start (inclusive) */
-#define BOARD_TYPE_TEST_RANGE_END 29 /* Test board range end (inclusive) */
-#define BOARD_TYPE_STRG_RANGE_START 30 /* Storage board range start (inclusive) */
-#define BOARD_TYPE_STRG_RANGE_END 99 /* Storage board range end (inclusive) */
-#define BOARD_TYPE_CAL_RANGE_START 100 /* Compute board range start (inclusive) */
-#define BOARD_TYPE_CAL_RANGE_END 169 /* Compute board range end (inclusive) */
-#define BOARD_TYPE_CLD_RANGE_START 170 /* Cloud board range start (inclusive) */
-#define BOARD_TYPE_CLD_RANGE_END 239 /* Cloud board range end (inclusive) */
-#define BOARD_TYPE_RSVD_RANGE_START 240 /* Reserved board range start (inclusive) */
-#define BOARD_TYPE_RSVD_RANGE_END 255 /* Reserved board range end (inclusive) */
+#define BOARD_TYPE_TEST_RANGE_START 1 /**< 测试单板起始值(包含) */
+#define BOARD_TYPE_TEST_RANGE_END 29 /**< 测试单板结束值(包含) */
+#define BOARD_TYPE_STRG_RANGE_START 30 /**< 存储单板起始值(包含) */
+#define BOARD_TYPE_STRG_RANGE_END 99 /**< 存储单板结束值(包含) */
+#define BOARD_TYPE_CAL_RANGE_START 100 /**< 计算单板起始值(包含) */
+#define BOARD_TYPE_CAL_RANGE_END 169 /**< 计算单板结束值(包含) */
+#define BOARD_TYPE_CLD_RANGE_START 170 /**< 云单板起始值(包含) */
+#define BOARD_TYPE_CLD_RANGE_END 239 /**< 云单板结束值(包含) */
+#define BOARD_TYPE_RSVD_RANGE_START 240 /**< 预留的单板起始值(包含) */
+#define BOARD_TYPE_RSVD_RANGE_END 255 /**< 预留的单板结束值(包含) */
typedef enum {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_TEST_EVB1_DDIE_2X200G = 3, /* 2X200G EVB1 DDIE Card */
- BOARD_TYPE_TEST_EVB1_SMDIE_1X200G = 4, /* 1X200G EVB1 SMDIE Card */
- BOARD_TYPE_TEST_EVB1_SSDIE_1X200G = 5, /* 1X200G EVB1 SSDIE Card */
- BOARD_TYPE_TEST_EVB2_DDIE_4X100G = 6, /* 4X100G EVB2 DDIE Card */
- BOARD_TYPE_TEST_EVB2_SMDIE_2X100G = 7, /* 2X100G EVB2 SMDIE Card */
- BOARD_TYPE_TEST_EVB2_SSDIE_2X100G = 8, /* 2X100G EVB2 SSDIE Card */
- BOARD_TYPE_TEST_EVB3_DDIE_4X25G = 9, /* 4X25G EVB3 DDIE Card */
- BOARD_TYPE_TEST_EVB3_SMDIE_2X25G = 10, /* 2X25G EVB3 SMDIE Card */
- BOARD_TYPE_TEST_EVB3_SSDIE_2X25G = 11, /* 2X25G EVB3 SSDIE Card */
- BOARD_TYPE_TEST_EVBS_SDIE_4X25G = 12, /* 4X25G EVBS SDIE Card */
- BOARD_TYPE_TEST_EVBS_SDIE_2X100G = 13, /* 2X100G EVBS SDIE Card */
- BOARD_TYPE_TEST_EVB1_2X400G = 14, /* 2X400G EVB1 Card */
- BOARD_TYPE_TEST_EVB2_1X800G = 15, /* 1X800G EVB2 Card */
- BOARD_TYPE_TEST_EVB3_2X200G_4x50G = 16, /* 2X200G_4X50G EVB3 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0, /**< Default config */
+ BOARD_TYPE_TEST_EVB_4X25G = 1, /**< EVB Board */
+ BOARD_TYPE_TEST_CEM_2X100G = 2, /**< 2X100G CEM Card */
+ BOARD_TYPE_TEST_EVB1_DDIE_2X200G = 3, /**< 2X200G EVB1 DDIE Card */
+ BOARD_TYPE_TEST_EVB1_SMDIE_1X200G = 4, /**< 1X200G EVB1 SMDIE Card */
+ BOARD_TYPE_TEST_EVB1_SSDIE_1X200G = 5, /**< 1X200G EVB1 SSDIE Card */
+ BOARD_TYPE_TEST_EVB2_DDIE_4X100G = 6, /**< 4X100G EVB2 DDIE Card */
+ BOARD_TYPE_TEST_EVB2_SMDIE_2X100G = 7, /**< 2X100G EVB2 SMDIE Card */
+ BOARD_TYPE_TEST_EVB2_SSDIE_2X100G = 8, /**< 2X100G EVB2 SSDIE Card */
+ BOARD_TYPE_TEST_EVB3_DDIE_4X25G = 9, /**< 4X25G EVB3 DDIE Card */
+ BOARD_TYPE_TEST_EVB3_SMDIE_2X25G = 10, /**< 2X25G EVB3 SMDIE Card */
+ BOARD_TYPE_TEST_EVB3_SSDIE_2X25G = 11, /**< 2X25G EVB3 SSDIE Card */
+ BOARD_TYPE_TEST_EVBS_SDIE_4X25G = 12, /**< 4X25G EVBS SDIE Card */
+ BOARD_TYPE_TEST_EVBS_SDIE_2X100G = 13, /**< 2X100G EVBS SDIE Card */
+ BOARD_TYPE_TEST_EVB1_2X400G = 14, /**< 2X400G EVB1 Card */
+ BOARD_TYPE_TEST_EVB2_1X800G = 15, /**< 1X800G EVB2 Card */
+ BOARD_TYPE_TEST_EVB3_2X200G_4x50G = 16, /**< 2X200G_4X50G EVB3 Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container
- * switch Card
- */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage
- * Onboard Card
- */
- BOARD_TYPE_STRG_SMARTIO_4X25G_OVS = 37, /* 4x25GE SmartIO OVS Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_2X100G_OVS = 43, /* 2x100GE SmartIO OVS Card */
- BOARD_TYPE_STRG_2X100G_TIOE_ATLANTIC = 44, /* 2X100GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_4X25G_TIOE_ATLANTIC = 45, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_TIOE_SMARTNIC = 46, /* 2X100GE ETH Standard Card TIOE */
- BOARD_TYPE_STRG_2X25G_TIOE_SMARTNIC = 47, /* 2X25GE ETH Standard Card TIOE */
- BOARD_TYPE_STRG_2X25G_OVS_SMARTNIC = 48, /* 2x25GE ETH Standard Card OVS */
- BOARD_TYPE_STRG_2X100G_ROCE_SMARTNIC = 49, /* 2X100GE ETH Standard Card ROCE */
- BOARD_TYPE_STRG_SMARTIO_2X25G_COMPUTE = 50, /* 2x25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X200G_ROCE_ATLANTIC = 51, /* 2X200G SmartIO ROCE Card */
- BOARD_TYPE_STRG_4X25G_OVS_LITE = 52, /* 4x25GE SmartIO OVS LITE Card */
- BOARD_TYPE_STRG_2X200G_ROCE = 53, /* 2X200G SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X64G_FC = 54, /* 4X64G FC SmartIO Card */
- BOARD_TYPE_STRG_2X100G_ROCE_SRIOV = 55, /* 2X100GE SmartIO Front Container Card */
- BOARD_TYPE_STRG_2X100G_ROCE_SRIOV_SW = 56, /* 2X100GE SmartIO Loopback Container Card */
- BOARD_TYPE_STRG_2X200G_ROCE_SRIOV = 57, /* 2X200GE SmartIO Front Container Card */
- BOARD_TYPE_STRG_2X200G_ROCE_SRIOV_SW = 58, /* 2X200GE SmartIO Loopback Container Card */
- BOARD_TYPE_STRG_2X200G_TIOE = 59, /* 2X200G SmartIO TIOE Card */
- BOARD_TYPE_STRG_DPU_A_SECURE = 60, /* Storage Security Card DPU-A */
- BOARD_TYPE_STRG_2X25G_DPU_A_FUNCTION = 61, /* 2X25G Storage Function Card DPU-A */
- BOARD_TYPE_STRG_2X25G_DPU_TIOE = 62, /* 2X25G DPU Card TIOE */
- BOARD_TYPE_STRG_2X200G_DPU_ROCE = 63, /* 2X200G DPU Card ROCE */
- BOARD_TYPE_STRG_4X25G_ROCE_SRIOV = 76, /* 4X25GE SmartIO Front Container Card */
- BOARD_TYPE_STRG_2X200G_ROCE_AA = 77, /* 2X200G SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_8X25G_TIOE = 78, /* 8X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X200G_OVS_LITE = 79, /* 2x200GE SmartIO OVS LITE Card */
- BOARD_TYPE_STRG_2X25G_ROCE_SMARTNIC = 80, /* 2X25GE ETH Standard Card ROCE */
- BOARD_TYPE_STRG_2X200G_ROCE_SMARTNIC = 81, /* 2X200GE ETH Standard Card ROCE */
- BOARD_TYPE_STRG_2X200G_TIOE_SMARTNIC = 82, /* 2X200GE ETH Standard Card TIOE */
- BOARD_TYPE_STRG_2X100G_OVS_SMARTNIC = 83, /* 2x100GE ETH Standard Card OVS */
- BOARD_TYPE_STRG_2X100G_ROCE_SMARTNIC_LIFT = 84, /* 2X100GE ETH Standard Card ROCE */
- BOARD_TYPE_STRG_2X100G_TIOE_SMARTNIC_LIFT = 85, /* 2X100GE ETH Standard Card TIOE */
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /**< 4X32G SmartIO FC Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE =
+ 31, /**< 4X25GE SmartIO TIOE Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE =
+ 32, /**< 4X25GE SmartIO ROCE Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA =
+ 33, /**< 4X25GE SmartIO ROCE_AA Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV =
+ 34, /**< 4X25GE SmartIO container Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW =
+ 35, /**< 4X25GE SmartIO container switch Card */
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE =
+ 36, /**< 4X25GE compute storage Onboard Card */
+ BOARD_TYPE_STRG_SMARTIO_4X25G_OVS = 37, /**< 4x25GE SmartIO卡OVS */
+ BOARD_TYPE_STRG_2X100G_TIOE = 40, /**< 2X100G SmartIO TIOE Card */
+ BOARD_TYPE_STRG_2X100G_ROCE = 41, /**< 2X100G SmartIO ROCE Card */
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /**< 2X100G SmartIO ROCE_AA Card */
+ BOARD_TYPE_STRG_2X100G_OVS = 43, /**< 2x100GE SmartIO卡OVS */
+ BOARD_TYPE_STRG_2X100G_TIOE_ATLANTIC = 44, /**< 2X100GE SmartIO卡TIOE */
+ BOARD_TYPE_STRG_4X25G_TIOE_ATLANTIC = 45, /**< 4X25GE SmartIO卡TIOE */
+ BOARD_TYPE_STRG_2X100G_TIOE_SMARTNIC = 46, /**< 2X100GE ETH标卡TIOE */
+ BOARD_TYPE_STRG_2X25G_TIOE_SMARTNIC = 47, /**< 2X25GE ETH标卡TIOE */
+ BOARD_TYPE_STRG_2X25G_OVS_SMARTNIC = 48, /**< 2x25GE ETH标卡OVS */
+ BOARD_TYPE_STRG_2X100G_ROCE_SMARTNIC = 49, /**< 2X100GE ETH标卡ROCE */
+ BOARD_TYPE_STRG_SMARTIO_2X25G_COMPUTE = 50, /**< 2x25GE SmartIO卡ROCE */
+ BOARD_TYPE_STRG_2X200G_ROCE_ATLANTIC = 51, /**< 2X200G SmartIO卡ROCE */
+ BOARD_TYPE_STRG_4X25G_OVS_LITE = 52, /**< 4x25GE SmartIO卡OVS LITE */
+ BOARD_TYPE_STRG_2X200G_ROCE = 53, /**< 2X200G SmartIO卡ROCE */
+ BOARD_TYPE_STRG_SMARTIO_4X64G_FC = 54, /**< 4X64G FC SmartIO卡 */
+ BOARD_TYPE_STRG_2X100G_ROCE_SRIOV =
+ 55, /**< 2X100GE SmartIO卡前端容器卡 */
+ BOARD_TYPE_STRG_2X100G_ROCE_SRIOV_SW =
+ 56, /**< 2X100GE SmartIO卡环回容器卡 */
+ BOARD_TYPE_STRG_2X200G_ROCE_SRIOV =
+ 57, /**< 2X200GE SmartIO卡前端容器卡 */
+ BOARD_TYPE_STRG_2X200G_ROCE_SRIOV_SW =
+ 58, /**< 2X200GE SmartIO卡环回容器卡 */
+ BOARD_TYPE_STRG_2X200G_TIOE = 59, /**< 2X200G SmartIO卡TIOE */
+ BOARD_TYPE_STRG_DPU_A_SECURE = 60, /**< 存储安全卡DPU-A */
+ BOARD_TYPE_STRG_2X25G_DPU_A_FUNCTION = 61, /**< 2X25G存储功能卡DPU-A */
+ BOARD_TYPE_STRG_2X25G_DPU_TIOE = 62, /**< 2X25G DPU卡TIOE */
+ BOARD_TYPE_STRG_2X200G_DPU_ROCE = 63, /**< 2X200G DPU卡ROCE */
+ BOARD_TYPE_STRG_4X25G_ROCE_SRIOV =
+ 76, /**< 4X25GE SmartIO卡前端容器卡 */
+ BOARD_TYPE_STRG_2X200G_ROCE_AA = 77, /**< 2X200G SmartIO卡ROCE_AA */
+ BOARD_TYPE_STRG_8X25G_TIOE = 78, /**< 8X25GE SmartIO卡TIOE */
+ BOARD_TYPE_STRG_2X200G_OVS_LITE = 79, /**< 2x200GE SmartIO卡OVS LITE */
+ BOARD_TYPE_STRG_2X25G_ROCE_SMARTNIC = 80, /**< 2X25GE ETH标卡ROCE */
+ BOARD_TYPE_STRG_2X200G_ROCE_SMARTNIC = 81, /**< 2X200GE ETH标卡ROCE */
+ BOARD_TYPE_STRG_2X200G_TIOE_SMARTNIC = 82, /**< 2X200GE ETH标卡TIOE */
+ BOARD_TYPE_STRG_2X100G_OVS_SMARTNIC = 83, /**< 2x100GE ETH标卡OVS */
+ BOARD_TYPE_STRG_2X100G_ROCE_SMARTNIC_LIFT =
+ 84, /**< 2X100GE ETH标卡ROCE */
+ BOARD_TYPE_STRG_2X100G_TIOE_SMARTNIC_LIFT =
+ 85, /**< 2X100GE ETH标卡TIOE */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2X100G DPU card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage
- * Onboard Card
- */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_2X100G_TCE = 117, /* 2X100G TCE Onboard Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_SMARTNIC = 119, /* 4X25G SmartIO Card */
- BOARD_TYPE_CAL_2X100G_SMARTNIC = 120, /* 2X100G SmartIO Card */
- BOARD_TYPE_CAL_6X25G_DPU = 121, /* 6X25G DPU */
- BOARD_TYPE_CAL_4X25G_DPU_BD = 122, /* 4*25G DPU Big Data Card */
- BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123, /* 2*25GE TianGong 4HOST Standard Card */
- BOARD_TYPE_CAL_2X200G_NIC_120MPPS = 124, /* 2X200G ETH Standard Card 120MPPS */
- BOARD_TYPE_CAL_2X10G_NIC_LOW = 125, /* 2X10G ETH Standard Card Low Power */
- BOARD_TYPE_CAL_2X200G_SMARTNIC = 126, /* 2*200G SmartIO Card */
- BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127, /* 2*200G Internet Card */
- BOARD_TYPE_CAL_2X100G_NIC_INTERNET = 128, /* 2*100G Internet Card */
- BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1*100GR2 DSFP56 Interface OCP Card */
- BOARD_TYPE_CAL_2X200G_DPU = 130, /* 2X200G DPU Card */
- BOARD_TYPE_CAL_2X100_OCP = 131, /* 2*100G DSFP56/QSFP56 Interface OCP Card */
- /* 2*400G UBC 1*8 chip half-width card / 2*8 chip half-width large card */
- BOARD_TYPE_CAL_2X400G_POD = 132,
- BOARD_TYPE_CAL_2X400G_UB_EXP = 133, /* 2*400G A5 Server Card */
- BOARD_TYPE_CAL_2X200G_V2 = 134, /* 2*200G PCIE Standard Card */
- BOARD_TYPE_CAL_1X400G = 135, /* 1X400G PCIE Standard Card */
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS =
+ 100, /**< 2X25G ETH Standard card 75MPPS */
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS =
+ 101, /**< 2X25G ETH Standard card 40MPPS */
+ BOARD_TYPE_CAL_2X100G_DPU = 102, /**< 2X100G DPU card */
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS =
+ 105, /**< 4X25G ETH Standard card 120MPPS */
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE =
+ 106, /**< 4X25GE compute storage Onboard Card */
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /**< 2X32G FC HBA card */
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /**< 2X16G FC HBA card */
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS =
+ 115, /**< 2X100G ETH Standard card 120MPPS */
+ BOARD_TYPE_CAL_2X25G_DPU = 116, /**< 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE = 117, /**< 2X100G TCE板载卡 */
+ BOARD_TYPE_CAL_4X25G_DPU = 118, /**< 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC = 119, /**< 4X25G SmartIO卡 */
+ BOARD_TYPE_CAL_2X100G_SMARTNIC = 120, /**< 2X100G SmartIO卡 */
+ BOARD_TYPE_CAL_6X25G_DPU = 121, /**< 6X25G DPU */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122, /**< 4*25G DPU大数据卡 */
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123, /**< 2*25GE天工4HOST标卡 */
+ BOARD_TYPE_CAL_2X200G_NIC_120MPPS = 124, /**< 2X200G ETH标卡 120MPPS */
+ BOARD_TYPE_CAL_2X10G_NIC_LOW = 125, /**< 2X10G ETH标卡低功耗 */
+ BOARD_TYPE_CAL_2X200G_SMARTNIC = 126, /**< 2*200G SmartIO卡 */
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127, /**< 2*200G 互联网卡 */
+ BOARD_TYPE_CAL_2X100G_NIC_INTERNET = 128, /**< 2*100G 互联网卡 */
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /**< 1*100GR2 DSFP56接口OCP卡 */
+ BOARD_TYPE_CAL_2X200G_DPU = 130, /**< 2X200G DPU卡 */
+ BOARD_TYPE_CAL_2X100_OCP = 131, /**< 2*100G DSFP56/QSFP56接口OCP卡 */
+ BOARD_TYPE_CAL_2X400G_POD =
+ 132, /**< 2*400G UBC 1*8芯片半宽卡/2*8芯片半宽大卡 */
+ BOARD_TYPE_CAL_2X400G_UB_EXP = 133, /**< 2*400G A5 Sever卡 */
+ BOARD_TYPE_CAL_2X200G_V2 = 134, /**< 2*200G PCIE标卡 */
+ BOARD_TYPE_CAL_1X400G = 135, /**< 1X400G PCIE标卡 */
- BOARD_TYPE_CAL_SP23X_2X10G = 136, /* 1872 2*10G PCIE Standard Card */
- BOARD_TYPE_CAL_SP23X_2X25G = 137, /* 1872 2*25G PCIE Standard Card */
- BOARD_TYPE_CAL_SP23X_2X100G = 138, /* 1872 2*100G PCIE Standard Card */
- BOARD_TYPE_CAL_SP23X_2X100G_OCP = 139, /* 1872 2*100G OCP Card */
- BOARD_TYPE_CAL_SP23X_1X200G = 140, /* 1872 1*200G PCIE Standard Card */
+ BOARD_TYPE_CAL_SP23X_2X10G = 136, /**< 1872 2*10G PCIE标卡 */
+ BOARD_TYPE_CAL_SP23X_2X25G = 137, /**< 1872 2*25G PCIE标卡 */
+ BOARD_TYPE_CAL_SP23X_2X100G = 138, /**< 1872 2*100G PCIE标卡 */
+ BOARD_TYPE_CAL_SP23X_2X100G_OCP = 139, /**< 1872 2*100G OCP卡 */
+ BOARD_TYPE_CAL_SP23X_1X200G = 140, /**< 1872 1*200G PCIE标卡 */
- BOARD_TYPE_CAL_2X400G_UBX_BOARD = 141, /* 1825 2*400G UBX BOARD */
- BOARD_TYPE_CAL_2X400G_UB_EXP_V1 = 142, /* 1825 2*400G UB EXP Custom Card */
+ BOARD_TYPE_CAL_2X400G_UBX_BOARD = 141, /**< 1825 2*400G UBX BOARD */
+ BOARD_TYPE_CAL_2X400G_UB_EXP_V1 = 142, /**< 1825 2*400G UB EXP定制卡 */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
- BOARD_TYPE_CLD_2X200G_SDI6_0 = 173, /* 2x200G SDI6.0 Card */
- BOARD_TYPE_CLD_2X200G_UNIC = 174, /* 2x200G UNIC Card */
- BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175, /* 4*25G SDI5.0.C Card */
- BOARD_TYPE_CLD_2X200G_SDI6_1 = 176, /* 2x200G SDI6.1 Card */
- BOARD_TYPE_CLD_2X400G_SDI_BOX = 177, /* 2*400G Cloud Intelligence SDI-BOX Card */
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /**< 2X100G SDI 5.1 Card */
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /**< 2x25G SDI5.0 Lite Card */
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /**< 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_2X200G_SDI6_0 = 173, /**< 2x200G SDI6.0 Card */
+ BOARD_TYPE_CLD_2X200G_UNIC = 174, /**< 2x200G UNIC Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175, /**< 4*25G SDI5.0.C卡 */
+ BOARD_TYPE_CLD_2X200G_SDI6_1 = 176, /**< 2x200G SDI6.1卡 */
+ BOARD_TYPE_CLD_2X400G_SDI_BOX = 177, /**< 2*400G 云智算SDI-BOX卡 */
- BOARD_TYPE_MAX_INDEX = 0xFF, /* Maximum card value */
+ BOARD_TYPE_MAX_INDEX = 0xFF, /**< 卡的最大值 */
} board_type_define_e;
-#define IS_EVB_BOARD_TYPE(type) \
- ((type) < BOARD_TYPE_STRG_SMARTIO_4X32G_FC) /**< 4*25G SDI5.0.C Card */
+#define IS_EVB_BOARD_TYPE(type) \
+ ((type) < BOARD_TYPE_STRG_SMARTIO_4X32G_FC) /**< 4*25G SDI5.0.C卡 */
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_cmd_base_defs.h
index 874b78763..06bee8040 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_cmd_base_defs.h
@@ -1,10 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mpu_cmd_base_defs.h
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_cmd_base_defs.h
* Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Creation time : 2023/09/22
+ * Last Modified :
* Description : MPU common definitions
*/
#ifndef MPU_CMD_BASE_DEFS_H
@@ -13,79 +12,98 @@
#include "base_type.h"
typedef enum {
- RES_TYPE_FLUSH_BIT = 0, /* flush function reset flag bit */
- RES_TYPE_MQM, /* mqm function reset flag bit */
- RES_TYPE_SMF, /* smf function reset flag bit */
- RES_TYPE_PF_BW_CFG, /* bandwidth configuration function reset flag bit */
-
- RES_TYPE_COMM = 10, /* common function reset flag bit */
- RES_TYPE_COMM_MGMT_CH, /* bandwidth configuration function reset flag bit,
- * clear mbox and aeq, The RES_TYPE_COMM bit must be set
- */
- RES_TYPE_COMM_CMD_CH, /* bandwidth configuration function reset flag bit,
- * clear cmdq and ceq, The RES_TYPE_COMM bit must be set
- */
- RES_TYPE_NIC, /* nic function reset flag bit */
- RES_TYPE_OVS, /* ovs function reset flag bit */
- RES_TYPE_VBS, /* vbs function reset flag bit */
- RES_TYPE_ROCE, /* roce function reset flag bit */
- RES_TYPE_FC, /* fc function reset flag bit */
- RES_TYPE_TOE, /* toe function reset flag bit */
- RES_TYPE_IPSEC, /* ipsec function reset flag bit */
- RES_TYPE_SMF_CACHE_INVALID, /* smf cache invalid function reset flag bit */
- RES_TYPE_MAX, /* maximum function reset flag bit value */
-} func_reset_flag_e; /* function reset flag, used to indicate which resource to clear */
-
-#define DEVICE_TYPE_L2NIC 0 /* L2NIC device */
-#define DEVICE_TYPE_NVME 1 /* nvme device */
-#define DEVICE_TYPE_VIRTIO_NET 2 /* virtio net device */
-#define DEVICE_TYPE_VIRTIO_BLK 3 /* virtio blk device */
-#define DEVICE_TYPE_VIRTIO_VSOCK 4 /* virtio vsock device */
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5 /* virtio net transition device */
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6 /* virtio blk transition device */
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7 /* virtio scsi transition device */
-#define DEVICE_TYPE_VIRTIO_HPC 8 /* virtio nhpc device */
-#define DEVICE_TYPE_VIRTIO_FS 9 /* virtio fs device */
+ RES_TYPE_FLUSH_BIT = 0, /**< flush的function reset标志位 */
+ RES_TYPE_MQM, /**< mqm的function reset标志位 */
+ RES_TYPE_SMF, /**< smf的function reset标志位 */
+ RES_TYPE_PF_BW_CFG, /**< bw 配置的function reset标志位 */
+
+ RES_TYPE_COMM = 10, /**< 公共的function reset标志位 */
+ RES_TYPE_COMM_MGMT_CH, /**< bw 配置的function reset标志位, clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /**< bw 配置的function reset标志位, clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC, /**< nic的function reset标志位 */
+ RES_TYPE_OVS, /**< ovs的function reset标志位 */
+ RES_TYPE_VBS, /**< vbsfunction reset标志位 */
+ RES_TYPE_ROCE, /**< roce的function reset标志位 */
+ RES_TYPE_FC, /**< fc的function reset标志位 */
+ RES_TYPE_TOE, /**< toe的function reset标志位 */
+ RES_TYPE_IPSEC, /**< ipsec的function reset标志位 */
+ RES_TYPE_SMF_CACHE_INVALID, /**< smf cache 无效的function reset标志位 */
+ RES_TYPE_MAX, /**<function reset标志位的最大值 */
+} func_reset_flag_e; /**< func reset的flag ,用于指示清理哪种资源 */
+
+typedef enum {
+ /* 基础设备一共预留预留16个 */
+ DEVICE_TYPE_L2NIC = 0, /**< L2NIC 设备 */
+ DEVICE_TYPE_TOE = 1, /**< TOE 设备 */
+ DEVICE_TYPE_ROCE = 2, /**< ROCE 设备 */
+ DEVICE_TYPE_UBOE = 3, /**< UBoE 设备 */
+
+ /* NVME/virtio设备占用18个: 1个HPC+1个NVME+16个VirtIO */
+ DEVICE_TYPE_VIO_HPC = 16, /**< 标准IO 热插拔控制设备 */
+ DEVICE_TYPE_NVME = 17, /**< nvme 设备 */
+ DEVICE_TYPE_VIRTIO_NET = 18, /**< virtio net 设备 */
+ DEVICE_TYPE_VIRTIO_BLK = 19, /**< virtio blk 设备 */
+ DEVICE_TYPE_VIRTIO_SCSI = 20, /**< virtio scsi 设备 */
+ DEVICE_TYPE_VIRTIO_VSOCK = 21, /**< virtio vsock 设备 */
+ DEVICE_TYPE_VIRTIO_FS = 22, /**< virtio fs 设备 */
+
+ /* 数控分离场景定义从64开始 */
+ DEVICE_TYPE_ROCE_NDAFE = 64, /**< NDA场景 ROCE 设备 */
+ DEVICE_TYPE_UBOE_NDAFE = 65, /**< NDA场景 UBoE 设备 */
+ DEVICE_TYPE_DATAFE = 66, /**< NDR场景 datafe 设备 */
+ DEVICE_TYPE_HEARTFE = 67, /**< 非直通心跳 设备 */
+
+ DEVICE_TYPE_NUM = 255,
+} mpu_device_type_e;
+
+/**
+ * @brief UE设备分段信息结构体
+ * 用于描述具有相同device_type的连续func_id范围
+ */
+typedef struct {
+ u8 segment_type; /* 0:PF 1:VF */
+ u8 segment_sub_type; /* 设备类型,对应mpu_device_type_e */
+ u16 glb_func_start; /* 该segment的func_id起始值(包含) */
+ u16 glb_func_end; /* 该segment的func_id结束值(不包含) */
+} ubc_dev_ue_info_s;
/**
- * @brief Check if device is virtio net device
- * @param device: device type
+ * @brief 判断是否为virtio net 设备
+ * @param device:device type
* @return true or false
*/
-#define MPU_DEVICE_IS_VIRTIO_NET(device) \
- (((device) == DEVICE_TYPE_VIRTIO_NET) || ((device) == DEVICE_TYPE_VIRTIO_NET_TRANSITION))
+#define MPU_DEVICE_IS_VIRTIO_NET(device) ((device) == DEVICE_TYPE_VIRTIO_NET)
/**
- * @brief Check if device is virtio blk device
- * @param device: device type
+ * @brief 判断是否为virtio blk 设备
+ * @param device:device type
* @return true or false
*/
-#define MPU_DEVICE_IS_VIRTIO_BLK(device) \
- (((device) == DEVICE_TYPE_VIRTIO_BLK) || ((device) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION))
+#define MPU_DEVICE_IS_VIRTIO_BLK(device) ((device) == DEVICE_TYPE_VIRTIO_BLK)
/**
- * @brief Check if device is virtio scsi device
- * @param device: device type
+ * @brief 判断是否为virtio scsi 设备
+ * @param device:device type
* @return true or false
*/
-#define MPU_DEVICE_IS_VIRTIO_SCSI(device) \
- ((device) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
+#define MPU_DEVICE_IS_VIRTIO_SCSI(device) ((device) == DEVICE_TYPE_VIRTIO_SCSI)
/**
- * @brief Check if device is virtio storage device
- * @param device: device type
+ * @brief 判断是否为virtio 存储 设备
+ * @param device:device type
* @return true or false
*/
#define MPU_DEVICE_IS_VIRTIO_STORAGE(device) \
(MPU_DEVICE_IS_VIRTIO_BLK(device) || MPU_DEVICE_IS_VIRTIO_SCSI(device))
/**
- * @brief Check if device is virtio device
- * @param device: device type
+ * @brief 判断是否为virtio 设备
+ * @param device:device type
* @return true or false
*/
-#define MPU_DEVICE_IS_VIRTIO(device) \
- (MPU_DEVICE_IS_VIRTIO_NET(device) || MPU_DEVICE_IS_VIRTIO_BLK(device) || \
+#define MPU_DEVICE_IS_VIRTIO(device) \
+ (MPU_DEVICE_IS_VIRTIO_NET(device) || \
+ MPU_DEVICE_IS_VIRTIO_BLK(device) || \
MPU_DEVICE_IS_VIRTIO_SCSI(device))
enum hinic5_svc_type {
@@ -104,43 +122,44 @@ enum hinic5_svc_type {
SVC_T_MAX,
};
-#define MGMT_MSG_CMD_OP_SET 1 /* Set command */
-#define MGMT_MSG_CMD_OP_GET 0 /* Get command */
-#define MGMT_MSG_CMD_OP_START 1 /* Start command */
-#define MGMT_MSG_CMD_OP_STOP 0 /* Stop command */
+#define MGMT_MSG_CMD_OP_SET 1 /**< 设置命令 */
+#define MGMT_MSG_CMD_OP_GET 0 /**< 获取命令 */
+#define MGMT_MSG_CMD_OP_START 1 /**< 开始命令 */
+#define MGMT_MSG_CMD_OP_STOP 0 /**< 停止命令 */
-/* Get die id, input parameter is mgmt_msg_head structure */
-#define MGMT_GET_DIE_ID(msg_head) \
- (((msg_head)->die_id_valid != 0) ? (msg_head)->die_id : 0)
+#define MGMT_GET_DIE_ID(msg_head) \
+ (((msg_head)->die_id_valid != 0) ? \
+ (msg_head)->die_id : \
+ 0) /**< 获取die id,入参为mgmt_msg_head结构体 */
struct mgmt_msg_head {
- u8 status; /* Response message return value */
- u8 version; /* Message version number */
- u8 rep_aeq_num; /* response aeq number, unused for now */
- u8 rsvd0; /* Reserved field */
- u8 die_id_valid : 1; /* Dual die selection valid bit (tool command selects primary/secondary die) */
- u8 die_id : 1; /* When die_id_valid is valid: die_id:0, primary die; die_id:1, secondary die */
- u8 rsvd1 : 6; /* Reserved field */
- u8 rsvd2[3]; /* Reserved field */
+ u8 status; /**< 响应消息的返回值 */
+ u8 version; /**< 消息的版本号 */
+ u8 rep_aeq_num; /**< response aeq number, unused for now */
+ u8 rsvd0; /**< 保留字段 */
+ u8 die_id_valid : 1; /**< 双die选择有效位(工具命令选择主/从die) */
+ u8 die_id : 1; /**< die_id_valid有效的前提下,die_id:0, 主die die_id:1, 从die */
+ u8 rsvd1 : 6; /**< 保留字段 */
+ u8 rsvd2[3]; /**< 保留字段 */
};
enum hinic5_fw_ver_type {
- HINIC5_FW_VER_TYPE_BOOT, /* BOOT firmware */
- HINIC5_FW_VER_TYPE_MPU, /* MPU firmware */
- HINIC5_FW_VER_TYPE_NPU, /* NPU firmware */
- HINIC5_FW_VER_TYPE_SMU_L0, /* SMU L0 firmware */
- HINIC5_FW_VER_TYPE_SMU_L1, /* SMU L1 firmware */
- HINIC5_FW_VER_TYPE_CFG, /* SMU configuration firmware */
- HINIC5_FW_VER_TYPE_PLATFORM, /* Basic platform */
- HINIC5_FW_VER_TYPE_ROCE_SCC, /* roce scc firmware */
- HINIC5_FW_VER_TYPE_ROCE_SCC_CS, /* roce scc customer firmware */
- HINIC5_FW_VER_TYPE_ROCE_IMP, /* roce imp firmware */
- HINIC5_FW_VER_TYPE_UBC_IMP, /* ubc imp firmware */
- HINIC5_FW_VER_TYPE_IMP, /* imp firmware */
- HINIC5_FW_VER_TYPE_PSM, /* PSM firmware */
- HINIC5_FW_VER_TYPE_UBG_IMP, /* ubg imp firmware */
- HINIC5_FW_VER_TYPE_UB_SCC, /* ub scc firmware */
- HINIC5_FW_VER_TYPE_GRAY_NPU = 100, /* Gray card NPU firmware */
+ HINIC5_FW_VER_TYPE_BOOT, /**< BOOT固件 */
+ HINIC5_FW_VER_TYPE_MPU, /**< MPU固件 */
+ HINIC5_FW_VER_TYPE_NPU, /**< NPU固件 */
+ HINIC5_FW_VER_TYPE_SMU_L0, /**< SMU L0固件 */
+ HINIC5_FW_VER_TYPE_SMU_L1, /**< SMU L1固件 */
+ HINIC5_FW_VER_TYPE_CFG, /**< SMU 配置固件 */
+ HINIC5_FW_VER_TYPE_PLATFORM, /**< 基础平台 */
+ HINIC5_FW_VER_TYPE_ROCE_SCC, /**< roce scc固件 */
+ HINIC5_FW_VER_TYPE_ROCE_SCC_CS, /**< roce scc客户固件 */
+ HINIC5_FW_VER_TYPE_ROCE_IMP, /**< roce imp固件 */
+ HINIC5_FW_VER_TYPE_UBC_IMP, /**< ubc imp固件 */
+ HINIC5_FW_VER_TYPE_IMP, /**< imp固件 */
+ HINIC5_FW_VER_TYPE_PSM, /**< PSM固件 */
+ HINIC5_FW_VER_TYPE_UBG_IMP, /**< ubg imp固件 */
+ HINIC5_FW_VER_TYPE_UB_SCC, /**< ub scc固件 */
+ HINIC5_FW_VER_TYPE_GRAY_NPU = 100, /**< 灰卡 NPU固件 */
};
#define PCIE_MODE_PORT_NUM 32
@@ -162,12 +181,12 @@ enum hinic5_fw_ver_type {
#define PCIE_MODE_ALL_PORT_MAP 0x1111
/**
- * @brief enum bus_type_e - Host side bus type
- * @details Used to distinguish different bus types on host side
+ * @brief enum bus_type_e - host侧总线类型
+ * @details 用于区分host侧不同总线类型
*/
typedef enum {
- BUS_TYPE_PCIE = 0, /**< pcie bus */
- BUS_TYPE_UBC = 1, /**< ubc bus */
+ BUS_TYPE_PCIE = 0, /**< pcie总线 */
+ BUS_TYPE_UBC = 1, /**< ubc总线 */
} bus_type_e;
#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd.h
index ae49db1ee..b020c37ba 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd.h
@@ -1,10 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mpu_inband_cmd.h
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_inband_cmd.h
* Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Creation time : 2023/09/22
+ * Last Modified :
* Description : In-band commands between the driver and the MPU
*/
@@ -13,115 +12,117 @@
/**< COMM Commands between Driver to MPU */
enum hinic5_mgmt_cmd {
- /**< FLR and resource cleanup related commands */
- COMM_MGMT_CMD_FUNC_RESET = 0, /**< Driver load/unload function reset resource cleanup */
- COMM_MGMT_CMD_FEATURE_NEGO, /**< FW and driver compatibility attribute negotiation */
- COMM_MGMT_CMD_FLUSH_DOORBELL, /**< Driver unload flush process, resource cleanup */
- COMM_MGMT_CMD_START_FLUSH, /**< Driver load/unload flush handshake */
- COMM_MGMT_CMD_SET_FUNC_FLR, /**< Driver actively triggers FLR through mbox process */
- COMM_MGMT_CMD_GET_GLOBAL_ATTR, /**< Get SM global table */
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE, /**< Set PPF FLR execution range */
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE, /**< Set whether corresponding function driver is loaded/used */
- COMM_MGMT_CMD_GET_FUNC_FLR_INFO, /**< Get FLR execution DFX information */
-
- /**< Driver interrupt resources */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10, /**< Get driver MSIX interrupt information */
-
- /**< Driver related configuration commands */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20, /**< Set CMDQ context */
- COMM_MGMT_CMD_SET_VAT, /**< Set VAT table */
- COMM_MGMT_CMD_CFG_PAGESIZE, /**< Configure root context page size */
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG, /**< Configure interrupt MSIX */
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG, /**< Configure CEQ */
- COMM_MGMT_CMD_SET_DMA_ATTR, /**< Configure driver DMA attributes */
- COMM_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT, /**< Configure enhanced CMDQ */
- COMM_MGMT_CMD_GET_FUNC_SECURE_MEM, /**< Get secure memory identifier */
- COMM_MGMT_CMD_SET_FUNC_PLUG_SRV, /**< Set hotplug BMP */
- COMM_MGMT_CMD_GET_FUNC_PLUG_SRV, /**< Get hotplug BMP */
- COMM_MGMT_CMD_SET_PPF_TBL_HTR_FLG, /**< Set hot-replacement identifier */
- COMM_MGMT_CMD_GET_FAST_MSG_CAP, /**< Get fast message capability */
- COMM_MGMT_CMD_SET_FAST_MSG_RQ_ADDR, /**< Set fast message address */
- COMM_MGMT_CMD_CLEAR_FAST_MSG_SML, /**< Clear fast message table entry */
-
- /**< INFRA configuration related command codes */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40, /**< MQM get chunk num */
- COMM_MGMT_CMD_SET_MQM_CFG_INFO, /**< Receive PPF and page_size from driver */
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA, /**< Receive search GPA address from driver */
- COMM_MGMT_CMD_SET_PPF_TMR, /**< Configure SMF timer */
- COMM_MGMT_CMD_SET_HT_GPA, /**< Set HT GPA (bank GPA) address */
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT, /**< Enable SMF timer */
- COMM_MGMT_CMD_SET_MBX_CRDT, /**< Set mailbox credit, for DFX performance tuning */
- COMM_MGMT_CMD_CFG_TEMPLATE, /**< Set/get temperature alarm threshold */
- COMM_MGMT_CMD_SET_MQM_LIMIT, /**< Set/get MQM rate limit configuration, used by 1823V100 Pangua driver */
- COMM_MGMT_CMD_SET_BAT_INFO, /**< Set BAT information */
- COMM_MGMT_CMD_SET_VIO_EN, /**< Set CPI MSI enable*/
- COMM_MGMT_CMD_CFG_DATA, /**< Configure function related parameters in template */
-
- /**< Information retrieval related command codes */
- COMM_MGMT_CMD_GET_FW_VERSION = 60, /**< Get FW version information */
- COMM_MGMT_CMD_GET_BOARD_INFO, /**< Get board information */
- COMM_MGMT_CMD_SYNC_TIME, /**< Sync driver timestamp */
- COMM_MGMT_CMD_GET_HW_PF_INFOS, /**< Get hardware PF information */
- COMM_MGMT_CMD_SEND_BDF_INFO, /**< Receive DBF information obtained by driver */
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO, /**< Get DBF information in virtio scenario */
- COMM_MGMT_CMD_GET_SML_TABLE_INFO, /**< Get SMLB table entry information */
- COMM_MGMT_CMD_GET_SDI_INFO, /**< Get SDI information (bare metal/VM) */
- COMM_MGMT_CMD_ROOT_CTX_LOAD, /**< Get root context information */
+ /**< flr及资源清理相关命令 */
+ COMM_MGMT_CMD_FUNC_RESET = 0, /**< 驱动加卸载function reset清理资源 */
+ COMM_MGMT_CMD_FEATURE_NEGO, /**< fw与驱动兼容性属性协商 */
+ COMM_MGMT_CMD_FLUSH_DOORBELL, /**< 驱动卸载flush流程,清理资源 */
+ COMM_MGMT_CMD_START_FLUSH, /**< 驱动加卸载flush握手 */
+ COMM_MGMT_CMD_SET_FUNC_FLR, /**< 驱动主动通过mbox流程触发flr */
+ COMM_MGMT_CMD_GET_GLOBAL_ATTR, /**< 获取sm全局表 */
+ COMM_MGMT_CMD_SET_PPF_FLR_TYPE, /**< 设置ppf flr执行范围 */
+ COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE, /**< 设置对应function驱动是否加载/使用 */
+ COMM_MGMT_CMD_GET_FUNC_FLR_INFO, /**< 获取flr执行dfx信息 */
+
+ /**< 驱动中断资源 */
+ COMM_MGMT_CMD_CFG_MSIX_NUM = 10, /**< 获取驱动msix中断信息 */
+
+ /**< 驱动相关配置命令 */
+ COMM_MGMT_CMD_SET_CMDQ_CTXT = 20, /**< 设置cmdq cxt */
+ COMM_MGMT_CMD_SET_VAT, /**< 设置vat表 */
+ COMM_MGMT_CMD_CFG_PAGESIZE, /**< 配置root cxt 页面大小 */
+ COMM_MGMT_CMD_CFG_MSIX_CTRL_REG, /**< 配置中断msix */
+ COMM_MGMT_CMD_SET_CEQ_CTRL_REG, /**< 配置ceq */
+ COMM_MGMT_CMD_SET_DMA_ATTR, /**< 配置驱动dma属性 */
+ COMM_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT, /**< 配置增强型cmdq */
+ COMM_MGMT_CMD_GET_FUNC_SECURE_MEM, /**< 获取安全内存标识 */
+ COMM_MGMT_CMD_SET_FUNC_PLUG_SRV, /**< 设置热拔插bmp */
+ COMM_MGMT_CMD_GET_FUNC_PLUG_SRV, /**< 获取热拔插bmp */
+ COMM_MGMT_CMD_SET_PPF_TBL_HTR_FLG, /**< 设置热替换标识 */
+ COMM_MGMT_CMD_GET_FAST_MSG_CAP, /**< 获取fast msg能力 */
+ COMM_MGMT_CMD_SET_FAST_MSG_RQ_ADDR, /**< 设置fast msg地址 */
+ COMM_MGMT_CMD_CLEAR_FAST_MSG_SML, /**< 清除fast msg表项 */
+
+ /**< INFRA配置相关命令字 */
+ COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40, /**< mqm获取chunk num */
+ COMM_MGMT_CMD_SET_MQM_CFG_INFO, /**< 从驱动接收ppf和page_size */
+ COMM_MGMT_CMD_SET_MQM_SRCH_GPA, /**< 从驱动接收search gpa地址 */
+ COMM_MGMT_CMD_SET_PPF_TMR, /**< 配置smf timer */
+ COMM_MGMT_CMD_SET_HT_GPA, /**< 设置 ht gpa (bank gpa) 地址 */
+ COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT, /**< 使能smf timer */
+ COMM_MGMT_CMD_SET_MBX_CRDT, /**< 设置mbox信用,dfx性能调优用 */
+ COMM_MGMT_CMD_CFG_TEMPLATE, /**< 设置/获取温度告警阈值 */
+ COMM_MGMT_CMD_SET_MQM_LIMIT, /**< 设置/获取mqm限速配置,1823V100盘古驱动使用. */
+ COMM_MGMT_CMD_SET_BAT_INFO, /**< 设置bat信息 */
+ COMM_MGMT_CMD_SET_VIO_EN, /**< 设置cpi MSI使能*/
+ COMM_MGMT_CMD_CFG_DATA, /**< 配置模板中的Function相关参数 */
+
+ /**< 信息获取相关命令字 */
+ COMM_MGMT_CMD_GET_FW_VERSION = 60, /**< 获取fw版本信息 */
+ COMM_MGMT_CMD_GET_BOARD_INFO, /**< 获取单板信息 */
+ COMM_MGMT_CMD_SYNC_TIME, /**< 同步驱动时间戳 */
+ COMM_MGMT_CMD_GET_HW_PF_INFOS, /**< 获取硬件pf信息 */
+ COMM_MGMT_CMD_SEND_BDF_INFO, /**< 接收驱动获取到的dbf信息 */
+ COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO, /**< virtio场景获取dbf信息 */
+ COMM_MGMT_CMD_GET_SML_TABLE_INFO, /**< 获取smlb表项信息 */
+ COMM_MGMT_CMD_GET_SDI_INFO, /**< 获取sdI信息(裸机/虚机) */
+ COMM_MGMT_CMD_ROOT_CTX_LOAD, /**< 获取root cxt信息 */
COMM_MGMT_CMD_GET_HW_BOND = 69, /* 1823V100 */
COMM_MGMT_CMD_MPU_AND_NPU_VER = 70, /* 1823V100 */
COMM_MGMT_CMD_GET_PF_BY_FUNC = 71, /* 1823V100 */
COMM_MGMT_CMD_GET_PF_BUS_BY_DEV = 72, /* 1823V100 */
- /**< Upgrade related command codes */
- COMM_MGMT_CMD_UPDATE_FW = 80, /**< FW upgrade */
- COMM_MGMT_CMD_ACTIVE_FW, /**< FW cold activation */
- COMM_MGMT_CMD_HOT_ACTIVE_FW, /**< FW hot activation */
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE, /**< FW hot activation done (currently unused) */
- COMM_MGMT_CMD_SWITCH_CFG, /**< Configuration file switch (currently unused) */
- COMM_MGMT_CMD_CHECK_FLASH, /**< Storage scenario flash silent detection */
- COMM_MGMT_CMD_CHECK_FLASH_RW, /**< Storage scenario pre-upgrade */
- COMM_MGMT_CMD_RESOURCE_CFG, /**< Original configuration template (currently unused) */
- COMM_MGMT_CMD_UPDATE_BIOS, /**< BIOS upgrade command (deprecated, BIOS upgrade merged with NIC upgrade) */
- COMM_MGMT_CMD_MPU_GIT_CODE, /**< Get version git commit */
- COMM_MGMT_QUERY_MODULE_IMAGES, /**< Image handshake, get firmware information */
- COMM_MGMT_CMD_UPDATE_CUSTOM_FW = 98, /* Upgrade CUSTOM_FW firmware, do not modify this value */
- COMM_MGMT_CMD_ACTIVE_CUSTOM_FW = 99, /* Activate CUSTOM_FW firmware */
-
- /**< Chip reset related */
- COMM_MGMT_CMD_FAULT_REPORT = 100, /**< MPU to driver information, exception alarm */
- COMM_MGMT_CMD_WATCHDOG_INFO, /**< MPU to driver information, watchdog alarm */
- COMM_MGMT_CMD_MGMT_RESET, /**< MPU to driver information, MPU last word */
- COMM_MGMT_CMD_FFM_SET, /**< MPU to driver message, exception interrupt display information */
-
- /**< Chip info/log related */
- COMM_MGMT_CMD_GET_LOG = 120, /**< Get firmware log */
- COMM_MGMT_CMD_TEMP_OP, /**< Get chip temperature */
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP, /**< Enable chip automatic reset following perst */
- COMM_MGMT_CMD_CFG_REG, /**< Configure chip register (currently unused) */
- COMM_MGMT_CMD_GET_CHIP_ID, /**< Get chip ID (multi-chip scenario) */
- COMM_MGMT_CMD_SYSINFO_DFX, /**< Get chip software system DFX information */
- COMM_MGMT_CMD_PCIE_DFX_NTC, /**< Notify driver to collect PCIE DFX information */
- COMM_MGMT_CMD_DICT_LOG_STATUS, /**< Get log collection status */
- COMM_MGMT_CMD_MSIX_INFO, /**< Configure MSIX information */
- COMM_MGMT_CMD_CHANNEL_DETECT, /**< Mailbox channel detection */
- COMM_MGMT_CMD_DICT_COUNTER_STATUS, /**< Get flash counter count */
- COMM_MGMT_CMD_UCODE_SM_COUNTER, /**< Get SM counter count */
+ /**< 升级相关命令字 */
+ COMM_MGMT_CMD_UPDATE_FW = 80, /**< fw升级 */
+ COMM_MGMT_CMD_ACTIVE_FW, /**< fw冷激活 */
+ COMM_MGMT_CMD_HOT_ACTIVE_FW, /**< fw热激活 */
+ COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE, /**< fw热激活完成(当前未使用) */
+ COMM_MGMT_CMD_SWITCH_CFG, /**< 配置文件切换(当前未使用) */
+ COMM_MGMT_CMD_CHECK_FLASH, /**< 存储场景flash静默检测 */
+ COMM_MGMT_CMD_CHECK_FLASH_RW, /**< 存储场景升级前 */
+ COMM_MGMT_CMD_RESOURCE_CFG, /**< 原配置模板(当前未使用) */
+ COMM_MGMT_CMD_UPDATE_BIOS, /**< bios升级命令(已废弃,bios升级和网卡升级合并) */
+ COMM_MGMT_CMD_MPU_GIT_CODE, /**< 获取版本git号 */
+ COMM_MGMT_QUERY_MODULE_IMAGES, /**< 镜像握手,获取固件信息 */
+ COMM_MGMT_CMD_UPDATE_CUSTOM_FW =
+ 98, /* 升级CUSTOM_FW固件,不可修改该值 */
+ COMM_MGMT_CMD_ACTIVE_CUSTOM_FW = 99, /* 激活CUSTOM_FW固件 */
+
+ /**< chip reset相关 */
+ COMM_MGMT_CMD_FAULT_REPORT = 100, /**< mpu发往驱动信息,异常告警 */
+ COMM_MGMT_CMD_WATCHDOG_INFO, /**< mpu发往驱动信息,看门狗告警 */
+ COMM_MGMT_CMD_MGMT_RESET, /**< mpu发往驱动信息,mpu LastWord */
+ COMM_MGMT_CMD_FFM_SET, /**< mpu发往驱动消息,异常中断显示信息 */
+
+ /**< chip info/log 相关 */
+ COMM_MGMT_CMD_GET_LOG = 120, /**< 获取固件log */
+ COMM_MGMT_CMD_TEMP_OP, /**< 获取芯片温度 */
+ COMM_MGMT_CMD_EN_AUTO_RST_CHIP, /**< 使能芯片跟随perst复位自动复位 */
+ COMM_MGMT_CMD_CFG_REG, /**< 配置芯片寄存器(当前未使用) */
+ COMM_MGMT_CMD_GET_CHIP_ID, /**< 获取芯片id(多芯片场景) */
+ COMM_MGMT_CMD_SYSINFO_DFX, /**< 获取芯片软件系统dfx信息 */
+ COMM_MGMT_CMD_PCIE_DFX_NTC, /**< 通知驱动收集pcie dfx信息 */
+ COMM_MGMT_CMD_DICT_LOG_STATUS, /**< 获取log收集状态 */
+ COMM_MGMT_CMD_MSIX_INFO, /**< 配置msix信息 */
+ COMM_MGMT_CMD_CHANNEL_DETECT, /**< mbox通道探测 */
+ COMM_MGMT_CMD_DICT_COUNTER_STATUS, /**< 获取flash counter计数 */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER, /**< 获取sm counter计数 */
COMM_MGMT_CMD_CLEAR_LOG = 132, /* 1823V100 */
COMM_MGMT_CMD_UCODE_SM_COUNTER_PER = 133, /* 1823V100 */
- /**< Switch workmode related */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /**< Configuration switch (multiple configuration files in card, deprecated) */
- COMM_MGMT_CMD_SWITCH_WORKMODE, /**< Switch work mode (deprecated) */
-
- /**< MPU related */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150, /**< Hot migration HPA DFX */
- COMM_MGMT_CMD_BDF_INFO, /**< Get PCIE BDF number */
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC, /**< Get NCSI configuration information */
- COMM_MGMT_CMD_CPI_TCAM_DBG, /**< CPI TCAM information debug (currently unused) */
- COMM_MGMT_CMD_LLDP_TX_FUNC_SET_PROC, /**< LLDP enable */
+ /**< switch workmode 相关 */
+ COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE =
+ 140, /**< 配置切换(卡内多份配置文件,已废弃) */
+ COMM_MGMT_CMD_SWITCH_WORKMODE, /**< 切换工作模式(已废弃) */
+
+ /**< mpu 相关 */
+ COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150, /**< 热迁移hpa dfx */
+ COMM_MGMT_CMD_BDF_INFO, /**< 获取pcie bdf号 */
+ COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC, /**< 获取ncsi配置信息 */
+ COMM_MGMT_CMD_CPI_TCAM_DBG, /**< cpi tcam信息调试(当前暂未使用) */
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET_PROC, /**< lldp使能 */
COMM_MGMT_CMD_FUNC_ENABLE_INFO = 155, /* 1823V100 */
COMM_MGMT_CMD_FUNC_VIRTIO_INFO = 156, /* 1823V100 */
- COMM_MGMT_CMD_NCSI_LOW_POWER_PROC, /* 1872V100 NCSI low power enable */
+ COMM_MGMT_CMD_NCSI_LOW_POWER_PROC, /* 1872V100 NCSI 低功耗使能 */
/**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
@@ -135,67 +136,68 @@ enum hinic5_mgmt_cmd {
/**< rsvd3 section */
COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
- COMM_MGMT_CMD_GET_INDIR_TABLE, /**< Tool read indirect table */
- COMM_MGMT_CMD_SET_INDIR_TABLE, /**< Tool write indirect table */
-
- /**< Move to DFT mode */
- COMM_MGMT_CMD_GET_TDIE_ID = 199, /**< Get totem die ID */
- COMM_MGMT_CMD_GET_UDIE_ID = 200, /**< Get UNIC die ID */
- COMM_MGMT_CMD_GET_EFUSE_TEST, /**< EFUSE test (currently unused) */
- COMM_MGMT_CMD_EFUSE_INFO_CFG, /**< Program EFUSE information */
- COMM_MGMT_CMD_GPIO_CTL, /**< GPIO test (currently unused) */
- COMM_MGMT_CMD_HI30_SERLOOP_START, /**< HI30 start loopback */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /**< HI30 stop loopback */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /**< HI30 BIST test (currently unused) */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /**< HI30 get BIST test result (currently unused) */
- COMM_MGMT_CMD_ECC_TEST, /**< Chip ECC test */
- COMM_MGMT_CMD_FUNC_BIST_TEST, /**< Chip function BIST test */
-
- COMM_MGMT_CMD_VPD_SET = 210, /**< Write VPD information to flash */
- COMM_MGMT_CMD_VPD_GET, /**< Tool reads flash VPD information */
-
- COMM_MGMT_CMD_ERASE_FLASH, /**< Erase flash (DFX version enabled) */
- COMM_MGMT_CMD_QUERY_FW_INFO, /**< Query firmware state machine information */
- COMM_MGMT_CMD_GET_CFG_INFO, /**< Get configuration information (function not yet enabled) */
- COMM_MGMT_CMD_GET_UART_LOG, /**< UART redirect output */
- COMM_MGMT_CMD_SET_UART_CMD, /**< UART redirect input */
- COMM_MGMT_CMD_SPI_TEST, /**< SPI test (DFX version enabled) */
-
- COMM_MGMT_CMD_HEART_EVENT, /**< Heartbeat detection (currently unused) */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /**< Message to driver, get BDF number (scheme replaced) */
- COMM_MGMT_CMD_LASTWORD_GET, /**< Message to driver, MPU last words */
- COMM_MGMT_CMD_READ_BIN_DATA, /**< Get firmware bin data (deprecated) */
- COMM_MGMT_CMD_GET_REG_VAL, /**< Read register (DFX version enabled) */
- COMM_MGMT_CMD_SET_REG_VAL, /**< Write register (DFX version enabled) */
+ COMM_MGMT_CMD_GET_INDIR_TABLE, /**< tool read indirect table */
+ COMM_MGMT_CMD_SET_INDIR_TABLE, /**< tool write indirect table */
+
+ /**< move to DFT mode */
+ COMM_MGMT_CMD_GET_TDIE_ID = 199, /**< 获取totem die id */
+ COMM_MGMT_CMD_GET_UDIE_ID = 200, /**< 获取unic die id */
+ COMM_MGMT_CMD_GET_EFUSE_TEST, /**< efuse测试(当前暂未使用) */
+ COMM_MGMT_CMD_EFUSE_INFO_CFG, /**< 烧写efuse信息 */
+ COMM_MGMT_CMD_GPIO_CTL, /**< gpio测试(当前暂未使用) */
+ COMM_MGMT_CMD_HI30_SERLOOP_START, /**< hi30开始环回 */
+ COMM_MGMT_CMD_HI30_SERLOOP_STOP, /**< hi30停止环回 */
+ COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /**< hi30 bist测试(当前暂未使用) */
+ COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /**< hi30 获取bist测试结果(当前暂未使用) */
+ COMM_MGMT_CMD_ECC_TEST, /**< 芯片ecc测试 */
+ COMM_MGMT_CMD_FUNC_BIST_TEST, /**< 芯片function bist测试 */
+
+ COMM_MGMT_CMD_VPD_SET = 210, /**< 写vpd信息到flash */
+ COMM_MGMT_CMD_VPD_GET, /**< 工具读取flash vpd信息 */
+
+ COMM_MGMT_CMD_ERASE_FLASH, /**< 擦除flash(dfx版本开启) */
+ COMM_MGMT_CMD_QUERY_FW_INFO, /**< 查询固件状态机信息 */
+ COMM_MGMT_CMD_GET_CFG_INFO, /**< 获取配置信息(功能暂未开启) */
+ COMM_MGMT_CMD_GET_UART_LOG, /**< 串口重定向输出 */
+ COMM_MGMT_CMD_SET_UART_CMD, /**< 串口重定向输入 */
+ COMM_MGMT_CMD_SPI_TEST, /**< spi测试(dfx版本开启) */
+
+ COMM_MGMT_CMD_HEART_EVENT, /**< 心跳检测(当前暂未使用) */
+ COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /**< 发往驱动的消息,获取bdf号(方案已替换) */
+ COMM_MGMT_CMD_LASTWORD_GET, /**< 发往驱动的消息,mpu临终遗言 */
+ COMM_MGMT_CMD_READ_BIN_DATA, /**< 获取固件bin数据(已废弃) */
+ COMM_MGMT_CMD_GET_REG_VAL, /**< 读取寄存器(dfx版本开启) */
+ COMM_MGMT_CMD_SET_REG_VAL, /**< 写寄存器(dfx版本开启) */
/**< COMM_MGMT_CMD_WWPN_GET, TBD: move to FC? */
/**< COMM_MGMT_CMD_WWPN_SET, TBD: move to FC? 229 */
- /**< Check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230, /**< Set virtio device type */
- COMM_MGMT_CMD_SET_MAC, /**< Set hardened MAC */
- COMM_MGMT_CMD_LOAD_PATCH, /**< Load MPU patch (deprecated) */
- COMM_MGMT_CMD_REMOVE_PATCH, /**< Remove MPU patch (deprecated) */
- COMM_MGMT_CMD_PATCH_ACTIVE, /**< Activate MPU patch (deprecated) */
- COMM_MGMT_CMD_PATCH_DEACTIVE, /**< Deactivate MPU patch (deprecated) */
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE, /**< Patch space refresh (deprecated) */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC, /**< Storage container scenario, set primary host */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC, /**< Get NCSI counter information */
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /**< Storage scenario, channel detection */
-
- /**< Hot patch reserved command codes */
- COMM_MGMT_CMD_RSVD_0 = 240, /**< Hot patch reserved command 0 */
- COMM_MGMT_CMD_RSVD_1, /**< Hot patch reserved command 1 */
- COMM_MGMT_CMD_RSVD_2, /**< Hot patch reserved command 2 */
- COMM_MGMT_CMD_RSVD_3, /**< Hot patch reserved command 3 */
- COMM_MGMT_CMD_SECTION_INTEGRITY, /** Customer firmware integrity verification */
-
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP, /**< Invalid field, version incorporated deletion, for compilation use */
-
- COMM_MGMT_CMD_GET_VER_COMPATIBLE_INFO = 254, /**< For tool version compatibility information */
-
- /**< Note: When adding cmd, do not modify existing command code values; please add in the preceding rsv section; ideally all branch cmd tables should be identical */
- COMM_MGMT_CMD_MAX = 255, /**< */
+ /**< check if needed */
+ COMM_MGMT_CMD_SET_VIRTIO_DEV = 230, /**< 设置vitro设备类型 */
+ COMM_MGMT_CMD_SET_MAC, /**< 设置固化mac */
+ COMM_MGMT_CMD_LOAD_PATCH, /**< load mpu patch(已废弃) */
+ COMM_MGMT_CMD_REMOVE_PATCH, /**< 移除mpu patch(已废弃) */
+ COMM_MGMT_CMD_PATCH_ACTIVE, /**< 激活mpu patch(已废弃) */
+ COMM_MGMT_CMD_PATCH_DEACTIVE, /**< 去激活mpu patch(已废弃) */
+ COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE, /**< pathc空间刷新(已废弃) */
+ COMM_MGMT_CMD_CONTAINER_HOST_PROC, /**< 存储容器场景,设置主host */
+ COMM_MGMT_CMD_NCSI_COUNTER_PROC, /**< 获取ncsi counter信息 */
+ COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /**< 存储场景,通道探测 */
+
+ /**< 热补丁保留命令字 */
+ COMM_MGMT_CMD_RSVD_0 = 240, /**< 热补丁保留命令0 */
+ COMM_MGMT_CMD_RSVD_1, /**< 热补丁保留命令1 */
+ COMM_MGMT_CMD_RSVD_2, /**< 热补丁保留命令2 */
+ COMM_MGMT_CMD_RSVD_3, /**< 热补丁保留命令3 */
+ COMM_MGMT_CMD_SECTION_INTEGRITY, /**客户固件完整性验证 */
+
+ COMM_MGMT_CMD_SEND_API_ACK_BY_UP, /**< 无效字段,版本收编删除,编译使用 */
+
+ COMM_MGMT_CMD_GET_VER_COMPATIBLE_INFO =
+ 254, /**< for tool ver compatible info */
+
+ /**< 注:添加cmd,不能修改已有命令字的值,请在前方rsv section中添加;原则上所有分支cmd表完全一致 */
+ COMM_MGMT_CMD_MAX = 255, /**< */
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd_defs.h
index 654bc22b9..e15bbdb92 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_inband_cmd_defs.h
@@ -1,10 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mpu_inband_cmd_defs.h
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * Filename : mpu_inband_cmd_defs.h
* Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Creation time : 2023/09/22
+ * Last Modified :
* Description : In-band command-related structures between the driver and the MPU
*/
@@ -13,246 +12,250 @@
#include "mpu_cmd_base_defs.h"
-#define HARDWARE_ID_1XX3V200_TAG 32 /* 1xx3v200 tag */
-#define DUMP_16B_PER_LINE 16 /* dump 16byte alignment */
-#define DUMP_4_VAR_PER_LINE 4 /* dump unit 4byte */
-#define FW_UPDATE_MGMT_TIMEOUT 3000000U /** mbox message upgrade command timeout */
+#define HARDWARE_ID_1XX3V200_TAG 32 /**< 1xx3v200 tag */
+#define DUMP_16B_PER_LINE 16 /**< dump 16byte对齐 */
+#define DUMP_4_VAR_PER_LINE 4 /**< dump 单位4byte */
+#define FW_UPDATE_MGMT_TIMEOUT 3000000U /** mbox消息升级命令超时时间 */
-#define FUNC_RESET_FLAG_MAX_VALUE ((1U << (RES_TYPE_MAX + 1)) - 1) /* func_reset_flag boundary value */
-struct comm_cmd_func_reset { /* driver load/unload scenario, function reset resource cleanup */
- struct mgmt_msg_head head; /* mbox message header */
+#define FUNC_RESET_FLAG_MAX_VALUE \
+ ((1U << (RES_TYPE_MAX + 1)) - 1) /**< func_reset_flag的边界值 */
+struct comm_cmd_func_reset { /**< 驱动加卸载场景,function reset清理资源 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* function id to reset */
- u16 rsvd1[3]; /* reserved field */
- u64 reset_flag; /* bitmap of specific reset resources */
+ u16 func_id; /**< 需要reset的function id */
+ u16 rsvd1[3]; /**< 保留字段 */
+ u64 reset_flag; /**< 具体reset资源的bitmap */
};
-struct comm_cmd_ppf_flr_type_set { /* flr scenario, set ppf flr execution range */
- struct mgmt_msg_head head; /* */
+struct comm_cmd_ppf_flr_type_set { /**< flr场景,设定ppf执行flr的范围 */
+ struct mgmt_msg_head head; /**< */
- u16 func_id; /* flr function id */
- u8 rsvd1[2]; /* reserved field */
- u32 ppf_flr_type; /* ppf flr execution range type, 0: ffp only, 1: all functions under ppf */
+ u16 func_id; /**< flr的function id */
+ u8 rsvd1[2]; /**< 保留字段 */
+ u32 ppf_flr_type; /**< ppf执行flr的范围类型,0: 仅ffp, 1: 改ppf下的所有function */
};
enum {
- COMM_F_API_CHAIN = 1U << 0, /* attribute negotiation, cpi chain */
- COMM_F_CLP = 1U << 1, /* attribute negotiation, clp */
- COMM_F_CHANNEL_DETECT = 1U << 2, /* attribute negotiation, channel detection */
- COMM_F_MBOX_SEGMENT = 1U << 3, /* attribute negotiation, mbox */
- COMM_F_CMDQ_NUM = 1U << 4, /* attribute negotiation, cmdq */
- COMM_F_VIRTIO_VQ_SIZE = 1U << 5, /* attribute negotiation, virtio vq size */
- COMM_F_EXTEND_CAP = 1U << 6, /* attribute negotiation, capability set extension */
- COMM_F_SMF_CACHE_INVALID = 1U << 7, /* attribute negotiation, cache invalidation */
- COMM_F_ONLY_ENHANCE_CMDQ = 1U << 8, /* attribute negotiation, enhanced cmdq */
- COMM_F_USE_REAL_RX_BUF_SIZE = 1U << 9, /* attribute negotiation, use real rx buffer */
- COMM_F_CMD_BUF_SIZE = 1U << 10, /* attribute negotiation, cmd buffer size */
- COMM_F_HTN_CMD = 1U << 11, /* attribute negotiation, Hard Tile - NIC (hardware nic) */
- COMM_F_MBOX_MSG_HEAD_SUPP_VER1 = 1U << 12, /* attribute negotiation, mode extension */
- COMM_F_FAST_MSG = 1U << 13, /* attribute negotiation, fast message */
- COMM_F_UFHD = 1U << 14, /* attribute negotiation, Update Firmware from Host DDR
- * - support DDR microcode hot upgrade
- */
- COMM_F_VIRTIO_FC_CACHE_MODE = 1U << 15, /* attribute negotiation,
- * driver supports Virtio function context cache mode */
- COMM_F_NON_PTP_SYNC = 1U << 16, /* attribute negotiation, non-ptp sync */
- COMM_F_HT_GPA = 1U << 17, /* attribute negotiation, HT GPA (Bank GPA) */
- COMM_F_UFHD_FLEX_SEG = 1U << 18, /* attribute negotiation, UFHD adds segment size negotiation capability.
- * This feature cannot be enabled simultaneously with COMM_F_UFHD.
- * To support segment size negotiation,
- * COMM_F_EXTEND_CAP needs to be enabled.
- */
-};
-
-/* mode extension version */
+ COMM_F_API_CHAIN = 1U << 0, /**< 属性协商,cpi chain */
+ COMM_F_CLP = 1U << 1, /**< 属性协商,clp */
+ COMM_F_CHANNEL_DETECT = 1U << 2, /**< 属性协商,通道探测 */
+ COMM_F_MBOX_SEGMENT = 1U << 3, /**< 属性协商,mbox */
+ COMM_F_CMDQ_NUM = 1U << 4, /**< 属性协商,cmdq */
+ COMM_F_VIRTIO_VQ_SIZE = 1U << 5, /**< 属性协商,vio vq size */
+ COMM_F_EXTEND_CAP = 1U << 6, /**< 属性协商,能力集扩展 */
+ COMM_F_SMF_CACHE_INVALID = 1U << 7, /**< 属性协商,cache invalid */
+ COMM_F_ONLY_ENHANCE_CMDQ = 1U << 8, /**< 属性协商,增强型cmdq */
+ COMM_F_USE_REAL_RX_BUF_SIZE = 1U << 9, /**< 属性协商,use real rx buf */
+ COMM_F_CMD_BUF_SIZE = 1U << 10, /**< 属性协商,cmd buf size */
+ COMM_F_HTN_CMD = 1U << 11, /**< 属性协商,Hard Tile - NIC (硬件nic) */
+ COMM_F_MBOX_MSG_HEAD_SUPP_VER1 = 1U << 12, /**< 属性协商,mode扩展 */
+ COMM_F_FAST_MSG = 1U << 13, /**< 属性协商,fast msg */
+ COMM_F_UFHD =
+ 1U
+ << 14, /**< 属性协商,Update Firmware from Host DDR - 支持 DDR 微码热升级 */
+ COMM_F_VIRTIO_FC_CACHE_MODE =
+ 1U
+ << 15, /**< 属性协商,驱动支持Virtio function context cache mode */
+ COMM_F_NON_PTP_SYNC = 1U << 16, /**< 属性协商,非ptp同步 */
+ COMM_F_HT_GPA = 1U << 17, /**< 属性协商,HT GPA (Bank GPA) */
+ COMM_F_UFHD_FLEX_SEG =
+ 1U << 18, /**< 属性协商,UFHD 增加支持 segement size 协商能力。
+ 该特性不能与 COMM_F_UFHD 特性同时开启。
+ 为支持 segment size 协商,需要开启 COMM_F_EXTEND_CAP。 */
+ COMM_F_VF_BAT_EXPANDED = 1U << 19, /**< 属性协商,VF BAT 扩容。
+ 拥有该特性的 VF 支持使用 PF BAT 空间,
+ PF 不支持该特性。 */
+};
+
+/**< mode扩展version */
#define CHECK_COMM_F_SUPP_MBOX_MSG_HEAD_VER1(feature) \
- (((feature) & COMM_F_MBOX_MSG_HEAD_SUPP_VER1) > 0)
+ (((feature)&COMM_F_MBOX_MSG_HEAD_SUPP_VER1) > 0)
enum {
- COMM_PLUG_SRV_NIC = 0, /* plug nic */
- COMM_PLUG_SRV_VROCE, /* plug vroce */
- COMM_PLUG_SRV_UB, /* plug ub */
+ COMM_PLUG_SRV_NIC = 0, /**< plug nic */
+ COMM_PLUG_SRV_VROCE, /**< plug vroce */
+ COMM_PLUG_SRV_UB, /**< plug ub */
COMM_PLUG_SRV_BUTT,
};
#define COMM_MAX_FEATURE_QWORD 4
-struct comm_cmd_feature_nego { /* attribute negotiation */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_feature_nego { /**< 属性协商 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 opcode; /* 1: set, 0: get */
- u8 rsvd[5]; /* reserved field */
- u64 s_feature[COMM_MAX_FEATURE_QWORD]; /* negotiation information */
+ u16 func_id; /**< 指定function id */
+ u8 opcode; /**< 1: set, 0: get */
+ u8 rsvd[5]; /**< 保留域段 */
+ u64 s_feature[COMM_MAX_FEATURE_QWORD]; /**< 协商信息 */
};
-struct comm_cmd_clear_doorbell { /* driver unload flush doorbell */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_clear_doorbell { /**< 驱动卸载flush db */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u16 rsvd1[3]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u16 rsvd1[3]; /**< 保留域段 */
};
-struct comm_cmd_clear_resource { /* driver unload flush process, cleanup resources */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_clear_resource { /**< 驱动卸载flush流程,清理资源 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u16 rsvd1[3]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u16 rsvd1[3]; /**< 保留域段 */
};
-struct comm_global_attr { /* get chip global attribute information */
- u8 max_host_num; /* maximum host number */
- u8 max_pf_num; /* maximum pf number */
- u16 vf_id_start; /* starting vf id */
+struct comm_global_attr { /**< 获取芯片全局属性信息 */
+ u8 max_host_num; /**< 最大host个数 */
+ u8 max_pf_num; /**< 最大pf个数 */
+ u16 vf_id_start; /**< 起始vf id */
- u8 mgmt_host_node_id; /* management host node id */
- u8 cmdq_num; /* cmdq number */
- u16 cmd_buf_size; /* cmd buffer size */
+ u8 mgmt_host_node_id; /**< 管理host节点id */
+ u8 cmdq_num; /**< cmdq个数 */
+ u16 cmd_buf_size; /**< cmd buff size */
- u32 rsvd2[8]; /* reserved field */
+ u32 rsvd2[8]; /**< 保留域段 */
};
-struct comm_cmd_heart_event { /* mbox heartbeat event between mpu and driver */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_heart_event { /**< mpu与驱动之间的mbox心跳事件 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 init_sta; /* 0: mpu init ok, 1: mpu init error */
- u8 rsvd1[3]; /* reserved field */
- u32 heart; /* heartbeat identifier */
- u32 heart_handshake; /* should be alwasys: 0x5A5A5A5A */
+ u8 init_sta; /**< 0: mpu init ok, 1: mpu init error */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 heart; /**< 心跳标识 */
+ u32 heart_handshake; /**< should be alwasys: 0x5A5A5A5A */
};
-struct comm_cmd_channel_detect { /* channel detection */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_channel_detect { /**< 通道探测 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u16 rsvd1[3]; /* reserved field 1 */
- u32 rsvd2[2]; /* reserved field 2 */
+ u16 func_id; /**< 指定function id */
+ u16 rsvd1[3]; /**< 保留域段1 */
+ u32 rsvd2[2]; /**< 保留域段2 */
};
-struct comm_cmd_func_svc_used_state { /* function usage state */
- struct mgmt_msg_head head; /* mbox message header */
- u16 func_id; /* specified function id */
- u16 svc_type; /* service type (not used currently) */
- u8 used_state; /* usage state */
- u8 rsvd[35]; /* */
+struct comm_cmd_func_svc_used_state { /**< function使用状态 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u16 func_id; /**< 指定function id */
+ u16 svc_type; /**< service类型(暂未使用) */
+ u8 used_state; /**< 使用状态 */
+ u8 rsvd[35]; /**< */
};
-struct comm_cmd_get_flr_info { /* flrdx information */
- struct mgmt_msg_head head; /* mbox message header */
- u16 func_id; /* specified function id */
- u8 flr_valid; /* flr valid bit */
- u8 flr_step; /* flr state machine */
- u32 flr_used_time_ms; /* flr elapsed time */
- u16 max_flr_time_func_id; /* function with longest flr time */
- u32 max_flr_used_time_ms; /* maximum flr time */
- u8 rsvd[30]; /* reserved field */
+struct comm_cmd_get_flr_info { /**< flrdx信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u16 func_id; /**< 指定function id */
+ u8 flr_valid; /**< flr有效位 */
+ u8 flr_step; /**< flr状态机 */
+ u32 flr_used_time_ms; /**< flr耗时时间 */
+ u16 max_flr_time_func_id; /**< 耗时最长function */
+ u32 max_flr_used_time_ms; /**< flr最长耗时 */
+ u8 rsvd[30]; /**< 保留域段 */
};
-struct sml_table_id_info { /* sml table information */
- u8 node_id; /* node id */
- u8 instance_id; /* instance id */
+struct sml_table_id_info { /**< sml表信息 */
+ u8 node_id; /**< 节点id */
+ u8 instance_id; /**< instance id */
};
-struct comm_cmd_get_sml_tbl_data { /* sml table content */
- struct mgmt_msg_head head; /* mbox message header */
- u8 tbl_data[512]; /* sml payload */
+struct comm_cmd_get_sml_tbl_data { /**< sml表内容 */
+ struct mgmt_msg_head head; /**<mbox消息头 */
+ u8 tbl_data[512]; /**< sml payload */
};
-struct comm_cmd_get_glb_attr { /* get chip global information */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_get_glb_attr { /**< 获取芯片全局信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- struct comm_global_attr attr; /* global information */
+ struct comm_global_attr attr; /**< 全局信息 */
};
-#define HINIC5_FW_VERSION_LEN 16 /* version length */
-#define HINIC5_FW_COMPILE_TIME_LEN 20 /* time length */
+#define HINIC5_FW_VERSION_LEN 16 /**< version长度 */
+#define HINIC5_FW_COMPILE_TIME_LEN 20 /**< 时间长度 */
-struct comm_cmd_get_fw_version { /* get firmware version */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_get_fw_version { /**< 获取固件版本号 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 fw_type; /* firmware type */
- u16 fw_dfx_vld : 1; /* version type, 0: release, 1: debug */
- u16 rsvd1 : 15; /* reserved field */
- char ver[HINIC5_FW_VERSION_LEN]; /* version */
- char time[HINIC5_FW_COMPILE_TIME_LEN]; /* time */
+ u16 fw_type; /**< 固件类型 */
+ u16 fw_dfx_vld : 1; /**< 版本类型,0: release, 1: debug */
+ u16 rsvd1 : 15; /**< 保留域段 */
+ char ver[HINIC5_FW_VERSION_LEN]; /**< 版本 */
+ char time[HINIC5_FW_COMPILE_TIME_LEN]; /**< 时间 */
};
-struct cmdq_ctxt_info { /* hardware define: cmdq context */
- u64 curr_wqe_page_pfn; /* wqe page information */
- u64 wq_block_pfn; /* wqe address */
+struct cmdq_ctxt_info { /**< hardware define: cmdq context */
+ u64 curr_wqe_page_pfn; /**< wqe页面信息 */
+ u64 wq_block_pfn; /**< wqe地址 */
};
-struct comm_cmd_cmdq_ctxt { /* configure cmdq context */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_cmdq_ctxt { /**< 配置cmdq context */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 cmdq_id; /* cmdq id */
- u8 rsvd1[5]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 cmdq_id; /**< cmdq id */
+ u8 rsvd1[5]; /**< 保留域段 */
- struct cmdq_ctxt_info ctxt; /* context information */
+ struct cmdq_ctxt_info ctxt; /**< ctx信息 */
};
-struct enhance_cmdq_ctxt_info { /* hardware define: enhanced cmdq context */
- u64 eq_cfg; /* eq cfg */
- u64 dfx_pi_ci; /* pointer pi ci */
+struct enhance_cmdq_ctxt_info { /**< hardware define: enhance cmdq context */
+ u64 eq_cfg; /**< eq cfg */
+ u64 dfx_pi_ci; /**< 指针pi ci */
- u64 pft_thd; /* pft thd */
- u64 pft_ci; /* pft ci */
+ u64 pft_thd; /**< pft thd */
+ u64 pft_ci; /**< pft ci */
- u64 rsv; /* reserved field */
- u64 ci_cla_addr; /* cla address */
+ u64 rsv; /**< 保留域段 */
+ u64 ci_cla_addr; /**< cla地址 */
};
-struct comm_cmd_enhance_cmdq_ctxt { /* enhanced cmdq ctx configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_enhance_cmdq_ctxt { /**< 增强型cmdq ctx配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 cmdq_id; /* cmdq id */
- u8 rsvd1[5]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 cmdq_id; /**< cmdq id */
+ u8 rsvd1[5]; /**< 保留域段 */
- struct enhance_cmdq_ctxt_info ctxt; /* ctx information */
+ struct enhance_cmdq_ctxt_info ctxt; /**< ctx信息 */
};
-struct comm_cmd_virtio_en { /* virtio config after sdk load */
- struct mgmt_msg_head head; /* mbox message header */
- u8 msien_snap_2_virtio_en; /* msien virtio enable */
+struct comm_cmd_virtio_en { /**< virtio 配置 到加载sdk之后 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 msien_snap_2_virtio_en; /**< msien virtio使能 */
u8 rsv[3];
};
-struct hinic5_cqm_cmd_func_secure_mem { /* secure memory information retrieval */
- struct mgmt_msg_head head; /* mbox message header */
- u16 func_id; /* specified function id */
- u16 rsvd0; /* reserved field */
- u32 gpa_hi; /* gpa high address */
- u32 gpa_lo; /* gpa low address */
- u32 len; /* length */
- u8 gpa_mode; /* gpa mode */
- u8 valid; /* valid bit */
- u8 rsvd1[2]; /* reserved field */
+struct cqm_cmd_func_secure_mem { /**< 安全内存信息获取 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u16 func_id; /**< 指定function id */
+ u16 rsvd0; /**< 保留域段 */
+ u32 gpa_hi; /**< gpa高位地址 */
+ u32 gpa_lo; /**< gpa低位地址 */
+ u32 len; /**< 长度 */
+ u8 gpa_mode; /**< gpa模式 */
+ u8 valid; /**< 有效位 */
+ u8 rsvd1[2]; /**< 保留域段 */
};
-struct nic_plug_cap { /* hotplug capability */
- u16 max_sqs; /* maximum sq size */
- u16 max_rqs; /* maximum rq size */
+struct nic_plug_cap { /**< 热拔插能力 */
+ u16 max_sqs; /**< 最大sq size */
+ u16 max_rqs; /**< 最大rq size */
};
-struct comm_cmd_plug_srv { /* hotplug service */
- struct mgmt_msg_head head; /* mbox message header */
- u16 func_id; /* specified function id */
- u8 srv_type; /* service type */
- u8 attach_en; /* enable flag */
- struct nic_plug_cap nic_cap; /* nic hotplug capability */
- u32 rsvd; /* reserved field */
+struct comm_cmd_plug_srv { /**< 热拔插服务 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u16 func_id; /**< 指定function id */
+ u8 srv_type; /**< service类型 */
+ u8 attach_en; /**< 使能标识 */
+ struct nic_plug_cap nic_cap; /**< nic热拔插能力 */
+ u32 rsvd; /**< 保留域段 */
};
-struct comm_cmd_fast_msg_cap { /* fast msg capability */
- struct mgmt_msg_head head; /* mbox message header */
- u32 func_id; /* specified function id */
- u32 fast_msg_depth; /* PF:2048, VF:512 */
- u32 fast_msg_page_size; /* message page size 256(unit K) */
- u32 rsvd[9]; /* reserved field */
+struct comm_cmd_fast_msg_cap { /**< fast msg能力 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 func_id; /**< 指定function id */
+ u32 fast_msg_depth; /**< PF:2048, VF:512 */
+ u32 fast_msg_page_size; /**< 消息页面大小256(单位K) */
+ u32 rsvd[9]; /**< 保留域段 */
};
-#define FAST_MSG_MAX_PAGE_NUM 32 /* fast msg page number */
+#define FAST_MSG_MAX_PAGE_NUM 32 /**< fast msg页面数量 */
struct comm_cmd_fast_msg_rq_addr {
struct mgmt_msg_head head;
u32 func_id;
@@ -261,78 +264,78 @@ struct comm_cmd_fast_msg_rq_addr {
u64 page_addr[FAST_MSG_MAX_PAGE_NUM];
};
-struct fast_msg_rq_addr { /* fast msg rq address */
- u64 rq_page_addr; /* rq page address */
+struct fast_msg_rq_addr { /**< fast msg rq地址 */
+ u64 rq_page_addr; /**< rq页面地址 */
};
-struct comm_cmd_set_fast_msg_rq_addr { /* fast msg rq address setting */
- struct mgmt_msg_head head; /* mbox message header */
- u32 func_id; /* specified function id */
- u32 page_num; /* page number */
- u32 rsvd[2]; /* reserved field */
- struct fast_msg_rq_addr page_addr[32]; /* page address */
+struct comm_cmd_set_fast_msg_rq_addr { /**< fast msg rq地址设置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 func_id; /**< 指定function id */
+ u32 page_num; /**< 页面数量 */
+ u32 rsvd[2]; /**< 保留域段 */
+ struct fast_msg_rq_addr page_addr[32]; /**< 页面地址 */
};
-struct comm_cmd_clear_fast_msg_sml_table { /* fast msg clear table entry */
- struct mgmt_msg_head head; /* mbox message header */
- u32 func_id; /* specified function id */
- u32 rsvd[5]; /* reserved field, 32 Bytes total */
+struct comm_cmd_clear_fast_msg_sml_table { /**< fast msg 清除表项 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 func_id; /**< 指定function id */
+ u32 rsvd[5]; /**< 保留域段, 32 Bytes total */
};
-struct comm_cmd_root_ctxt { /* root ctx configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_root_ctxt { /**< root ctx配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 set_cmdq_depth; /* cmdq depth set flag */
- u8 cmdq_depth; /* cmdq depth */
- u16 rx_buf_sz; /* rx buffer size */
- u8 lro_en; /* lro enable flag */
- u8 cmdq_mode; /* cmdq mode */
- u16 sq_depth; /* sq depth */
- u16 rq_depth; /* rq depth */
- u32 rsvd1; /* reserved field */
- u64 rsvd2; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 set_cmdq_depth; /**< cmdq深度设置标识 */
+ u8 cmdq_depth; /**< cmdq深度 */
+ u16 rx_buf_sz; /**< rx buff size */
+ u8 lro_en; /**< lro使能标识 */
+ u8 cmdq_mode; /**< cmdq模式 */
+ u16 sq_depth; /**< sq深度 */
+ u16 rq_depth; /**< rq深度 */
+ u32 rsvd1; /**< 保留域段 */
+ u64 rsvd2; /**< 保留域段 */
};
-struct comm_cmd_wq_page_size { /* root ctx wqe configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_wq_page_size { /**< root ctx wqe配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 opcode; /* operation indicator, 0: get, 1: set */
- u8 page_size; /* real_size=4KB*2^page_size, range(0~20) must be checked by driver */
- u32 rsvd1; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 opcode; /**< 操作标识,0:get,1:set */
+ u8 page_size; /**< real_size=4KB*2^page_size, range(0~20) must be checked by driver */
+ u32 rsvd1; /**< 保留域段 */
};
-struct comm_cmd_msix_config { /* msix interrupt configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_msix_config { /**< msix中断配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 opcode; /* operation indicator, 0: get, 1: set */
- u8 rsvd1; /* reserved field */
- u16 msix_index; /* interrupt idx */
- u8 pending_cnt; /* It specifies the maximum wait time for resending period. */
- u8 coalesce_timer_cnt; /* coalesce configuration */
- u8 resend_timer_cnt; /* resend count */
- u8 lli_timer_cnt; /* credit compensation configuration */
- u8 lli_credit_cnt; /* credit supplement threshold */
- u8 rsvd2[5]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 opcode; /**< 操作标识,0:get,1:set */
+ u8 rsvd1; /**< 保留域段 */
+ u16 msix_index; /**< 中断idx */
+ u8 pending_cnt; /**< It specifies the maximum wait time for resending period. */
+ u8 coalesce_timer_cnt; /**< 聚合配置 */
+ u8 resend_timer_cnt; /**< 重传计数 */
+ u8 lli_timer_cnt; /**< 信用补偿配置 */
+ u8 lli_credit_cnt; /**< 信用补充门限 */
+ u8 rsvd2[5]; /**< 保留域段 */
};
-struct comm_cmd_cfg_msix_num { /* msix interrupt number configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_cfg_msix_num { /**< msix中断数量配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 op_code; /* 1: alloc 0: free */
- u8 rsvd0; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 op_code; /**< 1: alloc 0: free */
+ u8 rsvd0; /**< 保留域段 */
- u16 msix_num; /* msix number */
- u16 rsvd1; /* reserved field */
+ u16 msix_num; /**< msix数量 */
+ u16 rsvd1; /**< 保留域段 */
};
-struct comm_cmd_dma_attr_config { /* dma attribute config (currently not used) */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_dma_attr_config { /**< dma属性配置(当前暂未使用) */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
+ u16 func_id; /**< 指定function id */
u8 entry_idx;
u8 st;
u8 at;
@@ -342,331 +345,325 @@ struct comm_cmd_dma_attr_config { /* dma attribute config (currently not used)
u32 resv1;
};
-struct comm_cmd_ppf_tbl_htrp_config { /* ppf hot replace configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_ppf_tbl_htrp_config { /**< ppf热替换配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u32 hotreplace_flag; /* hot replace flag */
+ u32 hotreplace_flag; /**< 热替换标识 */
};
-struct comm_cmd_ceq_ctrl_reg { /* ceq configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_ceq_ctrl_reg { /**< ceq配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u16 q_id; /* q id */
- u32 ctrl0; /* ceq ctrl0 */
- u32 ctrl1; /* ceq ctrl1 */
- u32 rsvd1; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u16 q_id; /**< q id */
+ u32 ctrl0; /**< ceq ctrl0 */
+ u32 ctrl1; /**< ceq ctrl1 */
+ u32 rsvd1; /**< 保留域段 */
};
-struct comm_cmd_func_tmr_bitmap_op { /* enable smf timer bitmap operation */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_func_tmr_bitmap_op { /**< 使能 smf timr bitmap操作 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 opcode; /* 1: start, 0: stop */
- u8 rsvd1[5]; /* reserved field */
+ u16 func_id; /**< 指定function id */
+ u8 opcode; /**< 1: start, 0: stop */
+ u8 rsvd1[5]; /**< 保留域段 */
};
-struct comm_cmd_ppf_tmr_op { /* smf timer configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_ppf_tmr_op { /**< smf timr配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 ppf_id; /* ppf id */
- u8 opcode; /* 1: start, 0: stop */
- u8 rsvd1[6]; /* reserved field */
+ u8 ppf_id; /**< ppf id */
+ u8 opcode; /**< 1: start, 0: stop */
+ u8 rsvd1[6]; /**< 保留域段 */
};
-#define HT_GPA_CLEAR 0 /* gpa clear */
-#define HT_GPA_SET 1 /* gpa set */
-struct comm_cmd_ht_gpa { /* gpa operation */
- struct mgmt_msg_head head; /* mbox message header */
+#define HT_GPA_CLEAR 0 /**< gpa clr */
+#define HT_GPA_SET 1 /**< gpa set */
+struct comm_cmd_ht_gpa { /**< gpa操作 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 host_id; /* specified host */
- u8 opcode; /* 1:set, 0: clear */
- u8 rsvd0[2]; /* reserved field */
- u32 rsvd1[7]; /* reserved field */
- u64 page_pa0; /* gpa address 0 */
- u64 page_pa1; /* gpa address 1 */
+ u8 host_id; /**< 指定host */
+ u8 opcode; /**< 1:set, 0: clear */
+ u8 rsvd0[2]; /**< 保留域段 */
+ u32 rsvd1[7]; /**< 保留域段 */
+ u64 page_pa0; /**< gpa地址0 */
+ u64 page_pa1; /**< gpa地址1 */
};
-struct comm_cmd_get_eqm_num { /* mqm eqm configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_get_eqm_num { /**< mqm eqm配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 host_id; /* specified host */
- u8 rsvd1[3]; /* reserved field */
- u32 chunk_num; /* chunk num */
- u32 search_gpa_num; /* search gpa num */
+ u8 host_id; /**< 指定host */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 chunk_num; /**< chunk num */
+ u32 search_gpa_num; /**< search gpa num */
};
-struct comm_cmd_eqm_cfg { /* mqm overflow configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_eqm_cfg { /**< mqm溢出配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 host_id; /* specified host */
- u8 valid; /* valid bit */
- u16 rsvd1; /* reserved field */
- u32 page_size; /* page size */
- u32 rsvd2; /* reserved field */
+ u8 host_id; /**< 指定host */
+ u8 valid; /**< 有效位 */
+ u16 rsvd1; /**< 保留域段 */
+ u32 page_size; /**< 页面size */
+ u32 rsvd2; /**< 保留域段 */
};
-struct comm_cmd_eqm_search_gpa { /* mqm search gpa configuration */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_eqm_search_gpa { /**< mqm search gpa配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u8 host_id; /* specified host */
- u8 rsvd1[3]; /* reserved field */
- u32 start_idx; /* start idx */
- u32 num; /* number */
- u32 rsvd2; /* reserved field */
- u64 gpa_hi52[0]; /* gpa */
+ u8 host_id; /**< 指定host */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 start_idx; /**< 起始idx */
+ u32 num; /**< 数量 */
+ u32 rsvd2; /**< 保留域段 */
+ u64 gpa_hi52[0]; /**< gpa */
};
struct comm_cmd_set_bat_info {
struct mgmt_msg_head head;
u16 func_id;
- u8 smf_id;
- u8 rsvd1;
+ u8 smf_id;
+ u8 rsvd1;
u32 bat_offset;
u32 data_size;
- u8 data[256];
-};
-
-struct hinic5_board_info { /* get board information */
- u8 board_type; /* board type */
- u8 port_num; /* port number */
- u8 port_speed; /* board speed */
- u8 host_width; /* port bandwidth */
- u8 host_num; /* supported host number */
- u8 pf_num; /* supported pf number */
- u16 vf_total_num; /* supported vf number */
- u8 tile_num; /* supported tile number */
- u8 qcm_num; /* supported qcm number */
- u8 core_num; /* supported tile core number */
- u8 work_mode; /* board work mode */
- u8 service_mode; /* board service mode */
- u8 board_mode; /* board mode */
- u8 boot_sel; /* boot mode */
- u8 board_id; /* board id */
- u32 cfg_addr; /* config file address */
- u32 service_en_bitmap; /* service enable feature */
- u8 scenes_id; /* scene id */
- u8 cfg_template_id; /* config template id */
- u8 hardware_id; /* hardware id */
- u8 spu_en; /* spu enable flag */
- u16 pf_vendor_id; /* device vendor id */
- u8 tile_bitmap; /* tile enable bitmap */
- u8 sm_bitmap; /* sm enable bitmap */
- u8 smf_bitmap_hi; /* high 4bit of smf */
- u8 board_type_hi; /* high 8bit of board_type */
- u8 host_type : 2; /* see BUS_TYPE_E 0 : pcie, 1 : ubc */
- u8 pg_grade : 2; /* see PARTIAL_GOOD_GRADE_MODE, 0 : fg, 1 : pg */
+ u8 data[256];
+};
+
+struct hinic5_board_info { /**< 获取板卡信息 */
+ u8 board_type; /**< 板卡类型 */
+ u8 port_num; /**< 网口数量 */
+ u8 port_speed; /**< 板卡速率 */
+ u8 host_width; /**< 网口带宽 */
+ u8 host_num; /**< 支持host数量 */
+ u8 pf_num; /**< 支持pf数量 */
+ u16 vf_total_num; /**< 支持vf数量 */
+ u8 tile_num; /**< 支持tile数量 */
+ u8 qcm_num; /**< 支持qcm数量 */
+ u8 core_num; /**< 支持tile core数量 */
+ u8 work_mode; /**< 板卡工作模式 */
+ u8 service_mode; /**< 板卡支持service模式 */
+ u8 board_mode; /**< 板卡模式 */
+ u8 boot_sel; /**< 启动模式 */
+ u8 board_id; /**< 板卡id */
+ u32 cfg_addr; /**< 配置文件地址 */
+ u32 service_en_bitmap; /**< service使能特性 */
+ u8 scenes_id; /**< 场景id */
+ u8 cfg_template_id; /**< 配置模板id */
+ u8 hardware_id; /**< 硬件id */
+ u8 spu_en; /**< spu使能标识 */
+ u16 pf_vendor_id; /**< 设备厂商id */
+ u8 tile_bitmap; /**< tile使能bitmap */
+ u8 sm_bitmap; /**< sm使能bitmap */
+ u8 smf_bitmap_hi; /**< 保存高4bit的smf */
+ u8 board_type_hi; /**< 保存高8bit的board_type */
+ u8 host_type : 2; /**< 取值参考BUS_TYPE_E 0 : pcie, 1 : ubc */
+ u8 pg_grade : 2; /**< 取值参考PARTIAL_GOOD_GRADE_MODE,0 : fg, 1 : pg */
u8 rsvd0 : 4;
u8 rsvd;
- u32 service_en_bitmap2; /* service enable feature extension */
+ u32 service_en_bitmap2; /**< service使能特性扩展 */
};
-struct comm_cmd_board_info { /* get board information */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_board_info { /**< 获取板卡信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- struct hinic5_board_info info; /* board information */
- u32 rsvd[20]; /* reserved field */
+ struct hinic5_board_info info; /**< 板卡信息 */
+ u32 rsvd[20]; /**< 保留域段 */
};
-struct comm_cmd_sync_time { /* driver time sync */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_sync_time { /**< 驱动时间同步 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u64 mstime; /* timestamp */
+ u64 mstime; /**< 时间戳 */
u64 sync_time;
};
-struct comm_cmd_sdi_info { /* get sdi information */
- struct mgmt_msg_head head; /* mbox message header */
- u32 cfg_sdi_mode; /* configure sdi mode */
+struct comm_cmd_sdi_info { /**< 获取sdi信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 cfg_sdi_mode; /**< 配置sdi模式 */
};
enum tool_run_env {
- TOOL_RUN_ENV_HOST, /* host side */
- TOOL_RUN_ENV_SPU, /* spu side */
+ TOOL_RUN_ENV_HOST, /**< host侧 */
+ TOOL_RUN_ENV_SPU, /**< spu侧 */
TOOL_RUN_ENV_INVALID = 0xFF
};
typedef u8 tool_run_env_u8;
enum chip_ver {
- CHIP_VER_HI1823V100, /* chip 1823v100 */
- CHIP_VER_HI1823EV100, /* chip 1823v100e */
- CHIP_VER_HI1823V200, /* chip 1823v200 */
- CHIP_VER_HI1872V100, /* chip 1872v100 */
- CHIP_VER_HI1825V100, /* chip 1825v100 */
+ CHIP_VER_HI1823V100, /**< 芯片1823v100 */
+ CHIP_VER_HI1823EV100, /**< 芯片1823v100e */
+ CHIP_VER_HI1823V200, /**< 芯片1823v200 */
+ CHIP_VER_HI1872V100, /**< 芯片1872v100 */
+ CHIP_VER_HI1825V100, /**< 芯片1825v100 */
CHIP_VER_INVALID = 0xFF
};
-typedef u8 chip_ver_u8; /* chip version */
+typedef u8 chip_ver_u8; /**< 芯片版本 */
enum chip_type {
- CHIP_TYPE_FPGA, /* chip fpga */
- CHIP_TYPE_ASIC, /* chip asic */
- CHIP_TYPE_EMU, /* chip emu */
- CHIP_TYPE_EDA, /* chip eda */
+ CHIP_TYPE_FPGA, /**< 芯片fpga */
+ CHIP_TYPE_ASIC, /**< 芯片asic */
+ CHIP_TYPE_EMU, /**< 芯片emu */
+ CHIP_TYPE_EDA, /**< 芯片eda */
CHIP_TYPE_INVALID = 0xFF
};
-typedef u8 chip_type_u8; /* chip platform */
+typedef u8 chip_type_u8; /**< 芯片平台 */
-struct comm_cmd_compatible_info { /* huoq environment information */
- struct mgmt_msg_head head; /* mbox message header */
- chip_ver_u8 chip_ver; /* chip version */
- tool_run_env_u8 host_env; /* host type */
- chip_type_u8 chip_type; /* chip type/platform */
- u8 dual_die_flag; /* dual die enable flag 0: no(single die), 1: yes(dual die) */
- u32 mpu_ver; /* mpu version */
- u32 npu_ver; /* microcode version */
- u32 rsv1[31]; /* reserved field */
+struct comm_cmd_compatible_info { /**< huoq环境信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ chip_ver_u8 chip_ver; /**< 芯片版本 */
+ tool_run_env_u8 host_env; /**< host类型 */
+ chip_type_u8 chip_type; /**< 芯片类型/平台 */
+ u8 dual_die_flag; /**< 双die使能标识 0:否(单die),1:是(双die) */
+ u32 mpu_ver; /**< mpu版本 */
+ u32 npu_ver; /**< 微码版本 */
+ u32 rsv1[31]; /**< 保留域段 */
};
/* func flr set */
-struct comm_cmd_func_flr_set { /* set function flr type */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_func_flr_set { /**< 设置function flr类型 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 type; /* 1: close set flush */
- u8 isall; /* whether to operate all vf under the corresponding pf 1: all vf */
+ u16 func_id; /**< 指定function id */
+ u8 type; /**< 1: close 置flush */
+ u8 isall; /**< 是否操作对应pf下的所有vf 1: all vf */
u32 rsvd;
};
-struct comm_cmd_bdf_info { /* get bdf number */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_bdf_info { /**< 获取bdf号 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 function_idx; /* specified function id */
- u8 rsvd1[2]; /* reserved field */
- u8 bus; /* bus number */
- u8 device; /* device number */
- u8 function; /* function number */
- u8 rsvd2[5]; /* reserved field */
+ u16 function_idx; /**< 指定function id */
+ u8 rsvd1[2]; /**< 保留域段 */
+ u8 bus; /**< 总线号 */
+ u8 device; /**< 设备号 */
+ u8 function; /**< function号 */
+ u8 rsvd2[5]; /**< 保留域段 */
};
-struct hw_pf_info { /* hardware pf information */
- u16 glb_func_idx; /* global function id */
- u16 glb_pf_vf_offset; /* starting vf id of this pf */
- u8 p2p_idx; /* p2p idx */
- u8 itf_idx; /* host id */
- u16 max_vfs; /* vf number */
- u16 max_queue_num; /* queue number */
- u16 vf_max_queue_num; /* vf supported queue number */
- u16 port_id; /* port id */
- u16 rsvd0; /* reserved field */
- u32 pf_service_en_bitmap; /* pf service en */
- u32 vf_service_en_bitmap; /* vf service en */
- u16 rsvd1[2]; /* reserved field */
+struct hw_pf_info { /**< 硬件pf信息 */
+ u16 glb_func_idx; /**< 全局function id */
+ u16 glb_pf_vf_offset; /**< 该pf的起始vf id */
+ u8 p2p_idx; /**< p2p idx */
+ u8 itf_idx; /**< host id */
+ u16 max_vfs; /**< vf数量 */
+ u16 max_queue_num; /**< 队列数量 */
+ u16 vf_max_queue_num; /**< vf支持的队列数量 */
+ u16 port_id; /**< 网口id */
+ u16 rsvd0; /**< 保留域段 */
+ u32 pf_service_en_bitmap; /**< pf的service en */
+ u32 vf_service_en_bitmap; /**< vf的service en */
+ u16 rsvd1[2]; /**< 保留域段 */
- u8 device_type; /* device type */
- u8 bus_num; /* bus number */
- u16 vf_stride; /* vf stride */
- u16 vf_offset; /* vf relative offset */
- u8 func_valid_map : 2; /* 0: present all functions, 1: present odd functions,
- * 2: present even functions, 3: invalid value
- */
- u8 rsvd2 : 6; /* reserved field */
- u8 rsvd; /* reserved field */
+ u8 device_type; /**< 设备类型 */
+ u8 bus_num; /**< 总线号 */
+ u16 vf_stride; /**< vf步长 */
+ u16 vf_offset; /**< vf相对偏移 */
+ u8 func_valid_map : 2; /**< 0:呈现所有function, 1: 呈现奇数function, 2:呈现偶数function, 3:无效值 */
+ u8 rsvd2 : 6; /**< 保留域段 */
+ u8 rsvd; /**< 保留域段 */
};
-#define CMD_MAX_MAX_PF_NUM 32 /* maximum pf number */
-struct hinic5_hw_pf_infos { /* hardware pf information */
- u8 num_pfs; /* pf number */
- u8 rsvd1[3]; /* reserved field */
+#define CMD_MAX_MAX_PF_NUM 32 /**< 最大pf数量 */
+struct hinic5_hw_pf_infos { /**< 硬件pf信息 */
+ u8 num_pfs; /**< pf个数 */
+ u8 rsvd1[3]; /**< 保留域段 */
- struct hw_pf_info infos[CMD_MAX_MAX_PF_NUM]; /* hardware pf information */
+ struct hw_pf_info infos[CMD_MAX_MAX_PF_NUM]; /**< 硬件pf信息 */
};
-struct comm_cmd_hw_pf_infos { /* hardware pf information */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_hw_pf_infos { /**< 硬件pf信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- struct hinic5_hw_pf_infos infos; /* pf information */
+ struct hinic5_hw_pf_infos infos; /**< pf信息 */
};
-#define DD_CFG_TEMPLATE_MAX_IDX 12 /* supported config template number */
-#define DD_CFG_TEMPLATE_MAX_TXT_LEN 64 /* supported config template size */
-#define CFG_TEMPLATE_OP_QUERY 0 /* query config template */
-#define CFG_TEMPLATE_OP_SET 1 /* set config template */
+#define DD_CFG_TEMPLATE_MAX_IDX 12 /**< 支持的配置模板数量 */
+#define DD_CFG_TEMPLATE_MAX_TXT_LEN 64 /**< 支持的配置模板大小 */
+#define CFG_TEMPLATE_OP_QUERY 0 /**< 查询配置模板 */
+#define CFG_TEMPLATE_OP_SET 1 /**< 设置配置模板 */
#define CFG_TEMPLATE_SET_MODE_BY_IDX 0
#define CFG_TEMPLATE_SET_MODE_BY_NAME 1
-struct comm_cmd_cfg_template { /* config version configuration */
- struct mgmt_msg_head head; /* mbox message header */
- u8 opt_type; /* 0: query 1: set */
- u8 set_mode; /* 0-index mode. 1-name mode. */
- u8 tp_err; /* template error flag */
- u8 rsvd0; /* reserved field */
-
- u8 cur_index; /* Current cfg tempalte index. */
- u8 cur_max_index; /* Max support cfg tempalte index. */
- u8 rsvd1[2]; /* reserved field */
- u8 cur_name[DD_CFG_TEMPLATE_MAX_TXT_LEN]; /* current template name */
- /* current template information */
- u8 cur_cfg_temp_info[DD_CFG_TEMPLATE_MAX_IDX][DD_CFG_TEMPLATE_MAX_TXT_LEN];
-
- u8 next_index; /* Next reset cfg tempalte index. */
- u8 next_max_index; /* Max support cfg tempalte index. */
- u8 rsvd2[2]; /* reserved field */
- u8 next_name[DD_CFG_TEMPLATE_MAX_TXT_LEN]; /* next template name */
- /* next template information */
- u8 next_cfg_temp_info[DD_CFG_TEMPLATE_MAX_IDX][DD_CFG_TEMPLATE_MAX_TXT_LEN];
-};
-
-#define MQM_SUPPORT_COS_NUM 8 /* cos number */
-#define MQM_INVALID_WEIGHT 256 /* mqm table size */
-#define MQM_LIMIT_SET_FLAG_READ 0 /* read */
-#define MQM_LIMIT_SET_FLAG_WRITE 1 /* write */
-struct comm_cmd_set_mqm_limit { /* mqm rate limit configuration */
- struct mgmt_msg_head head; /* mbox message header */
-
- u16 set_flag; /* set this flag to indicate configuration */
- u16 func_id; /* specified function id */
- u16 cos_weight[MQM_SUPPORT_COS_NUM]; /* weight for corresponding cos_id,
- * 0-255, 0 is SP scheduling.
- */
- u32 host_min_rate; /* minimum rate supported by this host */
- u32 func_min_rate; /* minimum rate supported by this function, unit Mbps */
- u32 func_max_rate; /* maximum rate supported by this function, unit Mbps */
- u8 rsvd[64]; /* reserved field */
-};
-
-enum core_type_e {
- CORE_TYPE_ARM = 0,
- CORE_TYPE_LINX = 1
-};
+struct comm_cmd_cfg_template { /**< 配置版本配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 opt_type; /**< 0: query 1: set */
+ u8 set_mode; /**< 0-index mode. 1-name mode. */
+ u8 tp_err; /**< 模板错误标识 */
+ u8 rsvd0; /**< 保留域段 */
+
+ u8 cur_index; /**< Current cfg tempalte index. */
+ u8 cur_max_index; /**< Max support cfg tempalte index. */
+ u8 rsvd1[2]; /**< 保留域段 */
+ u8 cur_name[DD_CFG_TEMPLATE_MAX_TXT_LEN]; /**< 当前模板名称 */
+ u8 cur_cfg_temp_info[DD_CFG_TEMPLATE_MAX_IDX]
+ [DD_CFG_TEMPLATE_MAX_TXT_LEN]; /**< 当前模板信息 */
+
+ u8 next_index; /**< Next reset cfg tempalte index. */
+ u8 next_max_index; /**< Max support cfg tempalte index. */
+ u8 rsvd2[2]; /**< 保留域段 */
+ u8 next_name[DD_CFG_TEMPLATE_MAX_TXT_LEN]; /**< 下一个模板名称 */
+ u8 next_cfg_temp_info[DD_CFG_TEMPLATE_MAX_IDX]
+ [DD_CFG_TEMPLATE_MAX_TXT_LEN]; /**< 下一个模板信息 */
+};
+
+#define MQM_SUPPORT_COS_NUM 8 /**< cos数量 */
+#define MQM_INVALID_WEIGHT 256 /**< mqm表大小 */
+#define MQM_LIMIT_SET_FLAG_READ 0 /**< read */
+#define MQM_LIMIT_SET_FLAG_WRITE 1 /**< write */
+struct comm_cmd_set_mqm_limit { /**< mqm限速配置 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+
+ u16 set_flag; /**< 置位该标记位表示设置 */
+ u16 func_id; /**< 指定function id */
+ u16 cos_weight
+ [MQM_SUPPORT_COS_NUM]; /**< 对应cos_id所占的权重,0-255, 0为SP调度. */
+ u32 host_min_rate; /**< 本host支持的最低限速 */
+ u32 func_min_rate; /**< 本function支持的最低限速,单位Mbps */
+ u32 func_max_rate; /**< 本function支持的最高限速,单位Mbps */
+ u8 rsvd[64]; /**< 保留域段 */
+};
+
+enum core_type_e { CORE_TYPE_ARM = 0, CORE_TYPE_LINX = 1 };
struct arm_core_reg_info {
- u64 elr; /* general register */
- u64 spsr; /* general register */
- u64 far; /* general register */
- u64 esr; /* general register */
- u64 xzr; /* general register */
- u64 x30; /* general register */
- u64 x29; /* general register */
- u64 x28; /* general register */
- u64 x27; /* general register */
- u64 x26; /* general register */
- u64 x25; /* general register */
- u64 x24; /* general register */
- u64 x23; /* general register */
- u64 x22; /* general register */
- u64 x21; /* general register */
- u64 x20; /* general register */
- u64 x19; /* general register */
- u64 x18; /* general register */
- u64 x17; /* general register */
- u64 x16; /* general register */
- u64 x15; /* general register */
- u64 x14; /* general register */
- u64 x13; /* general register */
- u64 x12; /* general register */
- u64 x11; /* general register */
- u64 x10; /* general register */
- u64 x09; /* general register */
- u64 x08; /* general register */
- u64 x07; /* general register */
- u64 x06; /* general register */
- u64 x05; /* general register */
- u64 x04; /* general register */
- u64 x03; /* general register */
- u64 x02; /* general register */
- u64 x01; /* general register */
- u64 x00; /* general register */
+ u64 elr; /**< 通用寄存器 */
+ u64 spsr; /**< 通用寄存器 */
+ u64 far; /**< 通用寄存器 */
+ u64 esr; /**< 通用寄存器 */
+ u64 xzr; /**< 通用寄存器 */
+ u64 x30; /**< 通用寄存器 */
+ u64 x29; /**< 通用寄存器 */
+ u64 x28; /**< 通用寄存器 */
+ u64 x27; /**< 通用寄存器 */
+ u64 x26; /**< 通用寄存器 */
+ u64 x25; /**< 通用寄存器 */
+ u64 x24; /**< 通用寄存器 */
+ u64 x23; /**< 通用寄存器 */
+ u64 x22; /**< 通用寄存器 */
+ u64 x21; /**< 通用寄存器 */
+ u64 x20; /**< 通用寄存器 */
+ u64 x19; /**< 通用寄存器 */
+ u64 x18; /**< 通用寄存器 */
+ u64 x17; /**< 通用寄存器 */
+ u64 x16; /**< 通用寄存器 */
+ u64 x15; /**< 通用寄存器 */
+ u64 x14; /**< 通用寄存器 */
+ u64 x13; /**< 通用寄存器 */
+ u64 x12; /**< 通用寄存器 */
+ u64 x11; /**< 通用寄存器 */
+ u64 x10; /**< 通用寄存器 */
+ u64 x09; /**< 通用寄存器 */
+ u64 x08; /**< 通用寄存器 */
+ u64 x07; /**< 通用寄存器 */
+ u64 x06; /**< 通用寄存器 */
+ u64 x05; /**< 通用寄存器 */
+ u64 x04; /**< 通用寄存器 */
+ u64 x03; /**< 通用寄存器 */
+ u64 x02; /**< 通用寄存器 */
+ u64 x01; /**< 通用寄存器 */
+ u64 x00; /**< 通用寄存器 */
};
struct linx_core_reg_info {
@@ -703,171 +700,167 @@ struct linx_core_reg_info {
u32 mepc;
u32 mstatus;
u32 mcause;
- u32 rsv[39]; /* total size of this structure must match struct arm_core_reg_info */
+ u32 rsv[39]; /**< 该结构体总大小与struct arm_core_reg_info保持一致 */
};
#define DATA_LEN_1K 1024
-struct comm_info_sw_watchdog { /* software watchdog timeout report interface */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_info_sw_watchdog { /**< 软狗超时信息上报接口 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- /* global information */
- u32 curr_time_h; /* time of infinite loop, cycle */
- u32 curr_time_l; /* time of infinite loop, cycle */
- u32 task_id; /* task of infinite loop */
- u8 core_type; /* see core_type_e definition */
- u8 rsv[3]; /* reserved field for extension */
+ /**< 全局信息 */
+ u32 curr_time_h; /**< 发生死循环的时间,cycle */
+ u32 curr_time_l; /**< 发生死循环的时间,cycle */
+ u32 task_id; /**< 发生死循环的任务 */
+ u8 core_type; /**< 参考core_type_e定义 */
+ u8 rsv[3]; /**< 保留字段,用于扩展 */
- /* register information, TSK_CONTEXT_S */
- u64 pc; /* general register */
+ /**< 寄存器信息,TSK_CONTEXT_S */
+ u64 pc; /**< 通用寄存器 */
union core_reg {
- struct arm_core_reg_info arm_reg;
+ struct arm_core_reg_info arm_reg;
struct linx_core_reg_info linx_reg;
} reg_info;
- /* stack control information, STACK_INFO_S */
- u64 stack_top; /* stack top */
- u64 stack_bottom; /* stack bottom */
- u64 sp; /* current stack SP pointer value */
- u32 curr_used; /* current stack usage size */
- u32 peak_used; /* historical peak stack usage */
- u32 is_overflow; /* stack overflow flag */
+ /**< 堆栈控制信息,STACK_INFO_S */
+ u64 stack_top; /**< 栈顶 */
+ u64 stack_bottom; /**< 栈底 */
+ u64 sp; /**< 栈当前SP指针值 */
+ u32 curr_used; /**< 栈当前使用的大小 */
+ u32 peak_used; /**< 栈使用的历史峰值 */
+ u32 is_overflow; /**< 栈是否溢出 */
- /* stack actual content */
- u32 stack_actlen; /* actual stack length (<=1024) */
- u8 stack_data[DATA_LEN_1K]; /* content beyond 1024 will be truncated */
+ /**< 堆栈具体内容 */
+ u32 stack_actlen; /**< 实际的堆栈长度(<=1024) */
+ u8 stack_data[DATA_LEN_1K]; /**< 超过1024部分,会被截断 */
};
-/* last words information */
-#define XREGS_NUM 31 /* register number */
-typedef struct tag_cpu_tick { /* time */
- u32 cnt_hi; /* cycle count high 32 bits */
- u32 cnt_lo; /* cycle count low 32 bits */
+/**< 临终遗言信息 */
+#define XREGS_NUM 31 /**< 寄存器数量 */
+typedef struct tag_cpu_tick { /**< 时间 */
+ u32 cnt_hi; /**< cycle计数高32位 */
+ u32 cnt_lo; /**< cycle计数低32位 */
} CPU_TICK;
-typedef struct tag_ax_exc_reg_info { /* general register */
- u64 ttbr0; /* general register */
- u64 ttbr1; /* general register */
- u64 tcr; /* general register */
- u64 mair; /* general register */
- u64 sctlr; /* general register */
- u64 vbar; /* general register */
- u64 current_el; /* general register */
- u64 sp; /* general register */
- /* memory layout of the following fields must be consistent with TskContext */
- u64 elr; /* general register */
- u64 spsr; /* general register */
- u64 far_r; /* general register */
- u64 esr; /* general register */
- u64 xzr; /* general register */
- u64 xregs[XREGS_NUM]; /* registers 0~30: x30~x0 */
+typedef struct tag_ax_exc_reg_info { /**< 通用寄存器 */
+ u64 ttbr0; /**< 通用寄存器 */
+ u64 ttbr1; /**< 通用寄存器 */
+ u64 tcr; /**< 通用寄存器 */
+ u64 mair; /**< 通用寄存器 */
+ u64 sctlr; /**< 通用寄存器 */
+ u64 vbar; /**< 通用寄存器 */
+ u64 current_el; /**< 通用寄存器 */
+ u64 sp; /**< 通用寄存器 */
+ /**< 以下字段的内存布局与TskContext保持一致 */
+ u64 elr; /**< 通用寄存器 */
+ u64 spsr; /**< 通用寄存器 */
+ u64 far_r; /**< 通用寄存器 */
+ u64 esr; /**< 通用寄存器 */
+ u64 xzr; /**< 通用寄存器 */
+ u64 xregs[XREGS_NUM]; /**< 寄存器0~30: x30~x0 */
} EXC_REGS_S;
typedef struct exc_call_stack_info {
- u32 depth; /* call stack depth */
- u64 addrList[10]; /* call stack address list */
- char nameList[10][64]; /* call stack function name list */
+ u32 depth; /* 调用栈深度 */
+ u64 addrList[10]; /* 调用栈地址列表 */
+ char nameList[10][64]; /* 调用栈函数名列表 */
} exc_call_stack_info_s;
typedef struct tag_exc_info {
- char os_ver[48]; /* OS version */
- char app_ver[64]; /* product version */
- u32 exc_cause; /* exception cause */
- u32 thread_type; /* thread type before exception */
- u32 thread_id; /* thread PID before exception */
- u16 byte_order; /* byte order */
- u16 cpu_type; /* CPU type */
- u32 cpu_id; /* CPU ID */
- CPU_TICK cpu_tick; /* CPU Tick */
- u32 nest_cnt; /* exception nesting count */
- u32 fatal_errno; /* fatal error code, valid when fatal error occurs */
- u64 uw_sp; /* stack pointer before exception */
- u64 stack_bottom; /* stack bottom before exception */
- /* core register context information when exception occurs, 82\57 must be at byte 152,
- * if changed, need to update OS_EXC_REGINFO_OFFSET macro in sre_platform.eh
- */
+ char os_ver[48]; /**< OS版本号 */
+ char app_ver[64]; /**< 产品版本号 */
+ u32 exc_cause; /**< 异常原因 */
+ u32 thread_type; /**< 异常前的线程类型 */
+ u32 thread_id; /**< 异常前线程PID */
+ u16 byte_order; /**< 字节序 */
+ u16 cpu_type; /**< CPU类型 */
+ u32 cpu_id; /**< CPU ID */
+ CPU_TICK cpu_tick; /**< CPU Tick */
+ u32 nest_cnt; /**< 异常嵌套计数 */
+ u32 fatal_errno; /**< 致命错误码,发生致命错误时有效 */
+ u64 uw_sp; /**< 异常前栈指针 */
+ u64 stack_bottom; /**< 异常前栈底 */
+ /**< 异常发生时的核内寄存器上下文信息,82\57必须位于152字节处,若改动,需更新sre_platform.eh中的OS_EXC_REGINFO_OFFSET宏 */
EXC_REGS_S reg_info;
} EXC_INFO_S;
typedef struct tag_exc_info_all {
- char os_ver[48]; /* OS version */
- char app_ver[64]; /* product version */
- u32 exc_cause; /* exception cause */
- u32 thread_type; /* thread type before exception */
- u32 thread_id; /* thread PID before exception */
- u16 byte_order; /* byte order */
- u16 cpu_type; /* CPU type */
- u32 cpu_id; /* CPU ID */
- CPU_TICK cpu_tick; /* CPU Tick */
- u32 nest_cnt; /* exception nesting count */
- u32 fatal_errno; /* fatal error code, valid when fatal error occurs */
- u64 uw_sp; /* stack pointer before exception */
- u64 stack_bottom; /* stack bottom before exception */
- /* core register context information when exception occurs, 82\57 must be at byte 152,
- * if changed, need to update OS_EXC_REGINFO_OFFSET macro in sre_platform.eh
- */
+ char os_ver[48]; /**< OS版本号 */
+ char app_ver[64]; /**< 产品版本号 */
+ u32 exc_cause; /**< 异常原因 */
+ u32 thread_type; /**< 异常前的线程类型 */
+ u32 thread_id; /**< 异常前线程PID */
+ u16 byte_order; /**< 字节序 */
+ u16 cpu_type; /**< CPU类型 */
+ u32 cpu_id; /**< CPU ID */
+ CPU_TICK cpu_tick; /**< CPU Tick */
+ u32 nest_cnt; /**< 异常嵌套计数 */
+ u32 fatal_errno; /**< 致命错误码,发生致命错误时有效 */
+ u64 uw_sp; /**< 异常前栈指针 */
+ u64 stack_bottom; /**< 异常前栈底 */
+ /**< 异常发生时的核内寄存器上下文信息,82\57必须位于152字节处,若改动,需更新sre_platform.eh中的OS_EXC_REGINFO_OFFSET宏 */
EXC_REGS_S reg_info;
exc_call_stack_info_s call_stack_info;
} EXC_INFO_ALL_S;
-#define MPU_LASTWORD_SIZE 1024 /* lastword single data length */
-typedef struct tag_comm_info_up_lastword { /* up lastword module interface reported to driver */
- struct mgmt_msg_head head; /* mbox message header */
+#define MPU_LASTWORD_SIZE 1024 /**< 临终遗言单次数据长度 */
+typedef struct tag_comm_info_up_lastword { /**< 上报给驱动的up lastword模块接口 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- EXC_INFO_S stack_info; /* stack information */
+ EXC_INFO_S stack_info; /**< 堆栈信息 */
- /* stack actual content */
- u32 stack_actlen; /* actual stack length (<=1024) */
- u8 stack_data[MPU_LASTWORD_SIZE]; /* payload content beyond 1024 will be truncated */
+ /* 堆栈具体内容 */
+ u32 stack_actlen; /**<实际的堆栈长度(<=1024) */
+ u8 stack_data[MPU_LASTWORD_SIZE]; /**< payload 超过1024部分,会被截断 */
} comm_info_up_lastword_s;
typedef struct {
u32 magic;
- u32 symbol_num; /* symbol number */
- u32 code_size; /* patch code size */
- u32 rsvd0[5]; /* reserved field */
- char git_tag[64]; /* cold baseline git tag */
- char compile_time[20]; /* compile time */
- u32 rsvd1; /* reserved field for 8-byte alignment */
+ u32 symbol_num; /**< 符号个数 */
+ u32 code_size; /**< 补丁代码大小 */
+ u32 rsvd0[5]; /**< 保留字段 */
+ char git_tag[64]; /**< 冷基线的git标签 */
+ char compile_time[20]; /**< 编译时间 */
+ u32 rsvd1; /**< 用于8字节对齐的保留字段 */
} patch_head_info_s;
-struct hinic5_cmd_update_firmware { /* firmware upgrade */
- struct mgmt_msg_head msg_head; /* mbox message header */
+struct hinic5_cmd_update_firmware { /**< 固件升级 */
+ struct mgmt_msg_head msg_head; /**< mbox消息头 */
struct {
- u32 sl : 1; /* last slice */
- u32 sf : 1; /* first slice */
- u32 flag : 1; /* partition flag */
- u32 bit_signed : 1; /* signature flag */
- u32 reserved : 12; /* reserved field */
- u32 fragment_len : 16; /* fragment length */
- } ctl_info; /* control information */
+ u32 sl : 1; /**< 尾片 */
+ u32 sf : 1; /**< 首片 */
+ u32 flag : 1; /**< 分区标识 */
+ u32 bit_signed : 1; /**< 签名标识 */
+ u32 reserved : 12; /**< 保留域段 */
+ u32 fragment_len : 16; /**< 分片长度 */
+ } ctl_info; /**< 控制信息 */
struct {
- u32 section_crc; /* sub-firmware crc */
- u32 section_type; /* sub-firmware type */
- } section_info; /* sub-firmware information */
+ u32 section_crc; /**< 子固件crc */
+ u32 section_type; /**< 子固件类型 */
+ } section_info; /**< 子固件信息 */
- u32 total_len; /* image length */
- u32 section_len; /* sub-firmware length */
- u32 section_version; /* sub-firmware version */
- u32 section_offset; /* sub-firmware offset */
- u32 data[384]; /* image data */
+ u32 total_len; /**< 镜像长度 */
+ u32 section_len; /**< 子固件长度 */
+ u32 section_version; /**< 子固件版本 */
+ u32 section_offset; /**< 子固件偏移 */
+ u32 data[384]; /**< 镜像数据 */
};
-struct hinic5_cmd_activate_firmware { /* image activation */
- struct mgmt_msg_head msg_head; /* mbox message header */
- u8 index; /* config file activation idx (default use 0) */
- u8 data[7]; /* payload */
+struct hinic5_cmd_activate_firmware { /**< 镜像激活 */
+ struct mgmt_msg_head msg_head; /**< mbox消息头 */
+ u8 index; /**< 配置文件激活idx(默认使用0) */
+ u8 data[7]; /**< payload */
};
-struct hinic5_cmd_switch_config { /* config file switch */
- struct mgmt_msg_head msg_head; /* mbox message header */
- u8 index; /* config file idx 0~1 */
- u8 data[7]; /* payload */
+struct hinic5_cmd_switch_config { /**< 配置文件切换 */
+ struct mgmt_msg_head msg_head; /**< mbox消息头 */
+ u8 index; /**< 配置文件idx0~1 */
+ u8 data[7]; /**< payload */
};
-/* start id defined for UB register access adaptation, used to identify UB module in interface, cannot conflict with INTERNAL_RING_NODE_ID_E */
+/* start 为适配ub访问寄存器,定义的id,用于接口中识别UB模块, 不能和INTERNAL_RING_NODE_ID_E冲突 */
enum hinic5_ub_mod_id {
HINIC5_UB_D2H = 64,
HINIC5_UB_LQ_TP = HINIC5_UB_D2H,
@@ -895,267 +888,166 @@ enum hinic5_ub_mod_id {
/* 1872 */
HINIC5_UB_END_IDX,
};
-/* end node id defined for UB register access adaptation, used to identify UB module in interface, cannot conflict with INTERNAL_RING_NODE_ID_E */
+/* end 为适配ub访问寄存器,定义的node id,用于接口中识别UB模块, 不能和INTERNAL_RING_NODE_ID_E冲突 */
-#define MAX_DATA_NUM (240)
-struct csr_msg { /* csr register read information */
+#define MAX_DATA_NUM (240)
+struct csr_msg { /**< csr寄存器读信息 */
struct {
- u32 node_id : 5; /* node id */
- u32 data_width : 10; /* access width */
- u32 module_id : 8; /* module id, used to identify which module the address belongs to (some modules have no node_id) */
- u32 rsvd : 9; /* reserved field */
+ u32 node_id : 5; /**< 节点id */
+ u32 data_width : 10; /**< 访问宽度 */
+ u32 module_id : 8; /**< 模块id,用于识别地址属于哪个模块(部分模块没有node_id) */
+ u32 rsvd : 9; /* 保留域段 */
} bits;
- u32 addr; /* address */
+ u32 addr; /**< 地址 */
};
-struct comm_cmd_mbox_csr_rd_req { /* csr register read request */
- struct mgmt_msg_head head; /* mbox message header */
- struct csr_msg csr_info[MAX_DATA_NUM]; /* payload */
- u32 data_num; /* register number */
+struct comm_cmd_mbox_csr_rd_req { /**< csr寄存器读请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ struct csr_msg csr_info[MAX_DATA_NUM]; /**< payload */
+ u32 data_num; /**< 寄存器个数 */
};
-struct comm_cmd_mbox_csr_rd_ret { /* csr register read */
- struct mgmt_msg_head head; /* mbox message header */
- u64 value[MAX_DATA_NUM]; /* register read result */
+struct comm_cmd_mbox_csr_rd_ret { /**< csr寄存器读 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u64 value[MAX_DATA_NUM]; /**< 寄存器读取结果 */
};
-struct comm_cmd_mbox_csr_rd_req_ex { /* csr register read request */
- struct mgmt_msg_head head; /* mbox message header */
- u32 data_num; /* register number */
- struct csr_msg csr_info[0]; /* filled according to actual read number */
+struct comm_cmd_mbox_csr_rd_req_ex { /**< csr寄存器读请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 data_num; /**< 寄存器个数 */
+ struct csr_msg csr_info[0]; /**< 根据实际读取个数填充 */
};
-struct comm_cmd_mbox_csr_rd_ret_ex { /* csr register read */
- struct mgmt_msg_head head; /* mbox message header */
- u64 value[0]; /* filled according to actual read number */
+struct comm_cmd_mbox_csr_rd_ret_ex { /**< csr寄存器读 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u64 value[0]; /**< 根据实际读取个数填充 */
};
-struct comm_cmd_mbox_csr_wt_req { /* csr register write */
- struct mgmt_msg_head head; /* mbox message header */
- struct csr_msg csr_info; /* csr control register information */
- u64 value; /* value */
+struct comm_cmd_mbox_csr_wt_req { /**< csr寄存器写 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ struct csr_msg csr_info; /**< csr控制寄存器信息 */
+ u64 value; /**< 值 */
};
-struct comm_cmd_mbox_csr_wt_ret { /* csr register write */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_mbox_csr_wt_ret { /**< csr寄存器写 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
};
#define INDIR_MAX_INDEX_NUM 480
#define INDIR_MAX_WT_INDEX_NUM 32
-struct comm_cmd_mbox_indir_addr { /* indirect table operation information */
- u32 indir_ctrl_addr; /* control register */
- u32 indir_timeout_addr; /* timeout register */
- u32 indir_data_addr; /* data register */
+struct comm_cmd_mbox_indir_addr { /**< 间接表操作信息 */
+ u32 indir_ctrl_addr; /**< 控制寄存器 */
+ u32 indir_timeout_addr; /**< 超时寄存器 */
+ u32 indir_data_addr; /**< 数据寄存器 */
};
-struct comm_cmd_mbox_indir_tab_rd_req { /* indirect table read request */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_mbox_indir_tab_rd_req { /**< 间接表读请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- struct comm_cmd_mbox_indir_addr indir_addr; /* indirect table control information */
- u32 tab_width; /* table entry width */
- u32 index_num; /* offset idx */
- u32 index[INDIR_MAX_INDEX_NUM]; /* payload */
+ struct comm_cmd_mbox_indir_addr indir_addr; /**< 间接表控制信息 */
+ u32 tab_width; /**< 表项宽度 */
+ u32 index_num; /**< offset idx */
+ u32 index[INDIR_MAX_INDEX_NUM]; /**< payload */
};
-struct comm_cmd_mbox_indir_tab_rd_ret { /* indirect table read request */
- struct mgmt_msg_head head; /* mbox message header */
- u32 data[INDIR_MAX_INDEX_NUM]; /* payload */
+struct comm_cmd_mbox_indir_tab_rd_ret { /**< 间接表读请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 data[INDIR_MAX_INDEX_NUM]; /**< payload */
};
-struct comm_cmd_mbox_indir_tab_wt_req { /* indirect table write request */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_mbox_indir_tab_wt_req { /**< 间接表写请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- struct comm_cmd_mbox_indir_addr indir_addr; /* indirect table control information */
- u32 tab_width; /* table entry width */
- u32 index; /* offset idx */
- u32 data[INDIR_MAX_WT_INDEX_NUM]; /* payload */
+ struct comm_cmd_mbox_indir_addr indir_addr; /**< 间接表控制信息 */
+ u32 tab_width; /**< 表项宽度 */
+ u32 index; /**< offset idx */
+ u32 data[INDIR_MAX_WT_INDEX_NUM]; /**< payload */
};
-struct comm_cmd_mbox_indir_tab_wt_ret { /* indirect table write request */
- struct mgmt_msg_head head; /* mbox message header */
+struct comm_cmd_mbox_indir_tab_wt_ret { /**< 间接表写请求 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
};
enum {
- MPU_LOG_CLEAR = 0, /* clear mpu log */
- SMU_LOG_CLEAR, /* clear smu log */
- NPU_LOG_CLEAR, /* clear npu log */
- SPU_LOG_CLEAR, /* clear spu log */
- MPU_LASTWORD_CLEAR, /* clear mpu lastword */
- NPU_LASTWORD_CLEAR, /* clear microcode lastword */
- ALL_LOG_CLEAR, /* clear all logs and lastwords */
- UBC_IMP_LOG_CLEAR, /* clear ubc imp log */
- UBC_IMP_LASTWORD_CLEAR, /* clear ubc imp lastword */
- ROCE_IMP_LOG_CLEAR, /* clear roce imp log */
- ROCE_IMP_LASTWORD_CLEAR, /* clear roce imp lastword */
- ROCE_SCC_LOG_CLEAR, /* clear roce scc log */
+ MPU_LOG_CLEAR = 0, /**< 清除mpu日志 */
+ SMU_LOG_CLEAR, /**< 清除smu日志 */
+ NPU_LOG_CLEAR, /**< 清除npu日志 */
+ SPU_LOG_CLEAR, /**< 清除spu日志 */
+ MPU_LASTWORD_CLEAR, /**< 清除mpu临终遗言 */
+ NPU_LASTWORD_CLEAR, /**< 清除微码临终遗言 */
+ ALL_LOG_CLEAR, /**< 清除全量日志&临终遗言 */
+ UBC_IMP_LOG_CLEAR, /**< 清除ubc imp日志 */
+ UBC_IMP_LASTWORD_CLEAR, /**< 清除ubc imp临终遗言 */
+ ROCE_IMP_LOG_CLEAR, /**< 清除roce imp日志 */
+ ROCE_IMP_LASTWORD_CLEAR, /**< 清除roce imp临终遗言 */
+ ROCE_SCC_LOG_CLEAR, /**< 清除roce scc日志 */
CLEAR_TYPE_BUTT,
};
-struct comm_cmd_clear_log { /* clear log */
- struct mgmt_msg_head head; /* mbox message header */
- u32 type; /* clear log type */
+struct comm_cmd_clear_log { /**< 清除log */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 type; /**< 清除日志类型 */
};
-struct cmd_sector_info { /* erase flash */
- struct mgmt_msg_head head; /* mbox message header */
- u32 offset; /* flash address */
- u32 len; /* flash erase length */
+struct cmd_sector_info { /**< 擦除flash */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 offset; /**< flash地址 */
+ u32 len; /**< flash擦除长度 */
};
enum flash_counter_info_req_type {
- FLASH_COUNTER_TYPE_GET_MPU_SIZE, /* mpu counter size get type */
- FLASH_COUNTER_TYPE_GET_MPU_DATA, /* mpu counter data get type */
- FLASH_COUNTER_TYPE_GET_NPU_SIZE, /* npu counter size get type */
- FLASH_COUNTER_TYPE_GET_NPU_DATA, /* npu counter data get type */
- FLASH_COUNTER_TYPE_INVALID /* counter get type invalid value */
+ FLASH_COUNTER_TYPE_GET_MPU_SIZE, /**< mpu counter大小获取类型 */
+ FLASH_COUNTER_TYPE_GET_MPU_DATA, /**< mpu counter数据获取类型 */
+ FLASH_COUNTER_TYPE_GET_NPU_SIZE, /**< npu counter大小获取类型 */
+ FLASH_COUNTER_TYPE_GET_NPU_DATA, /**< npu counter数据获取类型 */
+ FLASH_COUNTER_TYPE_INVALID /**< counter获取类型无效值 */
};
-struct flash_counter_info_req { /* get firmware counter information */
- struct mgmt_msg_head head; /* mbox message header */
- u8 type; /* flash_counter_info_req_type */
- u8 rsv[3]; /* reserved field */
- u32 offset; /* address offset */
- u32 length; /* data length */
+struct flash_counter_info_req { /**< 获取固件counter信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 type; /**< flash_counter_info_req_type */
+ u8 rsv[3]; /**< 保留域段 */
+ u32 offset; /**< 地址偏移 */
+ u32 length; /**< 数据长度 */
};
#define FLASH_COUNTER_TYPE_GET_DATA_MAX_SIZE 1024
-struct flash_counter_info_resp { /* get firmware counter information */
- struct mgmt_msg_head head; /* mbox message header */
- u32 length; /* data length */
- u8 data[FLASH_COUNTER_TYPE_GET_DATA_MAX_SIZE]; /* payload */
+struct flash_counter_info_resp { /**< 获取固件counter信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 length; /**< 数据长度 */
+ u8 data[FLASH_COUNTER_TYPE_GET_DATA_MAX_SIZE]; /**< payload */
};
typedef struct {
- u64 smu_images; /* smu image */
- u64 mpu_images; /* mpu image */
- u64 npu_images; /* npu image */
- u64 ppe_images; /* microcode ppe image */
- u64 cfg_images; /* config file image */
- u64 patch_images; /* mpu patch image */
- u64 rsvd[4]; /* reserved field */
-} module_images; /* firmware image type */
+ u64 smu_images; /**< smu镜像 */
+ u64 mpu_images; /**< mpu镜像 */
+ u64 npu_images; /**< npu镜像 */
+ u64 ppe_images; /**< 微码ppe镜像 */
+ u64 cfg_images; /**< 配置文件镜像 */
+ u64 patch_images; /**< mpu补丁镜像 */
+ u64 rsvd[4]; /**< 保留域段 */
+} module_images; /**< 固件镜像类型 */
typedef struct {
- struct mgmt_msg_head head; /* mbox message header */
- u32 rsvd[4]; /* reserved field */
-} comm_cmd_query_module_images_req; /* query image type */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u32 rsvd[4]; /**< 保留域段 */
+} comm_cmd_query_module_images_req; /**< 查询镜像类型 */
typedef struct {
- struct mgmt_msg_head head; /* mbox message header */
- module_images img; /* firmware image */
-} comm_cmd_query_module_images_rsp; /* query image type */
-
-typedef struct tag_mpu_ncsi_counter_info_s {
- u32 ncsi_rx_octets_total_ok; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_octets_bad; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_uc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_mc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_bc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_64octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_65to127octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_128to255octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_255to511octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_512to1023octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_1024to1518octets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pkts_1519tomaxoctets; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_fcs_errs; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_tagged; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_data_errs; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_align_errs; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_long_errs; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_jabber_errs; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pause_maccontrol_framcounter; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_unknow_maccontrol_framcounter; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_very_long_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_runt_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_short_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_filt_pkt_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_octets_total_filt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_octets_transmitte_ok; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_octets_transmitte_bad; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_uc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_mc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_bc_pkts; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_64octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_65to127octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_128to255octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_255to511octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_512to1023octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_1024to1518octets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pkts_1519tomaxoctets; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_underrun; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_tagged; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_crc_err; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pause_frams; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_overrun_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_lengthfield_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_fail_comma_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_frm_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_frm_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_xon_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_xoff_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_xon_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_empty_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_app_bd_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_add_bd_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_txbd_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_txbd_empty_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_txbd_code_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_txbd_min_frame_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_txbd_max_frame_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rls_bd_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_pkt_cnt_low; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_pkt_cnt_high; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_pkt_disc_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pt_ch_err_cnt0; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pt_ch_err_cnt1; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pt_ch_err_cnt2; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pt_ch_err_cnt3; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_pt_pkt_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_ctrl_ok_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_ctrl_disc_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_ctrl_chksum_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_ctrl_pkt_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_ctrl_len_mismatch_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_tx_ctrl_len_short; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_ch_ok_cnt0; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_ch_ok_cnt1; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_ch_ok_cnt2; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_pt_ch_ok_cnt3; /* ncsi register, see nmanager for details */
- u32 ncsi_rx_ctrl_pavload_len_err_cnt; /* ncsi register, see nmanager for details */
- u32 ncsi_ipsurx_hit_count; /* ncsi register, see nmanager for details */
- u32 pie_to_mpu_bd_cnt; /* ncsi register, see nmanager for details */
- u32 pie_to_ipsu_bd_cnt; /* ncsi register, see nmanager for details */
- u32 pie_to_ncsi_bd_cnt; /* ncsi register, see nmanager for details */
- u32 rsv[10];
-} mpu_ncsi_counter_info_s; /* ncsi register, see nmanager for details */
-
-#define NCSI_COUNT_OPT_TYPE_READ 0 /* ncsi counter read */
-#define NCSI_COUNT_OPT_TYPE_CLEAR 1 /* nsci counter clear */
-
-struct comm_cmd_ncsi_counter_req { /* get ncsi counter */
- struct mgmt_msg_head head; /* mbox message header */
- u8 opt_type; /* 0:read counter 1:counter clear */
- u8 rsvd[3];
-};
-
-struct comm_cmd_ncsi_counter_resp { /* get ncsi counter */
- struct mgmt_msg_head head; /* mbox message header */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ module_images img; /**< 固件镜像 */
+} comm_cmd_query_module_images_rsp; /**< 查询镜像类型 */
- mpu_ncsi_counter_info_s ncsi_cnt_info; /* counter information */
-};
#define SINGLE_EFUSE_BIN_SIZE 512
#define SEND_EFUSE_DATA_SIZE (SINGLE_EFUSE_BIN_SIZE * 3)
-struct send_efuse_data_s { /* efuse information burn */
- struct mgmt_msg_head head; /* mbox message header */
- u8 opt_type; /* efuse operation type: 1: burn efuse bin,
- * 2: hw rotpk switch to guest rotpk
- */
- u8 rsvd0[3]; /* reserved field */
- u32 total_len; /* entire package leng value */
- u32 data_csum; /* entire package data count sum value */
- u8 data[SEND_EFUSE_DATA_SIZE]; /* payload 1024B*/
+struct send_efuse_data_s { /**< efuse信息烧写 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 opt_type; /**< efuse操作类型:1: burn efuse bin,2: hw rotpk switch to guest rotpk */
+ u8 rsvd0[3]; /**< 保留域段 */
+ u32 total_len; /**< entire package leng value */
+ u32 data_csum; /**< entire package data count sum value */
+ u8 data[SEND_EFUSE_DATA_SIZE]; /**< payload 1024B*/
};
typedef enum {
@@ -1170,21 +1062,17 @@ typedef enum {
#define DFX_MAG_MAX_REG_NUM (32)
struct comm_info_dfx_mag_reg {
struct mgmt_msg_head head;
- u16 sel; /* direction: 0 - tx 1 - rx */
- u16 write; /* read/write flag: 0 - read 1 - write */
- u32 reg_addr; /* register address */
- u32 reg_cnt; /* starting from reg_addr as BASE_ADDR, number of consecutive registers to read (not bytes, but register count),
- * maximum 32
- */
- u32 clear; /* read clear flag: 0 - not read clear 1 - read clear (invalid for write operation) */
- u32 data[DFX_MAG_MAX_REG_NUM]; /* returned data, up to DFX_MAG_MAX_REG_NUM,
- * actual valid data count indicated by reg_cnt
- */
+ u16 sel; /**< 方向: 0 - tx 1 - rx */
+ u16 write; /**< 读写标志: 0 - 读 1 - 写 */
+ u32 reg_addr; /**< 寄存器地址 */
+ u32 reg_cnt; /**< 以reg_addr为BASE_ADDR,读取多少个连续的寄存器个数(不是字节数,是寄存器个数),最大32个 */
+ u32 clear; /**< 读清标志: 0 - 不读清 1 - 读清(写操作时此参数无效) */
+ u32 data[DFX_MAG_MAX_REG_NUM]; /**< 返回的数据,最多DFX_MAG_MAX_REG_NUM个,根据reg_cnt来标明实际有效数据个数 */
};
-#define UPDATE_CMD_HEAD_NEW_VERSION 0x1 /* duplicate packet command version from tool */
+#define UPDATE_CMD_HEAD_NEW_VERSION 0x1 // 工具下发的重复包命令版本
-/* firmware upgrade error code definition */
+/**< 固件升级错误码定义 */
enum hinic5_update_fw_err_code {
MPU_FW_UPDATE_OK = 0x00,
MPU_FW_UPDATE_START = 0x01,
@@ -1223,32 +1111,32 @@ enum hinic5_update_fw_err_code {
MPU_FW_UPDATE_HOT_ACTIVE_FAIL = 0xfe,
};
-struct fw_update_msg_st { /* */
- struct mgmt_msg_head msg_head; /* mbox message header */
+struct fw_update_msg_st { /**< */
+ struct mgmt_msg_head msg_head; /**< mbox消息头 */
struct {
- u32 SL : 1; /* last slice */
- u32 SF : 1; /* first slice */
- u32 Flag : 1; /* partition flag */
- u32 Signed : 1; /* signature flag */
- u32 Repeat : 1; /* fragment operation flash */
- u32 updatefw_main_area_flag : 1; /* main area flag */
- u32 Reserved : 10; /* reserved field */
- u32 Fragment_Len : 16; /* fragment length */
- } ctl_info; /* */
+ u32 SL : 1; /**< 尾片 */
+ u32 SF : 1; /**< 首片 */
+ u32 Flag : 1; /**< 分区标识 */
+ u32 Signed : 1; /**< 签名标识 */
+ u32 Repeat : 1; /**< 分片操作flash */
+ u32 updatefw_main_area_flag : 1; /**< 主区标识 */
+ u32 Reserved : 10; /**< 保留域段 */
+ u32 Fragment_Len : 16; /**分片长度< */
+ } ctl_info; /**< */
struct {
- u32 FW_section_CRC; /* fragment operation flash */
- u32 FW_section_type; /* sub-firmware type */
- } section_info; /* sub-firmware information */
+ u32 FW_section_CRC; /**< 分片操作flash */
+ u32 FW_section_type; /**< 子固件类型 */
+ } section_info; /**< 子固件信息 */
- u32 total_len; /* image length */
- u32 setion_total_len; /* sub-firmware length */
- u32 fw_section_version; /* sub-firmware version */
- u32 section_offset; /* sub-firmware offset */
- u32 data[384]; /* image data */
+ u32 total_len; /**< 镜像长度 */
+ u32 setion_total_len; /**< 子固件长度 */
+ u32 fw_section_version; /**< 子固件版本 */
+ u32 section_offset; /**< 子固件偏移 */
+ u32 data[384]; /**< 镜像数据 */
};
-/* hot activation type */
+/* 热激活类型 */
typedef enum {
HOT_ACTIVE_NONE = 0,
HOT_ACTIVE_MPU = 1,
@@ -1257,32 +1145,32 @@ typedef enum {
HOT_ACTIVE_SCC = 4,
} hot_active_type_e;
-/* MPU hot activation type */
+/* MPU热激活类型 */
typedef enum {
- MPU_HOT_ACTIVE_NONE, /* hot upgrade not yet performed */
- MPU_HOT_ACTIVE_PATCH, /* hot patch */
- MPU_HOT_ACTIVE_REPLACE, /* hot replace */
+ MPU_HOT_ACTIVE_NONE, /**< 还没有进行热升级 */
+ MPU_HOT_ACTIVE_PATCH, /**< 热补丁 */
+ MPU_HOT_ACTIVE_REPLACE, /**< 热替换 */
} mpu_hot_active_type_e;
-struct cmd_hot_active_fw { /* hot upgrade activation */
- struct mgmt_msg_head head; /* mbox message header */
- u8 type; /* activate sub-firmware type, 1: mpu; 2: ucode; 3: mpu & npu */
- u8 mpu_hot_active_type; /* MPU hot activation type, valid when type is MPU or MNPU */
- u8 data[6]; /* reserved field */
+struct cmd_hot_active_fw { /**< 热升级激活 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 type; /**< 激活子固件类型,1: mpu; 2: ucode; 3: mpu & npu */
+ u8 mpu_hot_active_type; /**< MPU热激活类型,当type为MPU或MNPU时有效 */
+ u8 data[6]; /**< 保留域段 */
};
-struct cmd_bat_set_info { /* hot upgrade bat table entry operation transition information */
- struct mgmt_msg_head head; /* mbox message header */
+struct cmd_bat_set_info { /**< 热升级bat表项操作过渡信息 */
+ struct mgmt_msg_head head; /**< mbox消息头 */
- u16 func_id; /* specified function id */
- u8 smf_id; /* smf idx */
- u8 rsvd1; /* reserved field */
- u32 bat_offset; /* bat offset */
- u32 data_size; /* data size */
- u8 data[256]; /* payload */
+ u16 func_id; /**< 指定function id */
+ u8 smf_id; /**< smf idx */
+ u8 rsvd1; /**< 保留域段 */
+ u32 bat_offset; /**< bat偏移 */
+ u32 data_size; /**< 数据大小 */
+ u8 data[256]; /**< payload */
};
-/* read dbf information */
+/* 读取dbf信息 */
typedef struct {
u32 device_id;
u32 vendor_id;
@@ -1298,8 +1186,8 @@ typedef struct {
typedef struct {
struct mgmt_msg_head head;
- u8 valid; /* 1: valid */
- u8 host_id; /* container home host, range 0 ~ 3 */
+ u8 valid; /* 1: valid */
+ u8 host_id; /* 容器归宿host,范围0 ~ 3 */
u8 rsvd[2];
} comm_cmd_con_sel_sta;
@@ -1320,9 +1208,9 @@ typedef struct vf_bdf_info {
struct comm_cmd_get_bdf_info_s {
struct mgmt_msg_head head;
- comm_pf_bdf_info_s pf_bdf_info[PCIE_MODE_PF_NUM];
- comm_vf_bdf_info_s vf_bdf_info[PCIE_MODE_PF_NUM];
- u32 vf_num; /* vf num */
+ comm_pf_bdf_info_s pf_bdf_info[PCIE_MODE_PF_NUM];
+ comm_vf_bdf_info_s vf_bdf_info[PCIE_MODE_PF_NUM];
+ u32 vf_num; /**< vf num */
};
typedef struct comm_virtio_dev_cmd {
@@ -1351,41 +1239,42 @@ struct comm_cmd_set_virtio_dev {
#define PSM_GIT_CHAR_NUM (20)
struct cmd_get_mpu_git_code {
struct mgmt_msg_head head; /* 8B */
- u8 rsvd[3]; /* reserved */
+ u8 rsvd[3]; /* 保留 */
u8 psm_en;
- char mpu_git_code[64]; /* git code and compile time, 60 characters */
- char psm_git_code[PSM_GIT_CHAR_NUM + 1]; /* psm git code and compile time, 20 characters */
- u8 rsvd1[3]; /* reserved */
+ char mpu_git_code[64]; /* git 号和编译时间长60个字符 */
+ char psm_git_code[PSM_GIT_CHAR_NUM +
+ 1]; /* psm git 号和编译时间长20个字符 */
+ u8 rsvd1[3]; /* 保留 */
};
-/* disable chip auto reset */
+/* 关闭芯片自复位 */
struct comm_cmd_enable_auto_rst_chip {
struct mgmt_msg_head head;
u8 op_code; /* 0: get 1: set */
- u8 enable; /* 1: enable auto reset chip; 0: disable auto reset chip */
+ u8 enable; /* 1: 使能自动复位芯片; 0: 禁止自动复位芯片 */
u8 rsvd[2];
};
-/* chip core temperature structure definition */
+/* 芯片核温结构体定义 */
struct comm_temp_in_info {
struct mgmt_msg_head head; /* 8B */
- u8 opt_type; /* 0:read operation 1:cfg operation */
+ u8 opt_type; /* 0:read operation 1:cfg operation */
u8 rsv[3];
- s32 max_temp; /* chip core temperature threshold */
- s32 min_temp; /* chip core temperature threshold */
+ s32 max_temp; /* 芯片核温阈值 */
+ s32 min_temp; /* 芯片核温阈值 */
};
struct comm_temp_out_info {
struct mgmt_msg_head head; /* 8B */
- s32 temp_data; /* read temperature */
- s32 max_temp_threshold; /* chip core temperature threshold */
- s32 min_temp_threshold; /* chip core temperature threshold */
- s32 max_temp; /* chip core temperature historical maximum */
- s32 min_temp; /* chip core temperature historical minimum */
+ s32 temp_data; /* 读出的温度 */
+ s32 max_temp_threshold; /* 芯片核温阈值 */
+ s32 min_temp_threshold; /* 芯片核温阈值 */
+ s32 max_temp; /* 芯片核温历史最大值 */
+ s32 min_temp; /* 芯片核温历史最小值 */
};
-/* chip id information */
+/* chip id信息 */
struct comm_chip_id_info {
struct mgmt_msg_head head;
@@ -1393,7 +1282,7 @@ struct comm_chip_id_info {
u8 rsvd[3];
};
-/* die id module interface */
+/* die id模块接口 */
struct comm_cmd_get_die_id {
struct mgmt_msg_head head;
@@ -1413,7 +1302,7 @@ struct comm_cmd_msix_info {
struct mgmt_msg_head head;
u8 rsvd1;
- u8 flag; /* 0-second map, 1-actual map, 2-first map entry */
+ u8 flag; /* 0-second map, 1-actual map, 2-first map entry */
u16 function_id;
};
@@ -1428,8 +1317,8 @@ enum log_status_type {
};
struct mpu_log_status_info {
struct mgmt_msg_head head;
- u8 type; /* 0: read 1: write */
- u8 log_status; /* 0: idle 1: busy */
+ u8 type; /* 0: 读 1:写 */
+ u8 log_status; /* 0:空闲 1:忙碌 */
u8 rsvd[2];
};
@@ -1446,7 +1335,7 @@ typedef struct {
u32 func_id;
u32 smf_id;
u32 queue_id;
- u32 smf_id_valid; /* whether the input smf_id is valid */
+ u32 smf_id_valid; // 传入smf_id是否有效
} comm_cmd_root_ctx_load_req_s;
typedef struct {
@@ -1458,16 +1347,16 @@ typedef struct {
} comm_cmd_root_ctx_load_ret_s;
struct cmd_query_fw {
- struct mgmt_msg_head head; /* 8B */
- u32 offset; /* offset, because the returned information is large, multiple returns are needed */
- u32 len; /* data length to read */
+ struct mgmt_msg_head head; // 8B
+ u32 offset; // 偏移,因为返回的信息比较大,因此,需要多次返回
+ u32 len; // 要读的数据长度
};
#define MAX_CMD_DATA_LEN (1024 + 512)
struct cmd_fw_info {
- struct mgmt_msg_head head; /* 8B */
- u32 len; /* actual data length read */
- u8 data[MAX_CMD_DATA_LEN]; /* maximum 1536 bytes per read */
+ struct mgmt_msg_head head; // 8B
+ u32 len; // 返回实际读到的数据长度
+ u8 data[MAX_CMD_DATA_LEN]; // 一次最多读1536字节数据
};
typedef struct {
@@ -1489,7 +1378,7 @@ typedef struct {
typedef struct {
u32 p_tx_left_tag;
u32 np_tx_left_tag;
- u32 cpl_tx_left_tag;
+ u32 cpl_tx_left_Tag;
u32 p_rx_left_tag;
u32 np_rx_left_tag;
u32 cpl_rx_left_tag;
@@ -1505,14 +1394,14 @@ typedef struct {
} pcie_topo_item_s;
#define CMD_PCIE_MAX_HOST_IDX 0xD
-typedef struct {
+typedef struct {
struct mgmt_msg_head head;
u32 cur_host;
u32 host_cnt;
pcie_topo_item_s item[CMD_PCIE_MAX_HOST_IDX + 1];
} comm_cmd_get_pcie_topo_s;
-typedef struct {
+typedef struct {
struct mgmt_msg_head head;
u32 type;
u32 condition1;
@@ -1575,13 +1464,13 @@ struct cmd_mpu_set_shaper {
#define PF_TYPE 0
#define VF_TYPE 1
#define CFG_BAR_INDEX_NUM 6
-#define CFG_BAR_SIZE_MIN_NUM 4
-#define CFG_PF_BAR_SIZE_MAX_NUM 64
-#define CFG_PF_BAR3_SIZE_MAX_NUM 128
-#define CFG_VF_BAR_SIZE_MAX_NUM 64
+#define CFG_BAR_SIZE_MIN_NUM 4
+#define CFG_PF_BAR_SIZE_MAX_NUM 64
+#define CFG_PF_BAR3_SIZE_MAX_NUM 128
+#define CFG_VF_BAR_SIZE_MAX_NUM 64
#define CFG_VF_BAR4_SIZE_MAX_NUM 4096
#define CFG_BAR_SIZE_INVALID_VALUE 0xFFFFFFFF
-#define CFG_BAR_TRANSLATE_KB_TO_BYTE(bar_size) (((bar_size) * 1024) - 1)
+#define CFG_BAR_TRANSLATE_KB_TO_BYTE(bar_size) (((bar_size)*1024) - 1)
#define CFG_BAR_TRANSLATE_BYTE_TO_KB(bar_size) (((bar_size) + 1) / 1024)
#define CFG_DATA_OP_GET 0
@@ -1615,22 +1504,20 @@ typedef struct mpu_nic_func_queue_s {
typedef struct mpu_nic_bar_s {
u32 magic_bar_set;
- u8 pf_bar_index; /* 0-3 */
- u8 vf_bar_index; /* 0,2,4 */
+ u8 pf_bar_index; /**< 0-3 */
+ u8 vf_bar_index; /**< 0,2,4 */
u8 pf_bar_set_flag;
u8 vf_bar_set_flag;
- u32 bar_mode; /* temp: 0 in tool, 0xFFFFFFFF in flash ;
- * permanently: 1 in tool, 0x1 in flash
- */
+ u32 bar_mode; /**< temp: 0 in tool, 0xFFFFFFFF in flash ; permanently: 1 in tool, 0x1 in flash */
u32 pf_bar_size[CFG_BAR_INDEX_NUM];
u32 vf_bar_size[CFG_BAR_INDEX_NUM];
} mpu_nic_bar;
struct comm_cmd_cfg_data {
struct mgmt_msg_head head;
- u8 opt_type; /* operation type 0: query 1: set 2: clear 4: bar set 5: bar clear */
+ u8 opt_type; /**< operation type 0: query 1: set 2: clear 4: bar set 5: bar clear */
u8 pf_index;
- u8 queue_bitmap; /* 0: pf_sq_rq 1: vf_sq_rq 2: vf_num */
+ u8 queue_bitmap; /**< 0: pf_sq_rq 1: vf_sq_rq 2: vf_num */
u8 pf_num;
u16 pf_sq_rq;
u16 vf_sq_rq;
@@ -1652,7 +1539,7 @@ enum voltage_type_e {
};
typedef struct comm_cmd_voltage_info_s {
struct mgmt_msg_head head;
- u8 type; /* see voltage_type_e */
+ u8 type; // 参考voltage_type_e
u8 rsv[3];
u16 vol_integer;
u16 vol_decimal;
@@ -1739,29 +1626,29 @@ typedef struct {
/*
* @ingroup OS_sem
- * semaphore type.
+ * 信号量类型。
*/
typedef enum {
- RTOS_SEM_TYPE_COUNT, /* counting semaphore */
- RTOS_SEM_TYPE_BIN, /* binary semaphore */
+ RTOS_SEM_TYPE_COUNT, /* 计数型信号量 */
+ RTOS_SEM_TYPE_BIN, /* 二进制信号量 */
RTOS_SEM_TYPE_BUTT
} rtos_sem_type_e;
/*
* @ingroup OS_sem
- * wakeup mode for blocked threads in semaphore module.
+ * 信号量模块被阻塞线程唤醒方式。
*/
typedef enum {
- RTOS_SEM_MODE_FIFO, /* semaphore FIFO wakeup mode */
- RTOS_SEM_MODE_PRIOR, /* semaphore priority wakeup mode */
- RTOS_SEM_MODE_BUTT /* invalid semaphore wakeup mode */
+ RTOS_SEM_MODE_FIFO, // 信号量FIFO唤醒模式
+ RTOS_SEM_MODE_PRIOR, // 信号量优先级唤醒模式
+ RTOS_SEM_MODE_BUTT // 信号量非法唤醒方式
} rtos_sem_mode_e;
typedef struct {
u32 count;
u32 owner;
u16 sem_id;
- u8 mode; /* semaphore wakeup mode */
+ u8 mode; // 信号量唤醒模式
u8 type;
} sem_info;
@@ -1783,19 +1670,19 @@ typedef struct {
#define SWITCH_RESET_OPT_WRITE 1
typedef enum {
- RESTORE_SET_TYPE_SWITCH = 0, /* startup partition switch flag */
- RESTORE_SET_TYPE_RESET, /* auto reset flag after partition switch */
- RESTORE_SET_TYPE_FAIL_COUNT, /* set SDK load failure detection count */
- RESTORE_SET_TYPE_TIMEOUT, /* set SDK load timeout */
+ RESTORE_SET_TYPE_SWITCH = 0, // 启动切区标志位
+ RESTORE_SET_TYPE_RESET, // 切区后自动复位标志位
+ RESTORE_SET_TYPE_FAIL_COUNT, // 设置检测SDK加载失败次数
+ RESTORE_SET_TYPE_TIMEOUT, // 设置SDK加载超时时间
RESTORE_SET_TYPE_BUTT
} fw_restore_set_e;
struct cmd_chip_switch_reset {
struct mgmt_msg_head head;
u8 op_code; /* 0: set 1: get */
- u8 type; /* fw_restore_set_e, reused as fail_count return value when reading */
- u8 value; /* value to set, reused as switch&reset return value when reading */
- u8 read_value; /* only used when reading, as timeout return value */
+ u8 type; /* fw_restore_set_e, 读时复用作为fail_count返回值 */
+ u8 value; /* 待设置的值, 读时复用作为switch&reset返回值 */
+ u8 read_value; /* 只在读时使用,为timeout返回值 */
};
/* integrity */
@@ -1803,7 +1690,7 @@ struct cmd_chip_switch_reset {
#define HASH_SIG_SIZE 512
#define KEY_HASH_SIZE 32
#define PUBKEY_SIZE 1024
-#define INTEGERITY_VERIFY_ENABLE 0x5A /* use magic number to indicate integrity verification is enabled */
+#define INTEGERITY_VERIFY_ENABLE 0x5A /* 使用魔法数字标识完整性验证开启 */
typedef enum {
INTEGERITY_CMD_ENABLE = 0,
INTEGERITY_CMD_UPDATE,
@@ -1812,13 +1699,13 @@ typedef enum {
} integrity_cmd_type;
typedef struct {
- u8 integrity_type; /* user firmware integrity protection switch */
- u8 rsvd[3]; /* reserved field*/
- u8 key_hash[KEY_HASH_SIZE]; /* customer root public key hash value */
+ u8 integrity_type; /* 用户固件完整性保护开关 */
+ u8 rsvd[3]; /* 预留字段 */
+ u8 key_hash[KEY_HASH_SIZE]; /* 客户根公钥哈希值 */
u8 pubkey[PUBKEY_SIZE];
u8 keysig[HASH_SIG_SIZE];
u8 newpubkey[PUBKEY_SIZE];
- u8 newkeysig[HASH_SIG_SIZE]; /* signature file used for update operation */
+ u8 newkeysig[HASH_SIG_SIZE]; /* 更新操作用到的签名文件 */
} cskey_status;
typedef struct {
@@ -1838,4 +1725,33 @@ typedef enum MPU_INTEGRITY_STATUS {
MPU_INTEGRITY_SMU_VERIFY_FAIL,
} MPU_INTEGRITY_STATUS_ENUM;
+typedef struct {
+ u8 cmd_type;
+ u8 slice_num;
+ u8 rsvd[2];
+ u8 pubkey[PUBKEY_SIZE];
+ u8 keysig[HASH_SIG_SIZE];
+} cmd_integrity_data_info;
+
+typedef struct {
+ struct mgmt_msg_head head;
+ cmd_integrity_data_info data;
+} cmd_integrity_info;
+
+/* 工具数据长度为1536(1.5K),工具最大发2k,包含头部 */
+struct cmd_update_fw {
+ struct mgmt_msg_head head; // 8B
+ u16 fw_flag : 5; // 首片、尾片标识,以及分区标识
+ u16 updatefw_main_area_flag : 1; // 只升级主区标识
+ u16 rsvd : 10;
+ u16 slice_len; // 当前分片长度,字节数
+ u32 fw_crc;
+ u32 fw_type;
+ u32 bin_total_len;
+ u32 bin_section_len;
+ u32 fw_verion;
+ u32 fw_offset;
+ u32 data[0];
+};
+
#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_mailbox_msg_header.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_mailbox_msg_header.h
index d5fcdfd99..b4e4cde40 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_mailbox_msg_header.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/mpu/mpu_mailbox_msg_header.h
@@ -1,10 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : mpu_mailbox_msg_header.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Filename : mpu_mailbox_msg_header.h
+ * Creation time : 2024/08/13
* Description : The message header if in-band commands between the driver and the MPU
*/
#ifndef MPU_MAILBOX_MSG_HEADER_H
@@ -12,29 +9,27 @@
#include "base_type.h"
-#define MPU_MAILBOX_HEADER_VER_0 0 /**< mailbox message version 0 */
-#define MPU_MAILBOX_HEADER_VER_1 1 /**< mailbox message version 1 */
+#define MPU_MAILBOX_HEADER_VER_0 0 /**< mailbox 消息version 0 */
+#define MPU_MAILBOX_HEADER_VER_1 1 /**< mailbox 消息version 1 */
-#define MPU_MAILBOX_HEADER_VER1_LEN_UNIT 4 /**< mailbox message length unit 4 bytes */
+#define MPU_MAILBOX_HEADER_VER1_LEN_UNIT 4 /**< mailbox 消息长度的单位4 bytes */
typedef union {
struct {
u32 func_id : 13; /**< indicates function id of this message */
u32 status : 1; /**< indicates the status of this message */
- u32 rsvd : 1; /**< reserved field */
- u32 source : 1; /* indicates the source of this message.
- * 0--mailbox 1--api cmd
- */
- u32 aeq_id : 2; /**< indicates message response aeq id */
- u32 msg_id : 4; /**< indicates the ID of this message */
- u32 cmd : 10; /**< user defined command */
+ u32 rsvd : 1; /**< 保留字段 */
+ u32 source : 1; /**< indicates the source of this message.0--mailbox 1--api cmd */
+ u32 aeq_id : 2; /**< indicates message response aeq id */
+ u32 msg_id : 4; /**< indicates the ID of this message */
+ u32 cmd : 10; /**< user defined command */
u32 msg_len : 11; /**< total message length, maximum (2 << 11) - 1 */
- u32 module : 5; /**< module id */
- u32 seg_len : 6; /**< current segment length */
- u32 no_ack : 1; /**< no_ack flag */
- u32 tlp : 1; /**< this bit indicates the message is tlp format */
- u32 seg_id : 6; /**< segment sequence id */
- u32 last_flg : 1; /**< the last segment flag */
+ u32 module : 5; /**< module id */
+ u32 seg_len : 6; /**< current segment length */
+ u32 no_ack : 1; /**< no_ack 标志 */
+ u32 tlp : 1; /**< this bit indicates the message is tlp格式 */
+ u32 seg_id : 6; /**< segment sequence id */
+ u32 last_flg : 1; /**< the last segment flag */
u32 direction : 1; /**< 0 send, 1 receive */
} v0;
@@ -42,21 +37,19 @@ typedef union {
u32 func_id : 13; /**< indicates function id of this message */
u32 status : 1; /**< indicates the status of this message */
u32 version : 1; /**< indicates the version of this message */
- u32 source : 1; /* indicates the source of this message.
- * 0--mailbox 1--api cmd
- */
- u32 aeq_id : 2; /**< indicates message response aeq id */
- u32 msg_id : 4; /**< indicates the ID of this message */
- u32 cmd : 10; /**< user defined command */
+ u32 source : 1; /**< indicates the source of this message.0--mailbox 1--api cmd */
+ u32 aeq_id : 2; /**< indicates message response aeq id */
+ u32 msg_id : 4; /**< indicates the ID of this message */
+ u32 cmd : 10; /**< user defined command */
u32 msg_len : 9; /**< total message length, maximum (2 << 11) - 1 */
- u32 rsvd0 : 2; /**< reserved field */
- u32 module : 6; /**< module id */
- u32 rsvd1 : 1; /**< reserved field */
- u32 seg_len : 4; /**< current segment length */
- u32 no_ack : 1; /**< no_ack flag */
- u32 tlp : 1; /**< this bit indicates the message is tlp format */
- u32 seg_id : 6; /**< segment sequence id */
- u32 last_flg : 1; /**< the last segment flag */
+ u32 rsvd0 : 2; /**< 保留字段 */
+ u32 module : 6; /**< module id */
+ u32 rsvd1 : 1; /**< 保留字段 */
+ u32 seg_len : 4; /**< current segment length */
+ u32 no_ack : 1; /**< no_ack 标志 */
+ u32 tlp : 1; /**< this bit indicates the message is tlp格式 */
+ u32 seg_id : 6; /**< segment sequence id */
+ u32 last_flg : 1; /**< the last segment flag */
u32 direction : 1; /**< 0 send, 1 receive */
} v1;
} mpu_mbx_header;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_cfg_comm.h
index 33f6dd27e..b3e3a8945 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_cfg_comm.h
@@ -1,14 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : nic config common header file
- */
+/******************************************************************************
+
+ Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ ******************************************************************************
+ File Name : nic_cfg_comm.h
+ Version : Initial Draft
+ Description : nic config common header file
+ Function List :
+ History :
+ Modification: Created file
+******************************************************************************/
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -20,53 +22,57 @@
#include "nic_mpu_cmd_structs.h"
#include "nic_mpu_cmd_structs_extend.h"
/* rss */
-#define HINIC5_RSS_TYPE_VALID_SHIFT 23 /**< RSS type valid bit shift */
-#define HINIC5_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24 /**< RSS type TCP IPv6 extension shift */
-#define HINIC5_RSS_TYPE_IPV6_EXT_SHIFT 25 /**< RSS type IPv6 extension header shift */
-#define HINIC5_RSS_TYPE_TCP_IPV6_SHIFT 26 /**< RSS type TCP IPv6 shift */
-#define HINIC5_RSS_TYPE_IPV6_SHIFT 27 /**< RSS type IPv6 shift */
-#define HINIC5_RSS_TYPE_TCP_IPV4_SHIFT 28 /**< RSS type TCP IPv4 shift */
-#define HINIC5_RSS_TYPE_IPV4_SHIFT 29 /**< RSS type IPv4 shift */
-#define HINIC5_RSS_TYPE_UDP_IPV6_SHIFT 30 /**< RSS type UDP IPv6 shift */
-#define HINIC5_RSS_TYPE_UDP_IPV4_SHIFT 31 /**< RSS type UDP IPv4 shift */
+#define HINIC5_RSS_TYPE_VALID_SHIFT \
+ 23 /**< 定义RSS(Receive Side Scaling)类型有效位的偏移量 */
+#define HINIC5_RSS_TYPE_TCP_IPV6_EXT_SHIFT \
+ 24 /**< 定义RSS类型TCP IPv6扩展的偏移量 */
+#define HINIC5_RSS_TYPE_IPV6_EXT_SHIFT 25 /**< 定义RSS类型IPv6扩展头的偏移量 */
+#define HINIC5_RSS_TYPE_TCP_IPV6_SHIFT 26 /**< 定义RSS类型TCP IPv6的偏移量 */
+#define HINIC5_RSS_TYPE_IPV6_SHIFT 27 /**< 定义RSS类型IPv6的偏移量 */
+#define HINIC5_RSS_TYPE_TCP_IPV4_SHIFT 28 /**< 定义RSS类型TCP IPv4的偏移量 */
+#define HINIC5_RSS_TYPE_IPV4_SHIFT 29 /**< 定义RSS类型IPv4的偏移量 */
+#define HINIC5_RSS_TYPE_UDP_IPV6_SHIFT 30 /**< 定义RSS类型UDP IPv6的偏移量 */
+#define HINIC5_RSS_TYPE_UDP_IPV4_SHIFT 31 /**< 定义RSS类型UDP IPv4的偏移量 */
/* vlan */
#define NIC_CVLAN_INSERT_ENABLE 0x1
-#define NIC_QINQ_INSERT_ENABLE 0x3
+#define NIC_QINQ_INSERT_ENABLE 0x3
#define NIC_CONFIG_ALL_QUEUE_VLAN_CTX 0xffff
/**
- * @brief Macro for setting RSS type
- * @param val value to set
- * @param member member to set
- * @return result after setting
+ * @brief 定义一个宏,用于设置RSS类型
+ * @param val 要设置的值
+ * @param member 要设置的成员
+ * @return 返回设置后的结果
*/
-#define HINIC5_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC5_RSS_TYPE_##member##_SHIFT)
+#define HINIC5_RSS_TYPE_SET(val, member) \
+ (((u32)(val)&0x1) << HINIC5_RSS_TYPE_##member##_SHIFT)
/**
- * @brief Macro for getting RSS type
- * @param val value to get
- * @param member member to get
- * @return result after getting
+ * @brief 定义一个宏,用于获取RSS类型
+ * @param val 要获取的值
+ * @param member 要获取的成员
+ * @return 返回获取到的结果
*/
-#define HINIC5_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC5_RSS_TYPE_##member##_SHIFT) & 0x1)
+#define HINIC5_RSS_TYPE_GET(val, member) \
+ (((u32)(val) >> HINIC5_RSS_TYPE_##member##_SHIFT) & 0x1)
/**
- * @brief RSS hash type enum definition
- * @details This enum represents the NIC RSS hash type
+ * @brief 定义RSS哈希类型枚举
+ * @details 此枚举用于表示网络接口卡(NIC)的接收方硬件分布(RSS)哈希类型
*/
enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0, /**< XOR hash type */
- NIC_RSS_HASH_TYPE_TOEP, /**< TOEP hash type */
+ NIC_RSS_HASH_TYPE_XOR = 0, /**< XOR哈希类型 */
+ NIC_RSS_HASH_TYPE_TOEP, /**< TOEP哈希类型 */
- NIC_RSS_HASH_TYPE_MAX /**< MUST BE THE LAST ONE */
+ NIC_RSS_HASH_TYPE_MAX /**< MUST BE THE LAST ONE */
};
/**
- * @brief CQE compact scenario ucode reported csum_err type enum
- * @details In CQE compact scenario, csum_err in CQE is compressed from 9bit to 2bit, with driver coordination as follows:
- * NIC_RX_CSUM_IPSU_OTHER_ERR: non-CQE-compact csum_err bit[8] != 0 ---> CQE compact csum_err = 2
- * NIC_RX_CSUM_HW_BYPASS_ERR: non-CQE-compact csum_err bit[7] != 0 ---> CQE compact csum_err = 3
- * l3 or l4 layer packet csum error: non-CQE-compact csum_err bit[0]~bit[6] != 0 ---> CQE compact csum_err = 1
+ * @brief 定义CQE合一场景下微码上报的csum_err类型枚举
+ * @details CQE合一场景下, CQE中csum_err由原来的9bit压缩到2bit, 与驱动保持以下配合
+ * NIC_RX_CSUM_IPSU_OTHER_ERR时, 即非CQE合一场景csum_err bit[8]不为0 ---> CQE合一场景csum_err修改成2
+ * NIC_RX_CSUM_HW_BYPASS_ERR时, 即非CQE合一场景csum_err bit[7]不为0 ---> CQE合一场景csum_err修改成3
+ * l3或l4层报文csum错误时, 非CQE合一场景csum_err bit[0]~bit[6]不为0 ---> CQE合一场景csum_err修改成1
*/
enum nic_compact_cqe_csum_err_type {
NIC_RX_COMPACT_CSUM_NO_ERROR = 0,
@@ -75,452 +81,461 @@ enum nic_compact_cqe_csum_err_type {
NIC_RX_COMPACT_HW_BYPASS_ERROR
};
-#define NIC_RSS_INDIR_SIZE 256 /**< RSS indirect table size */
-#define NIC_RSS_KEY_SIZE 40 /**< RSS key size */
+#define NIC_RSS_INDIR_SIZE 256 /**< 定义RSS间接表的大小为256 */
+#define NIC_RSS_KEY_SIZE 40 /**< 定义RSS ket大小为40 */
/* *
* Definition of the NIC receiving mode
*/
-#define NIC_RX_MODE_UC 0x01 /**< unicast mode */
-#define NIC_RX_MODE_MC 0x02 /**< multicast mode */
-#define NIC_RX_MODE_BC 0x04 /**< broadcast mode */
-#define NIC_RX_MODE_MC_ALL 0x08 /**< all multicast mode */
-#define NIC_RX_MODE_PROMISC 0x10 /**< promiscuous mode, receive all packets */
+#define NIC_RX_MODE_UC 0x01 /**< 单播模式 */
+#define NIC_RX_MODE_MC 0x02 /**< 组播模式 */
+#define NIC_RX_MODE_BC 0x04 /**< 广播模式 */
+#define NIC_RX_MODE_MC_ALL 0x08 /**< 全组播模式 */
+#define NIC_RX_MODE_PROMISC 0x10 /**< 混杂模式,接收所有的数据包 */
/* IEEE 802.1Qaz std */
-#define NIC_DCB_DSCP_NUM 0x8 /**< NIC DCB max DSCP value */
-#define NIC_DCB_IP_PRI_MAX 0x40 /**< NIC DCB max IP priority */
+#define NIC_DCB_DSCP_NUM 0x8 /**< 定义网络接口控制数据包(NIC DCB)的最大DSCP值 */
+#define NIC_DCB_IP_PRI_MAX \
+ 0x40 /**< 定义网络接口控制数据包(NIC DCB)的最大IP优先级 */
-#define NIC_DCB_PRIO_DWRR 0x0 /**< Priority allocation by strict bandwidth */
-#define NIC_DCB_PRIO_STRICT 0x1 /**< Priority allocation by strict priority */
+#define NIC_DCB_PRIO_DWRR \
+ 0x0 /**< 定义一个宏,表示优先级的分配方式为带宽的严格分配 */
+#define NIC_DCB_PRIO_STRICT \
+ 0x1 /**< 定义一个宏,表示优先级的分配方式为严格的优先级 */
-#define NIC_DCB_MAX_PFC_NUM 0x4 /**< Max priority flow control (PFC) number */
+#define NIC_DCB_MAX_PFC_NUM \
+ 0x4 /**< 定义一个宏,表示最大优先级流控制(PFC)的数量 */
#ifndef ETH_ALEN
-#define ETH_ALEN 6 /**< Single MAC address length */
+#define ETH_ALEN 6 /**< 定义单mac地址长度为6B */
#endif
#ifndef BIT
/**
- * @brief Macro to left shift a number by n bits in binary form
- * @param n number of bits to shift
- * @return result after left shifting by n bits
+ * @brief 定义一个宏,用于将一个数的二进制形式左移n位
+ * @param n 要左移的位数
+ * @return 返回左移n位后的结果
*/
#define BIT(n) (1UL << (n))
#endif
/**
- * @brief NIC feature capability enum definition
+ * @brief 网络接口卡功能能力枚举定义
*
- * @details Enum nic_feature_cap defines various feature capabilities of NIC.
- * Each enum value is a BIT mask position, which can be set or checked via bit operations.
+ * @details 枚举类型 nic_feature_cap 定义了网络接口卡的各种功能能力。
+ * 每个枚举值都是一个位掩码的BIT位,可以通过位操作来设置或者检查某个功能是否被支持。
*/
enum nic_feature_cap {
- NIC_F_CSUM_BIT = 0, /**< checksum calculation */
- NIC_F_SCTP_CRC_BIT = 1, /**< SCTP CRC check */
- NIC_F_TSO_BIT = 2, /**< TCP Segmentation Offload */
- NIC_F_LRO_BIT = 3, /**< Large Receive Offload */
- NIC_F_UFO_BIT = 4, /**< UDP Fragmentation Offload */
- NIC_F_RSS_BIT = 5, /**< Receive Side Scaling */
- NIC_F_RX_VLAN_FILTER_BIT = 6, /**< receive VLAN filter */
- NIC_F_RX_VLAN_STRIP_BIT = 7, /**< receive VLAN strip */
- NIC_F_TX_VLAN_INSERT_BIT = 8, /**< transmit VLAN insert */
- NIC_F_VXLAN_OFFLOAD_BIT = 9, /**< VXLAN Offload */
- NIC_F_IPSEC_OFFLOAD_BIT = 10, /**< IPsec Offload */
- NIC_F_FDIR_BIT = 11, /**< Flow Director */
- NIC_F_PROMISC_BIT = 12, /**< promiscuous mode */
- NIC_F_ALLMULTI_BIT = 13, /**< receive all multicast */
- NIC_F_XSFP_REPORT_BIT = 14, /**< XSFP status report */
- NIC_F_VF_MAC_BIT = 15, /**< virtual function MAC address */
- NIC_F_RATE_LIMIT_BIT = 16, /**< rate limit */
- NIC_F_RXQ_RECOVERY_BIT = 17, /**< receive queue recovery */
- NIC_F_PTP_1588_V2_BIT = 18, /**< PTP 1588v2 */
- NIC_F_TX_WQE_COMPACT_TASK_BIT = 19, /**< transmit WQE compact */
- NIC_F_RX_HW_COMPACT_CQE_BIT = 20, /**< HTN compact CQE */
- NIC_F_HTN_CMDQ_BIT = 21, /**< HTN command queue */
- NIC_F_GENEVE_OFFLOAD_BIT = 22, /**< Geneve Offload */
- NIC_F_IPXIP_OFFLOAD_BIT = 23, /**< IPXIP Offload */
- NIC_F_TC_FLOWER_OFFLOAD_BIT = 24, /**< TCAM flow control offload */
- NIC_F_HTN_FDIR_BIT = 25, /**< HTN FDIR function */
- NIC_F_SQ_RQ_CI_COALESCE_BIT = 26, /**< SQ RQ CI coalesce */
- NIC_F_RX_SW_COMPACT_CQE_BIT = 27, /**< ucode compact CQE */
- NIC_F_HALF_BOND_OFFLOAD_BIT = 28, /**< half Bond offload */
- NIC_F_MACSEC_OFFLOAD_BIT = 29, /**< MACSec offload */
- NIC_F_VEB_OFFLOAD_BIT = 30, /**< VEB offload */
- NIC_F_GET_COUNTER_BY_CMDQ_BIT = 31, /**< support reading vport counter via CMDQ */
- NIC_F_HTN_CMDQ_CAR_BIT = 32, /**< support setting CAR rate limit via CMDQ */
- NIC_F_ARP_DUAL_BIT = 33, /**< support ARP dual transmit */
+ NIC_F_CSUM_BIT = 0, /**< 校验和计算 */
+ NIC_F_SCTP_CRC_BIT = 1, /**< SCTP CRC校验 */
+ NIC_F_TSO_BIT = 2, /**< TCP Segmentation Offload */
+ NIC_F_LRO_BIT = 3, /**< Large Receive Offload */
+ NIC_F_UFO_BIT = 4, /**< UDP Fragmentation Offload */
+ NIC_F_RSS_BIT = 5, /**< Receive Side Scaling */
+ NIC_F_RX_VLAN_FILTER_BIT = 6, /**< 接收VLAN过滤 */
+ NIC_F_RX_VLAN_STRIP_BIT = 7, /**< 接收VLAN去除 */
+ NIC_F_TX_VLAN_INSERT_BIT = 8, /**< 发送VLAN插入 */
+ NIC_F_VXLAN_OFFLOAD_BIT = 9, /**< VXLAN Offload */
+ NIC_F_IPSEC_OFFLOAD_BIT = 10, /**< IPsec Offload */
+ NIC_F_FDIR_BIT = 11, /**< Flow Director */
+ NIC_F_PROMISC_BIT = 12, /**< 混杂模式 */
+ NIC_F_ALLMULTI_BIT = 13, /**< 接收所有组播 */
+ NIC_F_XSFP_REPORT_BIT = 14, /**< XSFP状态报告 */
+ NIC_F_VF_MAC_BIT = 15, /**< 虚拟函数MAC地址 */
+ NIC_F_RATE_LIMIT_BIT = 16, /**< 速率限制 */
+ NIC_F_RXQ_RECOVERY_BIT = 17, /**< 接收队列恢复 */
+ NIC_F_PTP_1588_V2_BIT = 18, /**< PTP 1588v2 */
+ NIC_F_TX_WQE_COMPACT_TASK_BIT = 19, /**< 发送WQE压缩 */
+ NIC_F_RX_HW_COMPACT_CQE_BIT = 20, /**< HTN合一CQE */
+ NIC_F_HTN_CMDQ_BIT = 21, /**< HTN命令队列 */
+ NIC_F_GENEVE_OFFLOAD_BIT = 22, /**< Geneve Offload */
+ NIC_F_IPXIP_OFFLOAD_BIT = 23, /**< IPXIP Offload */
+ NIC_F_TC_FLOWER_OFFLOAD_BIT = 24, /**< TCAM流控卸载 */
+ NIC_F_HTN_FDIR_BIT = 25, /**< HTN FDIR功能 */
+ NIC_F_SQ_RQ_CI_COALESCE_BIT = 26, /**< SQ RQ CI共用 */
+ NIC_F_RX_SW_COMPACT_CQE_BIT = 27, /**< ucode合一CQE */
+ NIC_F_HALF_BOND_OFFLOAD_BIT = 28, /**< 半Bond卸载 */
+ NIC_F_MACSEC_OFFLOAD_BIT = 29, /**< MACSec卸载 */
+ NIC_F_VEB_OFFLOAD_BIT = 30, /**< VEB卸载 */
+ NIC_F_GET_COUNTER_BY_CMDQ_BIT = 31, /**< 支持通过CMDQ读取vport计数 */
+ NIC_F_HTN_CMDQ_CAR_BIT = 32, /**< 支持通过CMDQ设置CAR限速 */
+ NIC_F_ARP_DUAL_BIT = 33, /**< 支持arp双发 */
};
-#define NIC_F_BIT(bit) ((u64)1 << (bit))
-#define NIC_F(name) NIC_F_BIT(NIC_F_##name##_BIT)
+#define NIC_F_BIT(bit) ((u64)1 << (bit))
+#define NIC_F(name) NIC_F_BIT(NIC_F_##name##_BIT)
-#define NIC_F_CSUM NIC_F(CSUM)
-#define NIC_F_SCTP_CRC NIC_F(SCTP_CRC)
-#define NIC_F_TSO NIC_F(TSO)
-#define NIC_F_LRO NIC_F(LRO)
-#define NIC_F_UFO NIC_F(UFO)
-#define NIC_F_RSS NIC_F(RSS)
+#define NIC_F_CSUM NIC_F(CSUM)
+#define NIC_F_SCTP_CRC NIC_F(SCTP_CRC)
+#define NIC_F_TSO NIC_F(TSO)
+#define NIC_F_LRO NIC_F(LRO)
+#define NIC_F_UFO NIC_F(UFO)
+#define NIC_F_RSS NIC_F(RSS)
#define NIC_F_RX_VLAN_FILTER NIC_F(RX_VLAN_FILTER)
#define NIC_F_RX_VLAN_STRIP NIC_F(RX_VLAN_STRIP)
#define NIC_F_TX_VLAN_INSERT NIC_F(TX_VLAN_INSERT)
#define NIC_F_VXLAN_OFFLOAD NIC_F(VXLAN_OFFLOAD)
#define NIC_F_IPSEC_OFFLOAD NIC_F(IPSEC_OFFLOAD)
-#define NIC_F_FDIR NIC_F(FDIR)
-#define NIC_F_PROMISC NIC_F(PROMISC)
-#define NIC_F_ALLMULTI NIC_F(ALLMULTI)
-#define NIC_F_XSFP_REPORT NIC_F(XSFP_REPORT)
-#define NIC_F_VF_MAC NIC_F(VF_MAC)
-#define NIC_F_RATE_LIMIT NIC_F(RATE_LIMIT)
-#define NIC_F_RXQ_RECOVERY NIC_F(RXQ_RECOVERY)
-#define NIC_F_PTP_1588_V2 NIC_F(PTP_1588_V2)
+#define NIC_F_FDIR NIC_F(FDIR)
+#define NIC_F_PROMISC NIC_F(PROMISC)
+#define NIC_F_ALLMULTI NIC_F(ALLMULTI)
+#define NIC_F_XSFP_REPORT NIC_F(XSFP_REPORT)
+#define NIC_F_VF_MAC NIC_F(VF_MAC)
+#define NIC_F_RATE_LIMIT NIC_F(RATE_LIMIT)
+#define NIC_F_RXQ_RECOVERY NIC_F(RXQ_RECOVERY)
+#define NIC_F_PTP_1588_V2 NIC_F(PTP_1588_V2)
#define NIC_F_TX_WQE_COMPACT_TASK NIC_F(TX_WQE_COMPACT_TASK)
#define NIC_F_RX_HW_COMPACT_CQE NIC_F(RX_HW_COMPACT_CQE)
-#define NIC_F_HTN_CMDQ NIC_F(HTN_CMDQ)
+#define NIC_F_HTN_CMDQ NIC_F(HTN_CMDQ)
#define NIC_F_GENEVE_OFFLOAD NIC_F(GENEVE_OFFLOAD)
#define NIC_F_IPXIP_OFFLOAD NIC_F(IPXIP_OFFLOAD)
#define NIC_F_TC_FLOWER_OFFLOAD NIC_F(TC_FLOWER_OFFLOAD)
-#define NIC_F_HTN_FDIR NIC_F(HTN_FDIR)
+#define NIC_F_HTN_FDIR NIC_F(HTN_FDIR)
#define NIC_F_SQ_RQ_CI_COALESCE NIC_F(SQ_RQ_CI_COALESCE)
#define NIC_F_RX_SW_COMPACT_CQE NIC_F(RX_SW_COMPACT_CQE)
#define NIC_F_HALF_BOND_OFFLOAD NIC_F(HALF_BOND_OFFLOAD)
#define NIC_F_MACSEC_OFFLOAD NIC_F(MACSEC_OFFLOAD)
-#define NIC_F_VEB_OFFLOAD NIC_F(VEB_OFFLOAD)
+#define NIC_F_VEB_OFFLOAD NIC_F(VEB_OFFLOAD)
#define NIC_F_GET_COUNTER_BY_CMDQ NIC_F(GET_COUNTER_BY_CMDQ)
-#define NIC_F_HTN_CMDQ_CAR NIC_F(HTN_CMDQ_CAR)
-#define NIC_F_ARP_DUAL NIC_F(ARP_DUAL)
-
-#define NIC_F_1823_MASK 0x1FFEF /**< all 1823 attributes */
-#define NIC_F_1825_MASK (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_LRO | NIC_F_RSS | \
- NIC_F_RX_VLAN_FILTER | NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | \
- NIC_F_VXLAN_OFFLOAD | NIC_F_IPSEC_OFFLOAD | NIC_F_FDIR | NIC_F_PROMISC | \
- NIC_F_ALLMULTI | NIC_F_XSFP_REPORT | NIC_F_VF_MAC | NIC_F_RATE_LIMIT | \
- NIC_F_TX_WQE_COMPACT_TASK | NIC_F_RX_SW_COMPACT_CQE | \
- NIC_F_HALF_BOND_OFFLOAD | NIC_F_GET_COUNTER_BY_CMDQ)
-
-#define NIC_F_182X_MASK (NIC_F_1823_MASK | NIC_F_1825_MASK) /**< all 182x attributes */
-
-#define NIC_F_1872_PF_MASK (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_TX_WQE_COMPACT_TASK | \
- NIC_F_RX_HW_COMPACT_CQE | NIC_F_HTN_CMDQ | NIC_F_PROMISC | \
- NIC_F_ALLMULTI | NIC_F_VXLAN_OFFLOAD | NIC_F_GENEVE_OFFLOAD | \
- NIC_F_IPXIP_OFFLOAD | NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | \
- NIC_F_RSS | NIC_F_RX_VLAN_FILTER | NIC_F_LRO | NIC_F_FDIR | \
- NIC_F_HTN_FDIR | NIC_F_SQ_RQ_CI_COALESCE | NIC_F_PTP_1588_V2 | \
- NIC_F_TC_FLOWER_OFFLOAD | NIC_F_MACSEC_OFFLOAD | NIC_F_VEB_OFFLOAD | \
- NIC_F_RATE_LIMIT | NIC_F_HTN_CMDQ_CAR | NIC_F_ARP_DUAL | \
- NIC_F_XSFP_REPORT) /**< all 187x PF attributes */
-
-#define NIC_F_1872_VF_MASK (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_TX_WQE_COMPACT_TASK | \
- NIC_F_RX_HW_COMPACT_CQE | NIC_F_HTN_CMDQ | NIC_F_ALLMULTI | \
- NIC_F_VXLAN_OFFLOAD | NIC_F_GENEVE_OFFLOAD | NIC_F_IPXIP_OFFLOAD | \
- NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | NIC_F_RSS | \
- NIC_F_RX_VLAN_FILTER | NIC_F_LRO | NIC_F_FDIR | NIC_F_HTN_FDIR | \
- NIC_F_SQ_RQ_CI_COALESCE | NIC_F_TC_FLOWER_OFFLOAD | \
- NIC_F_MACSEC_OFFLOAD | NIC_F_VEB_OFFLOAD | NIC_F_RATE_LIMIT | \
- NIC_F_HTN_CMDQ_CAR | NIC_F_ARP_DUAL) /**< all 187x VF attributes */
+#define NIC_F_HTN_CMDQ_CAR NIC_F(HTN_CMDQ_CAR)
+#define NIC_F_ARP_DUAL NIC_F(ARP_DUAL)
+
+#define NIC_F_1823_MASK 0x1FFEF /**< 1823的所有属性 */
+#define NIC_F_1825_MASK \
+ (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_LRO | NIC_F_RSS | \
+ NIC_F_RX_VLAN_FILTER | NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | \
+ NIC_F_VXLAN_OFFLOAD | NIC_F_IPSEC_OFFLOAD | NIC_F_FDIR | \
+ NIC_F_PROMISC | NIC_F_ALLMULTI | NIC_F_XSFP_REPORT | NIC_F_VF_MAC | \
+ NIC_F_RATE_LIMIT | NIC_F_TX_WQE_COMPACT_TASK | \
+ NIC_F_RX_SW_COMPACT_CQE | NIC_F_HALF_BOND_OFFLOAD | \
+ NIC_F_GET_COUNTER_BY_CMDQ)
+
+#define NIC_F_182X_MASK \
+ (NIC_F_1823_MASK | NIC_F_1825_MASK) /**< 182x的所有属性 */
+
+#define NIC_F_1872_PF_MASK \
+ (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_TX_WQE_COMPACT_TASK | \
+ NIC_F_RX_HW_COMPACT_CQE | NIC_F_HTN_CMDQ | NIC_F_PROMISC | \
+ NIC_F_ALLMULTI | NIC_F_VXLAN_OFFLOAD | NIC_F_GENEVE_OFFLOAD | \
+ NIC_F_IPXIP_OFFLOAD | NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | \
+ NIC_F_RSS | NIC_F_RX_VLAN_FILTER | NIC_F_LRO | NIC_F_FDIR | \
+ NIC_F_HTN_FDIR | NIC_F_SQ_RQ_CI_COALESCE | NIC_F_PTP_1588_V2 | \
+ NIC_F_TC_FLOWER_OFFLOAD | NIC_F_MACSEC_OFFLOAD | NIC_F_VEB_OFFLOAD | \
+ NIC_F_RATE_LIMIT | NIC_F_HTN_CMDQ_CAR | NIC_F_ARP_DUAL | \
+ NIC_F_XSFP_REPORT) /**< 187x PF的所有属性 */
+
+#define NIC_F_1872_VF_MASK \
+ (NIC_F_CSUM | NIC_F_SCTP_CRC | NIC_F_TSO | NIC_F_TX_WQE_COMPACT_TASK | \
+ NIC_F_RX_HW_COMPACT_CQE | NIC_F_HTN_CMDQ | NIC_F_ALLMULTI | \
+ NIC_F_VXLAN_OFFLOAD | NIC_F_GENEVE_OFFLOAD | NIC_F_IPXIP_OFFLOAD | \
+ NIC_F_RX_VLAN_STRIP | NIC_F_TX_VLAN_INSERT | NIC_F_RSS | \
+ NIC_F_RX_VLAN_FILTER | NIC_F_LRO | NIC_F_FDIR | NIC_F_HTN_FDIR | \
+ NIC_F_SQ_RQ_CI_COALESCE | NIC_F_TC_FLOWER_OFFLOAD | \
+ NIC_F_MACSEC_OFFLOAD | NIC_F_VEB_OFFLOAD | NIC_F_RATE_LIMIT | \
+ NIC_F_HTN_CMDQ_CAR | NIC_F_ARP_DUAL) /**< 187x VF的所有属性 */
#define NIC_F_1872_MASK (NIC_F_1872_PF_MASK | NIC_F_1872_VF_MASK)
#define NIC_F_ALL_MASK (NIC_F_182X_MASK | NIC_F_1872_MASK)
-#define HINIC5_TCAM_BLOCK_ENABLE 1 /**< TCAM block enable */
-#define HINIC5_TCAM_BLOCK_DISABLE 0 /**< TCAM block disable */
-#define HINIC5_MAX_TCAM_RULES_NUM 4096 /**< TCAM max rules number */
+#define HINIC5_TCAM_BLOCK_ENABLE 1 /**< TCAM块启用 */
+#define HINIC5_TCAM_BLOCK_DISABLE 0 /**< TCAM块禁用 */
+#define HINIC5_MAX_TCAM_RULES_NUM 4096 /**< TCAM的最大规则数量 */
/**
- * @brief NIC TCAM block type enum
- * @details This enum contains two types: NIC_TCAM_BLOCK_TYPE_LARGE and NIC_TCAM_BLOCK_TYPE_SMALL.
- * NIC_TCAM_BLOCK_TYPE_LARGE indicates block size 16, NIC_TCAM_BLOCK_TYPE_SMALL indicates block size 0.
+ * @brief 定义一个枚举类型,用于表示NIC TCAM块的类型。
+ * @details 这个枚举类型包含了两种类型:NIC_TCAM_BLOCK_TYPE_LARGE和NIC_TCAM_BLOCK_TYPE_SMALL。
+ * NIC_TCAM_BLOCK_TYPE_LARGE表示块大小为16,NIC_TCAM_BLOCK_TYPE_SMALL表示块大小为0。
*/
enum {
NIC_TCAM_BLOCK_TYPE_LARGE = 0, /**< block_size: 16 */
- NIC_TCAM_BLOCK_TYPE_SMALL, /**< block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /**< block_size: 0 */
NIC_TCAM_BLOCK_TYPE_MAX
};
/**
* @struct hinic5_tcam_key_ipv4_mem
- * @brief IPv4 TCAM key structure
- * @details This structure contains fields for IPv4 TCAM key including reserved bits, tunnel type, IP protocol type, IP type,
- * Func ID, source IPv4 address, destination IPv4 address, destination port, source port, outer source IPv4 address, outer destination IPv4 address, VNI, etc.
+ * @brief 定义了一个用于存储IPv4 TCAM键的结构体
+ * @details 该结构体包含了IPv4 TCAM键的各个字段,包括保留位、隧道类型、IP协议类型、IP类型、
+ * Func ID、源IPv4地址、目的IPv4地址、目的端口号、源端口号、外部源IPv4地址、外部目的IPv4地址、VNI等信息。
*/
struct hinic5_tcam_key_ipv4_mem {
- u32 rsvd1 : 4; /**< reserved bit 1 */
- u32 tunnel_type : 4; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol type */
- u32 rsvd0 : 16; /**< reserved bit 0 */
- u32 sipv4_h : 16; /**< source IPv4 address high 16 bits */
- u32 ip_type : 1; /**< IP type */
+ u32 rsvd1 : 4; /**< 保留位1 */
+ u32 tunnel_type : 4; /**< 隧道类型 */
+ u32 ip_proto : 8; /**< IP协议类型 */
+ u32 rsvd0 : 16; /**< 保留位0 */
+ u32 sipv4_h : 16; /**< 源IPv4地址的高16位 */
+ u32 ip_type : 1; /**< IP类型 */
u32 function_id : 15; /**< Func ID */
- u32 dipv4_h : 16; /**< destination IPv4 address high 16 bits */
- u32 sipv4_l : 16; /**< source IPv4 address low 16 bits */
- u32 rsvd2 : 16; /**< reserved bit 2 */
- u32 dipv4_l : 16; /**< destination IPv4 address low 16 bits */
- u32 rsvd3; /**< reserved bit 3 */
- u32 dport : 16; /**< destination port */
- u32 rsvd4 : 16; /**< reserved bit 4 */
- u32 rsvd5 : 16; /**< reserved bit 5 */
- u32 sport : 16; /**< source port */
- u32 outer_sipv4_h : 16; /**< outer source IPv4 address high 16 bits */
- u32 rsvd6 : 16; /**< reserved bit 6 */
- u32 outer_dipv4_h : 16; /**< outer destination IPv4 address high 16 bits */
- u32 outer_sipv4_l : 16; /**< outer source IPv4 address low 16 bits */
- u32 vni_h : 16; /**< VNI high 16 bits */
- u32 outer_dipv4_l : 16; /**< outer destination IPv4 address low 16 bits */
- u32 rsvd7 : 16; /**< reserved bit 7 */
- u32 vni_l : 16; /**< VNI low 16 bits */
+ u32 dipv4_h : 16; /**< 目的IPv4地址的高16位 */
+ u32 sipv4_l : 16; /**< 源IPv4地址的低16位 */
+ u32 rsvd2 : 16; /**< 保留位2 */
+ u32 dipv4_l : 16; /**< 目的IPv4地址的低16位 */
+ u32 rsvd3; /**< 保留位3 */
+ u32 dport : 16; /**< 目的端口号 */
+ u32 rsvd4 : 16; /**< 保留位4 */
+ u32 rsvd5 : 16; /**< 保留位5 */
+ u32 sport : 16; /**< 源端口号 */
+ u32 outer_sipv4_h : 16; /**< 外部源IPv4地址的高16位 */
+ u32 rsvd6 : 16; /**< 保留位6 */
+ u32 outer_dipv4_h : 16; /**< 外部目的IPv4地址的高16位 */
+ u32 outer_sipv4_l : 16; /**< 外部源IPv4地址的低16位 */
+ u32 vni_h : 16; /**< VNI的高16位 */
+ u32 outer_dipv4_l : 16; /**< 外部目的IPv4地址的低16位 */
+ u32 rsvd7 : 16; /**< 保留位7 */
+ u32 vni_l : 16; /**< VNI的低16位 */
};
/**
* @struct hinic5_tcam_key_ipv6_mem
- * @brief IPv6 TCAM key structure
- * @details This structure stores IPv6 TCAM key including source and destination IPv6 address parts,
- * and related protocol type, port number, etc.
+ * @brief 定义了一个用于存储IPv6 TCAM键的结构体
+ * @details 该结构体用于存储IPv6 TCAM键,包含了源IPv6地址和目标IPv6地址的各个部分,
+ * 以及相关的协议类型、端口号等信息。
*/
struct hinic5_tcam_key_ipv6_mem {
- u32 rsvd1 : 3; /**< reserved bit 1 */
- u32 outer_ip_type : 1; /**< outer IP type */
- u32 tunnel_type : 4; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol type */
- u32 rsvd0 : 16; /**< reserved bit 0 */
- u32 sipv6_key0 : 16; /**< source IPv6 address low 16 bits */
- u32 ip_type : 1; /**< IP type */
- u32 function_id : 15; /**< function ID */
- u32 sipv6_key2 : 16; /**< source IPv6 address part 2 */
- u32 sipv6_key1 : 16; /**< source IPv6 address part 1 */
- u32 sipv6_key4 : 16; /**< source IPv6 address part 4 */
- u32 sipv6_key3 : 16; /**< source IPv6 address part 3 */
- u32 sipv6_key6 : 16; /**< source IPv6 address part 6 */
- u32 sipv6_key5 : 16; /**< source IPv6 address part 5 */
- u32 dport : 16; /**< destination port */
- u32 sipv6_key7 : 16; /**< source IPv6 address part 7 */
- u32 dipv6_key0 : 16; /**< destination IPv6 address low 16 bits */
- u32 sport : 16; /**< source port */
- u32 dipv6_key2 : 16; /**< destination IPv6 address part 2 */
- u32 dipv6_key1 : 16; /**< destination IPv6 address part 1 */
- u32 dipv6_key4 : 16; /**< destination IPv6 address part 4 */
- u32 dipv6_key3 : 16; /**< destination IPv6 address part 3 */
- u32 dipv6_key6 : 16; /**< destination IPv6 address part 6 */
- u32 dipv6_key5 : 16; /**< destination IPv6 address part 5 */
- u32 rsvd2 : 16; /**< reserved bit 2 */
- u32 dipv6_key7 : 16; /**< destination IPv6 address part 7 */
+ u32 rsvd1 : 3; /**< 保留位1 */
+ u32 outer_ip_type : 1; /**< 外部IP类型 */
+ u32 tunnel_type : 4; /**< 隧道类型 */
+ u32 ip_proto : 8; /**< IP协议类型 */
+ u32 rsvd0 : 16; /**< 保留位0 */
+ u32 sipv6_key0 : 16; /**< 源IPv6地址的低16位 */
+ u32 ip_type : 1; /**< IP类型 */
+ u32 function_id : 15; /**< 功能ID */
+ u32 sipv6_key2 : 16; /**< 源IPv6地址的第二部分 */
+ u32 sipv6_key1 : 16; /**< 源IPv6地址的第一部分 */
+ u32 sipv6_key4 : 16; /**< 源IPv6地址的第四部分 */
+ u32 sipv6_key3 : 16; /**< 源IPv6地址的第三部分 */
+ u32 sipv6_key6 : 16; /**< 源IPv6地址的第六部分 */
+ u32 sipv6_key5 : 16; /**< 源IPv6地址的第五部分 */
+ u32 dport : 16; /**< 目标端口 */
+ u32 sipv6_key7 : 16; /**< 源IPv6地址的第七部分 */
+ u32 dipv6_key0 : 16; /**< 目标IPv6地址的低16位 */
+ u32 sport : 16; /**< 源端口 */
+ u32 dipv6_key2 : 16; /**< 目标IPv6地址的第二部分 */
+ u32 dipv6_key1 : 16; /**< 目标IPv6地址的第一部分 */
+ u32 dipv6_key4 : 16; /**< 目标IPv6地址的第四部分 */
+ u32 dipv6_key3 : 16; /**< 目标IPv6地址的第三部分 */
+ u32 dipv6_key6 : 16; /**< 目标IPv6地址的第六部分 */
+ u32 dipv6_key5 : 16; /**< 目标IPv6地址的第五部分 */
+ u32 rsvd2 : 16; /**< 保留位2 */
+ u32 dipv6_key7 : 16; /**< 目标IPv6地址的第七部分 */
};
/**
* @struct hinic5_tcam_key_vxlan_ipv6_mem
- * @brief VXLAN IPv6 TCAM key structure
- * @details This structure contains fields for VXLAN IPv6 TCAM key including reserved bits, tunnel type, IP protocol type, etc.
+ * @brief 定义了一个用于存储VXLAN IPv6 TCAM键的结构体
+ * @details 该结构体包含了VXLAN IPv6 TCAM键的各个字段,包括保留位、隧道类型、IP协议类型等。
*/
struct hinic5_tcam_key_vxlan_ipv6_mem {
- u32 rsvd1 : 4; /**< reserved bit 1 */
- u32 tunnel_type : 4; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol type */
- u32 rsvd0 : 16; /**< reserved bit 0 */
+ u32 rsvd1 : 4; /**< 保留位1 */
+ u32 tunnel_type : 4; /**< 隧道类型 */
+ u32 ip_proto : 8; /**< IP协议类型 */
+ u32 rsvd0 : 16; /**< 保留位0 */
- u32 dipv6_key0 : 16; /**< IPv6 destination address low 16 bits */
- u32 ip_type : 1; /**< IP type */
- u32 function_id : 15; /**< function ID */
+ u32 dipv6_key0 : 16; /**< IPv6目标地址的低16位 */
+ u32 ip_type : 1; /**< IP类型 */
+ u32 function_id : 15; /**< 功能ID */
- u32 dipv6_key2 : 16; /**< IPv6 destination address part 2 */
- u32 dipv6_key1 : 16; /**< IPv6 destination address part 1 */
+ u32 dipv6_key2 : 16; /**< IPv6目标地址的第二部分 */
+ u32 dipv6_key1 : 16; /**< IPv6目标地址的第一部分 */
- u32 dipv6_key4 : 16; /**< IPv6 destination address part 4 */
- u32 dipv6_key3 : 16; /**< IPv6 destination address part 3 */
+ u32 dipv6_key4 : 16; /**< IPv6目标地址的第四部分 */
+ u32 dipv6_key3 : 16; /**< IPv6目标地址的第三部分 */
- u32 dipv6_key6 : 16; /**< IPv6 destination address part 6 */
- u32 dipv6_key5 : 16; /**< IPv6 destination address part 5 */
+ u32 dipv6_key6 : 16; /**< IPv6目标地址的第六部分 */
+ u32 dipv6_key5 : 16; /**< IPv6目标地址的第五部分 */
- u32 dport : 16; /**< destination port */
- u32 dipv6_key7 : 16; /**< IPv6 destination address part 7 */
+ u32 dport : 16; /**< 目标端口 */
+ u32 dipv6_key7 : 16; /**< IPv6目标地址的第七部分 */
- u32 rsvd2 : 16; /**< reserved bit 2 */
- u32 sport : 16; /**< source port */
+ u32 rsvd2 : 16; /**< 保留位2 */
+ u32 sport : 16; /**< 源端口 */
- u32 outer_sipv4_h : 16; /**< outer source IPv4 address high 16 bits */
- u32 rsvd3 : 16; /**< reserved bit 3 */
+ u32 outer_sipv4_h : 16; /**< 外部源IPv4地址的高16位 */
+ u32 rsvd3 : 16; /**< 保留位3 */
- u32 outer_dipv4_h : 16; /**< outer destination IPv4 address high 16 bits */
- u32 outer_sipv4_l : 16; /**< outer source IPv4 address low 16 bits */
+ u32 outer_dipv4_h : 16; /**< 外部目标IPv4地址的高16位 */
+ u32 outer_sipv4_l : 16; /**< 外部源IPv4地址的低16位 */
- u32 vni_h : 16; /**< VXLAN network ID high 16 bits */
- u32 outer_dipv4_l : 16; /**< outer destination IPv4 address low 16 bits */
+ u32 vni_h : 16; /**< VXLAN网络标识的高16位 */
+ u32 outer_dipv4_l : 16; /**< 外部目标IPv4地址的低16位 */
- u32 rsvd4 : 16; /**< reserved bit 4 */
- u32 vni_l : 16; /**< VXLAN network ID low 16 bits */
+ u32 rsvd4 : 16; /**< 保留位4 */
+ u32 vni_l : 16; /**< VXLAN网络标识的低16位 */
};
/**
* @struct hinic5_tcam_key_mem_htn
- * @brief HTN TCAM key structure
- * @details This structure contains fields for HTN TCAM key including reserved bits, tunnel type, IP protocol type, etc.
+ * @brief 定义了一个用于存储htn TCAM键的结构体
+ * @details 该结构体包含了htn TCAM键的各个字段,包括保留位、隧道类型、IP协议类型等。
*/
struct hinic5_tcam_key_mem_htn {
- u32 function_id_h : 5; /**< function id high 5 bits */
- u32 tunnel_type : 3; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol type */
- u32 rsvd0 : 16; /**< reserved 16 bits */
+ u32 function_id_h : 5; /**< function id高5位 */
+ u32 tunnel_type : 3; /**< 存储隧道类型 */
+ u32 ip_proto : 8; /**< 存储IP协议类型 */
+ u32 rsvd0 : 16; /**< 保留16位 */
- u32 outer_sipv4_h : 16; /**< outer source IPv4 high 16 bits */
- u32 rsvd1 : 8; /**< reserved 8 bits */
- u32 outer_ip_type : 1; /**< outer IP type */
- u32 ip_type : 2; /**< IP type */
- u32 function_id_l : 5; /**< function id low 5 bits */
+ u32 outer_sipv4_h : 16; /**< 外部源IPv4的高16位 */
+ u32 rsvd1 : 8; /**< 保留8位 */
+ u32 outer_ip_type : 1; /**< 存储外部IP类型 */
+ u32 ip_type : 2; /**< 存储IP类型 */
+ u32 function_id_l : 5; /**< function id低5位 */
- u32 outer_dipv4_h : 16; /**< outer destination IPv4 high 16 bits */
- u32 outer_sipv4_l : 16; /**< outer source IPv4 low 16 bits */
+ u32 outer_dipv4_h : 16; /**< 外部目的IPv4的高16位 */
+ u32 outer_sipv4_l : 16; /**< 外部源IPv4的低16位 */
- u32 vni_h : 8; /**< high 8 bits virtual network identifier */
- u32 rsvd2 : 8; /**< reserved 8 bits */
- u32 outer_dipv4_l : 16; /**< outer destination IPv4 low 16 bits */
+ u32 vni_h : 8; /**< 高8位存储虚拟网络标识符 */
+ u32 rsvd2 : 8; /**< 保留8位 */
+ u32 outer_dipv4_l : 16; /**< 外部目的IPv4的低16位 */
- u32 sipv4_h : 16; /**< source IPv4 high 16 bits */
- u32 vni_l : 16; /**< low 8 bits virtual network identifier */
+ u32 sipv4_h : 16; /**< 源IPv4的高16位 */
+ u32 vni_l : 16; /**< 低8位存储虚拟网络标识符 */
- u32 rsvd5 : 16; /**< reserved 16 bits */
- u32 sipv4_l : 16; /**< source IPv4 low 16 bits */
+ u32 rsvd5 : 16; /**< 保留16位 */
+ u32 sipv4_l : 16; /**< 源IPv4的低16位 */
- u32 rsvd6; /**< reserved */
- u32 rsvd7; /**< reserved */
+ u32 rsvd6; /**< 保留 */
+ u32 rsvd7; /**< 保留 */
- u32 dipv4_h : 16; /**< destination IPv4 high 16 bits */
- u32 rsvd8 : 16; /**< reserved 16 bits */
+ u32 dipv4_h : 16; /**< 目的IPv4的高16位 */
+ u32 rsvd8 : 16; /**< 保留16位 */
- u32 sport : 16; /**< source port */
- u32 dipv4_l : 16; /**< destination IPv4 low 16 bits */
+ u32 sport : 16; /**< 源端口 */
+ u32 dipv4_l : 16; /**< 目的IPv4的低16位 */
- u32 rsvd9 : 16; /**< reserved 16 bits */
- u32 dport : 16; /**< destination port */
+ u32 rsvd9 : 16; /**< 保留16位 */
+ u32 dport : 16; /**< 目的端口 */
};
/**
* @struct hinic5_tcam_key_ipv6_mem_htn
- * @brief HTN IPv6 TCAM key structure
- * @details This structure contains fields for HTN IPv6 TCAM key including reserved bits, tunnel type, IP protocol type, etc.
+ * @brief 定义了一个用于存储htn ipv6 TCAM键的结构体
+ * @details 该结构体包含了htn ipv6 TCAM键的各个字段,包括保留位、隧道类型、IP协议类型等。
*/
struct hinic5_tcam_key_ipv6_mem_htn {
- u32 function_id_h : 5; /**< function id high 5 bits */
- u32 tunnel_type : 3; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol type */
- u32 rsvd0 : 16; /**< reserved 16 bits */
+ u32 function_id_h : 5; /**< function id高5位 */
+ u32 tunnel_type : 3; /**< 存储隧道类型 */
+ u32 ip_proto : 8; /**< 存储IP协议类型 */
+ u32 rsvd0 : 16; /**< 保留16位 */
- u32 sipv6_key0 : 16; /**< source IPv6 part 1 */
- u32 rsvd1 : 8; /**< reserved field 1, unused */
- u32 outer_ip_type : 1; /**< outer IP type, 1 bit */
- u32 ip_type : 2; /**< IP type, 2 bits */
- u32 function_id_l : 5; /**< function id low 5 bits */
+ u32 sipv6_key0 : 16; /**< 源IPv6的第一部分 */
+ u32 rsvd1 : 8; /**< 保留字段1,未使用 */
+ u32 outer_ip_type : 1; /**< 外部IP类型,1位 */
+ u32 ip_type : 2; /**< IP类型,2位 */
+ u32 function_id_l : 5; /**< function id低5位 */
- u32 sipv6_key2 : 16; /**< source IPv6 part 2 */
- u32 sipv6_key1 : 16; /**< source IPv6 part 1 */
+ u32 sipv6_key2 : 16; /**< 源IPv6的第二部分 */
+ u32 sipv6_key1 : 16; /**< 源IPv6的第一部分 */
- u32 sipv6_key4 : 16; /**< source IPv6 part 4 */
- u32 sipv6_key3 : 16; /**< source IPv6 part 3 */
+ u32 sipv6_key4 : 16; /**< 源IPv6的第四部分 */
+ u32 sipv6_key3 : 16; /**< 源IPv6的第三部分 */
- u32 sipv6_key6 : 16; /**< source IPv6 part 6 */
- u32 sipv6_key5 : 16; /**< source IPv6 part 5 */
+ u32 sipv6_key6 : 16; /**< 源IPv6的第六部分 */
+ u32 sipv6_key5 : 16; /**< 源IPv6的第五部分 */
- u32 dipv6_key0 : 16; /**< destination IPv6 part 1 */
- u32 sipv6_key7 : 16; /**< source IPv6 part 7 */
+ u32 dipv6_key0 : 16; /**< 目的IPv6的第一部分 */
+ u32 sipv6_key7 : 16; /**< 源IPv6的第七部分 */
- u32 dipv6_key2 : 16; /**< destination IPv6 part 2 */
- u32 dipv6_key1 : 16; /**< destination IPv6 part 1 */
+ u32 dipv6_key2 : 16; /**< 目的IPv6的第二部分 */
+ u32 dipv6_key1 : 16; /**< 目的IPv6的第一部分 */
- u32 dipv6_key4 : 16; /**< destination IPv6 part 4 */
- u32 dipv6_key3 : 16; /**< destination IPv6 part 3 */
+ u32 dipv6_key4 : 16; /**< 目的IPv6的第四部分 */
+ u32 dipv6_key3 : 16; /**< 目的IPv6的第三部分 */
- u32 dipv6_key6 : 16; /**< destination IPv6 part 6 */
- u32 dipv6_key5 : 16; /**< destination IPv6 part 5 */
+ u32 dipv6_key6 : 16; /**< 目的IPv6的第六部分 */
+ u32 dipv6_key5 : 16; /**< 目的IPv6的第五部分 */
- u32 sport : 16; /**< source port */
- u32 dipv6_key7 : 16; /**< destination IPv6 part 7 */
+ u32 sport : 16; /**< 源端口 */
+ u32 dipv6_key7 : 16; /**< 目的IPv6的第七部分 */
- u32 rsvd2 : 16; /**< reserved field 2, unused */
- u32 dport : 16; /**< destination port */
+ u32 rsvd2 : 16; /**< 保留字段2,未使用 */
+ u32 dport : 16; /**< 目的端口 */
};
/**
* @struct hinic5_tcam_key_vxlan_ipv6_mem_htn
- * @brief HTN VXLAN IPv6 TCAM key structure
- * @details This structure contains fields for HTN VXLAN IPv6 TCAM key including reserved bits, tunnel type, IP protocol type, etc.
+ * @brief 定义了一个用于存储htn vxlan ipv6 TCAM键的结构体
+ * @details 该结构体包含了htn vxlan ipv6 TCAM键的各个字段,包括保留位、隧道类型、IP协议类型等。
*/
struct hinic5_tcam_key_vxlan_ipv6_mem_htn {
- u32 function_id_h : 5; /**< function id high 5 bits */
- u32 tunnel_type : 3; /**< tunnel type */
- u32 ip_proto : 8; /**< IP protocol */
- u32 rsvd0 : 16; /**< reserved 16 bits */
+ u32 function_id_h : 5; /**< function id高5位 */
+ u32 tunnel_type : 3; /**< 隧道类型 */
+ u32 ip_proto : 8; /**< IP协议 */
+ u32 rsvd0 : 16; /**< 保留16位 */
- u32 outer_sipv4_h : 16; /**< outer source IPv4 address high 16 bits */
- u32 rsvd1 : 8; /**< reserved 8 bits */
- u32 outer_ip_type : 1; /**< outer IP type */
- u32 ip_type : 2; /**< IP type */
- u32 function_id_l : 5; /**< function id low 5 bits */
+ u32 outer_sipv4_h : 16; /**< 高16位外部源IPv4地址 */
+ u32 rsvd1 : 8; /**< 保留8位 */
+ u32 outer_ip_type : 1; /**< 外部IP类型 */
+ u32 ip_type : 2; /**< IP类型 */
+ u32 function_id_l : 5; /**< function id低5位 */
- u32 outer_dipv4_h : 16; /**< outer destination IPv4 address high 16 bits */
- u32 outer_sipv4_l : 16; /**< outer source IPv4 address low 16 bits */
+ u32 outer_dipv4_h : 16; /**< 高16位外部目的IPv4地址 */
+ u32 outer_sipv4_l : 16; /**< 低16位外部源IPv4地址 */
- u32 vni_h : 8; /**< high 8 bits virtual network identifier */
- u32 rsvd2 : 8; /**< reserved 8 bits */
- u32 outer_dipv4_l : 16; /**< outer destination IPv4 address low 16 bits */
+ u32 vni_h : 8; /**< 高8位虚拟网络标识符 */
+ u32 rsvd2 : 8; /**< 保留8位 */
+ u32 outer_dipv4_l : 16; /**< 低16位外部目的IPv4地址 */
- u32 rsvd3 : 16; /**< reserved 16 bits */
- u32 vni_l : 16; /**< low 16 bits virtual network identifier */
+ u32 rsvd3 : 16; /**< 保留16位 */
+ u32 vni_l : 16; /**< 低16位虚拟网络标识符 */
- u32 dipv6_key0 : 16; /**< destination IPv6 address part 0 */
- u32 rsvd4 : 16; /**< reserved 16 bits */
+ u32 dipv6_key0 : 16; /**< 第0部分的目的IPv6地址 */
+ u32 rsvd4 : 16; /**< 保留16位 */
- u32 dipv6_key2 : 16; /**< destination IPv6 address part 2 */
- u32 dipv6_key1 : 16; /**< destination IPv6 address part 1 */
+ u32 dipv6_key2 : 16; /**< 第2部分的目的IPv6地址 */
+ u32 dipv6_key1 : 16; /**< 第1部分的目的IPv6地址 */
- u32 dipv6_key4 : 16; /**< destination IPv6 address part 4 */
- u32 dipv6_key3 : 16; /**< destination IPv6 address part 3 */
+ u32 dipv6_key4 : 16; /**< 第4部分的目的IPv6地址 */
+ u32 dipv6_key3 : 16; /**< 第3部分的目的IPv6地址 */
- u32 dipv6_key6 : 16; /**< destination IPv6 address part 6 */
- u32 dipv6_key5 : 16; /**< destination IPv6 address part 5 */
+ u32 dipv6_key6 : 16; /**< 第6部分的目的IPv6地址 */
+ u32 dipv6_key5 : 16; /**< 第5部分的目的IPv6地址 */
- u32 sport : 16; /**< source port */
- u32 dipv6_key7 : 16; /**< destination IPv6 address part 7 */
+ u32 sport : 16; /**< 源端口 */
+ u32 dipv6_key7 : 16; /**< 第7部分的目的IPv6地址 */
- u32 rsvd5 : 16; /**< reserved 16 bits */
- u32 dport : 16; /**< destination port */
+ u32 rsvd5 : 16; /**< 保留16位 */
+ u32 dport : 16; /**< 目的端口 */
};
/**
* @struct tcam_key_ctrl_mem
- * @brief HTN control packet TCAM key structure
- * @details This structure contains fields for HTN VXLAN IPv6 TCAM key including reserved bits, tunnel type, IP protocol type, etc.
+ * @brief 定义了一个用于存储htn 控制报文 TCAM键的结构体
+ * @details 该结构体包含了htn vxlan ipv6 TCAM键的各个字段,包括保留位、隧道类型、IP协议类型等。
*/
struct tcam_key_ctrl_mem {
- u32 function_id1 : 5; /**< function id high 5 bits */
- u32 pkt_fmt : 3; /**< packet format */
- u32 packet_type : 8; /**< packet type */
- u32 rsvd0 : 16; /**< reserved field 0 */
-
- u32 rsvd2 : 16; /**< reserved field 2 */
- u32 rsvd1 : 8; /**< reserved field 1 */
- u32 outer_type : 1; /**< outer type */
- u32 inner_type : 2; /**< inner type */
- u32 function_id2 : 5; /**< function id low 5 bits */
-
- u32 rsvd3; /**< reserved field 3 */
- u32 rsvd4; /**< reserved field 4 */
- u32 rsvd5; /**< reserved field 5 */
- u32 rsvd6; /**< reserved field 6 */
- u32 rsvd7; /**< reserved field 7 */
- u32 rsvd8; /**< reserved field 8 */
- u32 rsvd9; /**< reserved field 9 */
- u32 rsvd10; /**< reserved field 10 */
- u32 rsvd11; /**< reserved field 11 */
+ u32 function_id1 : 5; /**< function id高5位 */
+ u32 pkt_fmt : 3; /**< 报文格式 */
+ u32 packet_type : 8; /**< 报文类型 */
+ u32 rsvd0 : 16; /**< 保留字段0 */
+
+ u32 rsvd2 : 16; /**< 保留字段2 */
+ u32 rsvd1 : 8; /**< 保留字段1 */
+ u32 outer_type : 1; /**< 外层类型 */
+ u32 inner_type : 2; /**< 内层类型 */
+ u32 function_id2 : 5; /**< function id低5位 */
+
+ u32 rsvd3; /**< 保留字段3 */
+ u32 rsvd4; /**< 保留字段4 */
+ u32 rsvd5; /**< 保留字段5 */
+ u32 rsvd6; /**< 保留字段6 */
+ u32 rsvd7; /**< 保留字段7 */
+ u32 rsvd8; /**< 保留字段8 */
+ u32 rsvd9; /**< 保留字段9 */
+ u32 rsvd10; /**< 保留字段10 */
+ u32 rsvd11; /**< 保留字段11 */
};
/**
* @struct tag_tcam_key
- * @brief TCAM key structure for storing TCAM key information and mask
- * @details This structure contains two unions for storing IPv4 key information and mask respectively.
+ * @brief TCAM键结构体,用于存储TCAM键的信息和掩码
+ * @details 该结构体包含两个联合体,分别用于存储IPv4键的信息和掩码。
*/
struct tag_tcam_key {
/**
- * @union
- * @brief TCAM key information
- */
+ * @union
+ * @brief TCAM键信息
+ */
union {
struct hinic5_tcam_key_ipv4_mem key_info;
struct tcam_key_ctrl_mem key_info_ctrl;
@@ -528,13 +543,14 @@ struct tag_tcam_key {
struct hinic5_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
struct hinic5_tcam_key_mem_htn key_info_htn;
struct hinic5_tcam_key_ipv6_mem_htn key_info_ipv6_htn;
- struct hinic5_tcam_key_vxlan_ipv6_mem_htn key_info_vxlan_ipv6_htn;
+ struct hinic5_tcam_key_vxlan_ipv6_mem_htn
+ key_info_vxlan_ipv6_htn;
};
/**
- * @union
- * @brief TCAM key mask
- */
+ * @union
+ * @brief TCAM键掩码
+ */
union {
struct hinic5_tcam_key_ipv4_mem key_mask;
struct tcam_key_ctrl_mem key_mask_ctrl;
@@ -542,175 +558,207 @@ struct tag_tcam_key {
struct hinic5_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
struct hinic5_tcam_key_mem_htn key_mask_htn;
struct hinic5_tcam_key_ipv6_mem_htn key_mask_ipv6_htn;
- struct hinic5_tcam_key_vxlan_ipv6_mem_htn key_mask_vxlan_ipv6_htn;
+ struct hinic5_tcam_key_vxlan_ipv6_mem_htn
+ key_mask_vxlan_ipv6_htn;
};
};
-#define TCAM_RULE_FDIR_TYPE 0 /**< TCAM rule type, FDIR type value is 0 */
-#define TCAM_RULE_PPA_TYPE 1 /**< TCAM rule type, PPA type value is 1 */
-#define TCAM_RULE_BIFURCATION_TYPE 2 /**< TCAM rule type, BIFURCATION type value is 2 */
+#define TCAM_RULE_FDIR_TYPE 0 /**< 定义TCAM规则的类型,FDIR类型对应值为0 */
+#define TCAM_RULE_PPA_TYPE 1 /**< 定义TCAM规则的类型,PPA类型对应值为1 */
+#define TCAM_RULE_BIFURCATION_TYPE \
+ 2 /**< 定义TCAM规则的类型,BIFURCATION类型对应值为1 */
/**
* @struct hinic5_phy_fpga_port_stats
- * @brief PHY FPGA port statistics structure
- * @details This structure stores PHY FPGA port statistics
+ * @brief 定义了一个结构体,用于存储PHY FPGA端口的统计信息
+ * @details 这里是结构体的详细描述
*/
struct hinic5_phy_fpga_port_stats {
- u64 mac_rx_total_octs_port; /**< total received bytes */
- u64 mac_tx_total_octs_port; /**< total transmitted bytes */
- u64 mac_rx_under_frame_pkts_port; /**< received frames with length less than 64 bytes */
- u64 mac_rx_frag_pkts_port; /**< received fragment packets */
- u64 mac_rx_64_oct_pkts_port; /**< received 64-byte packets */
- u64 mac_rx_127_oct_pkts_port; /**< received 127-byte packets */
- u64 mac_rx_255_oct_pkts_port; /**< received 255-byte packets */
- u64 mac_rx_511_oct_pkts_port; /**< received 511-byte packets */
- u64 mac_rx_1023_oct_pkts_port; /**< received 1023-byte packets */
- u64 mac_rx_max_oct_pkts_port; /**< received max length packets */
- u64 mac_rx_over_oct_pkts_port; /**< received oversized packets */
- u64 mac_tx_64_oct_pkts_port; /**< transmitted 64-byte packets */
- u64 mac_tx_127_oct_pkts_port; /**< transmitted 127-byte packets */
- u64 mac_tx_255_oct_pkts_port; /**< transmitted 255-byte packets */
- u64 mac_tx_511_oct_pkts_port; /**< transmitted 511-byte packets */
- u64 mac_tx_1023_oct_pkts_port; /**< transmitted 1023-byte packets */
- u64 mac_tx_max_oct_pkts_port; /**< transmitted max length packets */
- u64 mac_tx_over_oct_pkts_port; /**< transmitted oversized packets */
- u64 mac_rx_good_pkts_port; /**< received good packets */
- u64 mac_rx_crc_error_pkts_port; /**< received CRC error packets */
- u64 mac_rx_broadcast_ok_port; /**< received broadcast packets */
- u64 mac_rx_multicast_ok_port; /**< received multicast packets */
- u64 mac_rx_mac_frame_ok_port; /**< received MAC frame packets */
- u64 mac_rx_length_err_pkts_port; /**< received length error packets */
- u64 mac_rx_vlan_pkts_port; /**< received VLAN packets */
- u64 mac_rx_pause_pkts_port; /**< received pause packets */
- u64 mac_rx_unknown_mac_frame_port; /**< received unknown MAC frame packets */
- u64 mac_tx_good_pkts_port; /**< transmitted good packets */
- u64 mac_tx_broadcast_ok_port; /**< transmitted broadcast packets */
- u64 mac_tx_multicast_ok_port; /**< transmitted multicast packets */
- u64 mac_tx_underrun_pkts_port; /**< transmitted underrun packets */
- u64 mac_tx_mac_frame_ok_port; /**< transmitted MAC frame packets */
- u64 mac_tx_vlan_pkts_port; /**< transmitted VLAN packets */
- u64 mac_tx_pause_pkts_port; /**< transmitted pause packets */
+ u64 mac_rx_total_octs_port; /**< 接收的总字节数 */
+ u64 mac_tx_total_octs_port; /**< 发送的总字节数 */
+ u64 mac_rx_under_frame_pkts_port; /**< 接收的帧长度小于64字节的数据包数 */
+ u64 mac_rx_frag_pkts_port; /**< 接收的碎片数据包数 */
+ u64 mac_rx_64_oct_pkts_port; /**< 接收的64字节数据包数 */
+ u64 mac_rx_127_oct_pkts_port; /**< 接收的127字节数据包数 */
+ u64 mac_rx_255_oct_pkts_port; /**< 接收的255字节数据包数 */
+ u64 mac_rx_511_oct_pkts_port; /**< 接收的511字节数据包数 */
+ u64 mac_rx_1023_oct_pkts_port; /**< 接收的1023字节数据包数 */
+ u64 mac_rx_max_oct_pkts_port; /**< 接收的最大长度数据包数 */
+ u64 mac_rx_over_oct_pkts_port; /**< 接收的超长数据包数 */
+ u64 mac_tx_64_oct_pkts_port; /**< 发送的64字节数据包数 */
+ u64 mac_tx_127_oct_pkts_port; /**< 发送的127字节数据包数 */
+ u64 mac_tx_255_oct_pkts_port; /**< 发送的255字节数据包数 */
+ u64 mac_tx_511_oct_pkts_port; /**< 发送的511字节数据包数 */
+ u64 mac_tx_1023_oct_pkts_port; /**< 发送的1023字节数据包数 */
+ u64 mac_tx_max_oct_pkts_port; /**< 发送的最大长度数据包数 */
+ u64 mac_tx_over_oct_pkts_port; /**< 发送的超长数据包数 */
+ u64 mac_rx_good_pkts_port; /**< 接收的无错误数据包数 */
+ u64 mac_rx_crc_error_pkts_port; /**< 接收的CRC错误数据包数 */
+ u64 mac_rx_broadcast_ok_port; /**< 接收的广播数据包数 */
+ u64 mac_rx_multicast_ok_port; /**< 接收的多播数据包数 */
+ u64 mac_rx_mac_frame_ok_port; /**< 接收的MAC帧数据包数 */
+ u64 mac_rx_length_err_pkts_port; /**< 接收的长度错误数据包数 */
+ u64 mac_rx_vlan_pkts_port; /**< 接收的VLAN数据包数 */
+ u64 mac_rx_pause_pkts_port; /**< 接收的暂停数据包数 */
+ u64 mac_rx_unknown_mac_frame_port; /**< 接收的未知MAC帧数据包数 */
+ u64 mac_tx_good_pkts_port; /**< 发送的无错误数据包数 */
+ u64 mac_tx_broadcast_ok_port; /**< 发送的广播数据包数 */
+ u64 mac_tx_multicast_ok_port; /**< 发送的多播数据包数 */
+ u64 mac_tx_underrun_pkts_port; /**< 发送的缓冲区不足数据包数 */
+ u64 mac_tx_mac_frame_ok_port; /**< 发送的MAC帧数据包数 */
+ u64 mac_tx_vlan_pkts_port; /**< 发送的VLAN数据包数 */
+ u64 mac_tx_pause_pkts_port; /**< 发送的暂停数据包数 */
};
/**
* @struct hinic5_port_stats
- * @brief hinic5 port statistics structure
- * @details This structure contains management message header and physical port statistics
+ * @brief 定义了hinic5端口统计信息的结构体
+ * @details 该结构体包含了管理消息头部信息和物理端口统计信息
*/
struct hinic5_port_stats {
- struct hinic5_mgmt_msg_head msg_head; /**< management message header */
+ struct hinic5_mgmt_msg_head msg_head; /**< 管理消息头部信息 */
- struct hinic5_phy_fpga_port_stats stats; /**< physical port statistics */
+ struct hinic5_phy_fpga_port_stats stats; /**< 物理端口统计信息 */
};
/**
* @struct hinic5_rss_indir_table
- * @brief RSS indirect table structure
- * @details This structure stores RSS information including management message header, function ID, reserved field and indirect table.
+ * @brief 定义了一个RSS(Receive Side Scaling,接收端缩放)的间接查找表结构体
+ * @details 该结构体用于存储RSS的相关信息,包括管理消息头部、函数ID、保留字段和间接查找表。
*/
struct hinic5_rss_indir_table {
- struct hinic5_mgmt_msg_head msg_head; /**< management message header */
+ struct hinic5_mgmt_msg_head msg_head; /**< 管理消息头部 */
- u16 func_id; /**< func id */
- u16 rsvd1; /**< reserved field 1 */
- u8 indir[NIC_RSS_INDIR_SIZE]; /**< indirect table */
+ u16 func_id; /**< func id */
+ u16 rsvd1; /** 保留字段1 */
+ u8 indir[NIC_RSS_INDIR_SIZE]; /**< 间接查找表 */
};
-#define NIC_RSS_CMD_TEMP_ALLOC 0x01 /**< temporary RSS resource allocation */
-#define NIC_RSS_CMD_TEMP_FREE 0x02 /**< temporary RSS resource release */
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01 /**< 用于临时分配rss资源 */
+#define NIC_RSS_CMD_TEMP_FREE 0x02 /**< 用于临时释放rss资源 */
/**
* @struct hinic5_func_tbl_cfg_bitmap
- * @brief function table configuration bitmap structure
- * @details This structure represents function table configuration bitmap including init config, RX buffer size config and MTU config.
+ * @brief 函数表配置位图结构体
+ * @details 该结构体用于表示函数表配置位图,包含了初始化配置、接收缓冲区大小配置和最大传输单元配置。
*/
enum hinic5_func_tbl_cfg_bitmap {
- FUNC_CFG_INIT, /**< init config */
- FUNC_CFG_RX_BUF_SIZE, /**< RX buffer size config */
- FUNC_CFG_MTU, /**< max transmission unit config */
- FUNC_CFG_ISOLATION_VF_MAC, /**< cluster mode VF MAC config */
- FUNC_CFG_ISOLATION_VF_SVLAN, /**< cluster mode VF SVLAN config */
+ FUNC_CFG_INIT, /**< 初始化配置 */
+ FUNC_CFG_RX_BUF_SIZE, /**< 接收缓冲区大小配置 */
+ FUNC_CFG_MTU, /**< 最大传输单元配置 */
+ FUNC_CFG_ISOLATION_VF_MAC, /**< 集群模式VF MAC配置 */
+ FUNC_CFG_ISOLATION_VF_SVLAN, /**< 集群模式VF SVLAN配置 */
};
typedef struct mac_table_cnt {
- u32 valid_table_cnt; /**< valid MAC table count */
- u32 mac_table_cnt; /**< max supported MAC table count */
- u16 uc_mac_cnt; /**< unicast count */
- u16 mc_mac_cnt; /**< multicast count */
+ u32 valid_table_cnt; /**< 有效的MAC表数量 */
+ u32 mac_table_cnt; /**< 最大支持的MAC表数量 */
+ u16 uc_mac_cnt; /**< 单播计数 */
+ u16 mc_mac_cnt; /**< 组播计数 */
} mac_table_cnt_s;
#define NIC_FUNC_MAX_NUM 4096
typedef struct mac_table_res_stat {
- u16 uc_mac_cnt; /**< unicast table resource usage */
- u16 mc_mac_cnt; /**< multicast table resource usage */
- u16 share_mac_res_cur_cnt; /**< current shared resource pool usage */
- u16 share_mac_res_total; /**< shared resource pool total size */
- u16 func_uc_mac_cnt[NIC_FUNC_MAX_NUM]; /**< Func level unicast table resource usage */
+ u16 uc_mac_cnt; /**< 单播表资源使用统计 */
+ u16 mc_mac_cnt; /**< 组播表资源使用统计 */
+ u16 share_mac_res_cur_cnt; /**< 当前共享资源池使用统计 */
+ u16 share_mac_res_total; /**< 共享资源池总大小 */
+ u16 func_uc_mac_cnt[NIC_FUNC_MAX_NUM]; /**< Func粒度单播表资源使用统计 */
} mac_table_res_stat_s;
-#define HINIC5_CMD_OP_SET 1 /**< cmd operation type set */
-#define HINIC5_CMD_OP_GET 0 /**< cmd operation type get */
+#define HINIC5_CMD_OP_SET 1 /**< cmd操作类型为set */
+#define HINIC5_CMD_OP_GET 0 /**< cmd操作类型为get */
-#define HINIC5_CMD_OP_ADD 1 /**< cmd operation type add */
-#define HINIC5_CMD_OP_DEL 0 /**< cmd operation type del */
+#define HINIC5_CMD_OP_ADD 1 /**< cmd操作类型为add */
+#define HINIC5_CMD_OP_DEL 0 /**< cmd操作类型为del */
/**
- * @brief command type enum for different command types
- * @details This enum defines a series of command types for different contexts.
+ * @brief 定义枚举类型,用于表示不同的命令类型
+ * @details 这个枚举类型定义了一系列的命令类型,用于在不同的上下文中表示不同的操作。
*/
enum {
- PPA_TABLE_ID_CLEAN_CMD = 0, /**< clean PPA table command*/
- PPA_TABLE_ID_ADD_CMD, /**< add PPA table command*/
- PPA_TABLE_ID_DEL_CMD, /**< delete PPA table command*/
- FDIR_TABLE_ID_ADD_CMD, /**< add FDIR table command*/
- FDIR_TABLE_ID_DEL_CMD, /**< delete FDIR table command*/
- PPA_TABEL_ID_MAX /**< PPA table max value*/
+ PPA_TABLE_ID_CLEAN_CMD = 0, /**< 清理PPA表的命令*/
+ PPA_TABLE_ID_ADD_CMD, /**< 添加PPA表的命令*/
+ PPA_TABLE_ID_DEL_CMD, /**< 删除PPA表的命令*/
+ FDIR_TABLE_ID_ADD_CMD, /**< 添加FDIR表的命令*/
+ FDIR_TABLE_ID_DEL_CMD, /**< 删除FDIR表的命令*/
+ PPA_TABEL_ID_MAX /**< PPA表的最大值*/
};
/**
- * @brief NIC NVM data type enum
- * @details This enum contains multiple flags, each representing a type of NIC NVM data.
+ * @brief 定义一个枚举类型,用于表示网卡NVM数据的类型
+ * @details 这个枚举类型包含了多个标志位,每个标志位代表一种网卡NVM数据的类型。
*/
enum {
NIC_NVM_DATA_SET = BIT(0), /**< 1-save, 0-read */
- NIC_NVM_DATA_PXE = BIT(1), /**< PXE */
+ NIC_NVM_DATA_PXE = BIT(1), /**< PXE */
NIC_NVM_DATA_VLAN = BIT(2), /**< VLAN */
NIC_NVM_DATA_VLAN_PRI = BIT(3), /**< VLAN PRI */
- NIC_NVM_DATA_VLAN_ID = BIT(4), /**< VLAN ID */
- NIC_NVM_DATA_WORK_MODE = BIT(5), /**< work mode */
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6), /**< PF speed limit */
- NIC_NVM_DATA_GE_MODE = BIT(7), /**< GE mode */
+ NIC_NVM_DATA_VLAN_ID = BIT(4), /**< VLAN ID */
+ NIC_NVM_DATA_WORK_MODE = BIT(5), /**< 任务类型 */
+ NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6), /**< PPF限速 */
+ NIC_NVM_DATA_GE_MODE = BIT(7), /**< GE模式 */
NIC_NVM_DATA_AUTO_NEG = BIT(8), /**< AUTO NEG */
NIC_NVM_DATA_LINK_FEC = BIT(9), /**< LINK FEC */
- NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10), /**< PF adaptive link */
- NIC_NVM_DATA_SRIOV_CONTROL = BIT(11), /**< SRIOV CONTROL */
- NIC_NVM_DATA_EXTEND_MODE = BIT(12), /**< extend mode */
- NIC_NVM_DATA_RESET = BIT(31), /**< RESET */
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10), /**< PF自适应link */
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11), /**< SRIOV CONTROL */
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12), /**< 拓展模式 */
+ NIC_NVM_DATA_RESET = BIT(31), /**< RESET */
};
-#define BIOS_CFG_SIGNATURE 0x1923E518 /**< BIOS config signature */
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0) /**< BIOS op code all config macro */
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0) /**< BIOS op code write config macro */
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0) /**< BIOS op code PXE enable macro */
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0) /**< BIOS op code VLAN enable macro */
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0) /**< BIOS op code VLAN priority macro */
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0) /**< BIOS op code VLAN ID macro */
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0) /**< BIOS op code work mode macro */
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0) /**< BIOS op code PF bandwidth macro */
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0) /**< BIOS op code GE speed macro */
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0) /**< BIOS op code auto negotiation macro */
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0) /**< BIOS op code link FEC macro */
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0) /**< BIOS op code auto adapt macro */
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0) /**< BIOS op code SR-IOV enable macro */
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0) /**< BIOS op code extend mode macro */
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0) /**< BIOS op code reset default macro */
-
-#define ENHANCED_CMDQ_CTX_SIZE 0x30 /**< enhanced cmdq context size is 48 */
-
-#define FLOW_BIFURCATE_BIT (1U << 10) /* 1872 flow bifurcation bit is 10 */
-
-#define HINIC5_LRO_DEFAULT_COAL_PKT_SIZE 32
-#define HINIC5_LRO_DEFAULT_TIME_LIMIT 16
+#define BIOS_CFG_SIGNATURE 0x1923E518 /**< 定义BIOS配置签名 */
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != \
+ 0) /**< 定义BIOS操作码全部配置的宏 */
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val)&NIC_NVM_DATA_SET)) != \
+ 0) /**< 定义BIOS操作码写入配置的宏 */
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_PXE) != \
+ 0) /**< 定义BIOS操作码PXE启用的宏 */
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_VLAN) != \
+ 0) /**< 定义BIOS操作码VLAN启用的宏 */
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_VLAN_PRI) != \
+ 0) /**< 定义BIOS操作码VLAN优先级的宏 */
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_VLAN_ID) != \
+ 0) /**< 定义BIOS操作码VLAN ID的宏 */
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_WORK_MODE) != \
+ 0) /**< 定义BIOS操作码工作模式的宏 */
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_PF_SPEED_LIMIT) != \
+ 0) /**< 定义BIOS操作码PF带宽的宏 */
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_GE_MODE) != \
+ 0) /**< 定义BIOS操作码GE速度的宏 */
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_AUTO_NEG) != \
+ 0) /**< 定义BIOS操作码自动协商的宏 */
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_LINK_FEC) != \
+ 0) /**< 定义BIOS操作码链路FEC的宏 */
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_PF_ADAPTIVE_LINK) != \
+ 0) /**< 定义BIOS操作码自动适应的宏 */
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_SRIOV_CONTROL) != \
+ 0) /**< 定义BIOS操作码SR-IOV启用的宏 */
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val)&NIC_NVM_DATA_EXTEND_MODE) != \
+ 0) /**< 定义BIOS操作码扩展模式的宏 */
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != \
+ 0) /**< 定义BIOS操作码重置默认设置的宏 */
+
+#define ENHANCED_CMDQ_CTX_SIZE 0x30 /**< 定义增强型cmdq context size为48 */
+
+#define FLOW_BIFURCATE_BIT 1U << 10 /* 1872流分叉bit位为10 */
+
+#define HINIC5_LRO_DEFAULT_COAL_PKT_SIZE 32
+#define HINIC5_LRO_DEFAULT_TIME_LIMIT 16
#define HINIC5_SET_PORT_CAR_PROFILE 0
#define HINIC5_SET_PORT_CAR_STATE 1
@@ -721,26 +769,26 @@ enum {
#define HINIC5_FUNC_CAR_ID_OFFSET 16
-#define HINIC5_HTN_CMD_SET_CAR 0x26
-#define HINIC5_HTN_CMD_GET_CAR 0x27
+#define HINIC5_HTN_CMD_SET_CAR 0x26
+#define HINIC5_HTN_CMD_GET_CAR 0x27
-#define CAR_PROFILE_SIZE 32
-#define CAR_INDEX_UNIT 16
+#define CAR_PROFILE_SIZE 32
+#define CAR_INDEX_UNIT 16
#define NIC_MPU_LT_RD_NOT_SUPPORT_ERROR 253
#define NIC_MPU_LT_OPERA_RANGE_ERROR 254
-#define CMD_QOS_ETS_COS_TC BIT(0)
-#define CMD_QOS_ETS_TC_BW BIT(1)
-#define CMD_QOS_ETS_COS_PRIO BIT(2)
-#define CMD_QOS_ETS_COS_BW BIT(3)
-#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
-#define CMD_QOS_PORT_TRUST BIT(0)
-#define CMD_QOS_PORT_DFT_COS BIT(1)
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
-#define CMD_QOS_MAP_PCP2COS BIT(0)
-#define CMD_QOS_MAP_DSCP2COS BIT(1)
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
#define STD_SFP_INFO_MAX_SIZE 640
@@ -757,11 +805,11 @@ typedef enum {
HINIC5_NIC_OP_MAX,
} nic_cnt_op_e;
-#define VEB_OFFLOAD_QUERY 0
-#define VEB_OFFLOAD_SET 1
-#define VEB_OFFLOAD_STATUS_OFF 0
-#define VEB_OFFLOAD_STATUS_ON 1
-#define VEB_OFFLOAD_STATUS_INVALID 2
+#define VEB_OFFLOAD_QUERY 0
+#define VEB_OFFLOAD_SET 1
+#define VEB_OFFLOAD_STATUS_OFF 0
+#define VEB_OFFLOAD_STATUS_ON 1
+#define VEB_OFFLOAD_STATUS_INVALID 2
enum hinic5_port_car_type {
HINIC5_PORT_CAR_TYPE_PORT = 0,
@@ -786,10 +834,10 @@ enum hinic5_port_car_level {
};
typedef enum {
- NIC_SOFT_LRO_EN_OPERATE = 0, /* software LRO enable operation */
- NIC_HW_LRO_LEN_OPERATE, /* hardware LRO aggregation length operation */
- NIC_HW_LRO_NUM_OPERATE, /* hardware LRO aggregation count operation */
- NIC_HW_LRO_TIMER_OPERATE, /* hardware LRO aggregation time operation */
+ NIC_SOFT_LRO_EN_OPERATE = 0, /* 软件LRO使能操作 */
+ NIC_HW_LRO_LEN_OPERATE, /* 硬件LRO聚合长度操作 */
+ NIC_HW_LRO_NUM_OPERATE, /* 硬件LRO聚合数量操作 */
+ NIC_HW_LRO_TIMER_OPERATE, /* 硬件LRO聚合时间操作 */
NIC_LRO_CFG_OPERATE_MAX
} lro_cfg_operate_type_u;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd.h
index a6f0c46a7..a0eb860d8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd.h
@@ -1,10 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
+ * 头文件通过MAILBOX基线表格中的脚本自动生成。如有增删,请先修改基线表格,然后自动生成该头文件
+ * 修改流程见:https://wiki.huawei.com/domains/1574/wiki/8/WIKI202509298479069
* File Name : nic_mpu_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
* Description : NIC Commands between Driver and MPU
*/
@@ -17,204 +14,215 @@
*/
enum hinic5_nic_cmd {
HINIC5_NIC_CMD_VF_REGISTER = 0, /** < @see hinic5_cmd_register_vf */
- HINIC5_NIC_CMD_SET_FUNC_TBL = 5, /* Set FUNC table initialization, mtu value, etc.
- * @see hinic5_cmd_set_func_tbl
- */
- HINIC5_NIC_CMD_SET_VPORT_ENABLE = 6, /* func enable/disable flag (OVS uses PF to send on behalf)
- * @see hinic5_vport_state
- */
- HINIC5_NIC_CMD_SET_RX_MODE = 7, /* Set unicast, multicast promiscuous mode flags
- * @see hinic5_rx_mode_config
- */
- HINIC5_NIC_CMD_SQ_CI_ATTR_SET = 8, /* Set func CI attribute table
- * @see hinic5_cmd_cons_idx_attr
- */
- HINIC5_NIC_CMD_GET_VPORT_STAT = 9, /* Get func unicast, discard statistics
- * @see hinic5_port_stats_info/hinic5_cmd_vport_stats
- */
- HINIC5_NIC_CMD_CLEAN_VPORT_STAT = 10, /* Clean func unicast, discard statistics
- * @see hinic5_port_stats_info
- */
- HINIC5_NIC_CMD_CLEAR_QP_RESOURCE = 11, /* Clear func queue CPI CI value to 0
- * @see hinic5_cmd_clear_qp_resource
- */
+ HINIC5_NIC_CMD_SET_FUNC_TBL =
+ 5, /** < 设置FUNC表初始化、mtu值等 @see hinic5_cmd_set_func_tbl */
+ HINIC5_NIC_CMD_SET_VPORT_ENABLE =
+ 6, /** < func使能/去使能标记(OVS使用PF代发) @see hinic5_vport_state */
+ HINIC5_NIC_CMD_SET_RX_MODE =
+ 7, /** < 设置单播、组播混杂等标记 @see hinic5_rx_mode_config */
+ HINIC5_NIC_CMD_SQ_CI_ATTR_SET =
+ 8, /** < 设置func的CI属性表 @see hinic5_cmd_cons_idx_attr */
+ HINIC5_NIC_CMD_GET_VPORT_STAT =
+ 9, /** < 获取func 单播、丢包等统计 @see hinic5_port_stats_info/hinic5_cmd_vport_stats */
+ HINIC5_NIC_CMD_CLEAN_VPORT_STAT =
+ 10, /** < 清理func 单薄、丢包等统计 @see hinic5_port_stats_info */
+ HINIC5_NIC_CMD_CLEAR_QP_RESOURCE =
+ 11, /** < 清0 func队列的CPI CI值 @see hinic5_cmd_clear_qp_resource */
HINIC5_NIC_CMD_CFG_FLEX_QUEUE = 12, /** < rsvd */
- HINIC5_NIC_CMD_CFG_RX_LRO = 13, /** < Configure LRO enable @see hinic5_cmd_lro_config */
- HINIC5_NIC_CMD_CFG_LRO_TIMER = 14, /** < Enable LRO Timer @see hinic5_cmd_lro_timer */
- HINIC5_NIC_CMD_FEATURE_NEGO = 15, /** < func attribute negotiation @see hinic5_cmd_feature_nego */
- HINIC5_NIC_CMD_CFG_LOCAL_LRO_STATE = 16, /* Set func local_switch_lro_en
- * @see hinic5_cmd_local_lro_state
- */
- HINIC5_NIC_CMD_CACHE_OUT_QP_RES = 17, /* Clean L2NIC/SMMC_CLA Cache resource
- * @see hinic5_cmd_cache_out_qp_resource
- */
- HINIC5_NIC_CMD_SET_FUNC_ER_FWD_ID = 18, /* Set NIC ER forwarding ID, used for flow bifurcation (for computation, rsvd) */
- HINIC5_NIC_CMD_GET_MAC = 20, /** < func get MAC address @see hinic5_port_mac_set */
- HINIC5_NIC_CMD_SET_MAC = 21, /** < func set MAC address @see hinic5_port_mac_set */
- HINIC5_NIC_CMD_DEL_MAC = 22, /** < func delete MAC address @see hinic5_port_mac_set */
- HINIC5_NIC_CMD_UPDATE_MAC = 23, /** < func update MAC address @see hinic5_port_mac_update */
- HINIC5_NIC_CMD_GET_ALL_DEFAULT_MAC = 24, /* Get all default MAC addresses
- * @see nic_cmd_mac_info
- */
- HINIC5_NIC_CMD_CFG_FUNC_VLAN = 25, /* Add/delete func vlan device
- * @see hinic5_cmd_vlan_config
- */
- HINIC5_NIC_CMD_SET_VLAN_FILTER_EN = 26, /* Set func VLAN filter function
- * @see hinic5_cmd_set_vlan_filter
- */
- HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD = 27, /* Set func table rx_vlan_offload_en
- * @see hinic5_cmd_vlan_offload
- */
- HINIC5_NIC_CMD_OUTBAND_SET_FUNC_VLAN = 29, /* Outband set func vlan (for computation, rsvd) */
- HINIC5_NIC_CMD_CFG_VXLAN_PORT = 30, /** < Set vxlan_dprot (for computation, rsvd) */
- HINIC5_NIC_CMD_RX_RATE_CFG = 31, /** < rx rate limit bios setting (for computation, rsvd) */
- HINIC5_NIC_CMD_WR_ORDERING_CFG = 32, /* Set PCIe read/write strong ordering or relaxed ordering (for computation, rsvd) */
- HINIC5_NIC_CMD_MAC_SYNC = 33, /** < Set mac sync (for computation, rsvd) */
+ HINIC5_NIC_CMD_CFG_RX_LRO =
+ 13, /** < 配置LRO的使能等 @see hinic5_cmd_lro_config */
+ HINIC5_NIC_CMD_CFG_LRO_TIMER =
+ 14, /** < 使能LRO的Timer @see hinic5_cmd_lro_timer */
+ HINIC5_NIC_CMD_FEATURE_NEGO =
+ 15, /** < func的属性协商 @see hinic5_cmd_feature_nego */
+ HINIC5_NIC_CMD_CFG_LOCAL_LRO_STATE =
+ 16, /** < 设置func的local_switch_lro_en @see hinic5_cmd_local_lro_state */
+ HINIC5_NIC_CMD_CACHE_OUT_QP_RES =
+ 17, /** < 清理L2NIC/SMMC_CLA Cache资源 @see hinic5_cmd_cache_out_qp_resource */
+ HINIC5_NIC_CMD_SET_FUNC_ER_FWD_ID =
+ 18, /** < 设置NIC ER 转发ID,流分叉使用(计算使用,rsvd) */
+ HINIC5_NIC_CMD_GET_MAC =
+ 20, /** < func 获取MAC地址 @see hinic5_port_mac_set */
+ HINIC5_NIC_CMD_SET_MAC =
+ 21, /** < func 设置MAC地址 @see hinic5_port_mac_set */
+ HINIC5_NIC_CMD_DEL_MAC =
+ 22, /** < func 删除MAC地址 @see hinic5_port_mac_set */
+ HINIC5_NIC_CMD_UPDATE_MAC =
+ 23, /** < func 更新MAC地址 @see hinic5_port_mac_update */
+ HINIC5_NIC_CMD_GET_ALL_DEFAULT_MAC =
+ 24, /** < 获取所有默认MAC地址 @see nic_cmd_mac_info */
+ HINIC5_NIC_CMD_CFG_FUNC_VLAN =
+ 25, /** < 添加/删除func的vlan设备 @see hinic5_cmd_vlan_config */
+ HINIC5_NIC_CMD_SET_VLAN_FILTER_EN =
+ 26, /** < 设置func的VLAN过滤功能 @see hinic5_cmd_set_vlan_filter */
+ HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD =
+ 27, /** < 设置func表rx_vlan_offload_en @see hinic5_cmd_vlan_offload */
+ HINIC5_NIC_CMD_OUTBAND_SET_FUNC_VLAN =
+ 29, /** < 带外设置func的vlan(计算使用,rsvd) */
+ HINIC5_NIC_CMD_CFG_VXLAN_PORT =
+ 30, /** < 设置vxlan_dprot(计算使用,rsvd) */
+ HINIC5_NIC_CMD_RX_RATE_CFG =
+ 31, /** < rx限速bios设置(计算使用,rsvd) */
+ HINIC5_NIC_CMD_WR_ORDERING_CFG =
+ 32, /** < 设置PCIe的读写是强保序还是乱序(计算使用,rsvd) */
+ HINIC5_NIC_CMD_MAC_SYNC = 33, /** < 设置mac同步(计算使用,rsvd) */
HINIC5_NIC_CMD_SET_RQ_CI_CTX = 34, /** < @see hinic5_rq_cqe_ctx */
HINIC5_NIC_CMD_SET_RQ_ENABLE = 35, /** < @see hinic5_rq_enable */
- HINIC5_NIC_CMD_CFG_VF_VLAN = 40, /* Add/delete func vlan device (QinQ)
- * @see hinic5_cmd_vf_vlan_config
- */
- HINIC5_NIC_CMD_SET_SPOOFCHK_STATE = 41, /** < @see hinic5_cmd_spoofchk_set */
- HINIC5_NIC_CMD_SET_MAX_MIN_RATE = 42, /** < Set func rate limit @see hinic5_cmd_rate_cfg */
- HINIC5_NIC_CMD_CFG_CQE_COALESCE_OFFLOAD = 43, /* Set cqe coalesce offload function (for computation, rsvd) */
- HINIC5_NIC_CMD_CFG_CQE_COALESCE_OFFLOAD_TIMER = 44, /* Set cqe coalesce offload function timer
- * (for computation, rsvd)
- */
- HINIC5_NIC_CMD_CFG_VF_TRUST = 46, /** < Set vf trust enable @see hinic5_set_vf_trust */
- HINIC5_NIC_CMD_RSS_CFG = 60, /* Set func rss enable, rq_pri_num, etc.
- * @see hinic5_cmd_rss_config
- */
- HINIC5_NIC_CMD_RSS_TEMP_MGR = 61, /* Allocate/free func rss template table
- * @see hinic5_rss_template_mgmt
- */
- HINIC5_NIC_CMD_GET_RSS_CTX_TBL = 62, /* Set func rss context
- * @see hinic5_rss_context_table
- */
- HINIC5_NIC_CMD_CFG_RSS_HASH_KEY = 63, /* Set func rss key
- * @see hinic5_cmd_rss_hash_key
- */
- HINIC5_NIC_CMD_CFG_RSS_HASH_ENGINE = 64, /* Set func rss engine
- * @see hinic5_cmd_rss_engine_type
- */
- HINIC5_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC = 65, /* Set func rss type and rss type en
- * @see hinic5_rss_context_table
- */
- HINIC5_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66, /* Set global table ipcs_err_rss_en
- * @see hinic5_ipcs_err_rss_enable_operation_s
- */
- HINIC5_NIC_CMD_GTP_INNER_PARSE_STATUS = 67, /* Control gtp inner parse status (for computation, rsvd) */
- HINIC5_NIC_CMD_ADD_TC_FLOW = 80, /** < Add TCAM rule @see nic_cmd_fdir_add_rule */
- HINIC5_NIC_CMD_DEL_TC_FLOW = 81, /** < Delete TCAM rule @see nic_cmd_fdir_del_rules */
- HINIC5_NIC_CMD_GET_TC_FLOW = 82, /** < Get TCAM rule @see nic_cmd_fdir_get_rule */
- HINIC5_NIC_CMD_FLUSH_TCAM = 83, /* Clear all TCAM rules and blocks for a func
- * @see nic_cmd_flush_tcam_rules
- */
- HINIC5_NIC_CMD_CFG_TCAM_BLOCK = 84, /* Allocate/free func block resource
- * @see nic_cmd_ctrl_tcam_block_in/
- * @see nic_cmd_ctrl_tcam_block_out
- */
- HINIC5_NIC_CMD_ENABLE_TCAM = 85, /* Set func fdir_tcam_enable
- * @see nic_cmd_set_tcam_enable
- */
- HINIC5_NIC_CMD_GET_TCAM_BLOCK = 86, /* Get which func is using a certain block
- * @see nic_cmd_dfx_fdir_tcam_block_table
- */
- HINIC5_NIC_CMD_CFG_PPA_TABLE_ID = 87, /** < @see hinic5_ppa_cfg_table_id_cmd */
- HINIC5_NIC_CMD_SET_PPA_EN = 88, /* Set func table ppa enable @see hinic5_ppa_cfg_ppa_en_cmd */
+ HINIC5_NIC_CMD_CFG_VF_VLAN =
+ 40, /** < 添加/删除func的vlan设备(QinQ) @see hinic5_cmd_vf_vlan_config */
+ HINIC5_NIC_CMD_SET_SPOOFCHK_STATE =
+ 41, /** < @see hinic5_cmd_spoofchk_set */
+ HINIC5_NIC_CMD_SET_MAX_MIN_RATE =
+ 42, /** < 设置func的限速 @see hinic5_cmd_rate_cfg */
+ HINIC5_NIC_CMD_CFG_CQE_COALESCE_OFFLOAD =
+ 43, /** < 设置cqe聚合卸载功能(计算使用,rsvd) */
+ HINIC5_NIC_CMD_CFG_CQE_COALESCE_OFFLOAD_TIMER =
+ 44, /** < 设置cqe聚合卸载功能计时(计算使用,rsvd) */
+ HINIC5_NIC_CMD_CFG_VF_TRUST =
+ 46, /** < 设置vf trust使能 @see hinic5_set_vf_trust */
+ HINIC5_NIC_CMD_RSS_CFG =
+ 60, /** < 设置func的rss使能、rq_pri_num等 @see hinic5_cmd_rss_config */
+ HINIC5_NIC_CMD_RSS_TEMP_MGR =
+ 61, /** < 分配/释放func的rss模版表 @see hinic5_rss_template_mgmt */
+ HINIC5_NIC_CMD_GET_RSS_CTX_TBL =
+ 62, /** < 设置func的rss context @see hinic5_rss_context_table */
+ HINIC5_NIC_CMD_CFG_RSS_HASH_KEY =
+ 63, /** < 设置func的rss key @see hinic5_cmd_rss_hash_key */
+ HINIC5_NIC_CMD_CFG_RSS_HASH_ENGINE =
+ 64, /** < 设置func的rss engine @see hinic5_cmd_rss_engine_type */
+ HINIC5_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC =
+ 65, /** < 设置func的rss type和rss type en @see hinic5_rss_context_table */
+ HINIC5_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP =
+ 66, /** < 设置global表的ipcs_err_rss_en @see hinic5_ipcs_err_rss_enable_operation_s */
+ HINIC5_NIC_CMD_GTP_INNER_PARSE_STATUS =
+ 67, /** < 控制gtp内层解析状态(计算使用,rsvd) */
+ HINIC5_NIC_CMD_ADD_TC_FLOW =
+ 80, /** < 添加TCAM规则 @see nic_cmd_fdir_add_rule */
+ HINIC5_NIC_CMD_DEL_TC_FLOW =
+ 81, /** < 删除TCAM规则 @see nic_cmd_fdir_del_rules */
+ HINIC5_NIC_CMD_GET_TC_FLOW =
+ 82, /** < 获取TCAM规则 @see nic_cmd_fdir_get_rule */
+ HINIC5_NIC_CMD_FLUSH_TCAM =
+ 83, /** < 清除某func所有TCAM规则和block @see nic_cmd_flush_tcam_rules */
+ HINIC5_NIC_CMD_CFG_TCAM_BLOCK =
+ 84, /** < 分配/释放func的block资源 @see nic_cmd_ctrl_tcam_block_in/nic_cmd_ctrl_tcam_block_out */
+ HINIC5_NIC_CMD_ENABLE_TCAM =
+ 85, /** < 设置func的fdir_tcam_enable @see nic_cmd_set_tcam_enable */
+ HINIC5_NIC_CMD_GET_TCAM_BLOCK =
+ 86, /** < 获取某个block被哪个func使用 @see nic_cmd_dfx_fdir_tcam_block_table */
+ HINIC5_NIC_CMD_CFG_PPA_TABLE_ID =
+ 87, /** < @see hinic5_ppa_cfg_table_id_cmd */
+ HINIC5_NIC_CMD_SET_PPA_EN =
+ 88, /** < 设置func表的ppa使能 @see hinic5_ppa_cfg_ppa_en_cmd */
HINIC5_NIC_CMD_CFG_PPA_MODE = 89, /** < @see hinic5_ppa_cfg_mode_cmd */
- HINIC5_NIC_CMD_CFG_PPA_FLUSH = 90, /* Set global table ppa_flow_flush_en
- * @see hinic5_ppa_flush_en_cmd
- */
- HINIC5_NIC_CMD_SET_FDIR_STATUS = 91, /* Set SML FDIR linear table @see nic_cmd_set_fdir_status */
- HINIC5_NIC_CMD_GET_PPA_COUNTER = 92, /** < @see hinic5_ppa_fdir_query_cmd */
- HINIC5_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE = 93, /* Set/query func table flow_bifur_en
- * (for computation, rsvd)
- */
- HINIC5_NIC_CMD_SET_BOND_MASK = 94, /** < Set bond mask (for computation, rsvd) */
- HINIC5_NIC_CMD_GET_BLOCK_TC_FLOWS = 95, /* Get all rules under a block?
- * @see nic_cmd_fdir_get_block_rules
- */
- HINIC5_NIC_CMD_GET_BOND_MASK = 96, /** < Read bond mask (for computation, rsvd) */
+ HINIC5_NIC_CMD_CFG_PPA_FLUSH =
+ 90, /** < 设置global表的ppa_flow_flush_en @see hinic5_ppa_flush_en_cmd */
+ HINIC5_NIC_CMD_SET_FDIR_STATUS =
+ 91, /** < 设置SML FDIR线性表 @see nic_cmd_set_fdir_status */
+ HINIC5_NIC_CMD_GET_PPA_COUNTER =
+ 92, /** < @see hinic5_ppa_fdir_query_cmd */
+ HINIC5_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE =
+ 93, /** < 设置/查询func表的flow_bifur_en(计算使用,rsvd) */
+ HINIC5_NIC_CMD_SET_BOND_MASK =
+ 94, /** < 设置bond掩码(计算使用,rsvd) */
+ HINIC5_NIC_CMD_GET_BLOCK_TC_FLOWS =
+ 95, /** < 获取某个block下的所有规则? @see nic_cmd_fdir_get_block_rules */
+ HINIC5_NIC_CMD_GET_BOND_MASK =
+ 96, /** < 读取bond掩码(计算使用,rsvd) */
HINIC5_NIC_CMD_SET_PORT_ENABLE = 100, /** < @see hinic5_port_state */
- HINIC5_NIC_CMD_CFG_PAUSE_INFO = 101, /* Set/query port pause status
- * @see hinic5_cmd_pause_config
- */
- HINIC5_NIC_CMD_CFG_PORT_CAR = 102, /* Set/query/enable arp/icmp car rate limit
- * @see 182x:hinic5_cmd_set_port_car\
- * @see 1872:hinic5_cmd_set_car/hinic5_car_profile
- */
+ HINIC5_NIC_CMD_CFG_PAUSE_INFO =
+ 101, /** < 设置/查询port的pause状态 @see hinic5_cmd_pause_config */
+ HINIC5_NIC_CMD_CFG_PORT_CAR =
+ 102, /** < 设置/查询/使能 arp/icmp的car限速 @see 182x:hinic5_cmd_set_port_car\1872:hinic5_cmd_set_car/hinic5_car_profile */
HINIC5_NIC_CMD_SET_ER_DROP_PKT = 103, /** < rsvd */
HINIC5_NIC_CMD_VF_COS = 104, /** < @see hinic5_cmd_vf_dcb_state */
HINIC5_NIC_CMD_SETUP_COS_MAPPING = 105, /** < rsvd */
HINIC5_NIC_CMD_SET_ETS = 106, /** < rsvd */
HINIC5_NIC_CMD_SET_PFC = 107, /** < rsvd */
- HINIC5_NIC_CMD_QOS_ETS = 108, /* QoS ETS scheduling weight configuration/query @see hinic5_cmd_ets_cfg */
- HINIC5_NIC_CMD_QOS_PFC = 109, /** < QoS PFC configuration/query @see hinic5_cmd_set_pfc */
- HINIC5_NIC_CMD_QOS_DCB_STATE = 110, /* QoS configure func and its Port DCB state
- * @see hinic5_cmd_set_dcb_state
- */
- HINIC5_NIC_CMD_QOS_PORT_CFG = 111, /* QoS Port trust information configuration/query
- * @see hinic5_cmd_qos_port_cfg
- */
- HINIC5_NIC_CMD_QOS_MAP_CFG = 112, /* QoS PCP/DSCP mapping configuration/query
- * @see hinic5_cmd_qos_map_cfg
- */
- HINIC5_NIC_CMD_FORCE_PKT_DROP = 113, /* QoS Port PFC/Pause forced packet drop
- * @see hinic5_force_pkt_drop
- */
- HINIC5_NIC_CMD_CFG_TX_PROMISC_SKIP = 114, /* Set promisc PF whether to receive TX unknown unicast packets
- * @see hinic5_tx_promisc_cfg
- */
- HINIC5_NIC_CMD_GET_CIR_DROP = 115, /** < Read cir (for computation, rsvd) */
- HINIC5_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117, /* Set/query port table flow_bifur_en
- * (for computation, rsvd)
- */
- HINIC5_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118, /** < @see nic_cmd_tx_pause_notice */
- HINIC5_NIC_CMD_INQUIRT_PAUSE_CFG = 119, /* QoS PFC storm detection parameter configuration
- * @see nic_cmd_pause_inquiry_cfg
- */
- HINIC5_NIC_CMD_BIOS_CFG = 120, /** < Persist BIOS configuration/query @see nic_cmd_bios_cfg */
- HINIC5_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG = 121, /* Receive fast fault notification content
- * @see fault_msg_s
- */
- HINIC5_NIC_CMD_QOS_EXTEND_CFG = 122, /** < QoS extended configuration, supports TC rate limit configuration/query */
- HINIC5_NIC_CMD_BOND_LINK_INFO_GET = 130, /** < @see hinic5_bond_link_info */
- HINIC5_NIC_CMD_MACSEC_PN_EXPIRED_NOTICE = 131, /* @see tag_macsec_pn_expired_report_cmd_s */
+ HINIC5_NIC_CMD_QOS_ETS =
+ 108, /** < QoS ETS调度权重配置/查询 @see hinic5_cmd_ets_cfg */
+ HINIC5_NIC_CMD_QOS_PFC =
+ 109, /** < QoS PFC配置/查询 @see hinic5_cmd_set_pfc */
+ HINIC5_NIC_CMD_QOS_DCB_STATE =
+ 110, /** < QoS 配置func及其所属Port的DCB状态 @see hinic5_cmd_set_dcb_state */
+ HINIC5_NIC_CMD_QOS_PORT_CFG =
+ 111, /** < QoS Port的trust信息配置/查询 @see hinic5_cmd_qos_port_cfg */
+ HINIC5_NIC_CMD_QOS_MAP_CFG =
+ 112, /** < QoS PCP/DSCP映射配置/查询 @see hinic5_cmd_qos_map_cfg */
+ HINIC5_NIC_CMD_FORCE_PKT_DROP =
+ 113, /** < QoS Port的PFC/Pause强制丢包 @see hinic5_force_pkt_drop */
+ HINIC5_NIC_CMD_CFG_TX_PROMISC_SKIP =
+ 114, /** < 设置混杂PF是否接收TX未知单播报文 @see hinic5_tx_promisc_cfg */
+ HINIC5_NIC_CMD_GET_CIR_DROP = 115, /** < 读取cir(计算使用,rsvd) */
+ HINIC5_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE =
+ 117, /** < 设置/查询port表的flow_bifur_en(计算使用,rsvd) */
+ HINIC5_NIC_CMD_TX_PAUSE_EXCP_NOTICE =
+ 118, /** < @see nic_cmd_tx_pause_notice */
+ HINIC5_NIC_CMD_INQUIRT_PAUSE_CFG =
+ 119, /** < QoS PFC风暴检测参数配置 @see nic_cmd_pause_inquiry_cfg */
+ HINIC5_NIC_CMD_BIOS_CFG =
+ 120, /** < 固化BIOS配置/查询 @see nic_cmd_bios_cfg */
+ HINIC5_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG =
+ 121, /** < 接收快速故障通知内容 @see fault_msg_s */
+ HINIC5_NIC_CMD_QOS_EXTEND_CFG =
+ 122, /** < Qos 扩展配置,支持TC限速配置/查询 */
+ HINIC5_NIC_CMD_BOND_LINK_INFO_GET =
+ 130, /** < @see hinic5_bond_link_info */
+ HINIC5_NIC_CMD_MACSEC_PN_EXPIRED_NOTICE =
+ 131, /** < @see tag_macsec_pn_expired_report_cmd_s */
HINIC5_NIC_CMD_PASS_ARP_PKT = 132, /** < @see hinic5_arp_pkt_info */
HINIC5_NIC_CMD_BOND_DEV_CFG = 133, /** < @see hinic5_cmd_cfg_bond */
- HINIC5_NIC_CMD_BOND_DEV_CREATE = 134, /** < @see hinic5_cmd_create_bond */
- HINIC5_NIC_CMD_BOND_DEV_DELETE = 135, /** < @see hinic5_cmd_delete_bond */
- HINIC5_NIC_CMD_BOND_DEV_OPEN_CLOSE = 136, /** < @see hinic5_cmd_open_close_bond */
- HINIC5_NIC_CMD_BOND_INFO_GET = 137, /** < @see hinic5_bond_status_info */
- HINIC5_NIC_CMD_BOND_ACTIVE_INFO_GET = 138, /** < @see hinic5_bond_active_report_info */
- HINIC5_NIC_CMD_BOND_ACTIVE_NOTICE = 139, /** < @see nic_cmd_bond_active_report_info */
- HINIC5_NIC_CMD_GET_SM_TABLE = 140, /* Get MAC table and other information @see nic_cmd_dfx_sm_table */
- HINIC5_NIC_CMD_RD_LINE_TBL = 141, /* Get SM linear table information @see nic_mpu_lt_opera */
- HINIC5_NIC_CMD_SET_VEB = 143, /** < Query or configure veb offload mode @see hinic5_veb_set */
- HINIC5_NIC_CMD_NIC_VPORT_CNT = 144, /* Query or configure VF vport count
- * @see hinic5_nic_vport_cnt_info
- */
- HINIC5_NIC_CMD_SET_UCAPTURE_OPT = 160, /* RoCE packet capture function switch @see nic_cmd_capture_info */
- HINIC5_NIC_CMD_SET_VHD_CFG = 161, /* Set func table vhd_type related parameters @see nic_cmd_vhd_config */
- HINIC5_NIC_CMD_GET_UCAPTURE_INFO = 162, /* Get PF packet capture function enable status, iterate through PFs,
- * return bitmap of enabled packet capture functions (for computation, rsvd)
- */
- HINIC5_NIC_CMD_GET_OUTBAND_CFG = 170, /** < Get outband settings (for computation, rsvd) */
- HINIC5_NIC_CMD_OUTBAND_CFG_NOTICE = 171, /* Outband information get (for computation, rsvd) */
+ HINIC5_NIC_CMD_BOND_DEV_CREATE =
+ 134, /** < @see hinic5_cmd_create_bond */
+ HINIC5_NIC_CMD_BOND_DEV_DELETE =
+ 135, /** < @see hinic5_cmd_delete_bond */
+ HINIC5_NIC_CMD_BOND_DEV_OPEN_CLOSE =
+ 136, /** < @see hinic5_cmd_open_close_bond */
+ HINIC5_NIC_CMD_BOND_INFO_GET =
+ 137, /** < @see hinic5_bond_status_info */
+ HINIC5_NIC_CMD_BOND_ACTIVE_INFO_GET =
+ 138, /** < @see hinic5_bond_active_report_info */
+ HINIC5_NIC_CMD_BOND_ACTIVE_NOTICE =
+ 139, /** < @see nic_cmd_bond_active_report_info */
+ HINIC5_NIC_CMD_GET_SM_TABLE =
+ 140, /** < 获取mac表等一些信息 @see nic_cmd_dfx_sm_table */
+ HINIC5_NIC_CMD_RD_LINE_TBL =
+ 141, /** < 获取SM线性表的一些信息 @see nic_mpu_lt_opera */
+ HINIC5_NIC_CMD_SET_VEB =
+ 143, /** < 查询或配置veb卸载模式 @see hinic5_veb_set */
+ HINIC5_NIC_CMD_NIC_VPORT_CNT =
+ 144, /** < 查询或配置VF的vport计数 @see hinic5_nic_vport_cnt_info */
+ HINIC5_NIC_CMD_SET_UCAPTURE_OPT =
+ 160, /** < ROCE抓包功能开关 @see nic_cmd_capture_info */
+ HINIC5_NIC_CMD_SET_VHD_CFG =
+ 161, /** < 设置func表的vhd_type相关参数 @see nic_cmd_vhd_config */
+ HINIC5_NIC_CMD_GET_UCAPTURE_INFO =
+ 162, /** < 获取PF抓取报文功使能情况,遍历PF,返回使能抓包功能的位图(计算使用,rsvd) */
+ HINIC5_NIC_CMD_GET_OUTBAND_CFG =
+ 170, /** < 获取带外设置(计算使用,rsvd) */
+ HINIC5_NIC_CMD_OUTBAND_CFG_NOTICE =
+ 171, /** < 带外信息获取(计算使用,rsvd) */
HINIC5_NIC_CMD_FLUSH_TC_FLOW = 176, /** < @see hinic5_tc_flush_info */
- HINIC5_NIC_CMD_CFG_VXLAN_TBL = 177, /** < @see hinic5_tc_vxlan_tbl_cfg_info */
+ HINIC5_NIC_CMD_CFG_VXLAN_TBL =
+ 177, /** < @see hinic5_tc_vxlan_tbl_cfg_info */
HINIC5_NIC_CMD_MOVE_TC_TBL = 178, /** < @see hinic5_tc_move_info */
- HINIC5_NIC_CMD_CFG_TC_AGING_TBL = 179, /** < @see hinic5_tc_aging_info */
+ HINIC5_NIC_CMD_CFG_TC_AGING_TBL =
+ 179, /** < @see hinic5_tc_aging_info */
HINIC5_NIC_CMD_PFE_CNT = 180, /** < @see hinic5_tc_pfe_cnt_info */
- HINIC5_NIC_CMD_GET_PFE_CFG = 181, /** < @see hinic5_tc_pfe_cfg_reg_info */
+ HINIC5_NIC_CMD_GET_PFE_CFG =
+ 181, /** < @see hinic5_tc_pfe_cfg_reg_info */
HINIC5_NIC_CMD_CFG_PFE_TCAM = 182, /** < @see hinic5_tc_tcam_info */
- HINIC5_NIC_CMD_CFG_PFE_VTEP_IP = 183, /** < @see hinic5_tc_pfe_vtep_ip_cmd */
- HINIC5_NIC_CMD_SET_PFE_DEFAULT_ACTION = 184, /** < @see hinic5_tc_default_action_info */
- HINIC5_NIC_CMD_PFE_TCAM_FREQ = 185, /** < @see hinic5_tc_pfe_tcam_freq_info */
- HINIC5_NIC_CMD_CFG_TCAM_CLOCK_GATING = 186, /* @see hinic5_tc_tcam_clock_gating_cfg_info */
+ HINIC5_NIC_CMD_CFG_PFE_VTEP_IP =
+ 183, /** < @see hinic5_tc_pfe_vtep_ip_cmd */
+ HINIC5_NIC_CMD_SET_PFE_DEFAULT_ACTION =
+ 184, /** < @see hinic5_tc_default_action_info */
+ HINIC5_NIC_CMD_PFE_TCAM_FREQ =
+ 185, /** < @see hinic5_tc_pfe_tcam_freq_info */
+ HINIC5_NIC_CMD_CFG_TCAM_CLOCK_GATING =
+ 186, /** < @see hinic5_tc_tcam_clock_gating_cfg_info */
HINIC5_NIC_CMD_CFG_TC_FLOW_RULE = 187, /** < @see hinic5_tc_cfg_info */
- HINIC5_NIC_CMD_SET_PFE_CFG_PROFILE = 188, /** < @see hinic5_tc_pfe_cfg_profile_info */
+ HINIC5_NIC_CMD_SET_PFE_CFG_PROFILE =
+ 188, /** < @see hinic5_tc_pfe_cfg_profile_info */
HINIC5_NIC_CMD_GET_PORT_STAT = 200, /** < rsvd */
HINIC5_NIC_CMD_CLEAN_PORT_STAT = 201, /** < rsvd */
HINIC5_NIC_CMD_CFG_LOOPBACK_MODE = 202, /** < rsvd */
@@ -233,25 +241,38 @@ enum hinic5_nic_cmd {
HINIC5_NIC_CMD_CABLE_PLUG_EVENT = 215, /** < rsvd */
HINIC5_NIC_CMD_LINK_ERR_EVENT = 216, /** < rsvd */
HINIC5_NIC_CMD_SET_LED_STATUS = 217, /** < rsvd */
- HINIC5_NIC_CMD_MIG_SET_CEQ_CTRL = 230, /** < @see mig_nic_set_ceq_ctrl */
- HINIC5_NIC_CMD_MIG_CFG_MSIX_INFO = 231, /** < @see mig_nic_msix_info_rw */
- HINIC5_NIC_CMD_MIG_CFG_FUNC_VAT_TBL = 232, /** < @see mig_nic_func_vat_tbl */
+ HINIC5_NIC_CMD_MIG_SET_CEQ_CTRL =
+ 230, /** < @see mig_nic_set_ceq_ctrl */
+ HINIC5_NIC_CMD_MIG_CFG_MSIX_INFO =
+ 231, /** < @see mig_nic_msix_info_rw */
+ HINIC5_NIC_CMD_MIG_CFG_FUNC_VAT_TBL =
+ 232, /** < @see mig_nic_func_vat_tbl */
HINIC5_NIC_CMD_MIG_GET_VF_INFO = 233, /** < @see mig_nic_func_cfg */
- HINIC5_NIC_CMD_MIG_CHK_MBX_EMPTY = 234, /** < @see mig_nic_chk_mbx_empty */
- HINIC5_NIC_CMD_MIG_SET_VPORT_ENABLE = 235, /** < @see mig_nic_vport_state */
+ HINIC5_NIC_CMD_MIG_CHK_MBX_EMPTY =
+ 234, /** < @see mig_nic_chk_mbx_empty */
+ HINIC5_NIC_CMD_MIG_SET_VPORT_ENABLE =
+ 235, /** < @see mig_nic_vport_state */
HINIC5_NIC_CMD_MIG_CFG_SQ_CI = 236, /** < @see mig_nic_sq_ci */
HINIC5_NIC_CMD_MIG_CFG_RSS_TBL = 237, /** < @see mig_nic_cfg_rss_tbl */
- HINIC5_NIC_CMD_MIG_TMP_SET_CMDQ_CTX = 238, /** < @see mig_nic_tmp_cfg_cmdq_ctx */
+ HINIC5_NIC_CMD_MIG_TMP_SET_CMDQ_CTX =
+ 238, /** < @see mig_nic_tmp_cfg_cmdq_ctx */
HINIC5_NIC_CMD_MIG_STOP_SQ = 239, /** < @see nic_mig_sq_stop */
- HINIC5_NIC_CMD_MIG_CFG_FAST_MSG_ADDR = 240, /** < @see mig_nic_fast_msg_addr */
- HINIC5_NIC_CMD_MIG_SET_FUNC_FLR_MGMT = 241, /** < @see hinic5_cmd_set_pcie_flr_mgmt */
+ HINIC5_NIC_CMD_MIG_CFG_FAST_MSG_ADDR =
+ 240, /** < @see mig_nic_fast_msg_addr */
+ HINIC5_NIC_CMD_MIG_SET_FUNC_FLR_MGMT =
+ 241, /** < @see hinic5_cmd_set_pcie_flr_mgmt */
HINIC5_NIC_CMD_LRO_CFG = 242, /** < @see hinic5_cmd_lro_cfg */
- HINIC5_NIC_CMD_CFG_VF_LAG = 243, /** < Set vf_lag (for computation, rsvd) */
- HINIC5_NIC_CMD_VF_LAG_SYNC_BOND_STATE = 244, /* vf_lag sync bond state (for computation, rsvd) */
- HINIC5_NIC_CMD_EXTEND_SECTION1_START = 257, /* NIC Mbox reserved command code start, for computing product line use */
- HINIC5_NIC_CMD_EXTEND_SECTION1_END = 384, /* NIC Mbox reserved command code end, for computing product line use */
- HINIC5_NIC_CMD_EXTEND_SECTION2_START = 385, /* NIC Mbox reserved command code start, for storage product line use */
- HINIC5_NIC_CMD_EXTEND_SECTION2_END = 512 /* NIC Mbox reserved command code end, for storage product line use */
+ HINIC5_NIC_CMD_CFG_VF_LAG = 243, /** < 设置vf_lag(计算使用,rsvd) */
+ HINIC5_NIC_CMD_VF_LAG_SYNC_BOND_STATE =
+ 244, /** < vf_lag同步bond状态(计算使用,rsvd) */
+ HINIC5_NIC_CMD_EXTEND_SECTION1_START =
+ 257, /** < NIC Mbox保留命令字起始,计算产品线使用 */
+ HINIC5_NIC_CMD_EXTEND_SECTION1_END =
+ 384, /** < NIC Mbox保留命令字结束,计算产品线使用 */
+ HINIC5_NIC_CMD_EXTEND_SECTION2_START =
+ 385, /** < NIC Mbox保留命令字起始,数存产品线使用 */
+ HINIC5_NIC_CMD_EXTEND_SECTION2_END =
+ 512 /** < NIC Mbox保留命令字结束,数存产品线使用 */
};
#endif /* HINIC5_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_extend.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_extend.h
index 14bfd3b87..b357bed9c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_extend.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_extend.h
@@ -1,18 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_mpu_cmd_extend.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : This file is used to consolidate command codes from other product lines merged into Yinglong
+/**
+ * 该文件用于收编其他产品线回合到应龙仓的命令字
*/
#ifndef HINIC5_NIC_CMD_EXTEND_H
#define HINIC5_NIC_CMD_EXTEND_H
#ifndef HINIC5_NIC_CMD_CLEAR_ASSIGN_QP_RES
-#define HINIC5_NIC_CMD_CLEAR_ASSIGN_QP_RES 261 /** < clear resources of assigned qp > hinic5_cmd_clear_assign_qp_res */
+#define HINIC5_NIC_CMD_CLEAR_ASSIGN_QP_RES \
+ 261 /** < clear resources of assigned qp > hinic5_cmd_clear_assign_qp_res */
#endif
#endif /* HINIC5_NIC_CMD_EXTEND_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs.h
index 7a8476597..b85d13c8c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_mpu_cmd_structs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : mailbox command structure definition file, header file is automatically generated by scripts in MAILBOX baseline table. If adding or deleting, please modify the baseline table first, then automatically generate this header file
+ * mailbox命令字结构体定义文件
+ * 头文件通过MAILBOX基线表格中的脚本自动生成。如有增删,请先修改基线表格,然后自动生成该头文件
+ * 修改流程见:https://wiki.huawei.com/domains/1574/wiki/8/WIKI202509298479069
*/
#ifndef HINIC5_NIC_CMD_STRUCTS_H
@@ -18,13 +14,13 @@
#include "mpu_cmd_base_defs.h"
/**
- * @brief Management message head structure
- * @details This structure is used to store management message header information, including status, version and reserved fields.
+ * @brief 管理消息头部结构体
+ * @details 该结构体用于存储管理消息的头部信息,包括状态、版本和保留字段。
*/
struct hinic5_mgmt_msg_head {
- u8 status; /**< Status field */
- u8 version; /**< Version field */
- u8 rsvd0[6]; /**< Reserved field */
+ u8 status; /**< 状态字段 */
+ u8 version; /**< 版本字段 */
+ u8 rsvd0[6]; /**< 保留域段 */
};
/**
@@ -32,289 +28,289 @@ struct hinic5_mgmt_msg_head {
* @details nic vf register
*/
struct hinic5_cmd_register_vf {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 op_register; /**< 0 - unregister, 1 - register */
- u8 rsvd1[3]; /**< Reserved field */
- u32 support_extra_feature; /**< support extra feature */
- u8 rsvd2[32]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 op_register; /**< 0 - unregister, 1 - register */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 support_extra_feature; /**< support extra feature */
+ u8 rsvd2[32]; /**< 保留域段 */
};
/**
- * @brief Store function table configuration information
- * @details This structure contains WQE buffer size for receive queue, Maximum Transmission Unit (MTU) and reserved fields.
+ * @brief 存储函数表的配置信息
+ * @details 该结构体包含了接收队列的WQE缓冲区大小、最大传输单元(MTU)以及保留字段。
*/
struct hinic5_func_tbl_cfg {
- u16 rx_wqe_buf_size; /**< Receive queue WQE buffer size */
- u16 mtu; /**< Maximum Transmission Unit (MTU) */
- u8 rx_compact_wqe_en; /**< rx 8Byte wqe (combined cqe) enable */
- u8 rsvd0[3]; /**< Reserved field */
+ u16 rx_wqe_buf_size; /**< 接收队列的WQE缓冲区大小 */
+ u16 mtu; /**< 最大传输单元(MTU) */
+ u8 rx_compact_wqe_en; /**< rx 8Byte wqe(合一cqe)使能 */
+ u8 rsvd0[3]; /**< 保留域段 */
u8 mac[6];
u16 vlan_id;
- u32 rsvd1[6]; /**< Reserved field */
+ u32 rsvd1[6]; /**< 保留域段 */
};
/**
- * @brief Structure for setting function table
- * @details This structure is used for setting function table, including management message head, function ID, reserved field, configuration bitmap and function table configuration.
+ * @brief 用于设置函数表的结构体
+ * @details 该结构体用于设置函数表,包含了管理消息头部、函数ID、保留字段、配置位图和函数表配置等信息。
*/
struct hinic5_cmd_set_func_tbl {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd; /**< Reserved field */
- u32 cfg_bitmap; /**< Configuration bitmap, defined by hinic5_func_tbl_cfg_bitmap */
- struct hinic5_func_tbl_cfg tbl_cfg; /**< Configuration table */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd; /**< 保留域段 */
+ u32 cfg_bitmap; /**< 设置位图,由hinic5_func_tbl_cfg_bitmap定义 */
+ struct hinic5_func_tbl_cfg tbl_cfg; /**< 配置表 */
};
/**
- * @brief Configurable func-level attributes
+ * @brief 可配置的func级的属性
* @details nic vport state info
*/
struct hinic5_vport_state {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd1; /**< Reserved field */
- u8 state; /**< 0--disable, 1--enable */
- u8 num_qps; /**< queue pairs number */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd1; /**< 保留域段 */
+ u8 state; /**< 0--disable, 1--enable */
+ u8 num_qps; /**< queue pairs number */
u8 rx_compact_wqe_en;
- u8 rsvd2; /**< Reserved field */
+ u8 rsvd2; /**< 保留域段 */
};
/**
- * @brief Configurable func-level attributes
- * @details nic rx_mode command structure
+ * @brief 可配置的func级的属性
+ * @details nic 配置rx_mode命令结构体
*/
struct hinic5_rx_mode_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd1; /**< Reserved field */
- u32 rx_mode; /**< rx mode */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd1; /**< 保留域段 */
+ u32 rx_mode; /**< rx mode */
};
/**
- * @brief Configurable func-level attributes
- * @details nic set cons idx attr
+ * @brief 可配置的func级的属性
+ * @details nic 设置 cons idx attr
*/
struct hinic5_cmd_cons_idx_attr {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_idx; /**< Func ID */
- u8 dma_attr_off; /**< dma attribute offset */
- u8 pending_limit; /**< pending limit */
- u8 coalescing_time; /**< coalescing time */
- u8 intr_en; /**< interrupt enable */
- u16 intr_idx; /**< interrupt index */
- u32 l2nic_sqn; /**< l2nic sequence number */
- u32 rsvd1; /**< Reserved field */
- u64 ci_addr; /**< ci address */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_idx; /**< Func ID */
+ u8 dma_attr_off; /**< dma attribute offset */
+ u8 pending_limit; /**< pending limit */
+ u8 coalescing_time; /**< coalescing time */
+ u8 intr_en; /**< interrupt enable */
+ u16 intr_idx; /**< interrupt index */
+ u32 l2nic_sqn; /**< l2nic sequence number */
+ u32 rsvd1; /**< 保留域段 */
+ u64 ci_addr; /**< ci address */
};
/**
- * @brief Structure for storing port statistics
- * @details This structure contains management message head and two fields for storing port statistics.
+ * @brief 定义了一个用于存储端口统计信息的结构体
+ * @details 该结构体包含了管理消息头部和两个字段,用于存储端口统计信息。
*/
struct hinic5_port_stats_info {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd1; /**< 保留域段 */
};
/**
- * @brief Structure for storing vport statistics
- * @details Vport transmit and receive statistics, including unicast, multicast, broadcast packet count and byte count, plus sent and received discarded and error packet count.
+ * @brief 定义了一个结构体,用于存储vport的统计信息
+ * @details vport的发送和接收统计信息,包括单播、多播、广播包的数量和字节数,以及发送和接收被丢弃和出现错误的包数。
*/
struct hinic5_vport_stats {
- u64 tx_unicast_pkts_vport; /**< Transmitted unicast packets */
- u64 tx_unicast_bytes_vport; /**< Transmitted unicast bytes */
- u64 tx_multicast_pkts_vport; /**< Transmitted multicast packets */
- u64 tx_multicast_bytes_vport; /**< Transmitted multicast bytes */
- u64 tx_broadcast_pkts_vport; /**< Transmitted broadcast packets */
- u64 tx_broadcast_bytes_vport; /**< Transmitted broadcast bytes */
- u64 rx_unicast_pkts_vport; /**< Received unicast packets */
- u64 rx_unicast_bytes_vport; /**< Received unicast bytes */
- u64 rx_multicast_pkts_vport; /**< Received multicast packets */
- u64 rx_multicast_bytes_vport; /**< Received multicast bytes */
- u64 rx_broadcast_pkts_vport; /**< Received broadcast packets */
- u64 rx_broadcast_bytes_vport; /**< Received broadcast bytes */
- u64 tx_discard_vport; /**< Transmitted discarded packets */
- u64 rx_discard_vport; /**< Received discarded packets */
- u64 tx_err_vport; /**< Transmitted error packets */
- u64 rx_err_vport; /**< Received error packets */
-};
-
-/**
- * @brief Structure for storing vport statistics information
- * @details This structure contains vport statistics data, including management message head, statistics size, reserved fields, vport statistics and additional reserved fields.
+ u64 tx_unicast_pkts_vport; /**< 发送的单播包数 */
+ u64 tx_unicast_bytes_vport; /**< 发送的单播字节数 */
+ u64 tx_multicast_pkts_vport; /**< 发送的多播包数 */
+ u64 tx_multicast_bytes_vport; /**< 发送的多播字节数 */
+ u64 tx_broadcast_pkts_vport; /**< 发送的广播包数 */
+ u64 tx_broadcast_bytes_vport; /**< 发送的广播字节数 */
+ u64 rx_unicast_pkts_vport; /**< 接收的单播包数 */
+ u64 rx_unicast_bytes_vport; /**< 接收的单播字节数 */
+ u64 rx_multicast_pkts_vport; /**< 接收的多播包数 */
+ u64 rx_multicast_bytes_vport; /**< 接收的多播字节数 */
+ u64 rx_broadcast_pkts_vport; /**< 接收的广播包数 */
+ u64 rx_broadcast_bytes_vport; /**< 接收的广播字节数 */
+ u64 tx_discard_vport; /**< 发送被丢弃的包数 */
+ u64 rx_discard_vport; /**< 接收被丢弃的包数 */
+ u64 tx_err_vport; /**< 发送出现错误的包数 */
+ u64 rx_err_vport; /**< 接收出现错误的包数 */
+};
+
+/**
+ * @brief 定义了一个用于存储vport统计信息的结构体
+ * @details 该结构体包含了vport统计信息的相关数据,包括管理消息头部、统计信息的大小、保留字段、vport统计信息以及额外的保留字段。
*/
struct hinic5_cmd_vport_stats {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u32 stats_size; /**< Statistics size */
- u32 rsvd1; /**< Reserved field */
- struct hinic5_vport_stats stats; /**< vport statistics */
- u64 rsvd2[6]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u32 stats_size; /**< 统计信息的大小 */
+ u32 rsvd1; /**< 保留域段 */
+ struct hinic5_vport_stats stats; /**< vport统计信息 */
+ u64 rsvd2[6]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_clear_qp_resource
- * @details nic clear qp resource command structure
+ * @details nic 清除qp资源命令结构体
*/
struct hinic5_cmd_clear_qp_resource {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd1; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_lro_config
- * @details nic configure lro structure
+ * @details nic 配置lro结构体
*/
struct hinic5_cmd_lro_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 opcode; /**< operation code */
- u8 rsvd1; /**< Reserved field */
- u8 lro_ipv4_en; /**< LRO for IPv4 */
- u8 lro_ipv6_en; /**< LRO for IPv6 */
- u8 lro_max_pkt_len; /**< unit is 1K */
- u8 resv2[13]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 opcode; /**< operation code */
+ u8 rsvd1; /**< 保留域段 */
+ u8 lro_ipv4_en; /**< LRO for IPv4 */
+ u8 lro_ipv6_en; /**< LRO for IPv6 */
+ u8 lro_max_pkt_len; /**< unit is 1K */
+ u8 resv2[13]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_lro_timer
- * @details nic configure lro timer
+ * @details nic 配置lro timer
*/
struct hinic5_cmd_lro_timer {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 opcode; /**< 1: set timer value, 0: get timer value */
- u8 rsvd1; /**< Reserved field */
- u16 rsvd2; /**< Reserved field */
- u32 timer; /**< timer value */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 opcode; /**< 1: set timer value, 0: get timer value */
+ u8 rsvd1; /**< 保留域段 */
+ u16 rsvd2; /**< 保留域段 */
+ u32 timer; /**< timer value */
};
#define NIC_MAX_FEATURE_QWORD 4
/**
* @brief hinic5_cmd_feature_nego
- * @details nic auto-negotiation feature command structure
+ * @details nic自协商特性命令结构体
*/
struct hinic5_cmd_feature_nego {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 opcode; /**< opeartion code 1: set, 0: get */
- u8 rsvd; /**< Reserved field */
- u64 s_feature[NIC_MAX_FEATURE_QWORD]; /**< feature */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 opcode; /**< opeartion code 1: set, 0: get */
+ u8 rsvd; /**< 保留域段 */
+ u64 s_feature[NIC_MAX_FEATURE_QWORD]; /**< feature */
};
/**
* @brief hinic5_cmd_local_lro_state
- * @details nic set lro state
+ * @details nic 设置lro state
*/
struct hinic5_cmd_local_lro_state {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< 1: set timer value, 0: get timer value */
- u8 opcode; /**< 0: get state, 1: set state */
- u8 state; /**< 0: disable, 1: enable */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 1: set timer value, 0: get timer value */
+ u8 opcode; /**< 0: get state, 1: set state */
+ u8 state; /**< 0: disable, 1: enable */
};
/**
* @brief hinic5_cmd_cache_out_qp_resource
- * @details nic set cache_out_qp_resource
+ * @details nic 设置 cache_out_qp_resource
*/
struct hinic5_cmd_cache_out_qp_resource {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 rsvd1; /**< 保留域段 */
};
/**
- * @brief Receive queue completion queue context structure
- * @details This structure is used to describe the context information of receive queue completion queue
+ * @brief 定义了一个接收队列完成队列上下文结构体
+ * @details 该结构体用于描述接收队列完成队列的上下文信息
*/
struct hinic5_rq_cqe_ctx {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 cqe_type; /**< Completion queue type */
- u8 rq_id; /**< Receive queue ID */
- u8 threshold_cqe_num; /**< Completion queue threshold */
- u8 rsvd1; /**< Reserved field */
- u16 msix_entry_idx; /**< MSI-X entry index */
- u16 rsvd2; /**< Reserved field */
- u32 ci_addr_hi; /**< Completion queue address high */
- u32 ci_addr_lo; /**< Completion queue address low */
- u16 timer_loop; /**< Timer loop count */
- u16 rsvd3; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 cqe_type; /**< 完成队列类型 */
+ u8 rq_id; /**< 接收队列ID */
+ u8 threshold_cqe_num; /**< 完成队列阈值 */
+ u8 rsvd1; /**< 保留域段 */
+ u16 msix_entry_idx; /**< MSI-X入口索引 */
+ u16 rsvd2; /**< 保留域段 */
+ u32 ci_addr_hi; /**< 完成队列地址的高位 */
+ u32 ci_addr_lo; /**< 完成队列地址的低位 */
+ u16 timer_loop; /**< 定时器循环次数 */
+ u16 rsvd3; /**< 保留域段 */
};
struct hinic5_rq_enable {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
u32 rq_id;
u8 rq_enable;
- u8 rsvd1[3]; /**< Reserved field */
+ u8 rsvd1[3]; /**< 保留域段 */
};
-#define ETH_ALEN 6 /**< Ethernet address length */
+#define ETH_ALEN 6 /**< Ethernet address length */
/**
* @brief hinic5_port_mac_set
- * @details nic port mac set command structure
+ * @details nic port mac设置命令结构体
*/
struct hinic5_port_mac_set {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 vlan_id; /**< vlan id */
- u8 vf_lag_en; /**< vf_lag enable flag (for computation, reserved) */
- u8 rsvd1; /**< Reserved field */
- u8 mac[ETH_ALEN]; /**< mac address */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 vlan_id; /**< vlan id */
+ u8 vf_lag_en; /**< vf_lag使能标志位(计算使用,保留) */
+ u8 rsvd1; /**< 保留域段 */
+ u8 mac[ETH_ALEN]; /**< mac address */
};
/**
* @brief hinic5_port_mac_update
- * @details nic port mac update command structure
+ * @details nic port mac修改命令结构体
*/
struct hinic5_port_mac_update {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 vlan_id; /**< vlan id */
- u16 rsvd1; /**< Reserved field */
- u8 old_mac[ETH_ALEN]; /**< mac address */
- u16 rsvd2; /**< Reserved field */
- u8 new_mac[ETH_ALEN]; /**< mac address */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 vlan_id; /**< vlan id */
+ u16 rsvd1; /**< 保留域段 */
+ u8 old_mac[ETH_ALEN]; /**< mac address */
+ u16 rsvd2; /**< 保留域段 */
+ u8 new_mac[ETH_ALEN]; /**< mac address */
};
#define CHIP_ATTR_MAC_MAX_SIZE 192
/**
* @brief nic_cmd_mac_info
- * @details MAC module interface
+ * @details MAC模块接口
*/
struct nic_cmd_mac_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 valid_bitmap; /**< valid bitmap, unused */
- u16 rsvd1; /**< Reserved field */
- u8 host_id[32]; /**< host id, unused */
- u8 port_id[32]; /**< port id, unused */
- u8 mac_addr[CHIP_ATTR_MAC_MAX_SIZE]; /**< mac addr */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 valid_bitmap; /**< valid bitmap, 未使用 */
+ u16 rsvd1; /**< 保留域段 */
+ u8 host_id[32]; /**< host id, 未使用 */
+ u8 port_id[32]; /**< port id, 未使用 */
+ u8 mac_addr[CHIP_ATTR_MAC_MAX_SIZE]; /**< mac addr */
};
/**
* @brief hinic5_cmd_vlan_config
- * @details nic configure vlan information
+ * @details nic 配置vlan信息
*/
struct hinic5_cmd_vlan_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 opcode; /**< opration code */
- u8 rsvd1; /**< Reserved field */
- u16 vlan_id; /**< vlan id */
- u8 blacklist_flag; /**< Blacklist flag (for computation, reserved) */
- u8 rsvd2; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 opcode; /**< opration code */
+ u8 rsvd1; /**< 保留域段 */
+ u16 vlan_id; /**< vlan id */
+ u8 blacklist_flag; /**< 黑名单标志位(计算使用,保留) */
+ u8 rsvd2; /**< 保留域段 */
};
struct hinic5_cmd_vxlan_port_info {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 opcode; /**< opration code */
- u8 cfg_mode; /**< Priority flag */
- u16 vxlan_port; /**< Target port */
- u8 pkt_fmt; /**< 0: vxlan packet 1: vxlan_gpe packet */
- u8 rsvd2; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 opcode; /**< opration code */
+ u8 cfg_mode; /**< 优先级标志位 */
+ u16 vxlan_port; /**< 目标port */
+ u8 pkt_fmt; /**< 0:vxlan报文 1:vxlan_gpe报文 */
+ u8 rsvd2; /**< 保留域段 */
};
/**
@@ -322,180 +318,177 @@ struct hinic5_cmd_vxlan_port_info {
* @details nic set vlan filter
*/
struct hinic5_cmd_set_vlan_filter {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 rsvd1[2]; /**< Reserved field */
- u32 vlan_filter_ctrl; /**< bit0:vlan filter en; bit1:broadcast_filter_en */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 rsvd1[2]; /**< 保留域段 */
+ u32 vlan_filter_ctrl; /**< bit0:vlan filter en; bit1:broadcast_filter_en */
};
/**
* @brief hinic5_cmd_vlan_offload
- * @details nic set vlan offload
+ * @details nic 设置 vlan offload
*/
struct hinic5_cmd_vlan_offload {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 vlan_offload; /**< vlan offload */
- u8 rsvd1[5]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 vlan_offload; /**< vlan offload */
+ u8 rsvd1[5]; /**< 保留域段 */
};
struct hinic5_smac_check_state {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 smac_check_en; /**< 1: enable 0: disable */
- u8 op_code; /**< 1: set 0: get */
- u8 flash_en; /**< Flash enable flag */
- u8 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 smac_check_en; /**< 1: enable 0: disable */
+ u8 op_code; /**< 1: set 0: get */
+ u8 flash_en; /**< flash使能标志位 */
+ u8 rsvd; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_vf_vlan_config
- * @details nic configure vf vlan information
+ * @details nic 配置vf的vlan信息
*/
struct hinic5_cmd_vf_vlan_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 opcode; /**< opration code */
- u8 rsvd1; /**< Reserved field */
- u16 vlan_id; /**< vlan id */
- u8 qos; /**< qos */
- u8 rsvd2[5]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 opcode; /**< opration code */
+ u8 rsvd1; /**< 保留域段 */
+ u16 vlan_id; /**< vlan id */
+ u8 qos; /**< qos */
+ u8 rsvd2[5]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_vf_trust_config
- * @details nic configure vf trust information
+ * @details nic 配置vf的trust信息
*/
struct hinic5_cmd_vf_trust_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u16 vlan_id; /**< vlan id */
- u8 trust; /* vf_trust: 0-disable; 1-enable */
- u8 rsvd2[67]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u16 vlan_id; /**< vlan id */
+ u8 trust; /* vf_trust: 0-disable; 1-enable */
+ u8 rsvd2[67]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_spoofchk_set
- * @details nic configure spoofchk
+ * @details nic 配置 spoofchk
*/
struct hinic5_cmd_spoofchk_set {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 state; /**< state */
- u8 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 state; /**< state */
+ u8 rsvd1; /**< 保留域段 */
};
-#define NIC_RATE_DIRECT_RX_BW 0 /**< RX bandwidth rate limit */
-#define NIC_RATE_DIRECT_TX_BW 1 /**< TX bandwidth rate limit */
-#define NIC_RATE_DIRECT_RX_PERCENT 2 /**< RX percentage rate limit (setting command 1872 implementation differs) other parts are identical */
-#define NIC_RATE_DIRECT_TX_PERCENT 3 /**< TX percentage rate limit */
-#define NIC_RATE_OP_SET 0 /**< Rate limit set */
-#define NIC_RATE_OP_GET 1 /**< Rate limit query */
-#define NIC_RATE_OP_FLASH 2 /**< FLASH persist */
-#define NIC_RATE_OP_UNUSE 4 /**< For compatibility adaptation, for 1823 (since this field won't be read, it will actually perform rate limit configuration), 1872/1825 and later generations actually do nothing and return directly */
+#define NIC_RATE_DIRECT_RX_BW 0 /**< RX带宽限速 */
+#define NIC_RATE_DIRECT_TX_BW 1 /**< TX带宽限速 */
+#define NIC_RATE_DIRECT_RX_PERCENT \
+ 2 /**< RX百分比限速 (设置命令1872实现存在差异) 其他部分完全一样 */
+#define NIC_RATE_DIRECT_TX_PERCENT 3 /**< TX百分比限速 */
+#define NIC_RATE_OP_SET 0 /**< 限速设置 */
+#define NIC_RATE_OP_GET 1 /**< 限速查询 */
+#define NIC_RATE_OP_FLASH 2 /**< FLASH固化 */
+#define NIC_RATE_OP_UNUSE \
+ 4 /**< 用于兼容性适配,针对1823(由于不会去读该域段,因此实际会做限速配置的操作),1872/1825等后面代次则实际不做任何操作直接返回 */
/**
* @brief hinic5_cmd_rate_cfg
- * @details nic rate configuration
+ * @details nic rate 速率配置
*/
struct hinic5_cmd_rate_cfg {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 cfg_mode; /* BIT[0]: set and query, 0-set, 1-query;
- * BIT[1]: whether to support persist to Flash Currently only supports percentage rate limit persisting;
- * BIT[2]: if 1 means do nothing and return directly
- */
- u8 direct; /* Direction: 0-RX bandwidth limit 1-TX bandwidth limit 2-RX_RATE percentage 3-TX_RATE percentage */
- u32 cir; /**< C bucket rate Mbps old field name min_rate */
- u32 pir; /* P bucket rate Mbps if bandwidth limit, represents C bucket rate (Mbps),
- * if direct is percentage limit, represents percentage, old field name max_rate
- */
- u32 cbs; /**< C bucket depth Mbit 0 uses default bucket depth */
- u32 pbs; /**< P bucket depth Mbit 0 uses default bucket depth */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 cfg_mode; /**< BIT[0]:设置和查询, 0-设置, 1代表查询; BIT[1]:是否支持固化到Flash 目前仅支持百分比限速的固化;BIT[2]:若为1表示什么都不操作直接返回 */
+ u8 direct; /**< 方向: 0-RX带宽限速 1-TX带宽限速 2-RX_RATE百分比 3-TX_RATE百分比 */
+ u32 cir; /**< C桶速率 Mbps 旧域段名称min_rate */
+ u32 pir; /**< P桶速率 Mbps 若为带宽限速,则代表C桶速率(Mbps),若direct为百分比限速,则代表百分比,旧域段名称max_rate */
+ u32 cbs; /**< C桶桶深 Mbit 0则使用默认桶深 */
+ u32 pbs; /**< P桶桶深 Mbit 0则使用默认桶深 */
};
-#define NIC_RATE_MODE_PERCENT 0 /**< Effective as percentage rate limit. */
-#define NIC_RATE_MODE_BANDWIDTH 1 /**< Effective as bandwidth rate limit. */
+#define NIC_RATE_MODE_PERCENT 0 /**< 按照百分比限速生效. */
+#define NIC_RATE_MODE_BANDWIDTH 1 /**< 按照带宽限速生效. */
+#define ERR_RATE_BW_PARAM_OVERFLOW 254 /* Bandwidth rate param overflow */
/**
* @brief hinic5_cmd_rate_cfg_ret
- * @details nic rate configuration query
+ * @details nic rate 速率配置查询
*/
struct hinic5_cmd_rate_cfg_ret {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 car_id; /**< RX direction rate limit needs to return CAR_ID */
- u8 rate_mode; /**< Current rate limit mode: 0-percentage rate limit 1-bandwidth rate limit */
- u8 rsvd; /**< Reserved field */
- u32 cir; /**< C bucket rate Mbps old field name min_rate */
- u32 pir; /* P bucket rate Mbps if bandwidth limit, represents C bucket rate (Mbps),
- * if direct is percentage limit, represents percentage, old field name max_rate
- */
- u32 cbs; /**< C bucket depth Mbit 0 uses default bucket depth */
- u32 pbs; /**< P bucket depth Mbit 0 uses default bucket depth */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 car_id; /**< RX方向限速需要返回CAR_ID */
+ u8 rate_mode; /**< 当前限速生效的模式:0-百分比限速 1-带宽限速 */
+ u8 rsvd; /**< 保留域段 */
+ u32 cir; /**< C桶速率 Mbps 旧域段名称min_rate */
+ u32 pir; /**< P桶速率 Mbps 若为带宽限速,则代表C桶速率(Mbps),若direct为百分比限速,则代表百分比,旧域段名称max_rate */
+ u32 cbs; /**< C桶桶深 Mbit 0则使用默认桶深 */
+ u32 pbs; /**< P桶桶深 Mbit 0则使用默认桶深 */
};
-#define NIC_DCB_COS_MAX 0x8 /**< Define maximum priority (COS) for NIC DCB */
+#define NIC_DCB_COS_MAX \
+ 0x8 /**< 定义网络接口控制数据包(NIC DCB)的最大优先级(COS) */
/**
- * @brief Structure for RSS configuration
- * @details This structure contains various parameters needed for RSS configuration, such as function ID, RSS enable flag, priority queue number, priority to traffic class mapping, queue pair number, etc.
+ * @brief 定义了一个用于RSS配置的结构体
+ * @details 该结构体包含了RSS配置所需的各种参数,如函数ID、RSS使能标志、优先级队列数量、优先级与流量类别的映射关系、队列对数量等。
*/
struct hinic5_cmd_rss_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID, used to identify which function's RSS is being configured */
- u8 rss_en; /* RSS enable flag, if 1 means RSS function is enabled, 0 means disabled */
- u8 rq_priority_number; /* Number of priority queues, which determines the specific implementation of RSS */
- u8 prio_tc[NIC_DCB_COS_MAX]; /* Mapping between priority and traffic class, array length is NIC_DCB_COS_MAX */
- u16 num_qps; /**< Number of queue pairs, which determines the specific implementation of RSS */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID,用于标识当前配置的是哪个函数的RSS */
+ u8 rss_en; /**< RSS使能标志,如果为1则表示RSS功能开启,0则表示关闭 */
+ u8 rq_priority_number; /**< 优先级队列的数量,决定了RSS的具体实现方式 */
+ u8 prio_tc[NIC_DCB_COS_MAX]; /**< 优先级与流量类别的映射关系,数组长度为NIC_DCB_COS_MAX */
+ u16 num_qps; /**< 队列对的数量,决定了RSS的具体实现方式 */
+ u16 rsvd1; /**< 保留域段 */
};
/**
- * @brief RSS (Receive Side Scaling) template management structure
- * @details This structure is used for managing RSS templates, including management message head, function ID, command, template ID, etc.
+ * @brief 定义了一个RSS(Receive Side Scaling,接收端缩放)模板管理结构体
+ * @details 该结构体用于管理RSS模板,包含了管理消息头部、函数ID、命令、模板ID等信息
*/
struct hinic5_rss_template_mgmt {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID, used to identify the function module corresponding to the current message */
- u8 cmd; /**< Command, used to identify the operation to be executed */
- u8 template_id; /**< Template ID, used to identify the template corresponding to the current operation */
- u8 rsvd1[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID,用于标识当前消息对应的功能模块 */
+ u8 cmd; /**< 命令,用于标识需要执行的操作 */
+ u8 template_id; /**< 模板ID,用于标识当前操作对应的模板 */
+ u8 rsvd1[4]; /**< 保留域段 */
};
/**
- * @brief RSS (Receive Side Scaling) context table structure
- * @details This structure contains RSS context table data, including management message head, func id, context information, and reserved fields.
+ * @brief 定义了一个RSS(Receive Side Scaling,接收端缩放)上下文表结构体
+ * @details 该结构体包含了rss context表内的相关数据,包含管理消息头部、func id、上下文信息以及保留字段。
*/
struct hinic5_rss_context_table {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID, used to identify the function module corresponding to the current message */
- u16 rsvd1; /**< Reserved field */
- u32 context; /**< RSS context */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID,用于标识当前消息对应的功能模块 */
+ u16 rsvd1; /**< 保留域段 */
+ u32 context; /**< RSS上下文 */
};
-#define NIC_RSS_KEY_SIZE 40 /**< Define RSS key size as 40 */
+#define NIC_RSS_KEY_SIZE 40 /**< 定义RSS ket大小为40 */
/**
- * @brief Structure for RSS hash key
- * @details This structure is used to store RSS hash key related information
+ * @brief 定义了一个用于RSS哈希键的结构体
+ * @details 该结构体用于存储RSS哈希键相关信息
*/
struct hinic5_cmd_rss_hash_key {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 opcode; /**< Operation code */
- u8 rsvd1; /**< Reserved field */
- u8 key[NIC_RSS_KEY_SIZE]; /**< RSS hash key */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 opcode; /**< 操作码 */
+ u8 rsvd1; /**< 保留域段 */
+ u8 key[NIC_RSS_KEY_SIZE]; /**< RSS哈希键 */
};
/**
- * @brief Structure for RSS engine type
- * @details This structure is used to describe RSS engine type related information
+ * @brief 定义了一个用于RSS引擎类型的结构体
+ * @details 该结构体用于描述RSS引擎类型相关的信息
*/
struct hinic5_cmd_rss_engine_type {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 opcode; /**< Operation code */
- u8 hash_engine; /**< Hash engine */
- u8 rsvd1[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 opcode; /**< 操作码 */
+ u8 hash_engine; /**< 哈希引擎 */
+ u8 rsvd1[4]; /**< 保留域段 */
};
/**
@@ -503,67 +496,59 @@ struct hinic5_cmd_rss_engine_type {
* @details IP checksum error packets, enable rss quadruple hash
*/
struct hinic5_ipcs_err_rss_enable_operation_s {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
u8 en_tag;
- u8 type; /**< 1: set 0: get */
- u8 rsvd[2]; /**< Reserved field */
+ u8 type; /**< 1: set 0: get */
+ u8 rsvd[2]; /**< 保留域段 */
};
/**
- * @brief Network interface command filter delete rule structure
- * @details This structure is used to store network interface command filter delete rule related information.
+ * @brief 网络接口命令过滤删除规则的结构体
+ * @details 该结构体用于存储网络接口命令过滤删除规则的相关信息。
*/
struct nic_cmd_fdir_del_rules {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 type; /**< Type */
- u8 rsvusrdata; /**< User data */
- u32 index_start; /**< Index start position */
- u32 index_num; /**< Index count */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 type; /**< 类型 */
+ u8 rsvusrdata; /**< 用户数据 */
+ u32 index_start; /**< 索引开始位置 */
+ u32 index_num; /**< 索引数量 */
};
/**
- * @brief Structure for flushing TCAM rules
- * @details This structure contains management message head and function ID two members, used for flushing TCAM rules.
+ * @brief 定义了一个用于刷新TCAM规则的结构体
+ * @details 该结构体包含了管理消息头部和函数ID两个成员,用于刷新TCAM规则。
*/
struct nic_cmd_flush_tcam_rules {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u16 rsvd; /**< 保留域段 */
};
/**
- * @brief Input structure for allocating TCAM block
- * @details This structure is used for TCAM block allocation input parameters, including head information, function ID, allocation flag, TCAM type, TCAM block index, and allocation block count, etc.
+ * @brief 分配TCAM块的输入结构体
+ * @details 该结构体用于分配TCAM块的输入参数,包含头部信息、函数ID、分配标志、TCAM类型、TCAM块索引和分配块数量等信息。
*/
struct nic_cmd_ctrl_tcam_block_in {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 alloc_en; /**< 0: Free allocated tcam block, 1: Allocate new tcam block */
- u8 tcam_type; /* 0: Allocate 16 size tcam block,
- * 1: Allocate 0 size tcam block, others reserved
- */
- u16 tcam_block_index; /**< index */
- u16 alloc_block_num; /* Driver sends to uP indicating the block size driver wants to allocate
- * uP returns to driver interface, indicating the tcam block size uP supports allocating
- */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 alloc_en; /**< 0: 释放分配的tcam block, 1: 申请新的tcam block */
+ u8 tcam_type; /**< 0: 分配16 size 的tcam block, 1: 分配0 size的tcam block, 其他预留 */
+ u16 tcam_block_index; /**< index */
+ u16 alloc_block_num; /**< 驱动发给uP表示驱动希望分配的block大小。uP返回给驱动的接口,表示uP 支持的分配的tcam block大小 */
};
/**
- * @brief Output structure for allocating TCAM block
- * @details This structure is used to store allocation TCAM block output information.
+ * @brief 分配TCAM块输出结构体
+ * @details 该结构体用于存储分配TCAM块的输出信息。
*/
struct nic_cmd_ctrl_tcam_block_out {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 alloc_en; /**< 0: Free allocated tcam block, 1: Allocate new tcam block */
- u8 tcam_type; /* 0: Allocate 16 size tcam block,
- * 1: Allocate 0 size tcam block, others reserved
- */
- u16 tcam_block_index; /**< index */
- u16 mpu_alloc_block_size; /* Driver sends to uP indicating the block size driver wants to allocate,
- * uP returns to driver interface, indicating the tcam block size uP supports allocating
- */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 alloc_en; /**< 0: 释放分配的tcam block, 1: 申请新的tcam block */
+ u8 tcam_type; /**< 0: 分配16 size 的tcam block, 1: 分配0 size的tcam block, 其他预留 */
+ u16 tcam_block_index; /**< index */
+ u16 mpu_alloc_block_size; /**< 驱动发给uP表示驱动希望分配的block大小,uP返回给驱动的接口,表示uP 支持的分配的tcam block大小 */
};
/**
@@ -571,515 +556,512 @@ struct nic_cmd_ctrl_tcam_block_out {
* @details enable tcam
*/
struct nic_cmd_set_tcam_enable {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Function ID */
- u8 tcam_enable; /**< tcam enable */
- u8 rsvd1; /**< Reserved field */
- u32 rsvd2; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< 函数ID */
+ u8 tcam_enable; /**< tcam enable */
+ u8 rsvd1; /**< 保留域段 */
+ u32 rsvd2; /**< 保留域段 */
};
/**
- * @brief Input structure for allocating TCAM block
- * @details This structure is used for TCAM block allocation input parameters, including head information, function ID, allocation flag, TCAM type, TCAM block index and allocation block count, etc.
+ * @brief 分配TCAM块的输入结构体
+ * @details 该结构体用于分配TCAM块的输入参数,包含头部信息、函数ID、分配标志、TCAM类型、TCAM块索引和分配块数量等信息。
*/
struct nic_cmd_dfx_fdir_tcam_block_table {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 tcam_type; /**< TCAM type */
- u8 valid; /**< Valid flag */
- u16 tcam_block_index; /**< TCAM block index */
- u16 use_function_id; /**< Used function ID */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 tcam_type; /**< TCAM类型 */
+ u8 valid; /**< 有效标志位 */
+ u16 tcam_block_index; /**< TCAM块索引 */
+ u16 use_function_id; /**< 使用的函数ID */
+ u16 rsvd; /**< 保留域段 */
};
struct hinic5_ppa_cfg_table_id_cmd {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 rsvd0; /**< Reserved field */
- u16 cmd; /**< command */
- u16 table_id; /**< table id */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 rsvd0; /**< 保留域段 */
+ u16 cmd; /**< command */
+ u16 table_id; /**< table id */
+ u16 rsvd1; /**< 保留域段 */
};
struct hinic5_ppa_cfg_ppa_en_cmd {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< function id */
- u8 ppa_en; /**< ppa enable */
- u8 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< function id */
+ u8 ppa_en; /**< ppa enable */
+ u8 rsvd; /**< 保留域段 */
};
struct hinic5_ppa_cfg_mode_cmd {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 rsvd0; /**< function id */
- u8 ppa_mode; /**< ppa mode */
- u8 qpc_func_nums; /**< qpc function numbers */
- u16 base_qpc_func_id; /**< base qpc function id */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 rsvd0; /**< function id */
+ u8 ppa_mode; /**< ppa mode */
+ u8 qpc_func_nums; /**< qpc function numbers */
+ u16 base_qpc_func_id; /**< base qpc function id */
+ u16 rsvd1; /**< 保留域段 */
};
struct hinic5_ppa_flush_en_cmd {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 rsvd0; /**< Reserved field */
- u8 flush_en; /**< 0 flush done, 1 in flush operation */
- u8 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 rsvd0; /**< 保留域段 */
+ u8 flush_en; /**< 0 flush done, 1 in flush operation */
+ u8 rsvd1; /**< 保留域段 */
};
struct nic_cmd_set_fdir_status {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< function id */
- u16 index; /**< index */
- u8 pkt_type_en; /**< packet type enable */
- u8 pkt_type; /**< packet type */
- u8 qid; /**< queue id */
- u8 flag; /**< packet drop flag */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< function id */
+ u16 index; /**< index */
+ u8 pkt_type_en; /**< packet type enable */
+ u8 pkt_type; /**< packet type */
+ u8 qid; /**< queue id */
+ u8 flag; /**< packet drop flag */
};
struct hinic5_ppa_fdir_query_cmd {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u32 index; /**< index */
- u32 rsvd; /**< Reserved field */
- u64 pkt_nums; /**< packet type */
- u64 pkt_bytes; /**< packet bytes */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u32 index; /**< index */
+ u32 rsvd; /**< 保留域段 */
+ u64 pkt_nums; /**< packet type */
+ u64 pkt_bytes; /**< packet bytes */
};
struct hinic5_port_state {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< function id */
- u16 rsvd1; /**< Reserved field */
- u8 state; /**< 0--disable, 1--enable */
- u8 rsvd2[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< function id */
+ u16 rsvd1; /**< 保留域段 */
+ u8 state; /**< 0--disable, 1--enable */
+ u8 rsvd2[3]; /**< 保留域段 */
};
struct hinic5_cmd_pause_config {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 opcode; /**< operation code */
- u16 rsvd1; /**< Reserved field */
- u8 auto_neg; /**< auto negotiation */
- u8 rx_pause; /**< receive pause */
- u8 tx_pause; /**< send pause */
- u8 rsvd2[5]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 opcode; /**< operation code */
+ u16 rsvd1; /**< 保留域段 */
+ u8 auto_neg; /**< auto negotiation */
+ u8 rx_pause; /**< receive pause */
+ u8 tx_pause; /**< send pause */
+ u8 rsvd2[5]; /**< 保留域段 */
};
struct hinic5_port_car_info {
- u32 cir; /**< unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 xir; /**< unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 cbs; /**< unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
- u32 xbs; /**< unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 cir; /**< unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /**< unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /**< unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /**< unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
};
/**
* @brief hinic5_cmd_set_port_car
- * @details nic set car rate limit command structure (1825)
+ * @details nic 设置car限速命令结构体(1825)
*/
struct hinic5_cmd_set_port_car {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 opcode; /**< 0--set car profile, 1--set car state, 2--get car profile */
- u8 state; /**< 0--disable, 1--enable */
- u8 level; /**< limit level */
- struct hinic5_port_car_info car; /**< car info */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 opcode; /**< 0--set car profile, 1--set car state, 2--get car profile */
+ u8 state; /**< 0--disable, 1--enable */
+ u8 level; /**< limit level */
+ struct hinic5_port_car_info car; /**< car info */
};
struct hinic5_cmd_set_car_option {
- u8 type; /**< 0:port, 1:func, 2:vnic group*/
+ u8 type; /**< 0:port, 1:func, 2:vnic group*/
u8 port_id;
u16 func_id;
u8 car_enable;
- u8 opcode; /**< 0--set car profile, 1--get car profile */
+ u8 opcode; /**< 0--set car profile, 1--get car profile */
u8 pkt_type;
u8 car_alg_type;
};
/**
* @brief hinic5_cmd_set_car
- * @details nic set car rate limit command structure (1872)
+ * @details nic 设置car限速命令结构体(1872)
*/
struct hinic5_cmd_set_car {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
struct hinic5_cmd_set_car_option option;
- struct hinic5_port_car_info car; /**< car info */
+ struct hinic5_port_car_info car; /**< car info */
};
/**
* @brief hinic5_car_profile
- * @details nic set car rate limit command structure (1872)
+ * @details nic 设置car限速命令结构体(1872)
*/
struct hinic5_car_profile {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 car_id; /**< car id */
- u8 level; /**< limit level */
- u8 rsvd; /**< Reserved field */
- u32 profile[4]; /**< car profile */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 car_id; /**< car id */
+ u8 level; /**< limit level */
+ u8 rsvd; /**< 保留域段 */
+ u32 profile[4]; /**< car profile */
};
-#define NIC_DCB_TC_MAX 0x8 /**< Maximum traffic class (TC) for NIC DCB */
+#define NIC_DCB_TC_MAX \
+ 0x8 /**< 定义网络接口控制数据包(NIC DCB)的最大流量类别(TC) */
/**
* @brief hinic5_cmd_ets_cfg
- * @details nic configure ets command structure
+ * @details nic 配置ets命令结构体
*/
struct hinic5_cmd_ets_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 op_code; /**< 1 - set, 0 - get */
- u8 cfg_bitmap; /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio,
- * bit3 - cos_bw, bit4 - tc_prio
- */
- u8 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 op_code; /**< 1 - set, 0 - get */
+ u8 cfg_bitmap; /**< bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 rsvd; /**< 保留域段 */
u8 cos_tc[NIC_DCB_COS_MAX];
u8 tc_bw[NIC_DCB_TC_MAX];
- u8 cos_prio[NIC_DCB_COS_MAX]; /**< 0 - DWRR, 1 - STRICT */
+ u8 cos_prio[NIC_DCB_COS_MAX]; /**< 0 - DWRR, 1 - STRICT */
u8 cos_bw[NIC_DCB_COS_MAX];
- u8 tc_prio[NIC_DCB_TC_MAX]; /**< 0 - DWRR, 1 - STRICT */
+ u8 tc_prio[NIC_DCB_TC_MAX]; /**< 0 - DWRR, 1 - STRICT */
};
struct hinic5_cmd_set_pfc {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 op_code; /**< 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
- u8 pfc_en; /**< pfc_en and pfc_bitmap must be set simultaneously */
- u8 pfc_bitmap; /**< pfc bitmap */
- u8 rsvd[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 op_code; /**< 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /**< pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap; /**< pfc bitmap */
+ u8 rsvd[4]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_set_dcb_state
- * @details nic set dcb state command structure
+ * @details nic 设置dcb state命令结构体
*/
struct hinic5_cmd_set_dcb_state {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< port id */
- u8 op_code; /**< 0 - get dcb state, 1 - set dcb state */
- u8 state; /**< 0 - disable, 1 - enable dcb */
- u8 port_state; /**< 0 - disable, 1 - enable dcb */
- u8 rsvd[7]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< port id */
+ u8 op_code; /**< 0 - get dcb state, 1 - set dcb state */
+ u8 state; /**< 0 - disable, 1 - enable dcb */
+ u8 port_state; /**< 0 - disable, 1 - enable dcb */
+ u8 rsvd[7]; /**< 保留域段 */
};
struct hinic5_cmd_qos_port_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 op_code; /**< 0 - get, 1 - set */
- u8 cfg_bitmap; /**< bit0 - trust, bit1 - dft_cos */
- u8 rsvd0; /**< Reserved field */
- u8 trust; /**< trust state */
- u8 dft_cos; /**< dft cos */
- u8 rsvd1[18]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 op_code; /**< 0 - get, 1 - set */
+ u8 cfg_bitmap; /**< bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0; /**< 保留域段 */
+ u8 trust; /**< trust state */
+ u8 dft_cos; /**< dft cos */
+ u8 rsvd1[18]; /**< 保留域段 */
};
struct hinic5_cmd_qos_map_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 op_code; /**< operation code */
- u8 cfg_bitmap; /**< bit0 - pcp2cos, bit1 - dscp2cos */
- u16 rsvd0; /**< Reserved field */
- u8 pcp2cos[8]; /**< Must configure all 8 together */
- u8 dscp2cos[64]; /* When configuring dscp2cos, if cos value is set to 0xFF, MPU will ignore this dscp priority configuration
- * Allows configuring multiple dscp to cos mappings at once
- */
- u32 rsvd1[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 op_code; /**< operation code */
+ u8 cfg_bitmap; /**< bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0; /**< 保留域段 */
+ u8 pcp2cos[8]; /**< 必须8个一起配置 */
+ u8 dscp2cos[64]; /**< 配置dscp2cos时,若cos值设置为0xFF,MPU则忽略此dscp优先级的配置,允许一次性配置多个dscp跟cos的映射关系 */
+ u32 rsvd1[4]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_qos_extend_cfg
- * @details nic configure qos command extended structure
+ * @details nic 配置qos命令扩展结构体
*/
struct hinic5_cmd_qos_extend_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 port_id; /**< port id */
- u8 op_code; /**< bit0: 1-set tc rate limit, 0-get tc rate limit */
- u16 rsvd0; /**< Reserved field */
- u16 port_speed; /**< Port speed, unit Gbps */
- u16 rsvd1; /**< Reserved field */
- u32 rate_limit[NIC_DCB_COS_MAX]; /**< TC rate limit value, unit Mbps */
- u32 port_cir; /**< Port cir value, unit Mbps */
- u32 rsvd2[115]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 port_id; /**< port id */
+ u8 op_code; /**< bit0: 1-set tc rate limit, 0-get tc rate limit */
+ u16 rsvd0; /**< 保留域段 */
+ u16 port_speed; /**< 端口速率, 单位Gbps */
+ u16 rsvd1; /**< 保留域段 */
+ u32 rate_limit[NIC_DCB_COS_MAX]; /**< tc限速速率值, 单位Mbps */
+ u32 port_cir; /**< port的cir值, 单位Mbps */
+ u32 rsvd2[115]; /**< 保留域段 */
};
/**
* @brief hinic5_force_pkt_drop
- * @details nic force pkt drop command structure
+ * @details nic force pkt drop命令结构体
*/
struct hinic5_force_pkt_drop {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u8 port; /**< port id */
- u8 rsvd1[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 port; /**< port id */
+ u8 rsvd1[3]; /**< 保留域段 */
};
/**
* @brief nic_cmd_pause_inquiry_cfg
- * @details pfc storm detection configuration
+ * @details pfc风暴检测配置
*/
struct nic_cmd_pause_inquiry_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 valid; /**< valid */
- u32 type; /**< 1: set, 2: get */
- u32 rx_inquiry_pause_drop_pkts_en; /**< rx drop packet enable */
- u32 rx_inquiry_pause_period_ms; /**< rx pause detection period default 200ms */
- u32 rx_inquiry_pause_times; /**< rx pause detection times default 1 */
- u32 rx_inquiry_pause_frame_thd; /* rx pause detection threshold
- * default PAUSE_FRAME_THD_10G/25G/40G/100
- */
- u32 rx_inquiry_tx_total_pkts; /**< rx pause detection tx packet total */
- u32 tx_inquiry_pause_en; /**< tx pause detection enable */
- u32 tx_inquiry_pause_period_ms; /**< tx pause detection period default 200ms */
- u32 tx_inquiry_pause_times; /**< tx pause detection times default 5 */
- u32 tx_inquiry_pause_frame_thd; /**< tx pause detection threshold */
- u32 tx_inquiry_rx_total_pkts; /**< tx pause detection rx packet total */
- u32 rsvd[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 valid; /**< valid */
+ u32 type; /**< 1: set, 2: get */
+ u32 rx_inquiry_pause_drop_pkts_en; /**< rx 卸包使能 */
+ u32 rx_inquiry_pause_period_ms; /**< rx pause 检测周期 默认 200ms */
+ u32 rx_inquiry_pause_times; /**< rx pause 检测次数 默认1次 */
+ u32 rx_inquiry_pause_frame_thd; /**< rx pause 检测阈值 默认 PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_tx_total_pkts; /**< rx pause 检测tx收包总数 */
+ u32 tx_inquiry_pause_en; /**< tx pause 检测使能 */
+ u32 tx_inquiry_pause_period_ms; /**< tx pause 检测周期 默认 200ms */
+ u32 tx_inquiry_pause_times; /**< tx pause 检测次数 默认 5次 */
+ u32 tx_inquiry_pause_frame_thd; /**< tx pause 检测阈值 */
+ u32 tx_inquiry_rx_total_pkts; /**< tx pause 检测rx收包总数 */
+ u32 rsvd[4]; /**< 保留域段 */
};
struct nic_bios_cfg {
- u32 signature; /**< Signature, used to verify FLASH content validity */
- u8 pxe_en; /**< PXE enable: 0 - disable 1 - enable */
+ u32 signature; /**< 签名,用于判断FLASH的内容合法性 */
+ u8 pxe_en; /**< PXE enable: 0 - disable 1 - enable */
u8 extend_mode;
- u8 rsvd0[2]; /**< Reserved field */
- u8 pxe_vlan_en; /**< PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /**< PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /**< PXE VLAN ID 1-4094 */
- u32 service_mode; /**< Reference CHIPIF_SERVICE_MODE_x macro */
- u32 pf_bw; /**< PF rate, percentage 0-100 */
- u8 speed; /**< enum of port speed */
- u8 auto_neg; /**< Auto-negotiation switch 0 - field invalid 1 - on 2 - off */
- u8 lanes; /**< lane num */
- u8 fec; /**< FEC mode, reference enum mag_cmd_port_fec */
- u8 auto_adapt; /**< Auto-adapt mode configuration 0 - invalid config 1 - on 2 - off */
- u8 func_valid; /**< Indicates whether func_id is valid; 0 - invalid, other - valid */
- u8 func_id; /**< This member is meaningful only when func_valid is not 0 */
- u8 sriov_en; /**< SRIOV-EN: 0 - invalid config, 1 - on, 2 - off */
+ u8 rsvd0[2]; /**< 保留域段 */
+ u8 pxe_vlan_en; /**< PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_pri; /**< PXE VLAN priority: 0-7 */
+ u16 pxe_vlan_id; /**< PXE VLAN ID 1-4094 */
+ u32 service_mode; /**< 参考CHIPIF_SERVICE_MODE_x 宏 */
+ u32 pf_bw; /**< PF速率,百分比 0-100 */
+ u8 speed; /**< enum of port speed */
+ u8 auto_neg; /**< 自协商开关 0 - 字段无效 1 - 开2 - 关 */
+ u8 lanes; /**< lane num */
+ u8 fec; /**< FEC模式, 参考 enum mag_cmd_port_fec */
+ u8 auto_adapt; /**< 自适应模式配置0 - 无效配置 1 - 开启 2 - 关闭 */
+ u8 func_valid; /**< 指示func_id是否有效; 0 - 无效,other - 有效 */
+ u8 func_id; /**< 当func_valid不为0时,该成员才有意义 */
+ u8 sriov_en; /**< SRIOV-EN: 0 - 无效配置, 1 - 开启, 2 - 关闭 */
};
struct nic_cmd_bios_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 op_code; /**< Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
- struct nic_bios_cfg bios_cfg; /**< BIOS configuration */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 op_code; /**< Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg; /**< BIOS configuration */
};
/**
- * @brief Structure for storing semi-offload bond func link status information
- * @details Semi-offload bond create/update/delete will send link messages to non-slave funcs
+ * @brief 定义了一个用于存储半卸载bond func link状态信息的结构体
+ * @details 半卸载bond创建/更新/删除会给非slave的func发送link消息
*/
struct hinic5_bond_link_info {
- struct hinic5_mgmt_msg_head head; /**< Management message head information */
- u8 bond_en; /**< Bond enable status 0:disable 1:enable */
- u8 port_id; /**< port id */
- u8 link_status; /**< Bond non-slave device link status 0:down 1:up */
- u8 rsvd[13]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 管理消息头部信息 */
+ u8 bond_en; /**< bond 是否开启 0:关闭 1:开启 */
+ u8 port_id; /**< port id */
+ u8 link_status; /**< bond的非slave设备link状态 0:down 1:up */
+ u8 rsvd[13]; /**< 保留域段 */
};
/**
- * @brief Internal parse information structure when PN threshold exceeded interrupt occurs
- * @details Contains threshold, SC index, AN and other information
+ * @brief 发生PN超阈值中断时, 内部解析信息结构体
+ * @details 包含阈值、SC索引、AN等信息
*/
struct macsec_pn_expired_report_info {
- u64 sci[32]; /**< SCI of SC corresponding to threshold exceeded event */
- u8 an[32]; /**< AN number of SA corresponding to threshold exceeded event */
- u8 pn_expired_size; /**< SA threshold */
- u8 reserved[7]; /**< Reserved field */
+ u64 sci[32]; /**< 发生超阈值事件对应SC的SCI */
+ u8 an[32]; /**< 发生超阈值事件对应SA的AN号 */
+ u8 pn_expired_size; /**< SA阈值 */
+ u8 reserved[7]; /**< 保留域段 */
};
/**
- * @brief MACsec PN threshold report message structure
- * @details When PN threshold exceeded interrupt occurs, report message structure to driver
+ * @brief macsec pn阈值上报消息结构体
+ * @details 发生PN超阈值中断时, 向驱动上报消息结构体定义
*/
struct macsec_pn_expired_report_cmd {
- struct hinic5_mgmt_msg_head head; /**< Management message head information */
- struct macsec_pn_expired_report_info info; /**< Threshold exceeded related structure information */
- u64 reserved; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 管理消息头部信息 */
+ struct macsec_pn_expired_report_info info; /**< 超阈值相关结构体信息 */
+ u64 reserved; /**< 保留域段 */
};
/**
- * @brief Structure for deleting bond
- * @details This structure contains all information needed for deleting bond
+ * @brief 定义了一个用于删除bond的结构体
+ * @details 该结构体包含了删除bond所需的所有信息
*/
struct hinic5_cmd_delete_bond {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 bond_id; /**< Bond ID */
- u32 rsvd[2]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 bond_id; /**< bond的ID */
+ u32 rsvd[2]; /**< 保留域段 */
};
/**
- * @brief Structure for storing bond device open/close information
- * @details This structure contains bond device open/close information, including bond device number, open/close flag, and reserved fields.
+ * @brief 定义一个结构体,用于存储bond设备的开启/关闭信息
+ * @details 该结构体包含了bond设备的开启/关闭信息,包括bond设备号、开启/关闭标识和保留字段。
*/
struct hinic5_open_close_bond_info {
- u32 bond_id; /**< Bond device number */
- u32 open_close_flag; /**< Open/close bond flag: 1 is open, 0 is close */
- u32 rsvd[2]; /**< Reserved field */
+ u32 bond_id; /**< bond设备号 */
+ u32 open_close_flag; /**< 开启/关闭bond标识:1为open, 0为close */
+ u32 rsvd[2]; /**< 保留域段 */
};
/**
- * @brief Structure for storing MPU bond message interface related information
- * @details This structure contains management message head information and MPU bond open or close related information
+ * @brief 定义了一个结构体,用于存储MPU bond的消息接口的相关信息
+ * @details 该结构体包含了管理消息头部的信息和MPU bond的开启或关闭的相关信息
*/
struct hinic5_cmd_open_close_bond {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- struct hinic5_open_close_bond_info open_close_bond_info; /* Store MPU bond open or close
- * related information
- */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ struct hinic5_open_close_bond_info
+ open_close_bond_info; /**< 存储MPU bond的开启或关闭的相关信息 */
};
/**
- * @brief LACPDU port related fields
- * @details This structure is used to describe port related parameters in LACPDU (Link Aggregation Control Protocol Data Unit).
+ * @brief LACPDU的port相关字段
+ * @details 该结构体用于描述LACPDU(链接聚合控制协议数据单元)中的port相关参数。
*/
struct lacp_port_params {
- u16 port_number; /**< Port number */
- u16 port_priority; /**< Port priority */
- u16 key; /**< Key */
- u16 system_priority; /**< System priority */
- u8 system[ETH_ALEN]; /**< System MAC address */
- u8 port_state; /**< Port state */
- u8 rsvd; /**< Reserved field */
+ u16 port_number; /**< 端口号 */
+ u16 port_priority; /**< 端口优先级 */
+ u16 key; /**< 密钥 */
+ u16 system_priority; /**< 系统优先级 */
+ u8 system[ETH_ALEN]; /**< 系统MAC地址 */
+ u8 port_state; /**< 端口状态 */
+ u8 rsvd; /**< 保留域段 */
};
/**
- * @brief Structure for storing LACP (Link Aggregation Control Protocol) port information
- * @details This structure contains multiple members, each with its specific meaning and purpose.
+ * @brief 定义了一个结构体,用于存储LACP(链接聚合控制协议)端口的信息
+ * @details 该结构体包含了多个成员,每个成员都有其特定的含义和用途。
*/
struct lacp_port_info {
- u32 selected; /**< Indicates whether this port is selected */
- u32 aggregator_port_id; /**< Used aggregator port ID */
- struct lacp_port_params actor; /**< Actor port parameters */
- struct lacp_port_params partner; /**< Partner port parameters */
- u64 tx_lacp_pkts; /**< Transmitted LACP packets count */
- u64 rx_lacp_pkts; /**< Received LACP packets count */
- u64 rx_8023ad_drop; /**< Dropped 802.3ad packets count */
- u64 tx_8023ad_drop; /**< Transmitted 802.3ad packets count */
- u64 unknown_pkt_drop; /**< Dropped unknown packets count */
- u64 rx_marker_pkts; /**< Received marker packets count */
- u64 tx_marker_pkts; /**< Transmitted marker packets count */
+ u32 selected; /**< 表示该端口是否被选中 */
+ u32 aggregator_port_id; /**< 使用的 aggregator port ID */
+ struct lacp_port_params actor; /**< actor port参数 */
+ struct lacp_port_params partner; /**< partner port参数 */
+ u64 tx_lacp_pkts; /**< 发送的LACP数据包数量 */
+ u64 rx_lacp_pkts; /**< 接收的LACP数据包数量 */
+ u64 rx_8023ad_drop; /**< 丢弃的802.3ad数据包数量 */
+ u64 tx_8023ad_drop; /**< 发送的802.3ad数据包数量 */
+ u64 unknown_pkt_drop; /**< 丢弃的未知数据包数量 */
+ u64 rx_marker_pkts; /**< 接收的marker数据包数量 */
+ u64 tx_marker_pkts; /**< 发送的marker数据包数量 */
};
-#define BOND_MAX_PORT_NUM 4 /**< Bond supports maximum port number */
-#define BOND_MAX_HOST_NUM 4 /**< Bond supports maximum host number */
+#define BOND_MAX_PORT_NUM 4 /**< bond 支持最大port数量 */
+#define BOND_MAX_HOST_NUM 4 /**< bond 支持最大host数量 */
/**
- * @brief Structure for storing bond status information
- * @details This structure contains various bond status information, such as bond_id, link status, slave port status, port count, etc., and also contains lacp information for each port, and the count of times each host successfully and failed to report lacp negotiation results, etc.
+ * @brief 定义了一个用于存储bond状态信息的结构体
+ * @details 该结构体包含了bond状态的各种信息,如bond_id、链路状态、slave port状态、port个数等,并且还包含了每个port的lacp信息,以及每个host成功和失败上报lacp协商结果的次数等。
*/
struct hinic5_bond_status_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 bond_id; /**< Bond id */
- u32 bon_mmi_status; /**< This bond sub-device link status */
- u32 active_bitmap; /**< This bond sub-device slave port status */
- u32 port_count; /**< This bond sub-device count */
- struct lacp_port_info port_info[BOND_MAX_PORT_NUM]; /**< Each port lacp information */
- u64 success_report_cnt[BOND_MAX_HOST_NUM]; /* Count of times each host successfully reported lacp negotiation result */
- u64 fail_report_cnt[BOND_MAX_HOST_NUM]; /* Count of times each host failed to report lacp negotiation result */
- u64 poll_timeout; /**< Poll timeout */
- u64 fast_periodic_timeout; /**< Fast periodic timeout */
- u64 slow_periodic_timeout; /**< Slow periodic timeout */
- u64 short_timeout; /**< Short timeout */
- u64 long_timeout; /**< Long timeout */
- u64 aggregate_wait_timeout; /**< Aggregate wait timeout */
- u64 tx_period_timeout; /**< Transmit period timeout */
- u64 rx_marker_timer; /**< RX marker timer */
- u8 bond_mode; /**< Bond mode */
- u8 arp_dual_en; /**< ARP dual transmit enable flag */
- u8 rsvd[6]; /**< Reserved field */
-};
-
-/**
- * @brief Structure for storing bond active report information
- * @details This structure contains bond active report related information, such as management message head information, bond device ID, bond sub-device link status, bond sub-device slave port status, etc.
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 bond_id; /**< bond id */
+ u32 bon_mmi_status; /**< 该bond子设备的链路状态 */
+ u32 active_bitmap; /**< 该bond子设备的slave port状态 */
+ u32 port_count; /**< 该bond子设备个数 */
+ struct lacp_port_info
+ port_info[BOND_MAX_PORT_NUM]; /**< 每个port的lacp信息 */
+ u64 success_report_cnt
+ [BOND_MAX_HOST_NUM]; /**< 每个host成功上报lacp协商结果次数 */
+ u64 fail_report_cnt
+ [BOND_MAX_HOST_NUM]; /**< 每个host上报lacp协商结果失败次数 */
+ u64 poll_timeout; /**< 轮询超时时间 */
+ u64 fast_periodic_timeout; /**< 快速周期性超时时间 */
+ u64 slow_periodic_timeout; /**< 慢速周期性超时时间 */
+ u64 short_timeout; /**< 短超时时间 */
+ u64 long_timeout; /**< 长超时时间 */
+ u64 aggregate_wait_timeout; /**< 聚合等待超时时间 */
+ u64 tx_period_timeout; /**< 发送周期超时时间 */
+ u64 rx_marker_timer; /**< RX标记定时器 */
+ u8 bond_mode; /**< bond模式 */
+ u8 arp_dual_en; /**< arp双发使能标记 */
+ u8 rsvd[6]; /**< 保留域段 */
+};
+
+/**
+ * @brief 定义了一个用于存储bond活动报告信息的结构体
+ * @details 该结构体包含了bond活动报告的相关信息,如管理消息头部信息、bond设备的ID、bond子设备的链路状态、bond子设备的slave port状态等。
*/
struct hinic5_bond_active_report_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 bond_id; /**< Bond ID */
- u32 bon_mmi_status; /**< Bond sub-device link status */
- u32 active_bitmap; /**< Bond sub-device slave port status */
- u8 rsvd[16]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 bond_id; /**< bond的ID */
+ u32 bon_mmi_status; /**< bond子设备的链路状态 */
+ u32 active_bitmap; /**< bond子设备的slave port状态 */
+ u8 rsvd[16]; /**< 保留域段 */
};
-#define DFX_SM_TBL_BUF_MAX 768 /**< Define DFX allocated SM table maximum as 768B */
-#define MAC_TBL_RD_TYPE_MAC_INFO 0 /**< Identifier for getting MAC table content data type */
-#define MAC_TBL_RD_TYPE_MAC_RES_STAT 1 /**< Identifier for getting MAC resource statistics data type */
+#define DFX_SM_TBL_BUF_MAX 768 /**< 定义DFX分配的SM表最多为768B */
+#define MAC_TBL_RD_TYPE_MAC_INFO 0 /**< 标识获取数据类型为MAC表内容 */
+#define MAC_TBL_RD_TYPE_MAC_RES_STAT 1 /**< 标识获取数据类型为MAC资源统计 */
/**
- * @brief MAC table parameters
- * @details This structure is used to store MAC table parameters, including tbl_index, cnt and total_cnt.
+ * @brief MAC表参数
+ * @details 该结构体用于存储MAC表参数,包括tbl_index、cnt和total_cnt。
*/
struct mac_table_arg {
- u32 tbl_index; /**< MAC table index */
- u32 cnt; /**< Count */
- u32 total_cnt; /**< Total count */
- u8 mac_tbl_rd_type; /**< 0-Read MAC content, 1-Read MAC table resource statistics */
- u8 rsvd[3]; /**< Reserved field */
+ u32 tbl_index; /**< MAC表索引 */
+ u32 cnt; /**< 计数 */
+ u32 total_cnt; /**< 总计数 */
+ u8 mac_tbl_rd_type; /**< 0-读取MAC内容, 1-读取MAC表资源统计 */
+ u8 rsvd[3]; /**< 保留字段 */
};
/**
- * @brief VLAN circuit table parameters
- * @details This structure is used to store VLAN circuit table parameters, including er_id and vlan_id.
+ * @brief VLAN电路表参数
+ * @details 该结构体用于存储VLAN电路表参数,包括er_id和vlan_id。
*/
struct vlan_elb_table_arg {
- u32 er_id; /**< er ID */
- u32 vlan_id; /**< VLAN ID */
+ u32 er_id; /**< er ID */
+ u32 vlan_id; /**< VLAN ID */
};
/**
- * @brief VLAN filter parameters (VLAN Filter1 Table)
- * @details This structure is used to store VLAN filter parameters, including tbl_index and func_id.
+ * @brief VLAN过滤参数(VLAN Filter1 Table)
+ * @details 该结构体用于存储VLAN过滤参数,包括tbl_index和func_id。
*/
struct vlan_filter_arg {
- u32 tbl_index; /**< VLAN Filter1 table index */
- u32 func_id; /**< Function ID */
+ u32 tbl_index; /**< VLAN Filter1表索引 */
+ u32 func_id; /**< 功能ID */
};
/**
- * @brief VLAN filter parameters (VLAN Filter2 Table)
- * @details This structure is used to store VLAN filter parameters, including vlan_id.
+ * @brief VLAN过滤参数(VLAN Filter2 Table)
+ * @details 该结构体用于存储VLAN过滤参数,包括vlan_id。
*/
struct vlan_filter2_arg {
- u32 vlan_id; /**< VLAN ID */
+ u32 vlan_id; /**< VLAN ID */
};
/**
- * @brief Multicast circuit table parameters
- * @details This structure is used to store multicast circuit table parameters, including mc_id.
+ * @brief 多播电路表参数
+ * @details 该结构体用于存储多播电路表参数,包括mc_id。
*/
struct mc_elb_arg {
- u32 mc_id; /**< Multicast ID */
+ u32 mc_id; /**< 多播ID */
};
/**
- * @brief Function table parameters
- * @details This structure is used to store function table parameters, including func_id.
+ * @brief 功能表参数
+ * @details 该结构体用于存储功能表参数,包括func_id。
*/
struct func_tbl_arg {
- u32 func_id; /**< Function ID */
+ u32 func_id; /**< 功能ID */
};
/**
- * @brief Port table parameters
- * @details This structure is used to store port table parameters, including port_id.
+ * @brief 端口表参数
+ * @details 该结构体用于存储端口表参数,包括port_id。
*/
struct port_tbl_arg {
- u32 port_id; /**< Port ID */
+ u32 port_id; /**< 端口ID */
};
/**
- * @brief This structure is used to store FDIR IO table parameters, including tbl_index, cnt and total_cnt.
- * @details This structure is used to store port table parameters, including port_id.
+ * @brief 该结构体用于存储FDIR IO表参数,包括tbl_index、cnt和total_cnt。
+ * @details 该结构体用于存储端口表参数,包括port_id。
*/
struct fdir_io_table_arg {
- u32 tbl_index; /**< FDIR IO table index */
- u32 cnt; /**< Count */
- u32 total_cnt; /**< Total count */
+ u32 tbl_index; /**< FDIR IO表索引 */
+ u32 cnt; /**< 计数 */
+ u32 total_cnt; /**< 总计数 */
};
/**
- * @brief FlexQ table parameters
- * @details This structure is used to store FlexQ table parameters, including tbl_index, cnt, total_cnt, left_cnt_die0 and left_cnt_die1.
+ * @brief FlexQ表参数
+ * @details 该结构体用于存储FlexQ表参数,包括tbl_index、cnt、total_cnt、left_cnt_die0和left_cnt_die1。
*/
struct flexq_table_arg {
- u32 tbl_index; /**< FlexQ table index */
- u32 cnt; /**< Count */
- u32 total_cnt; /**< Total count */
- u16 left_cnt_die0; /**< Remaining count DIE0 */
- u16 left_cnt_die1; /**< Remaining count DIE1 */
+ u32 tbl_index; /**< FlexQ表索引 */
+ u32 cnt; /**< 计数 */
+ u32 total_cnt; /**< 总计数 */
+ u16 left_cnt_die0; /**< 剩余计数DIE0 */
+ u16 left_cnt_die1; /**< 剩余计数DIE1 */
};
/**
- * @brief Define a union for storing various types of parameters
- * @details This union contains multiple structures, each representing a different parameter type. These parameter types include MAC table parameters, VLAN circuit table parameters, VLAN filter parameters, multicast circuit table parameters, function table parameters, port table parameters, FDIR IO table parameters, and FlexQ table parameters. Each parameter type has its specific member variables, such as tbl_index, cnt, total_cnt, etc.
+ * @brief 定义一个联合体,用于存储各种类型的参数
+ * @details 该联合体包含了多个结构体,每个结构体代表不同的参数类型。这些参数类型包括MAC表参数、VLAN电路表参数、VLAN过滤参数、多播电路表参数、功能表参数、端口表参数、FDIR IO表参数和FlexQ表参数。每个参数类型都有其特定的成员变量,如tbl_index、cnt、total_cnt等。
*/
typedef union {
struct mac_table_arg mac_table_arg;
@@ -1091,63 +1073,65 @@ typedef union {
struct port_tbl_arg port_tbl_arg;
struct fdir_io_table_arg fdir_io_table_arg;
struct flexq_table_arg flexq_table_arg;
- u32 args[4]; /**< Parameter array */
+ u32 args[4]; /**< 参数数组 */
} sm_tbl_args;
/**
- * @brief Network interface controller command data analysis table structure
- * @details This structure is used to store network interface controller command data analysis table related information
+ * @brief 定义了一个网络接口控制器命令的数据分析表结构体
+ * @details 该结构体用于存储网络接口控制器命令的数据分析表相关信息
*/
struct nic_cmd_dfx_sm_table {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u32 tbl_type; /**< Table type, used to identify table purpose */
- sm_tbl_args args; /**< Table parameters, used to pass table related parameters */
- u8 tbl_buf[DFX_SM_TBL_BUF_MAX]; /**< Table buffer, used to store table data */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u32 tbl_type; /**< 表类型,用于标识表的用途 */
+ sm_tbl_args args; /**< 表参数,用于传递表的相关参数 */
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX]; /**< 表缓冲区,用于存储表的数据 */
};
-#define MAC_TBL_UC_CNT_FUNC_RD_NUM 256 /**< Single command reads maximum 256 Function unicast statistics */
+#define MAC_TBL_UC_CNT_FUNC_RD_NUM \
+ 256 /**< 单次命令最多读取256个Function的单播统计 */
/**
- * @brief MAC table entry shared data resource structure (used to convert nic_cmd_dfx_sm_table structure tbl_buf data)
- * @details This structure is used to store unicast, multicast, shared resource, unicast exclusive resource usage
+ * @brief 定义了一个MAC表项共享数据资源的结构体(用于转换nic_cmd_dfx_sm_table结构体的tbl_buf数据)
+ * @details 该结构体用于存储单播、组播、共享资源,单播独占资源的使用情况
*/
typedef struct nic_cmd_dfx_mac_res_stats_info {
- u16 uc_mac_cnt; /**< Unicast table resource usage statistics */
- u16 mc_mac_cnt; /**< Multicast table resource usage statistics */
- u16 share_mac_res_cur_cnt; /* Current shared resource pool usage statistics */
- u16 share_mac_res_total; /**< Shared resource pool total size */
- u16 func_uc_mac_cnt[MAC_TBL_UC_CNT_FUNC_RD_NUM]; /* Func granularity unicast table resource usage statistics */
- u8 rsvd[248]; /**< Reserved field */
+ u16 uc_mac_cnt; /**< 单播表资源使用统计 */
+ u16 mc_mac_cnt; /**< 组播表资源使用统计 */
+ u16 share_mac_res_cur_cnt; /**< 当前共享资源池使用统计 */
+ u16 share_mac_res_total; /**< 共享资源池总大小 */
+ u16 func_uc_mac_cnt
+ [MAC_TBL_UC_CNT_FUNC_RD_NUM]; /**< Func粒度单播表资源使用统计 */
+ u8 rsvd[248]; /**< 保留字段 */
} nic_cmd_dfx_mac_res_stats_info_s;
/**
* @brief mpu_lt_info
- * @details nic liner table info
+ * @details nic liner tabel info
*/
struct mpu_lt_info {
- u8 node; /**< node id */
- u8 inst; /**< instance id */
- u8 entry_size; /**< entry size */
- u8 sml_table_id; /**< sml table id */
- u32 lt_index; /**< liner table index */
- u32 offset; /**< offset */
- u32 len; /**< length */
+ u8 node; /**< node id */
+ u8 inst; /**< instance id */
+ u8 entry_size; /**< entry size */
+ u8 sml_table_id; /**< sml table id */
+ u32 lt_index; /**< liner tabel index */
+ u32 offset; /**< offset */
+ u32 len; /**< length */
};
struct nic_mpu_lt_opera {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
struct mpu_lt_info net_lt_cmd;
- u8 data[100]; /**< data */
+ u8 data[100]; /**< data */
};
struct hinic5_veb_set {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
- u16 opcode; /**< Operation type: 0=query, 1=configure */
- u16 set_status; /**< Configuration request value: 0=off, 1=on */
- u16 cur_status; /**< Current status: 0=off, 1=on, 2=error */
- u16 rsvd0; /**< Reserved field */
- u32 rsvd[30]; /**< Reserved field */
+ u16 opcode; /**< 操作类型: 0=查询, 1=配置 */
+ u16 set_status; /**< 配置请求值: 0=off, 1=on */
+ u16 cur_status; /**< 当前状态: 0=off, 1=on, 2=error */
+ u16 rsvd0; /**< 保留字段 */
+ u32 rsvd[30]; /**< 保留字段 */
};
/**
@@ -1155,36 +1139,36 @@ struct hinic5_veb_set {
* @details ucode capture cfg info
*/
struct nic_cmd_capture_info {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u32 op_type; /**< operation type */
- u32 func_port; /**< function port */
- u32 is_en_trx; /**< Also used as tx_rx */
- u32 offset_cos; /**< Also used as cos */
- u32 data_vlan; /**< Also used as vlan */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u32 op_type; /**< operation type */
+ u32 func_port; /**< function port */
+ u32 is_en_trx; /**< 也作为tx_rx */
+ u32 offset_cos; /**< 也作为cos */
+ u32 data_vlan; /**< 也作为vlan */
};
struct nic_cmd_vhd_config {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< function id */
- u8 vhd_type; /**< vhd type */
- u8 virtio_small_enable; /**< 0: mergeable mode, 1: small mode */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< function id */
+ u8 vhd_type; /**< vhd type */
+ u8 virtio_small_enable; /**< 0: mergeable mode, 1: small mode */
};
-#define TC_ACL_KEY_BYTE 44 /**< 320 bits + 2 byte pad align to 4 byte */
+#define TC_ACL_KEY_BYTE 44 /**< 320 bits + 2 byte pad align to 4 byte */
/**
* @brief struct hinic5_tc_action_info
* @details info about tc action
*/
struct hinic5_tc_action_info {
- u16 action_flag; /**< action flag */
- u16 output; /**< output */
- u8 flow_queue; /**< flow queue */
- u8 vxlan_tbl_index; /**< vxlan table index */
- u16 vlan_tag; /**< vlan tag */
- u32 flow_mark; /**< flow mark */
- u16 vlan_sel; /**< type of vlan frame */
- u16 count_id; /**< count id */
+ u16 action_flag; /**< action flag */
+ u16 output; /**< output */
+ u8 flow_queue; /**< flow queue */
+ u8 vxlan_tbl_index; /**< vxlan table index */
+ u16 vlan_tag; /**< vlan tag */
+ u32 flow_mark; /**< flow mark */
+ u16 vlan_sel; /**< type of vlan frame */
+ u16 count_id; /**< count id */
};
/**
@@ -1192,26 +1176,26 @@ struct hinic5_tc_action_info {
* @details info about add/del tc flower rule
*/
struct hinic5_tc_cfg_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 key_tcam_mem[TC_ACL_KEY_BYTE]; /**< tcam key mem */
- u8 mask_tcam_mem[TC_ACL_KEY_BYTE]; /**< tcam mask mem */
- struct hinic5_tc_action_info action; /**< action info */
- u16 opcode; /**< 0:del, 1:add */
- u16 index; /**< index id */
- u8 group_vld; /**< tcam group vld */
- u8 group_id; /**< tcam group id */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 key_tcam_mem[TC_ACL_KEY_BYTE]; /**< tcam key mem */
+ u8 mask_tcam_mem[TC_ACL_KEY_BYTE]; /**< tcam mask mem */
+ struct hinic5_tc_action_info action; /**< action info */
+ u16 opcode; /**< 0:del, 1:add */
+ u16 index; /**< index id */
+ u8 group_vld; /**< tcam group vld */
+ u8 group_id; /**< tcam group id */
+ u16 rsvd; /**< 保留域段 */
};
-#define ACL_LCAM_BITMAP_LEN 32 /**< 320 bits + 2 byte pad align to 4 byte */
+#define ACL_LCAM_BITMAP_LEN 32 /**< 320 bits + 2 byte pad align to 4 byte */
/**
* @brief struct hinic5_tc_flush_info
* @details info about add/del tc flower rule
*/
struct hinic5_tc_flush_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u64 active_bitmap[ACL_LCAM_BITMAP_LEN]; /**< active bitmap */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u64 active_bitmap[ACL_LCAM_BITMAP_LEN]; /**< active bitmap */
};
/**
@@ -1219,16 +1203,16 @@ struct hinic5_tc_flush_info {
* @details info about tc vxlan header
*/
struct hinic5_tc_vxlan_hdr_info {
- u8 dmac[6]; /**< destination mac */
- u8 smac[6]; /**< source mac */
- u16 vlan; /**< vlan tag */
- u8 tos; /**< type of service */
- u8 rsvd0; /**< Reserved field */
- u8 sip[4]; /**< source ip */
- u8 dip[4]; /**< destination ip */
- u16 sport; /**< source port */
- u16 rsvd1; /**< Reserved field */
- u32 vni; /**< bit[0:23]: vni, bit[24:31]: rsvd */
+ u8 dmac[6]; /**< destination mac */
+ u8 smac[6]; /**< source mac */
+ u16 vlan; /**< vlan tag */
+ u8 tos; /**< type of service */
+ u8 rsvd0; /**< 保留域段 */
+ u8 sip[4]; /**< source ip */
+ u8 dip[4]; /**< destination ip */
+ u16 sport; /**< source port */
+ u16 rsvd1; /**< 保留域段 */
+ u32 vni; /**< bit[0:23]: vni, bit[24:31]: rsvd */
};
/**
@@ -1236,22 +1220,22 @@ struct hinic5_tc_vxlan_hdr_info {
* @details info about add/get/del tunnel encap vxlan table entry
*/
struct hinic5_tc_vxlan_tbl_cfg_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- struct hinic5_tc_vxlan_hdr_info vxlan_hdr; /**< vxlan header */
- u16 index; /**< index id */
- u16 opcode; /**< 0:del, 1:add, 2:get */
- u32 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ struct hinic5_tc_vxlan_hdr_info vxlan_hdr; /**< vxlan header */
+ u16 index; /**< index id */
+ u16 opcode; /**< 0:del, 1:add, 2:get */
+ u32 rsvd; /**< 保留域段 */
};
/**
* @brief struct hinic5_tc_move_info
- * @details pfe tcam rule delete command structure
+ * @details pfe tcam rule 删除命令结构体
*/
struct hinic5_tc_move_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 old_index; /**< old index */
- u32 new_index; /**< new index */
- u32 len; /**< length */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 old_index; /**< old index */
+ u32 new_index; /**< new index */
+ u32 len; /**< length */
};
/**
@@ -1259,10 +1243,10 @@ struct hinic5_tc_move_info {
* @details pfe profile config from register
*/
struct hinic5_tc_pfe_cfg_profile_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 reg_value; /**< register value */
- u32 opcode; /**< 0: select profile 1: 3-2 shift 2: 3-1-2 shift */
- u32 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 reg_value; /**< register value */
+ u32 opcode; /**< 0: select profile 1: 3-2 shift 2: 3-1-2 shift */
+ u32 rsvd; /**< 保留域段 */
};
#define PFE_ACL_AGING_BLOCK_NUM 128
@@ -1272,13 +1256,13 @@ struct hinic5_tc_pfe_cfg_profile_info {
* @details info about pfe tc aging table
*/
struct hinic5_tc_aging_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 addr; /**< address */
- u16 opcode; /**< 0:get, 1:set, 2:status */
- u32 entry_h[PFE_ACL_AGING_BLOCK_NUM]; /**< high 32 entry */
- u32 entry_l[PFE_ACL_AGING_BLOCK_NUM]; /**< lower 32 entry */
- u16 status; /**< pfe aging table enable status, 0:disable; 1:enable */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 addr; /**< address */
+ u16 opcode; /**< 0:get, 1:set, 2:status */
+ u32 entry_h[PFE_ACL_AGING_BLOCK_NUM]; /**< high 32 entry */
+ u32 entry_l[PFE_ACL_AGING_BLOCK_NUM]; /**< lower 32 entry */
+ u16 status; /**< pfe aging table enable status, 0:disable; 1:enable */
+ u16 rsvd; /**< 保留域段 */
};
#define HTN_CNT_SIZE 8
@@ -1288,14 +1272,14 @@ struct hinic5_tc_aging_info {
* @details pfe count info
*/
struct hinic5_tc_pfe_cnt_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 htn_cnt[HTN_CNT_SIZE]; /**< HTN count */
- u16 mode; /**< 0:tx, 1:rx */
- u16 opcode; /**< 0:get, 1:reset */
- u32 count_id; /**< count id */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 htn_cnt[HTN_CNT_SIZE]; /**< HTN count */
+ u16 mode; /**< 0:tx, 1:rx */
+ u16 opcode; /**< 0:get, 1:reset */
+ u32 count_id; /**< count id */
};
-/* VF available vport count resources */
+/* VF 可用的vport计数资源 */
#define MAX_NIC_COUNT_ID 24
/**
@@ -1303,15 +1287,15 @@ struct hinic5_tc_pfe_cnt_info {
* @details nic vport count info
*/
struct hinic5_nic_vport_cnt_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- struct hinic5_vport_stats stats; /**< vport statistics */
- u32 cnt_res[MAX_NIC_COUNT_ID]; /**< func id for allocating vport count resources */
- u32 cur_cnt; /**< Current number of occupied resources */
- u32 func_id; /**< func id to configure or query */
- u32 index; /**< chip index corresponding to func id */
- u32 opcode; /**< See nic_vport_cnt_op_e */
- u32 rsv1; /**< Reserved field */
- u64 rsv2[192]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ struct hinic5_vport_stats stats; /**< vport统计 */
+ u32 cnt_res[MAX_NIC_COUNT_ID]; /**< 分配vport计数资源的func id */
+ u32 cur_cnt; /**< 当前被占用的资源数 */
+ u32 func_id; /**< 配置或查询的func id */
+ u32 index; /**< 配置或查询的func id对应的芯片index */
+ u32 opcode; /**< 参考 nic_vport_cnt_op_e */
+ u32 rsv1; /**< 保留域段 */
+ u64 rsv2[192]; /**< 保留域段 */
};
/**
@@ -1319,10 +1303,10 @@ struct hinic5_nic_vport_cnt_info {
* @details pfe config from register
*/
struct hinic5_tc_pfe_cfg_reg_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 reg_value; /**< register value */
- u32 reg_value2; /**< register value */
- u32 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 reg_value; /**< register value */
+ u32 reg_value2; /**< register value */
+ u32 rsvd; /**< 保留域段 */
};
#define TC_XY_KEY_SIZE 11
@@ -1332,54 +1316,52 @@ struct hinic5_tc_pfe_cfg_reg_info {
* @details info about tcam info
*/
struct hinic5_tc_tcam_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 key_x[TC_XY_KEY_SIZE]; /**< tcam key_x info */
- u32 key_y[TC_XY_KEY_SIZE]; /**< tcam key_y info */
- struct hinic5_tc_action_info action; /**< action info */
- u16 opcode; /**< 0:del, 1:add, 2:group, 3:get */
- u16 index; /**< index id */
- u8 group_cnt; /**< group cnt */
- u8 rsvd[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 key_x[TC_XY_KEY_SIZE]; /**< tcam key_x info */
+ u32 key_y[TC_XY_KEY_SIZE]; /**< tcam key_y info */
+ struct hinic5_tc_action_info action; /**< action info */
+ u16 opcode; /**< 0:del, 1:add, 2:group, 3:get */
+ u16 index; /**< index id */
+ u8 group_cnt; /**< group cnt */
+ u8 rsvd[3]; /**< 保留域段 */
};
#define PFE_VTEP_TBL_IP_SIZE 4
#define PFE_VTEP_TBL_IP_NUM 8
struct pfe_vtep_ip {
- u32 is_ipv6; /**< 0: ipv4, 1: ipv6 */
- u32 ip_addr[PFE_VTEP_TBL_IP_SIZE]; /* ip_addr[0]: IPv6 DIP[127:96] or IPv4 DIP[31:0]
- * ip_addr[1]: IPv6 DIP[95:64] or IPv4 need set to 0
- * ip_addr[2]: IPv6 DIP[63:32] or IPv4 need set to 0
- * ip_addr[3]: IPv6 DIP[31:0] or IPv4 need set to 0
- */
+ u32 is_ipv6; /**< 0: ipv4, 1: ipv6 */
+ u32 ip_addr[PFE_VTEP_TBL_IP_SIZE]; /**< ip_addr[0]: IPv6 DIP[127:96] or IPv4 DIP[31:0]
+ ip_addr[1]: IPv6 DIP[95:64] or IPv4 need set to 0
+ ip_addr[2]: IPv6 DIP[63:32] or IPv4 need set to 0
+ ip_addr[3]: IPv6 DIP[31:0] or IPv4 need set to 0 */
};
/**
* @brief struct hinic5_tc_pfe_vtep_ip_cmd
- * @details PFE vtep table configuration
+ * @details pfe vtep表配置
*/
struct hinic5_tc_pfe_vtep_ip_cmd {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- struct pfe_vtep_ip dip[PFE_VTEP_TBL_IP_NUM]; /**< destination ip */
- u16 num; /**< num of ip in dip table */
- u16 opcode; /**< 0: del, 1: add, 2: query */
- u32 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ struct pfe_vtep_ip dip[PFE_VTEP_TBL_IP_NUM]; /**< destination ip */
+ u16 num; /**< num of ip in dip table */
+ u16 opcode; /**< 0: del, 1: add, 2: query */
+ u32 rsvd; /**< 保留域段 */
};
-#define DEFAULT_ACTION_REG_NUM 9 /**< Number of registers involved in default ACTION (TX: 2, RX: 1, each ACTION: 3 registers) */
+#define DEFAULT_ACTION_REG_NUM \
+ 9 /**< 默认ACTION(TX2个,RX1个,每个ACTION3个寄存器)涉及的寄存器个数 */
/**
* @brief struct hinic5_tc_default_action_info
* @details info about pfe default action
*/
struct hinic5_tc_default_action_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 opcode; /**< action type: 0:drop; 1:upcall; 2:show; 3:output to port */
- u8 addr; /* default action reg addr:
- * 0:tx default action1; 1:tx default action2; 2:rx default action
- */
- u16 index; /**< func index */
- u32 action[DEFAULT_ACTION_REG_NUM]; /**< default action info */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 opcode; /**< action type: 0:drop; 1:upcall; 2:show; 3:output to port */
+ u8 addr; /**< default action reg addr: 0:tx default action1; 1:tx default action2; 2:rx default action */
+ u16 index; /**< func index */
+ u32 action[DEFAULT_ACTION_REG_NUM]; /**< default action info */
};
/**
@@ -1387,11 +1369,11 @@ struct hinic5_tc_default_action_info {
* @details pfe tcam_freq info
*/
struct hinic5_tc_pfe_tcam_freq_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 tcam_sel; /**< TCAM_CLK_SEL */
- u8 mode; /**< 1:500MHz, 2:250MHz, 3:125MHz */
- u8 opcode; /**< 0:get, 1:set */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 tcam_sel; /**< TCAM_CLK_SEL */
+ u8 mode; /**< 1:500MHz, 2:250MHz, 3:125MHz */
+ u8 opcode; /**< 0:get, 1:set */
+ u16 rsvd; /**< 保留域段 */
};
/**
@@ -1399,86 +1381,78 @@ struct hinic5_tc_pfe_tcam_freq_info {
* @details info about tcam clock gating
*/
struct hinic5_tc_tcam_clock_gating_cfg_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 opcode; /**< 0: get, 1: set */
- u8 status; /**< 0: clock off, 1: clock on */
- u16 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 opcode; /**< 0: get, 1: set */
+ u8 status; /**< 0: 时钟关断, 1: 时钟打开 */
+ u16 rsvd; /**< 保留域段 */
};
#define MAX_CEQ_PER_FUNC 0x20
/**
- * @brief Structure for setting NIC interrupt control
- * @details Contains information needed for setting NIC interrupt control
+ * @brief 定义了一个用于设置NIC中断控制的结构体
+ * @details 该结构体包含了设置NIC中断控制所需的各种信息
*/
struct mig_nic_set_ceq_ctrl {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 ceq_num; /**< Number of CEQ controls */
- u8 rsvd; /**< Reserved field */
- u32 ceq_ctrl0[MAX_CEQ_PER_FUNC]; /* CEQ controller 0 array
- * Each element corresponds to a CEQ controller
- */
- u32 ceq_ctrl1[MAX_CEQ_PER_FUNC]; /* CEQ controller 1 array
- * Each element corresponds to a CEQ controller
- */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 ceq_num; /**< 中断控制的数量 */
+ u8 rsvd; /**< 保留域段 */
+ u32 ceq_ctrl0[MAX_CEQ_PER_FUNC]; /**< 中断控制器0的数组,每个元素对应一个中断控制器 */
+ u32 ceq_ctrl1[MAX_CEQ_PER_FUNC]; /**< 中断控制器1的数组,每个元素对应一个中断控制器 */
};
-#define MAX_INTR_NUM 0x80 /**< Maximum interrupt number 128 */
+#define MAX_INTR_NUM 0x80 /**< 最大中断数量128 */
/**
- * @brief Structure for NIC MSI-X interrupt info migration
- * @details Contains management message head, func id, interrupt number, MSI-X control register operation and MSI-X control register 0 and 4 values.
+ * @brief 定义了一个用于迁移NIC中断信息的结构体
+ * @details 该结构体包含了管理消息头部、函数ID、中断号、MSI-X控制寄存器操作以及MSI-X控制寄存器0和4的值。
*/
struct mig_nic_msix_info_rw {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 intr_num; /**< Interrupt number */
- u8 msi_ctl_csr_op; /* MSI-X control register operation
- * Identifies the type of MSI-X control register operation
- */
- u32 msix_ctrl0[MAX_INTR_NUM]; /* MSI-X control register 0 values
- * One value per interrupt
- */
- u32 msix_ctrl4[MAX_INTR_NUM]; /* MSI-X control register 1 values
- * One value per interrupt
- */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 intr_num; /**< 中断号 */
+ u8 msi_ctl_csr_op; /**< MSI-X控制寄存器操作,用于标识对MSI-X控制寄存器的操作类型 */
+ u32 msix_ctrl0
+ [MAX_INTR_NUM]; /**< MSI-X控制寄存器0的值,每个中断对应一个值 */
+ u32 msix_ctrl4
+ [MAX_INTR_NUM]; /**< MSI-X控制寄存器1的值,每个中断对应一个值 */
};
-#define MIG_FUNC_TBL_SIZE 0x50 /**< TBL size = (64 + 16(rsvd)) */
-#define MIG_VAT_TBL_SIZE 0x10 /**< vat size: 0x10 */
+#define MIG_FUNC_TBL_SIZE 0x50 /**< TBL size = (64 + 16(rsvd)) */
+#define MIG_VAT_TBL_SIZE 0x10 /**< vat size: 0x10 */
/**
- * @brief Structure for storing NIC function and virtual address table information
- * @details Contains management message head, func id, opcode, function usage flag, function table and virtual address table.
+ * @brief 定义了一个结构体,用于存储网络接口卡的功能和虚拟地址表信息
+ * @details 该结构体包含了网络接口卡的管理消息头部、功能ID、操作码、功能使用标志、功能表和虚拟地址表等信息。
*/
struct mig_nic_func_vat_tbl {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 opcode; /**< Operation code */
- u8 func_used; /**< Function usage flag */
- u8 func_tbl[MIG_FUNC_TBL_SIZE]; /**< func table */
- u8 vat_tbl[MIG_VAT_TBL_SIZE]; /**< Virtual address table */
- u8 rsvd[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 opcode; /**< 操作码 */
+ u8 func_used; /**< function使用标志 */
+ u8 func_tbl[MIG_FUNC_TBL_SIZE]; /**< func表 */
+ u8 vat_tbl[MIG_VAT_TBL_SIZE]; /**< 虚拟地址表 */
+ u8 rsvd[4]; /**< 保留域段 */
};
#define MIG_FAST_MSG_VF_PAGE_NUM 4
/**
- * @brief Structure for storing NIC VF information
- * @details Contains VF information such as number of send queues, receive queues, command queues, etc.
+ * @brief 定义了一个结构体,用于存储网络接口的虚拟功能信息
+ * @details 结构体中包含了网络接口的虚拟功能信息,如发送队列数量、接收队列数量、命令队列数量等。
*/
struct mig_nic_vf_info {
- u8 sq_num; /**< Number of send queues */
- u8 rq_num; /**< Number of receive queues */
- u8 cmdq_num; /**< Number of command queues */
- u8 cmdq_depth; /**< Command queue depth */
- u32 rq_depth; /**< Receive queue depth */
- u32 sq_depth; /**< Send queue depth */
- u32 sq_ci_base_addr_h; /**< High bits of send queue completion pointer base address */
- u32 sq_ci_base_addr_l; /**< Low bits of send queue completion pointer base address */
- u16 bat_size; /**< Batch size */
- u8 valid; /**< Valid flag */
+ u8 sq_num; /**< 发送队列数量 */
+ u8 rq_num; /**< 接收队列数量 */
+ u8 cmdq_num; /**< 命令队列数量 */
+ u8 cmdq_depth; /**< 命令队列深度 */
+ u32 rq_depth; /**< 接收队列深度 */
+ u32 sq_depth; /**< 发送队列深度 */
+ u32 sq_ci_base_addr_h; /**< 发送队列完成指针基地址的高位 */
+ u32 sq_ci_base_addr_l; /**< 发送队列完成指针基地址的低位 */
+ u16 bat_size; /**< 批处理大小 */
+ u8 valid; /**< 有效标志 */
u8 fast_msg_en;
u8 fast_msg_page_num;
u8 rsvd[3];
@@ -1486,237 +1460,233 @@ struct mig_nic_vf_info {
};
/**
- * @brief Structure for storing NIC function configuration information
- * @details Contains NIC management message head, func id, reserved field and VF information.
+ * @brief 定义了一个结构体,用于存储网卡功能配置信息
+ * @details 该结构体包含了网卡管理消息头部信息、功能ID、保留字段和虚拟功能信息。
*/
struct mig_nic_func_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u16 rsvd; /**< Reserved field */
- struct mig_nic_vf_info vf_info; /**< VF information */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u16 rsvd; /**< 保留域段 */
+ struct mig_nic_vf_info vf_info; /**< VF信息 */
};
/**
- * @brief Structure for checking if mailbox is empty
- * @details Used to check if the NIC mailbox is empty for subsequent operations.
+ * @brief 此结构体用于检查消息盒是否为空
+ * @details 此结构体主要用于检查网络接口卡的消息盒是否为空,以便于进行后续的操作。
*/
struct mig_nic_chk_mbx_empty {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 bme; /**< Flag indicating if mailbox is empty */
- u8 is_func_used; /**< Flag indicating if func is in use */
- u8 cmdq_num; /**< get cmdq num for stop cmdq */
- u8 rsvd[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 bme; /**< 表示消息盒是否为空的标志 */
+ u8 is_func_used; /**< 表示func是否被使用的标志 */
+ u8 cmdq_num; /**< get cmdq num for stop cmdq */
+ u8 rsvd[3]; /**< 保留域段 */
};
/**
- * @brief Structure for representing NIC vport state for migration
- * @details Contains vport state information such as management message head, func id, state, etc.
+ * @brief 定义了一个结构体,用于表示迁移网络接口虚拟端口的状态
+ * @details 该结构体包含了网络接口虚拟端口的状态信息,如管理消息头部、功能ID、状态等。
*/
struct mig_nic_vport_state {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u16 rsvd1; /**< Reserved field */
- u8 state; /**< 0--disable, 1--enable */
- u8 rsvd2[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u16 rsvd1; /**< 保留域段 */
+ u8 state; /**< 0--disable, 1--enable */
+ u8 rsvd2[3]; /**< 保留域段 */
};
-#define SQ_CI_ATTR_SIZE 0x14 /**< SQ CI address length */
-#define SQ_CI_INDIR_TBL_SIZE 0x20 /**< SQ CI indirect table size */
-#define MAX_CI_TBL_NUM 0x20 /**< mailbox max 2kb, one sq ci(attr + tbl) 52B, 32 *52 = 1664B < 2kb */
+#define SQ_CI_ATTR_SIZE 0x14 /**< SQ CI地址长度 */
+#define SQ_CI_INDIR_TBL_SIZE 0x20 /**< SQ CI间接表大小 */
+#define MAX_CI_TBL_NUM \
+ 0x20 /**< mailbox max 2kb, one sq ci(attr + tbl) 52B, 32 *52 = 1664B < 2kb */
/**
- * @brief Structure for storing single NIC send queue control information
- * @details Contains sq_ci_tbl and sq_ci_attr for storing send queue control table and attributes respectively.
+ * @brief 定义一个结构体,用于存储单个NIC的发送队列控制信息
+ * @details 该结构体包含两个成员,sq_ci_tbl和sq_ci_attr,分别用于存储发送队列控制表和发送队列控制属性。
*/
struct mig_nic_single_sq_ci {
- u8 sq_ci_tbl[SQ_CI_INDIR_TBL_SIZE]; /**< sq ci table */
- u8 sq_ci_attr[SQ_CI_ATTR_SIZE]; /**< sq ci address table */
+ u8 sq_ci_tbl[SQ_CI_INDIR_TBL_SIZE]; /**< sq ci表 */
+ u8 sq_ci_attr[SQ_CI_ATTR_SIZE]; /**< sq ci地址表 */
};
/**
- * @brief NIC structure for storing network interface information
- * @details Contains NIC basic information and service queue information
+ * @brief 网络接口结构体,用于存储网络接口的信息
+ * @details 该结构体包含了网络接口的基本信息和服务队列的信息
*/
struct mig_nic_sq_ci {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< Function ID for identifying NIC function */
- u8 opcode; /**< Operation code for identifying NIC operation type */
- u8 curr_sq_id; /* Current service queue ID
- * Identifies the service queue currently in use
- */
- u8 round_queue_num; /* Number of round queues
- * Identifies the number of round queues for the NIC
- */
- u8 rsvd[3]; /**< Reserved field */
- struct mig_nic_single_sq_ci sq_ci[MAX_CI_TBL_NUM]; /**< Single sq ci information */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< 功能ID,用于标识网络接口的功能 */
+ u8 opcode; /**< 操作码,用于标识网络接口的操作类型 */
+ u8 curr_sq_id; /**< 当前的服务队列ID,用于标识当前正在使用的服务队列 */
+ u8 round_queue_num; /**< 循环队列数量,用于标识网络接口的循环队列数 */
+ u8 rsvd[3]; /**< 保留域段 */
+ struct mig_nic_single_sq_ci sq_ci[MAX_CI_TBL_NUM]; /**< 单个sq的ci信息 */
};
-#define RSS_INDIR_TBL_SIZE 0x200 /**< RSS indirect table size */
-#define RSS_KEY_SIZE 0x28 /**< RSS key size */
+#define RSS_INDIR_TBL_SIZE 0x200 /**< rss间接表的大小 */
+#define RSS_KEY_SIZE 0x28 /**< rss key的大小 */
/**
- * @brief Structure for NIC Receive Side Scaling (RSS)
- * @details Contains RSS related parameters for configuring NIC RSS functionality.
+ * @brief 定义了一个用于网络接口的接收方缩放(RSS)的结构体
+ * @details 该结构体包含了RSS相关的各种参数,用于配置网络接口的RSS功能。
*/
struct mig_nic_rss_tbl {
- u8 rss_enable; /**< RSS enable/disable flag */
- u8 rss_hash_engine; /**< RSS hash engine type */
- u16 rsvd; /**< Reserved field */
- u32 rss_ctx; /**< RSS context */
- u8 rss_indri_tbl[RSS_INDIR_TBL_SIZE]; /**< RSS indirect table */
- u8 rss_key[RSS_KEY_SIZE]; /**< RSS key */
+ u8 rss_enable; /**< 启用或禁用RSS的标志 */
+ u8 rss_hash_engine; /**< RSS哈希引擎的类型 */
+ u16 rsvd; /**< 保留域段 */
+ u32 rss_ctx; /**< RSS上下文 */
+ u8 rss_indri_tbl[RSS_INDIR_TBL_SIZE]; /**< RSS间接表 */
+ u8 rss_key[RSS_KEY_SIZE]; /**< RSS密钥 */
};
/**
- * @brief Structure for NIC configuration with management message head, func id, opcode, reserved fields and RSS table
- * @details Used for NIC configuration including management message head, func id, opcode, reserved fields and RSS table.
+ * @brief 定义了一个用于网络接口配置的结构体,包含了管理消息头、功能ID、操作码、预留字段和RSS表的信息
+ * @details 该结构体用于网络接口的配置,包含了管理消息头、功能ID、操作码、预留字段和RSS表的信息,可以用于实现网络接口的各种配置操作。
*/
struct mig_nic_cfg_rss_tbl {
- struct mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 opcode; /**< Operation code */
- u8 rsvd; /**< Reserved field */
- struct mig_nic_rss_tbl rss_tbl; /**< RSS table */
+ struct mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 opcode; /**< 操作码 */
+ u8 rsvd; /**< 保留域段 */
+ struct mig_nic_rss_tbl rss_tbl; /**< rss表 */
};
-#define MAX_CMDQ_NUM 0x4 /**< Maximum cmdq number */
-#define ENHANCED_CMDQ_CTX_SIZE 0x30 /**< Enhanced cmdq context size is 48 */
+#define MAX_CMDQ_NUM 0x4 /**< 最大cmdq数量 */
+#define ENHANCED_CMDQ_CTX_SIZE 0x30 /**< 定义增强型cmdq context size为48 */
/**
- * @brief Structure for storing NIC temporary configuration command queue context
- * @details Contains management message head, func id, command queue number, reserved fields and command queue context
+ * @brief 定义了一个结构体,用于存储网卡临时配置命令队列的上下文信息
+ * @details 该结构体包含了管理消息头部、函数ID、命令队列数量、保留字段和命令队列上下文等信息
*/
struct mig_nic_tmp_cfg_cmdq_ctx {
- struct mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 cmdq_num; /**< cmdq number */
- u8 rsvd; /**< Reserved field */
- u8 cmdq_ctx[MAX_CMDQ_NUM * ENHANCED_CMDQ_CTX_SIZE]; /**< cmdq context */
+ struct mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 cmdq_num; /**< cmdq数量 */
+ u8 rsvd; /**< 保留域段 */
+ u8 cmdq_ctx[MAX_CMDQ_NUM * ENHANCED_CMDQ_CTX_SIZE]; /**< cmdq上下文 */
};
/**
- * @brief NIC migration queue stop info structure
- * @details Used to describe NIC migration queue stop related information.
+ * @brief 网卡迁移队列停止信息结构体
+ * @details 该结构体用于描述网卡迁移队列停止的相关信息。
*/
struct nic_mig_sq_stop {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 is_stop; /**< Whether to stop */
- u8 sq_num; /**< sq queue number */
- u8 rsvd[4]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 is_stop; /**< 是否停止 */
+ u8 sq_num; /**< sq队列号 */
+ u8 rsvd[4]; /**< 保留域段 */
};
struct mig_nic_fast_msg_addr {
- struct mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 opcode; /**< Operation code */
- u8 page_num; /**< page num */
- u32 rsvd; /**< Reserved field */
- u64 page_addr[MIG_FAST_MSG_VF_PAGE_NUM]; /**< page addr */
+ struct mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 opcode; /**< 操作码 */
+ u8 page_num; /**< page num */
+ u32 rsvd; /**< 保留域段 */
+ u64 page_addr[MIG_FAST_MSG_VF_PAGE_NUM]; /**< page addr */
};
/**
* @brief struct hinic5_cmd_set_pcie_flr_mgmt
- * @details NIC set pcie flr command structure
+ * @details nic 设置pcie flr命令结构体
*/
struct hinic5_cmd_set_pcie_flr_mgmt {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u16 rsvd1; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u16 rsvd1; /**< 保留域段 */
};
struct hinic5_cmd_lro_cfg {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func id */
- u8 data; /**< data to be set or get */
- u8 data_type; /**< data type: See lro_cfg_operate_type enum definition */
- u8 opcode; /**< 0: get, 1: set */
- u8 rsvd1[3]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func id */
+ u8 data; /**< data to be set or get */
+ u8 data_type; /**< data type: 参考 lro_cfg_operate_type 枚举定义 */
+ u8 opcode; /**< 0: get, 1: set */
+ u8 rsvd1[3]; /**< 保留域段 */
};
-#define NIC_DCB_UP_MAX 0x8 /**< Maximum user priority (UP) for NIC DCB */
+#define NIC_DCB_UP_MAX \
+ 0x8 /**< 定义网络接口控制数据包(NIC DCB)的最大用户优先级(UP) */
/**
* @brief hinic5_dcb_state
- * @details nic dcb state command structure
+ * @details nic dcb state命令结构体
*/
struct hinic5_dcb_state {
- u8 dcb_on; /**< dcb on or off */
- u8 default_cos; /**< default cos */
- u8 trust; /**< trust state */
- u8 rsvd1; /**< Reserved field */
- u8 pcp2cos[NIC_DCB_UP_MAX]; /**< pcp to cos */
- u8 dscp2cos[64]; /**< dscp to cos */
- u32 rsvd2[7]; /**< Reserved field */
+ u8 dcb_on; /**< dcb on or off */
+ u8 default_cos; /**< default cos */
+ u8 trust; /**< trust state */
+ u8 rsvd1; /**< 保留域段 */
+ u8 pcp2cos[NIC_DCB_UP_MAX]; /**< pcp to cos */
+ u8 dscp2cos[64]; /**< dscp to cos */
+ u32 rsvd2[7]; /**< 保留域段 */
};
/**
* @brief hinic5_cmd_vf_dcb_state
- * @details nic vf dcb state command structure
+ * @details nic vf dcb state命令结构体
*/
struct hinic5_cmd_vf_dcb_state {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- struct hinic5_dcb_state state; /**< dcb state */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ struct hinic5_dcb_state state; /**< dcb state */
};
struct hinic5_cmd_port_info {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
u8 port_id;
- u8 rsvd1[3]; /**< Reserved field */
+ u8 rsvd1[3]; /**< 保留域段 */
u8 port_type;
u8 autoneg_cap;
u8 autoneg_state;
u8 duplex;
u8 speed;
u8 fec;
- u16 rsvd2; /**< Reserved field */
- u32 rsvd3[4]; /**< Reserved field */
+ u16 rsvd2; /**< 保留域段 */
+ u32 rsvd3[4]; /**< 保留域段 */
};
/**
* @brief nic_cmd_bond_active_report_info
- * @details Async message notification structure sent to host after lacp negotiation result update
+ * @details lacp协商结果更新之后向主机侧发送异步消息通知结构体
*/
struct nic_cmd_bond_active_report_info {
- struct mgmt_msg_head head; /**< Command message head */
+ struct mgmt_msg_head head; /**< 命令字消息头 */
u32 bond_id;
- u32 bon_mmi_status; /**< Bond sub-device link status */
- u32 active_bitmap; /**< Bond sub-device slave port status */
- u8 rsvd[16]; /**< Reserved field */
+ u32 bon_mmi_status; /**< 该bond子设备的链路状态 */
+ u32 active_bitmap; /**< 该bond子设备的slave port状态 */
+ u8 rsvd[16]; /**< 保留域段 */
};
/**
* @brief nic_cmd_tx_pause_notice
- * @details pfc/pause storm tx exception report
+ * @details pfc/pause风暴tx异常上报
*/
struct nic_cmd_tx_pause_notice {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 tx_pause_except; /**< 1: exception, 0: normal */
- u32 except_level; /**< Exception level */
- u32 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 tx_pause_except; /**< 1: 异常,0: 正常 */
+ u32 except_level; /**< 异常等级 */
+ u32 rsvd; /**< 保留域段 */
};
#pragma pack(4)
typedef struct fault_msg_s {
- struct mgmt_msg_head msg_head; /**< Command message head */
- u8 num; /**< Number of custom packets to send */
- u8 rsvd[3]; /**< Reserved field */
+ struct mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u8 num; /**< 发送的自定义报文数量 */
+ u8 rsvd[3]; /**< 保留域段 */
u16 real_size;
- u8 mode; /**< 0: read, 1: write */
- u8 type; /**< 0: send notification later, 1: send notification immediately */
- u8 data[0]; /**< Size specified by real_size */
+ u8 mode; /**< 0: read, 1: write */
+ u8 type; /**< 0:不立即发送通知, 1: 立即发送通知 */
+ u8 data[0]; /**< 大小由real_size指定 */
} fault_msg_t;
#pragma pack()
-#define TCAM_FLOW_KEY_SIZE 44 /**< TCAM key size is 44B */
+#define TCAM_FLOW_KEY_SIZE 44 /**< 定义tcam key的大小为44B */
typedef struct {
- u32 qid : 10; /* If flag==1, fdir_qid represents group id;
- * If flag==0, fdir_qid represents qid
- */
+ u32 qid : 10; /**< 如果flag==1,则fdir_qid表示group id;如果flag==0则fdir_qid表示qid */
u32 flag : 1;
- u32 rsvd : 21; /**< Reserved field */
+ u32 rsvd : 21; /**< 保留域段 */
} qid_htn_s;
typedef union {
@@ -1725,148 +1695,145 @@ typedef union {
} qid_u;
/**
- * @brief Structure for storing TCAM lookup result
- * @details Contains Flow Director compound destination information (qid/group + flag) and reserved field.
+ * @brief 定义一个结构体,用于存储TCAM查找的结果
+ * @details 包含Flow Director的复合目标信息(qid/group + flag)和保留字段。
*/
struct tcam_result {
qid_u fdir_info;
- u32 rsvd; /**< Reserved field */
+ u32 rsvd; /**< 保留域段 */
};
/**
- * @brief Structure for storing TCAM flow key x and y values
- * @details TCAM flow key is a data structure for flow table lookup, where x and y values are the two components of the flow key.
+ * @brief 定义一个结构体,用于存储TCAM流键的x和y值
+ * @details 结构体用于存储TCAM流键的x和y值,TCAM流键是一种用于流表查找的数据结构,其中x和y值是流键的两个组成部分。
*/
struct tcam_key_x_y {
- u8 x[TCAM_FLOW_KEY_SIZE]; /**< x value, size is TCAM_FLOW_KEY_SIZE */
- u8 y[TCAM_FLOW_KEY_SIZE]; /**< y value, size is TCAM_FLOW_KEY_SIZE */
+ u8 x[TCAM_FLOW_KEY_SIZE]; /**< x值,大小为TCAM_FLOW_KEY_SIZE */
+ u8 y[TCAM_FLOW_KEY_SIZE]; /**< y值,大小为TCAM_FLOW_KEY_SIZE */
};
/**
- * @brief Structure for storing NIC TCAM configuration rules
- * @details Contains TCAM configuration rule index, data and key for storing and managing TCAM configuration rules in NIC.
+ * @brief 用于存储网络接口控制器(NIC)的TCAM配置规则
+ * @details 包含了TCAM配置规则的索引、数据和键,用于在NIC中存储和管理TCAM配置规则。
*/
struct nic_tcam_cfg_rule {
- u32 index; /**< Rule index */
- struct tcam_result data; /**< Rule data */
- struct tcam_key_x_y key; /**< Rule key */
+ u32 index; /**< 规则的索引 */
+ struct tcam_result data; /**< 规则的数据 */
+ struct tcam_key_x_y key; /**< 规则的键 */
};
/**
- * @brief TCAM configuration rule
- * @details Contains TCAM rule configuration information such as rule key, mask, action, etc.
+ * @brief TCAM配置规则
+ * @details 包含了TCAM规则的各种配置信息,如规则的键值、掩码、动作等。
*/
struct nic_cmd_fdir_add_rule {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< Func ID */
- u8 type; /**< Rule type */
- u8 usrdata; /**< User data */
- struct nic_tcam_cfg_rule rule; /**< Configuration table */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< Func ID */
+ u8 type; /**< 规则类型 */
+ u8 usrdata; /**< 用户数据 */
+ struct nic_tcam_cfg_rule rule; /**< 配置表 */
};
/**
- * @brief Structure for NIC command filter get rule
- * @details Used to store NIC fdir get rule related information.
+ * @brief 网络接口命令过滤器获取规则的结构体
+ * @details 该结构体用于存储网络接口命令过滤器获取规则的相关信息。
*/
struct nic_cmd_fdir_get_rule {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u32 index; /**< Index field */
- u8 valid; /**< Valid field */
- u8 type; /**< Type field */
- u16 rsvd; /**< Reserved field */
- struct tcam_key_x_y key; /**< TCAM key field */
- struct tcam_result data; /**< TCAM result field */
- u64 packet_count; /**< Packet count field */
- u64 byte_count; /**< Byte count field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u32 index; /**< 索引字段 */
+ u8 valid; /**< 有效性字段 */
+ u8 type; /**< 类型字段 */
+ u16 rsvd; /**< 保留域段 */
+ struct tcam_key_x_y key; /**< TCAM键字段 */
+ struct tcam_result data; /**< TCAM结果字段 */
+ u64 packet_count; /**< 包计数字段 */
+ u64 byte_count; /**< 字节计数字段 */
};
-#define NIC_TCAM_BLOCK_LARGE_NUM 256 /**< Maximum TCAM BLOCK number is 256 */
-#define NIC_TCAM_BLOCK_LARGE_SIZE 16 /**< Maximum block size is 16 */
-#define TCAM_RULE_FDIR_TYPE 0 /**< TCAM rule type, FDIR type value is 0 */
-#define TCAM_RULE_PPA_TYPE 1 /**< TCAM rule type, PPA type value is 1 */
+#define NIC_TCAM_BLOCK_LARGE_NUM 256 /**< 定义TCAM BLOCK最大值为256 */
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16 /**< 定义一个block最大size为16 */
+#define TCAM_RULE_FDIR_TYPE 0 /**< 定义TCAM规则的类型,FDIR类型对应值为0 */
+#define TCAM_RULE_PPA_TYPE 1 /**< 定义TCAM规则的类型,PPA类型对应值为1 */
/**
- * @brief Structure for getting TCAM block rules
- * @details Used to get TCAM block rules, including TCAM block type, TCAM table type, TCAM block index, valid array, TCAM key array and TCAM result array.
+ * @brief 获取TCAM块规则的结构体
+ * @details 该结构体用于获取TCAM块规则,包括TCAM块类型、TCAM表类型、TCAM块索引、有效性数组、TCAM键数组和TCAM结果数组。
*/
struct nic_cmd_fdir_get_block_rules {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 tcam_block_type; /**< TCAM block type, currently only NIC_TCAM_BLOCK_TYPE_LARGE */
- u8 tcam_table_type; /* TCAM rule type
- * TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
- */
- u16 tcam_block_index; /**< TCAM block index */
- u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< Valid array */
- struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< TCAM key array */
- struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< TCAM result array */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 tcam_block_type; /**< TCAM块类型,目前仅有 NIC_TCAM_BLOCK_TYPE_LARGE */
+ u8 tcam_table_type; /**< TCAM规则类型,TCAM_RULE_PPA_TYPE 或 TCAM_RULE_FDIR_TYPE */
+ u16 tcam_block_index; /**< TCAM块索引 */
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< 有效性数组 */
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< TCAM键数组 */
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE]; /**< TCAM结果数组 */
};
struct hinic5_rate_xir_xbs {
- u32 cir; /**< unit: kbps */
- u32 pir; /**< unit: kbps */
- u32 cbs; /**< unit: Byte */
- u32 pbs; /**< unit: Byte */
+ u32 cir; /**< unit: kbps */
+ u32 pir; /**< unit: kbps */
+ u32 cbs; /**< unit: Byte */
+ u32 pbs; /**< unit: Byte */
};
/**
- * @brief NIC tx MQM rate configuration
- * @details Used to set and get func MQM rate limit parameters and set func mapping table.
+ * @brief nic tx MQM速率配置
+ * @details 用于设置和获取func的MQM限速参数以及设置fun映射表。
*/
struct hinic5_cmd_tx_limit_rate {
- struct hinic5_mgmt_msg_head msg_head; /**< Command message head */
- u16 func_id; /**< func ID */
- u8 op_code; /**< Operation type: 0 - default; 1 - get; 2 - set; 3 - map */
- u8 vnicgrp_flag; /**< vnicgrp operation flag: 0 - vnic; 1 - vnic group */
- u32 vnicgrp_id; /**< vnic group ID */
- u32 vnic_id; /**< vnic ID */
- u8 limit_type; /**< Rate limit type: 0 - pps; 1 - bps */
- u8 rsvd1[3]; /**< Reserved field */
- struct hinic5_rate_xir_xbs rate_para; /**< rate_cfg */
- u32 rsvd2[64]; /**< Reserved field */
+ struct hinic5_mgmt_msg_head msg_head; /**< 命令字消息头 */
+ u16 func_id; /**< func ID */
+ u8 op_code; /**< 操作类型: 0 - 默认; 1 - get; 2 - set; 3 - map */
+ u8 vnicgrp_flag; /**< vnicgrp操作标识:0 - vnic;1 - vnic group */
+ u32 vnicgrp_id; /**< vnic group ID */
+ u32 vnic_id; /**< vnic ID */
+ u8 limit_type; /**< 限速类型:0 - pps; 1-bps */
+ u8 rsvd1[3]; /**< 保留域段 */
+ struct hinic5_rate_xir_xbs rate_para; /**< rate_cfg */
+ u32 rsvd2[64]; /**< 保留域段 */
};
-#define HINIC5_TX_SET_PROMISC_SKIP 0 /**< Set promiscuous mode for unknown unicast packets */
-#define HINIC5_TX_GET_PROMISC_SKIP 1 /**< Get promiscuous mode for unknown unicast packets */
+#define HINIC5_TX_SET_PROMISC_SKIP 0 /**< 设置混杂接收未知单播报文 */
+#define HINIC5_TX_GET_PROMISC_SKIP 1 /**< 读取混杂接收未知单播报文 */
/**
- * @brief Set promiscuous mode for unknown unicast packets
- * @details This structure is used to enable/disable forwarding unknown unicast packets to promiscuous PF
+ * @brief 设置混杂是否接收未知单播报文
+ * @details 该结构体用于开关是否上送单播未知报文到开混杂PF,包括
*/
struct hinic5_tx_promisc_cfg {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u8 port_id; /**< Network port id */
- u8 promisc_skip_en; /**< 0: disable forwarding 1: enable forwarding */
- u8 opcode; /**< 0: set 1: get */
- u8 rsvd; /**< Reserved field */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u8 port_id; /**< 网络侧端口id */
+ u8 promisc_skip_en; /**< 0:关闭上送 1:打开上送 */
+ u8 opcode; /**< 0:设置 1:读取 */
+ u8 rsvd; /**< 保留域段 */
};
#define HINIC5_ARP_PKT_MAX_LEN 512
/**
- * @brief Structure for passing ARP packet info to MPU
- * @details Used to pass ARP or ND packets that need to be sent by MPU
+ * @brief 向MPU传递ARP相关报文内容结构体
+ * @details 该结构体用于向MPU传递需要代发的ARP或ND报文
*/
struct hinic5_arp_pkt_info {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
- u16 func_id; /**< func ID */
- u16 pkt_length; /**< Packet length */
- u16 origin_queue_id; /**< Queue id where driver sent the packet */
- u8 rsvd[2]; /**< Reserved field */
- u32 rsvd1[4]; /**< Reserved field */
- u8 pkt_buf[HINIC5_ARP_PKT_MAX_LEN]; /**< Packet buffer */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ u16 func_id; /**< func ID */
+ u16 pkt_length; /**< 报文长度 */
+ u16 origin_queue_id; /**< 驱动发送报文的队列id */
+ u8 rsvd[2]; /**< 保留域段 */
+ u32 rsvd1[4]; /**< 保留域段 */
+ u8 pkt_buf[HINIC5_ARP_PKT_MAX_LEN]; /**< 报文缓冲区 */
};
/**
- * @brief Structure for passing Bond configuration to MPU
- * @details Used to pass offload Bond configuration to MPU
+ * @brief 向MPU传递Bond配置信息结构体
+ * @details 该结构体用于向MPU传递卸载Bond配置信息
*/
struct hinic5_cmd_cfg_bond {
- struct hinic5_mgmt_msg_head head; /**< Command message head */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
u16 func_id;
- u8 opcode; /**< operation code: 1 set arp status, 0 get arp status */
- u8 arp_en; /**< ARP dual-send enable */
- u32 rsvd; /**< Reserved field */
+ u8 opcode; /**< operation code: 1 set arp status, 0 get arp status */
+ u8 arp_en; /**< ARP双发使能 */
+ u32 rsvd; /**< 保留域段 */
};
#endif /* HINIC5_NIC_CMD_STRUCTS_H */
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs_extend.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs_extend.h
index bc6aa5006..184ba40f2 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs_extend.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_cmd_structs_extend.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_mpu_cmd_structs_extend.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef HINIC5_NIC_CMD_STRUCTS_EXTEND_H
#define HINIC5_NIC_CMD_STRUCTS_EXTEND_H
@@ -21,8 +11,8 @@
#ifndef FUNC_MAX_CLEAR_QP_NUM
#define FUNC_MAX_CLEAR_QP_NUM 256
/**
- * @brief Define a structure for clearing qp resources by queue level
- * @details qp_num indicates the number of queues to clear, qp indicates the local_id of the queues to clear under func
+ * @brief 定义了一个按队列级别清理qp res结构体
+ * @details qp_num表示要清理的队列个数,qp表示要清理队列的在func下的local_id
*/
struct hinic5_cmd_clear_assign_qp_res {
struct hinic5_mgmt_msg_head msg_head;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_tc_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_tc_cmd_defs.h
index 220a65175..914290ed8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_tc_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_mpu_tc_cmd_defs.h
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_mpu_tc_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+ * Copyright (c) Huawei Technologies Co. Ltd. 2024-2024. All rights reserved.
*/
#ifndef NIC_MPU_TC_CMD_DEFS_H
@@ -34,7 +28,7 @@ enum tcam_clock_gating_status {
TCAM_CLOCK_GATING_ENABLED
};
-/* Action address in struct hinic5_tc_default_action_info */
+/* struct hinic5_tc_default_action_info中action地址 */
#define ACTION_REG_TX1_1 0
#define ACTION_REG_TX1_2 1
#define ACTION_REG_TX1_3 2
@@ -45,7 +39,7 @@ enum tcam_clock_gating_status {
#define ACTION_REG_RX2 7
#define ACTION_REG_RX3 8
-/* Default ACTION address in corresponding register */
+/* 对应寄存器中默认ACTION地址 */
enum hinic5_tc_default_action_addr {
HINIC5_TC_DEFAULT_ACTION_ADDR_TX1 = 0, /**< tx default action1 */
HINIC5_TC_DEFAULT_ACTION_ADDR_TX2, /**< tx default action2 */
@@ -66,13 +60,9 @@ enum hinic5_tc_cfg_rule_ops {
HINIC5_TC_CFG_RULE_OPS_ADD
};
-enum pfe_cnt_ops {
- PFE_CNT_OPS_GET,
- PFE_CNT_OPS_RESET,
- PFE_CNT_OPS_MAX
-};
+enum pfe_cnt_ops { PFE_CNT_OPS_GET, PFE_CNT_OPS_RESET, PFE_CNT_OPS_MAX };
-/* TCAM 3 frequency modes: 1:500MHz, 2:250MHz, 3:125MHz */
+/* TCAM 3种频率:1:500MHz, 2:250MHz, 3:125MHz */
#define MAX_PFE_TCAM_FREQ_MODE_NUM 3
enum pfe_tcam_freq_ops {
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd.h
index 49b146444..fc9528912 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_npu_cmd.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
* File Name : nic_npu_cmd.h
* Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Created : 2019/4/25
+ * Last Modified :
* Description : NIC Commands between Driver and NPU
+ * Function List :
*/
#ifndef NIC_NPU_CMD_H
@@ -13,68 +13,57 @@
/**
* @enum hinic5_ucode_cmd
- * @brief Defines various commands related to NIC ucode
+ * @brief 定义了各种与NIC ucode相关的命令
*
- * @details This structure defines a series of commands related to NIC ucode, which are used to control NIC ucode behavior.
+ * @details 这个结构体定义了一系列与NIC ucode相关的命令,这些命令用于控制NIC ucode的行为。
*/
enum hinic5_ucode_cmd {
- HINIC5_UCODE_CMD_MODIFY_QUEUE_CTX = 0, /* Modify queue context.
- * @see > hinic5_sq_ctxt_block
- */
- HINIC5_UCODE_CMD_CLEAN_QUEUE_CONTEXT = 1, /* Clean queue context.
- * @see > hinic5_clean_queue_ctxt
- */
- HINIC5_UCODE_CMD_ARM_SQ = 2, /* Unused */
- HINIC5_UCODE_CMD_ARM_RQ = 3, /* Unused */
- HINIC5_UCODE_CMD_SET_RSS_INDIR_TABLE = 4, /* Set RSS indirect table.
- * @see > nic_rss_indirect_tbl
- */
- HINIC5_UCODE_CMD_SET_RSS_CONTEXT_TABLE = 5, /* Set RSS context table.
- * @see > nic_rss_context_tbl
- */
- HINIC5_UCODE_CMD_GET_RSS_INDIR_TABLE = 6, /* Get RSS indirect table.
- * @see > l2nic_cmdq_rss_indir_get
- */
- HINIC5_UCODE_CMD_GET_RSS_CONTEXT_TABLE = 7, /* Unused */
- HINIC5_UCODE_CMD_SET_IQ_ENABLE = 8, /* Unused */
- HINIC5_UCODE_CMD_SET_RQ_FLUSH = 10, /* Set RQ flush.
- * @see > hinic5_cmd_set_rq_flush
- */
- HINIC5_UCODE_CMD_MODIFY_VLAN_CTX = 11, /* Get rxq information.
- * @see > nic_vlan_ctx
- */
- HINIC5_UCODE_CMD_PPA_HASH_TABLE = 12, /* Unused*/
- HINIC5_UCODE_CMD_RXQ_INFO_GET = 13, /* Get rxq information.
- * @see > hinic5_rxq_hw, < rxq_check_info
- */
- HINIC5_UCODE_MIG_CFG_Q_CTX = 16, /* Hot migration operation context table.
- * @see > l2nic_migrate_op_ctx
- */
- HINIC5_UCODE_MIG_CHK_SQ_STOP = 17, /* Unused */
- HINIC5_UCODE_MIG_CHK_RQ_STOP = 18, /* Hot migration check rq start/stop status.
- * @see > l2nic_cmdq_migrate_check_rq_stop
- */
- HINIC5_UCODE_MIG_CHK_CMDQ_STOP = 19, /* Hot migration check cmdq start/stop status.
- * @see > l2nic_cmdq_migrate_check_cmdq_stop
- */
- HINIC5_UCODE_MIG_CFG_BAT_INFO = 20, /* Hot migration read/write bat table.
- * @see > l2nic_migrate_cfg_bat
- */
- HINIC5_UCODE_MIG_COMPENSATE_INTR = 21, /* Hot migration interrupt compensation.
- * @see > l2nic_cmdq_migrate_compensate_intr
- */
+ HINIC5_UCODE_CMD_MODIFY_QUEUE_CTX =
+ 0, /**< 修改队列上下文。@see > hinic5_sq_ctxt_block */
+ HINIC5_UCODE_CMD_CLEAN_QUEUE_CONTEXT =
+ 1, /**< 清理队列上下文。@see > hinic5_clean_queue_ctxt */
+ HINIC5_UCODE_CMD_ARM_SQ = 2, /**< 未使用 */
+ HINIC5_UCODE_CMD_ARM_RQ = 3, /**< 未使用 */
+ HINIC5_UCODE_CMD_SET_RSS_INDIR_TABLE =
+ 4, /**< 设置RSS间接表。@see > nic_rss_indirect_tbl */
+ HINIC5_UCODE_CMD_SET_RSS_CONTEXT_TABLE =
+ 5, /**< 设置RSS上下文表。@see > nic_rss_context_tbl */
+ HINIC5_UCODE_CMD_GET_RSS_INDIR_TABLE =
+ 6, /**< 获取RSS间接表。@see > l2nic_cmdq_rss_indir_get */
+ HINIC5_UCODE_CMD_GET_RSS_CONTEXT_TABLE = 7, /**< 未使用 */
+ HINIC5_UCODE_CMD_SET_IQ_ENABLE = 8, /**< 未使用 */
+ HINIC5_UCODE_CMD_SET_RQ_FLUSH =
+ 10, /**< 设置RQ刷新。@see > hinic5_cmd_set_rq_flush */
+ HINIC5_UCODE_CMD_MODIFY_VLAN_CTX =
+ 11, /**< 获取rxq信息。@see > nic_vlan_ctx */
+ HINIC5_UCODE_CMD_PPA_HASH_TABLE = 12, /**< 未使用*/
+ HINIC5_UCODE_CMD_RXQ_INFO_GET =
+ 13, /**< 获取rxq信息。@see > hinic5_rxq_hw, < rxq_check_info */
+ HINIC5_UCODE_MIG_CFG_Q_CTX =
+ 16, /**< 热迁移操作上下文表。@see > l2nic_migrate_op_ctx */
+ HINIC5_UCODE_MIG_CHK_SQ_STOP = 17, /**< 未使用 */
+ HINIC5_UCODE_MIG_CHK_RQ_STOP =
+ 18, /**< 热迁移检查rq启停状态。@see > l2nic_cmdq_migrate_check_rq_stop */
+ HINIC5_UCODE_MIG_CHK_CMDQ_STOP =
+ 19, /**< 热迁移检查cmdq启停状态。@see > l2nic_cmdq_migrate_check_cmdq_stop */
+ HINIC5_UCODE_MIG_CFG_BAT_INFO =
+ 20, /**< 热迁移读写bat表。@see > l2nic_migrate_cfg_bat */
+ HINIC5_UCODE_MIG_COMPENSATE_INTR =
+ 21, /**< 热迁移中断补偿。@see > l2nic_cmdq_migrate_compensate_intr */
HINIC5_UCODE_MIG_CFG_FAST_MSG = 22,
- HINIC5_UCODE_CMD_CLEAR_VPORT_STATS = 23, /* Get counter statistics.
- * @see > l2nic_cmdq_get_vport_stats
- */
- HINIC5_UCODE_CMD_GET_VPORT_STATS = 24, /* Clear counter statistics.
- * @see > l2nic_cmdq_clear_vport_stats
- */
+ HINIC5_UCODE_CMD_CLEAR_VPORT_STATS =
+ 23, /**< 获取counter统计。@see > l2nic_cmdq_get_vport_stats */
+ HINIC5_UCODE_CMD_GET_VPORT_STATS =
+ 24, /**< 清除counter统计。@see > l2nic_cmdq_clear_vport_stats */
- HINIC5_UCODE_CMD_EXTEND_SECTION1_START = 192, /* NIC CMDQ reserved command start, for computing product line use */
- HINIC5_UCODE_CMD_EXTEND_SECTION1_END = 223, /* NIC CMDQ reserved command end, for computing product line use */
- HINIC5_UCODE_CMD_EXTEND_SECTION2_START = 224, /* NIC CMDQ reserved command start, for storage product line use */
- HINIC5_UCODE_CMD_EXTEND_SECTION2_END = 255, /* NIC CMDQ reserved command end, for storage product line use */
+ HINIC5_UCODE_CMD_EXTEND_SECTION1_START =
+ 192, /** < NIC CMDQ保留命令字起始,计算产品线使用 */
+ HINIC5_UCODE_CMD_EXTEND_SECTION1_END =
+ 223, /** < NIC CMDQ保留命令字结束,计算产品线使用 */
+ HINIC5_UCODE_CMD_EXTEND_SECTION2_START =
+ 224, /** < NIC CMDQ保留命令字起始,数存产品线使用 */
+ HINIC5_UCODE_CMD_EXTEND_SECTION2_END =
+ 255, /** < NIC CMDQ保留命令字结束,数存产品线使用 */
HINIC5_UCODE_CMD_MAX = 255,
};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_tc_rule_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_tc_rule_defs.h
index 6f6169829..3c601647b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_tc_rule_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/nic/nic_tc_rule_defs.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_tc_rule_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef NIC_TC_RULE_DEFS_H
#define NIC_TC_RULE_DEFS_H
@@ -17,34 +7,36 @@
enum hinic5_tc_rule_profile_id_e {
/* vlan, tunnel */
- HINIC5_TC_PROFILE_TUN_ETH = 0, /* eth */
- HINIC5_TC_PROFILE_TUN_ETH_VLAN = 1, /* eth/vlan */
- HINIC5_TC_PROFILE_TUN_ETH_QINQ = 2, /* eth/svlan/cvlan */
+ HINIC5_TC_PROFILE_TUN_ETH = 0, /* eth */
+ HINIC5_TC_PROFILE_TUN_ETH_VLAN = 1, /* eth/vlan */
+ HINIC5_TC_PROFILE_TUN_ETH_QINQ = 2, /* eth/svlan/cvlan */
/* vlan, non-tunnel */
- HINIC5_TC_PROFILE_ETH = 3, /* eth */
- HINIC5_TC_PROFILE_ETH_VLAN = 4, /* eth/vlan */
- HINIC5_TC_PROFILE_ETH_QINQ = 5, /* eth/svlan/cvlan */
+ HINIC5_TC_PROFILE_ETH = 3, /* eth */
+ HINIC5_TC_PROFILE_ETH_VLAN = 4, /* eth/vlan */
+ HINIC5_TC_PROFILE_ETH_QINQ = 5, /* eth/svlan/cvlan */
/* ipv4, tunnel */
- HINIC5_TC_PROFILE_TUN_ETH_IP4 = 6, /* eth/ipv4 */
- HINIC5_TC_PROFILE_TUN_ETH_IP4_TCPORUDP = 7, /* eth/ipv4/udp_or_tcp */
+ HINIC5_TC_PROFILE_TUN_ETH_IP4 = 6, /* eth/ipv4 */
+ HINIC5_TC_PROFILE_TUN_ETH_IP4_TCPORUDP = 7, /* eth/ipv4/udp_or_tcp */
/* ipv4, non-tunnel */
- HINIC5_TC_PROFILE_ETH_IP4 = 8, /* eth/ipv4 */
- HINIC5_TC_PROFILE_ETH_IP4_TCPORUDP = 9, /* eth/ipv4/udp_or_tcp */
+ HINIC5_TC_PROFILE_ETH_IP4 = 8, /* eth/ipv4 */
+ HINIC5_TC_PROFILE_ETH_IP4_TCPORUDP = 9, /* eth/ipv4/udp_or_tcp */
/* ipv6, tunnel */
- HINIC5_TC_PROFILE_TUN_ETH_IP6 = 10, /* eth/ipv6 */
- HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP = 11, /* eth/ipv6/udp_or_tcp */
+ HINIC5_TC_PROFILE_TUN_ETH_IP6 = 10, /* eth/ipv6 */
+ HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP = 11, /* eth/ipv6/udp_or_tcp */
/* ipv6, non-tunnel */
- HINIC5_TC_PROFILE_ETH_IP6 = 12, /* eth/ipv6 */
- HINIC5_TC_PROFILE_ETH_IP6_TCPORUDP = 13, /* eth/ipv6/udp_or_tcp */
-
- /* Tunnel packets that fail vtep dip check */
- HINIC5_TC_PROFILE_OUTER_IP_INNER_IP = 14, /* eth/ipv4(6)/udp/vxlan/eth/ipv4 */
- HINIC5_TC_PROFILE_OUTER_IP_INNER_IP_TCPORUDP = 15, /* eth/ipv4(6)/udp/vxlan/eth/ipv4/udp_or_tcp */
+ HINIC5_TC_PROFILE_ETH_IP6 = 12, /* eth/ipv6 */
+ HINIC5_TC_PROFILE_ETH_IP6_TCPORUDP = 13, /* eth/ipv6/udp_or_tcp */
+
+ /* vtep dip检查不通过的隧道报文 */
+ HINIC5_TC_PROFILE_OUTER_IP_INNER_IP =
+ 14, /* eth/ipv4(6)/udp/vxlan/eth/ipv4 */
+ HINIC5_TC_PROFILE_OUTER_IP_INNER_IP_TCPORUDP =
+ 15, /* eth/ipv4(6)/udp/vxlan/eth/ipv4/udp_or_tcp */
HINIC5_TC_PROFILE_MAX = 16
};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/comm_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/comm_defs.h
index 6c64dcce3..250e36188 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/comm_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/comm_defs.h
@@ -1,54 +1,55 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : drivermpunpusmu COMM defines
- */
+/* *****************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ ******************************************************************************
+ File Name : comm_defs.h
+ Version : Initial Draft
+ Created : 2023/10/8
+ Last Modified :
+ Description : driver/mpu/npu/smu COMM defines
+ Function List :
+***************************************************************************** */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
/* CMDQ MODULE_TYPE */
-typedef enum hinic5_mod_type {
- HINIC5_MOD_DEPRECATED
-} hinic5_mod_type_e;
+typedef enum hinic5_mod_type { HINIC5_MOD_DEPRECATED } hinic5_mod_type_e;
/**
- * @brief Note: The following module macros must use direct numeric definitions, no calculations allowed, otherwise CMDQ REGISTER function will be disabled
+ * @brief 注意:以下模块宏必须使用直接数字定义,不能存在运算, 否则CMDQ REGISTER功能将失效
*/
-#define HINIC5_MOD_COMM 0 /* HW communication module */
-#define HINIC5_MOD_L2NIC 1 // (HINIC5_MOD_COMM + 1) /* L2NIC module */
-#define HINIC5_MOD_ROCE 2 // (HINIC5_MOD_L2NIC + 1)
-#define HINIC5_MOD_PLOG 3 // (HINIC5_MOD_ROCE + 1)
-#define HINIC5_MOD_TOE 4 // (HINIC5_MOD_PLOG + 1)
-#define HINIC5_MOD_UB 5 // (HINIC5_MOD_TOE + 1)
-#define HINIC5_MOD_VROCE 6 // (HINIC5_MOD_UB + 1)
-#define HINIC5_MOD_CFGM 7 // (HINIC5_MOD_VROCE + 1) /* Configuration module */
-#define HINIC5_MOD_HINIC5_CQM 8 // (HINIC5_MOD_CFGM + 1)
-#define HINIC5_MOD_VMSEC 9 // (HINIC5_MOD_HINIC5_CQM + 1)
-#define COMM_MOD_FC 10 // (HINIC5_MOD_VMSEC + 1)
-#define HINIC5_MOD_OVS 11 // (COMM_MOD_FC + 1)
-#define HINIC5_MOD_VBS 12 // (HINIC5_MOD_OVS + 1)
-#define HINIC5_MOD_MIGRATE 13 // (HINIC5_MOD_VBS + 1)
-#define HINIC5_MOD_HILINK 14 // (HINIC5_MOD_MIGRATE + 1)
-#define HINIC5_MOD_CRYPT 15 // (HINIC5_MOD_HILINK + 1) /* secure crypto module */
-#define HINIC5_MOD_VIO 16 // (HINIC5_MOD_CRYPT + 1)
-#define HINIC5_MOD_IMU 17 // (HINIC5_MOD_VIO + 1)
-#define HINIC5_MOD_DFT 18 // (HINIC5_MOD_IMU + 1) /* DFT */
-#define HINIC5_MOD_MACSEC 19 // (HINIC5_MOD_DFT + 1)
-#define HINIC5_MOD_SW_FUNC 20 // (HINIC5_MOD_MACSEC + 1) /* Software module id, for PF/VF and multi-host */
-#define HINIC5_MOD_NST 21 // (HINIC5_MOD_SW_FUNC + 1)
-#define HINIC5_MOD_HTN 22 // (HINIC5_MOD_NST + 1)
-#define HINIC5_MOD_JBOF 23 // (HINIC5_MOD_HTN + 1)
+#define HINIC5_MOD_COMM 0 /* HW communication module */
+#define HINIC5_MOD_L2NIC 1 // (HINIC5_MOD_COMM + 1) /* L2NIC module */
+#define HINIC5_MOD_ROCE 2 // (HINIC5_MOD_L2NIC + 1)
+#define HINIC5_MOD_PLOG 3 // (HINIC5_MOD_ROCE + 1)
+#define HINIC5_MOD_TOE 4 // (HINIC5_MOD_PLOG + 1)
+#define HINIC5_MOD_UB 5 // (HINIC5_MOD_TOE + 1)
+#define HINIC5_MOD_VROCE 6 // (HINIC5_MOD_UB + 1)
+#define HINIC5_MOD_CFGM 7 // (HINIC5_MOD_VROCE + 1) /* Configuration module */
+#define HINIC5_MOD_CQM 8 // (HINIC5_MOD_CFGM + 1)
+#define HINIC5_MOD_VMSEC 9 // (HINIC5_MOD_CQM + 1)
+#define COMM_MOD_FC 10 // (HINIC5_MOD_VMSEC + 1)
+#define HINIC5_MOD_OVS 11 // (COMM_MOD_FC + 1)
+#define HINIC5_MOD_VBS 12 // (HINIC5_MOD_OVS + 1)
+#define HINIC5_MOD_MIGRATE 13 // (HINIC5_MOD_VBS + 1)
+#define HINIC5_MOD_HILINK 14 // (HINIC5_MOD_MIGRATE + 1)
+#define HINIC5_MOD_CRYPT \
+ 15 // (HINIC5_MOD_HILINK + 1) /* secure crypto module */
+#define HINIC5_MOD_VIO 16 // (HINIC5_MOD_CRYPT + 1)
+#define HINIC5_MOD_IMU 17 // (HINIC5_MOD_VIO + 1)
+#define HINIC5_MOD_DFT 18 // (HINIC5_MOD_IMU + 1) /* DFT */
+#define HINIC5_MOD_MACSEC 19 // (HINIC5_MOD_DFT + 1)
+#define HINIC5_MOD_SW_FUNC \
+ 20 // (HINIC5_MOD_MACSEC + 1) /* Software module id, for PF/VF and multi-host */
+#define HINIC5_MOD_NST 21 // (HINIC5_MOD_SW_FUNC + 1)
+#define HINIC5_MOD_HTN 22 // (HINIC5_MOD_NST + 1)
+#define HINIC5_MOD_JBOF 23 // (HINIC5_MOD_HTN + 1)
#define HINIC5_MOD_FAKE_FMSG 24 // (HINIC5_MOD_JBOF + 1)
-#define HINIC5_MOD_UBCNET 25 // (HINIC5_MOD_FAKE_FMSG + 1)
-#define HINIC5_MOD_CFM 26 // (HINIC5_MOD_UBCNET + 1)
-#define HINIC5_MOD_HIHTR 27 // (HINIC5_MOD_CFM + 1)
-#define HINIC5_MOD_MAX 28 // (HINIC5_MOD_HIHTR + 1)
-#define HINIC5_MOD_HW_MAX HINIC5_MOD_MAX
+#define HINIC5_MOD_UBCNET 25 // (HINIC5_MOD_FAKE_FMSG + 1)
+#define HINIC5_MOD_CFM 26 // (HINIC5_MOD_UBCNET + 1)
+#define HINIC5_MOD_HIHTR 27 // (HINIC5_MOD_CFM + 1)
+#define HINIC5_MOD_MAX 28 // (HINIC5_MOD_DMMU + 1)
+#define HINIC5_MOD_HW_MAX HINIC5_MOD_MAX
#define MODULE_ID(module) #module
#define HINIC5_MOD(module) MODULE_ID(module)
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hinic5_comm_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hinic5_comm_cmd.h
index 9eb430010..28d4cda3d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hinic5_comm_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/hinic5_comm_cmd.h
@@ -1,12 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_comm_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : COMM Commands between Driver and MPU
- */
+/* *****************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
+ ******************************************************************************
+ File Name : hinic5_comm_cmd.h
+ Version : Initial Draft
+ Created : 2019/4/25
+ Last Modified :
+ Description : COMM Commands between Driver and MPU
+ Function List :
+***************************************************************************** */
#ifndef HINIC5_COMMON_CMD_H
#define HINIC5_COMMON_CMD_H
@@ -21,13 +22,13 @@
* @details COMM Commands between Driver and MPU
*/
enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2, /**< Command to set UCODE_ARM bit */
- COMM_CMD_SEND_NPU_DFT_CMD, /**< Send NPU debug command */
- COMM_CMD_MICROLOG_PRINT_CNT_CLEAR, /**< Command to clear microlog print count */
- COMM_CMD_UCODE_FAST_MSG_CMD, /**< Command to send fast message */
- COMM_CMD_UCODE_FAST_MSG_CLEAR, /**< Command to clear fast message */
- COMM_CMD_MICROLOG_GPA_SET, /**< Save host address of cache log to sml table */
- COMM_CMD_MICROLOG_CTRL_INFO_SET, /**< Update log control information to sml table */
+ COMM_CMD_UCODE_ARM_BIT_SET = 2, /**< 设置UCODE_ARM位的命令 */
+ COMM_CMD_SEND_NPU_DFT_CMD, /**< 发送NPU的调试命令 */
+ COMM_CMD_MICROLOG_PRINT_CNT_CLEAR, /**< 清除微日志打印计数的命令 */
+ COMM_CMD_UCODE_FAST_MSG_CMD, /**< 发送快速消息的命令 */
+ COMM_CMD_UCODE_FAST_MSG_CLEAR, /**< 清除快速消息的命令 */
+ COMM_CMD_MICROLOG_GPA_SET, /**< 将缓存日志的主机地址保存到sml表 */
+ COMM_CMD_MICROLOG_CTRL_INFO_SET, /**< 更新日志控制信息到sml表 */
};
typedef struct tag_cmdq_microlog_gpa_set {
@@ -59,12 +60,12 @@ typedef struct tag_micro_log_item {
union {
struct {
#if (BYTE_ORDER == BIG_ENDIAN)
- u32 action : 1; /* 1:record log 0:print */
- u32 type : 2; /* 0:err 1:trace 2:info */
- u32 feature : 5; /* 0:l2nic 1:roce 2:toe 3:ioe 4:feoe */
+ u32 action : 1; /* 1:记录日志 0:打印 */
+ u32 type : 2; /* 0:err 1:trace 2:info */
+ u32 feature : 5; /* 0:l2nic 1:roce 2:toe 3:ioe 4:feoe */
u32 core_id : 6;
u32 thread_id : 2;
- u32 valid_param_num : 8; /* Number of valid parameters */
+ u32 valid_param_num : 8; /* 有效的参数数量 */
u32 tile_id : 3;
u32 ctrl_flag : 1;
u32 rsv : 4;
@@ -72,12 +73,12 @@ typedef struct tag_micro_log_item {
u32 rsv : 4;
u32 ctrl_flag : 1;
u32 tile_id : 3;
- u32 valid_param_num : 8; /* Number of valid parameters */
+ u32 valid_param_num : 8; /* 有效的参数数量 */
u32 thread_id : 2;
u32 core_id : 6;
- u32 feature : 5; /* 0:l2nic 1:roce 2:toe 3:ioe 4:feoe */
- u32 type : 2; /* 0:err 1:trace 2:info */
- u32 action : 1; /* 1:record log 0:print */
+ u32 feature : 5; /* 0:l2nic 1:roce 2:toe 3:ioe 4:feoe */
+ u32 type : 2; /* 0:err 1:trace 2:info */
+ u32 action : 1; /* 1:记录日志 0:打印 */
#endif
} bs;
u32 value;
@@ -85,13 +86,13 @@ typedef struct tag_micro_log_item {
u32 string_addr;
u32 data[DFX_LOG_PRINT_MAX_PARA];
- u32 func_name_addr; /* File name must not exceed 26 characters */
+ u32 func_name_addr; /* 文件名不超过26个字符 */
union {
struct {
#if (BYTE_ORDER == BIG_ENDIAN)
- u32 line : 16; /* Aligned with log_items in mpu, line only needs 16bit */
- u32 log_seq : 16; /* Equivalent to log_pi, range: 0~65535. As log seq, to detect if microcode log is lost */
+ u32 line : 16; /* 对标mpu中log_items,其中的line只需要16bit */
+ u32 log_seq : 16; /* 等价于log_pi,范围:0~65535。作为日志seq, 检测是否丢微码日志 */
#else
u32 log_seq : 16;
u32 line : 16;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/npu_cmdq_base_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/npu_cmdq_base_defs.h
index 4bf7817d0..fa6db492c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/npu_cmdq_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/npu_cmdq_base_defs.h
@@ -1,12 +1,14 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : npu_cmdq_base_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : common command queue interface
- */
+/******************************************************************************
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+ ******************************************************************************
+ File Name : npu_cmdq_base_defs.h
+ Version : Initial Draft
+ Description : common command queue interface
+ Function List :
+ History :
+ Modification: Created file
+
+******************************************************************************/
#ifndef NPU_CMDQ_BASE_DEFS_H
#define NPU_CMDQ_BASE_DEFS_H
@@ -57,22 +59,21 @@ union cmdq_wqe_cs_dw0 {
union cmdq_wqe_cs_dw1 {
struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
+ u32 token : 16; // [15:0]
+ u32 cmd : 8; // [23:16]
+ u32 mod : 5; // [28:24]
u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr; // This structure is used when the driver writes the wqe.
+ u32 obit : 1; // [31]
+ } drv_wr; // This structure is used when the driver writes the wqe.
struct {
- u32 mod : 5; // [4:0]
+ u32 mod : 5; // [4:0]
u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb; // The uCode writes back the structure of the CS_DW1.
- // The driver reads and uses the structure.
+ u32 cmd : 8; // [15:8]
+ u32 arm : 1; // [16]
+ u32 rsvd : 14; // [30:17]
+ u32 obit : 1; // [31]
+ } wb; // The uCode writes back the structure of the CS_DW1. The driver reads and uses the structure.
u32 val;
};
@@ -80,7 +81,7 @@ union cmdq_wqe_cs_dw1 {
struct cmdq_sge {
u32 pa_h; // Upper 32 bits of the physical address
u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
+ u32 len; // Invalid bit[31].
u32 resv;
};
@@ -88,19 +89,19 @@ struct cmdq_sge {
struct cmdq_wqe_ctrls {
union {
struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
+ u32 bdsl : 8; // [7:0]
+ u32 drvsl : 2; // [9:8]
+ u32 rsv : 4; // [13:10]
+ u32 wf : 1; // [14]
+ u32 cf : 1; // [15]
+ u32 tsl : 5; // [20:16]
+ u32 va : 1; // [21]
+ u32 df : 1; // [22]
+ u32 cr : 1; // [23]
+ u32 difsl : 3; // [26:24]
+ u32 csl : 2; // [28:27]
u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
+ u32 obit : 1; // [31]
} bs;
u32 val;
} header;
@@ -121,7 +122,7 @@ struct cmdq_wqe_cs {
union cmdq_wqe_inline_header {
struct {
u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
+ u32 rsv : 21; // [31:11]
} bs;
u32 val;
};
@@ -131,7 +132,7 @@ union cmdq_wqe_bds {
struct {
struct cmdq_sge bds_sge;
u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
+ } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
};
/* Definition of CMDQ WQE */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/sml_table_struct_dict_def.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/sml_table_struct_dict_def.h
index db1d67b0e..2475db9cb 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/sml_table_struct_dict_def.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_develop_interface/fw_msg_intf/public/sml_table_struct_dict_def.h
@@ -1,22 +1,27 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : sml_table_struct_dict_def.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : SML Table structure metadata registration macro definition
+ * @file sml_table_struct_dict_def.h
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * @brief SML Table 结构体元数据注册宏定义
+ *
+ * 本文件定义了用于将结构体信息注入二进制符号表的宏接口。
+ * 开启 DEFINE_TABLE_STRUCT_ENABLE 宏后,调用 DEFINE_TABLE_STRUCT_VAR
+ * 将在链接后的二进制文件中生成特定前缀的符号,供 sml_table_struct_dict_gen.py 脚本解析。
*/
#ifndef SML_TABLE_STRUCT_DICT_DEF_H
#define SML_TABLE_STRUCT_DICT_DEF_H
#ifdef DEFINE_TABLE_STRUCT_ENABLE
-#define DEFINE_TABLE_STRUCT_VAR_DIRECT(struct_name, table_name, entry_id, entry_num) \
- volatile struct_name sml_table_struct_var_prefix__##struct_name##__##entry_id##__##entry_num; \
- volatile const char sml_table_struct_table_name_var_prefix__##struct_name[] = #table_name
+#define DEFINE_TABLE_STRUCT_VAR_DIRECT(struct_name, table_name, entry_id, \
+ entry_num) \
+ volatile struct_name \
+ sml_table_struct_var_prefix__##struct_name##__##entry_id##__##entry_num; \
+ volatile const char \
+ sml_table_struct_table_name_var_prefix__##struct_name[] = \
+ #table_name
-#define DEFINE_TABLE_STRUCT_VAR(struct_name, table_name, entry_id, entry_num) \
- DEFINE_TABLE_STRUCT_VAR_DIRECT(struct_name, table_name, entry_id, entry_num)
+#define DEFINE_TABLE_STRUCT_VAR(struct_name, table_name, entry_id, entry_num) \
+ DEFINE_TABLE_STRUCT_VAR_DIRECT(struct_name, table_name, entry_id, \
+ entry_num)
#else
#define DEFINE_TABLE_STRUCT_VAR(struct_name, table_name, entry_id, entry_num)
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond.c
index 3d5953ef7..b9abbf406 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bond.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [BOND]" fmt
@@ -19,19 +13,24 @@
#include <linux/netdevice.h>
#include <linux/list.h>
+#include "securec.h"
+#include "ossl_knl.h"
#include "comm_defs.h"
#include "cfg_mgmt_mpu_cmd_defs.h"
-#include "hinic5_lld.h"
-#include "hinic5_vram_common.h"
-#include "hinic5_srv_nic.h"
-#include "hinic5_hw.h"
#include "bond_mpu_cmd_defs.h"
-#include "bond_cfm_cmd.h"
#include "cfm_cmd.h"
+#include "bond_cfm_cmd.h"
+#include "vram_common.h"
+#include "hinic5_hw.h"
+#include "hinic5_lld.h"
+#include "hinic5_srv_nic.h"
#include "hinic5_bond_inner.h"
-#include "ossl_knl.h"
#include "hinic5_bond.h"
+#define HINIC5_BOND_DETACH_WAIT_TIMEOUT 10000
+#define HINIC5_BOND_DETACH_USLEEP_TIME_MIN 990
+#define HINIC5_BOND_DETACH_USLEEP_TIME_MAX 1000
+
enum bond_service_proc_pos {
BOND_BEFORE_ACTIVE,
BOND_AFTER_ACTIVE,
@@ -43,13 +42,14 @@ enum bond_service_proc_pos {
};
#define PCI_DBDF(dom, bus, dev, func) \
- (((dom) << 16) | ((bus) << 8) | ((dev) << 3) | ((func) & 0x7))
+ (((dom) << 16) | ((bus) << 8) | ((dev) << 3) | ((func)&0x7))
struct hinic5_bond_mngr {
u32 cnt;
- struct hinic5_bond_dev __rcu **bond_dev;
+ struct hinic5_bond_dev **bond_dev;
struct socket *rtnl_sock;
struct list_head bond_chip_list;
+ struct workqueue_struct *wq;
};
enum bond_event_cmd {
@@ -77,14 +77,10 @@ static event_func g_bond_event_func[HINIC5_BOND_USER_NUM][BOND_POS_MAX];
static DEFINE_MUTEX(g_bond_attach_func_mutex);
static attach_func g_bond_attach_func[HINIC5_BOND_USER_NUM];
-static DEFINE_MUTEX(g_bond_mutex);
-static struct hinic5_bond_mngr bond_mngr = {
- .cnt = 0,
- .rtnl_sock = NULL,
- .bond_dev = NULL,
-};
+DEFINE_MUTEX(g_bond_mutex);
+struct hinic5_bond_mngr bond_mngr = { 0 };
-struct srcu_struct bdev_srcu; /* cfm bond global SRCU lock */
+DEFINE_MUTEX(g_bond_detach_mutex);
#define BDEV_IS_VALID(id) (bond_mngr.bond_dev && bond_mngr.bond_dev[(id)])
@@ -98,22 +94,33 @@ struct socket **hinic5_get_bond_mngr_sock_addr(void)
return &bond_mngr.rtnl_sock;
}
-bool bond_call_srv_attach_func(enum hinic5_bond_user user, struct bonding *bond)
+void hinic5_bond_detach_mutex_lock(void)
+{
+ mutex_lock(&g_bond_detach_mutex);
+}
+void hinic5_bond_detach_mutex_unlock(void)
+{
+ mutex_unlock(&g_bond_detach_mutex);
+}
+
+struct workqueue_struct *hinic5_bond_get_mngr_wq(void)
{
- bool need_attach = false;
+ return bond_mngr.wq;
+}
+bool hinic5_bond_can_attach(enum hinic5_bond_user user, struct bonding *bond)
+{
+ bool can_attach = false;
mutex_lock(&g_bond_attach_func_mutex);
if (g_bond_attach_func[user])
- need_attach = g_bond_attach_func[user](bond);
+ can_attach = g_bond_attach_func[user](bond);
mutex_unlock(&g_bond_attach_func_mutex);
-
- return need_attach;
+ return can_attach;
}
static bool bond_dev_is_activated(struct hinic5_bond_dev *bdev)
{
bool is_activated = false;
-
spin_lock(&bdev->lock);
is_activated = (bdev->status == BOND_DEV_STATUS_ACTIVATED);
spin_unlock(&bdev->lock);
@@ -131,14 +138,13 @@ static u32 bond_gen_uplink_id(struct hinic5_bond_dev *bdev)
spin_lock(&bdev->lock);
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(bdev->bond_attr.slaves, i) != 0) {
- if (bdev->tracker.ndev[i] == NULL) {
+ if (bdev->tracker.ndev[i] == NULL)
continue;
- }
- lld_dev = hinic5_get_lld_dev_by_netdev(bdev->tracker.ndev[i]);
- if (lld_dev == NULL) {
+ lld_dev = hinic5_get_lld_dev_by_netdev(
+ bdev->tracker.ndev[i]);
+ if (lld_dev == NULL)
continue;
- }
- /* TODO: Waiting for SDK to provide interface */
+ /* TODO: 等待SDK提供接口 */
pdev = to_pci_dev(lld_dev->dev);
domain = (u32)pci_domain_nr(pdev->bus);
bus = pdev->bus->number;
@@ -159,9 +165,9 @@ void bond_dev_free_chip_bond_id(struct hinic5_bond_dev *bdev)
struct hinic5_bond_chip *bond_chip = NULL;
u32 chip_bid = HINIC5_BOND_START_ID;
- mutex_lock(&g_bond_mutex);
list_for_each_entry(node_tmp, &bond_mngr.bond_chip_list, node) {
- if (strncmp(node_tmp->chip_name, bdev->chip_name, IFNAMSIZ) == 0) {
+ if (strncmp(node_tmp->chip_name, bdev->chip_name, IFNAMSIZ) ==
+ 0) {
bond_chip = node_tmp;
break;
}
@@ -170,12 +176,15 @@ void bond_dev_free_chip_bond_id(struct hinic5_bond_dev *bdev)
if (bond_chip) {
/* find chip_bond_id is exit */
for (; chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++) {
- if (bond_chip->chip_bond_id[chip_bid] == bdev->bond_attr.bond_id) {
- bond_chip->chip_bond_id[chip_bid] = HINIC5_INVALID_BOND_ID;
+ if (bond_chip->chip_bond_id[chip_bid] ==
+ bdev->bond_attr.bond_id) {
+ bond_chip->chip_bond_id[chip_bid] =
+ HINIC5_INVALID_BOND_ID;
bond_chip->bond_num--;
- bond_master_info(bdev->bond->dev,
- "Bond chip %s bond id %u free success\n",
- bdev->chip_name, chip_bid);
+ bond_master_info(
+ bdev->bond->dev,
+ "Bond chip %s bond id %u free success\n",
+ bdev->chip_name, chip_bid);
break;
}
}
@@ -183,14 +192,15 @@ void bond_dev_free_chip_bond_id(struct hinic5_bond_dev *bdev)
if (bond_chip->bond_num == 0) {
list_del(&bond_chip->node);
kfree(bond_chip);
- bond_master_info(bdev->bond->dev, "Bond chip node %s free success\n",
+ bond_master_info(bdev->bond->dev,
+ "Bond chip node %s free success\n",
bdev->chip_name);
}
}
- mutex_unlock(&g_bond_mutex);
}
-static int bond_dev_alloc_chip_bond_id(struct hinic5_bond_dev *bdev, char *chip_name, const u32 chip_name_len)
+static int bond_dev_alloc_chip_bond_id(struct hinic5_bond_dev *bdev,
+ char *chip_name, const u32 chip_name_len)
{
struct hinic5_bond_chip *node_tmp = NULL;
struct hinic5_bond_chip *bond_chip = NULL;
@@ -198,16 +208,13 @@ static int bond_dev_alloc_chip_bond_id(struct hinic5_bond_dev *bdev, char *chip_
int err = 0;
mutex_lock(&g_bond_mutex);
- /* Initialize bdev chip name */
- if (chip_name_len >= sizeof(bdev->chip_name)) {
- err = -EINVAL;
- goto exit;
- }
- memcpy(bdev->chip_name, chip_name, chip_name_len);
- bdev->chip_name[chip_name_len] = '\0';
+ /* 初始化bdev的chip name */
+ (void)memcpy_s(bdev->chip_name, sizeof(bdev->chip_name), chip_name,
+ chip_name_len);
list_for_each_entry(node_tmp, &bond_mngr.bond_chip_list, node) {
- if (strncmp(node_tmp->chip_name, chip_name, chip_name_len) == 0) {
+ if (strncmp(node_tmp->chip_name, chip_name, chip_name_len) ==
+ 0) {
bond_chip = node_tmp;
break;
}
@@ -216,51 +223,68 @@ static int bond_dev_alloc_chip_bond_id(struct hinic5_bond_dev *bdev, char *chip_
if (bond_chip) {
/* find chip_bond_id is exit */
for (; chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++) {
- if (bond_chip->chip_bond_id[chip_bid] == bdev->bond_attr.bond_id)
+ if (bond_chip->chip_bond_id[chip_bid] ==
+ bdev->bond_attr.bond_id)
goto exit;
}
/* find new chip_bond_id */
- for (chip_bid = HINIC5_BOND_START_ID; chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++) {
- if (bond_chip->chip_bond_id[chip_bid] == HINIC5_INVALID_BOND_ID) {
+ for (chip_bid = HINIC5_BOND_START_ID;
+ chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++) {
+ if (bond_chip->chip_bond_id[chip_bid] ==
+ HINIC5_INVALID_BOND_ID) {
bdev->chip_bond_id = chip_bid;
- bond_chip->chip_bond_id[chip_bid] = (u8)bdev->bond_attr.bond_id;
+ bond_chip->chip_bond_id[chip_bid] =
+ (u8)bdev->bond_attr.bond_id;
bond_chip->bond_num++;
- bond_master_info(bdev->bond->dev,
- "Bond chip %s bond id %u alloc success\n",
- bdev->chip_name, chip_bid);
+ bond_master_info(
+ bdev->bond->dev,
+ "Bond chip %s bond id %u alloc success\n",
+ bdev->chip_name, chip_bid);
break;
}
}
if (chip_bid >= HINIC5_MAX_BOND_ID_PER_CARD) {
- bond_master_err(bdev->bond->dev, "bond_dev_get_chip_bond_id: chip_bond_id is full\n");
+ bond_master_err(
+ bdev->bond->dev,
+ "bond_dev_get_chip_bond_id: chip_bond_id is full\n");
err = -EINVAL;
}
} else {
- bond_chip = kzalloc(sizeof(struct hinic5_bond_chip), GFP_KERNEL);
+ bond_chip =
+ kzalloc(sizeof(struct hinic5_bond_chip), GFP_KERNEL);
if (!bond_chip) {
- bond_master_err(bdev->bond->dev, "Bond chip %s node alloc failed\n", chip_name);
+ bond_master_err(bdev->bond->dev,
+ "Bond chip %s node alloc failed\n",
+ chip_name);
err = -ENOMEM;
goto exit;
}
- bond_master_info(bdev->bond->dev, "bond chip %s node alloc success\n", chip_name);
+ bond_master_info(bdev->bond->dev,
+ "bond chip %s node alloc success\n",
+ chip_name);
bdev->chip_bond_id = chip_bid;
- memcpy(bond_chip->chip_name, chip_name, chip_name_len);
- bond_master_info(bdev->bond->dev, "Bond chip %s bond id %u alloc success\n", bdev->chip_name, chip_bid);
- bond_chip->chip_bond_id[chip_bid++] = (u8)bdev->bond_attr.bond_id;
+ memcpy_s(bond_chip->chip_name, chip_name_len, chip_name,
+ chip_name_len);
+ bond_master_info(bdev->bond->dev,
+ "Bond chip %s bond id %u alloc success\n",
+ bdev->chip_name, chip_bid);
+ bond_chip->chip_bond_id[chip_bid++] =
+ (u8)bdev->bond_attr.bond_id;
bond_chip->bond_num++;
- for (; chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++) {
- bond_chip->chip_bond_id[chip_bid] = HINIC5_INVALID_BOND_ID;
- }
+ for (; chip_bid < HINIC5_MAX_BOND_ID_PER_CARD; chip_bid++)
+ bond_chip->chip_bond_id[chip_bid] =
+ HINIC5_INVALID_BOND_ID;
list_add_tail(&bond_chip->node, &bond_mngr.bond_chip_list);
}
exit:
if (err != 0)
- memset(bdev->chip_name, 0, sizeof(bdev->chip_name)); /* Clear bdev chip name */
+ memset_s(bdev->chip_name, sizeof(bdev->chip_name), 0,
+ sizeof(bdev->chip_name)); /* 清除bdev的chip name */
mutex_unlock(&g_bond_mutex);
return err;
}
@@ -269,8 +293,8 @@ static int bond_dev_alloc_chip_bond_id(struct hinic5_bond_dev *bdev, char *chip_
u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
{
struct hinic5_lld_dev *lld_dev = NULL;
- char chip_name[IFNAMSIZ] = {0};
- char ndev_name[IFNAMSIZ] = {0};
+ char chip_name[IFNAMSIZ] = { 0 };
+ char ndev_name[IFNAMSIZ] = { 0 };
bool is_replaced = false;
u32 tracker_cnt = 0;
u8 port_id = 0;
@@ -278,16 +302,19 @@ u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
lld_dev = hinic5_get_lld_dev_by_netdev(ndev);
if (lld_dev == NULL || hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
- bond_slave_err(bdev->bond->dev, ndev, "invalid slave: %s\n", ndev->name);
+ bond_slave_err(bdev->bond->dev, ndev, "invalid slave: %s\n",
+ ndev->name);
return PORT_INVALID_ID;
}
- bond_slave_info(bdev->bond->dev, ndev, "track ndev name: %s\n", ndev->name);
+ bond_slave_info(bdev->bond->dev, ndev, "track ndev name: %s\n",
+ ndev->name);
port_id = hinic5_physical_port_id(lld_dev->hwdev);
err = hinic5_get_chip_name(lld_dev, chip_name, sizeof(chip_name));
if (err != 0) {
- bond_slave_err(bdev->bond->dev, ndev, "Bond Slave get chip name err %d\n", err);
+ bond_slave_err(bdev->bond->dev, ndev,
+ "Bond Slave get chip name err %d\n", err);
return PORT_INVALID_ID;
}
@@ -296,9 +323,10 @@ u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
if (bdev->tracker.cnt > 0 && strcmp(bdev->chip_name, chip_name) != 0) {
/* Only support bond for same card */
spin_unlock(&bdev->lock);
- bond_slave_err(bdev->bond->dev, ndev,
- "Bond track err, slave not for same card, bond dev chip_name %s, slave chip name %s\n",
- bdev->chip_name, chip_name);
+ bond_slave_err(
+ bdev->bond->dev, ndev,
+ "Bond track err, slave not for same card, bond dev chip_name %s, slave chip name %s\n",
+ bdev->chip_name, chip_name);
return PORT_INVALID_ID;
}
tracker_cnt = bdev->tracker.cnt;
@@ -308,7 +336,8 @@ u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
if (tracker_cnt == 0) {
err = bond_dev_alloc_chip_bond_id(bdev, chip_name, IFNAMSIZ);
if (err != 0) {
- bond_slave_err(bdev->bond->dev, ndev, "Alloc bond chip id err %d\n", err);
+ bond_slave_err(bdev->bond->dev, ndev,
+ "Alloc bond chip id err %d\n", err);
return PORT_INVALID_ID;
}
}
@@ -317,8 +346,9 @@ u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
/* attach netdev to the port position associated with it */
if (bdev->tracker.ndev[port_id]) {
is_replaced = true;
- memcpy(ndev_name, bdev->tracker.ndev[port_id]->name,
- sizeof(bdev->tracker.ndev[port_id]->name));
+ (void)memcpy_s(ndev_name, sizeof(ndev_name),
+ bdev->tracker.ndev[port_id]->name,
+ sizeof(bdev->tracker.ndev[port_id]->name));
} else {
bdev->tracker.cnt++;
}
@@ -328,13 +358,38 @@ u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev)
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
spin_unlock(&bdev->lock);
if (is_replaced)
- bond_slave_warn(bdev->bond->dev, ndev, "Old ndev: %s is replaced\n", ndev_name);
- bond_slave_info(bdev->bond->dev, ndev, "TRACK cnt: %u, slave ndev name: %s\n",
- tracker_cnt, ndev->name);
+ bond_slave_warn(bdev->bond->dev, ndev,
+ "Old ndev: %s is replaced\n", ndev_name);
+ bond_slave_info(bdev->bond->dev, ndev,
+ "TRACK cnt: %u, slave ndev name: %s\n", tracker_cnt,
+ ndev->name);
return port_id;
}
+void bond_dev_untrack_port(struct hinic5_bond_dev *bdev, u8 port_id)
+{
+ u32 track_cnt = 0;
+ const struct net_device *untrack_ndev = NULL;
+ spin_lock(&bdev->lock);
+ if (bdev->tracker.ndev[port_id] != NULL) {
+ untrack_ndev = bdev->tracker.ndev[port_id];
+ track_cnt = --bdev->tracker.cnt;
+ bdev->tracker.ndev[port_id] = NULL;
+ }
+ spin_unlock(&bdev->lock);
+ if (track_cnt == 0) {
+ mutex_lock(&g_bond_mutex);
+ bond_dev_free_chip_bond_id(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
+ if (untrack_ndev != NULL)
+ bond_master_info(
+ bdev->bond->dev,
+ "untrack port:%u, untrack ndev: %s, tracker cnt: %u\n",
+ port_id, untrack_ndev->name, track_cnt);
+}
+
struct hinic5_bond_dev *bond_get_bdev(const struct bonding *bond)
{
struct hinic5_bond_dev *bdev = NULL;
@@ -358,86 +413,101 @@ struct hinic5_bond_dev *bond_get_bdev(const struct bonding *bond)
static int bond_get_service_en_bitmap(struct hinic5_bond_dev *bdev)
{
int err;
- struct hinic5_board_info info = {0};
- struct hinic5_lld_dev *lld_dev = hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
-
- if (!lld_dev) {
- bond_master_err(bdev->bond->dev, "no available hinic5 lld device, chip_name: %s\n",
- bdev->chip_name);
+ struct hinic5_board_info info = { 0 };
+ struct hinic5_lld_dev *lld_dev =
+ hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
+ if (lld_dev == NULL) {
+ bond_master_err(
+ bdev->bond->dev,
+ "no available hinic5 lld device, chip_name: %s\n",
+ bdev->chip_name);
return -ENXIO;
}
err = hinic5_get_board_info(lld_dev->hwdev, &info, HINIC5_CHANNEL_NIC);
if (err != 0) {
- bond_master_err(bdev->bond->dev, "bond get board info failed\n");
+ bond_master_err(bdev->bond->dev,
+ "bond get board info failed\n");
return err;
}
- bond_master_info(bdev->bond->dev, "get service_en_bitmap success: %d", info.service_en_bitmap);
+ bond_master_info(bdev->bond->dev, "get service_en_bitmap success: %d",
+ info.service_en_bitmap);
bdev->service_en_bitmap = info.service_en_bitmap;
- return 0;
+ return EOK;
}
-static int bond_send_mpu_cfm_msg(struct hinic5_bond_dev *bdev, struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
+static int bond_send_mpu_cfm_msg(struct hinic5_bond_dev *bdev,
+ struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
{
int err = 0;
u16 msg_cmd_type = g_cfm_cmd_covert[cmd_type];
u16 out_size = sizeof(cfm_bond_cmd_s);
- cfm_bond_cmd_s cfm_bond_cmd_info = {0};
- struct hinic5_lld_dev *lld_dev = hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
-
- if (!lld_dev) {
- bond_master_err(bdev->bond->dev,
- "no available hinic5 lld device(cfm), chip_name: %s\n",
- bdev->chip_name);
+ cfm_bond_cmd_s cfm_bond_cmd_info = { 0 };
+ struct hinic5_lld_dev *lld_dev =
+ hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
+ if (lld_dev == NULL) {
+ bond_master_err(
+ bdev->bond->dev,
+ "no available hinic5 lld device(cfm), chip_name: %s\n",
+ bdev->chip_name);
return -ENXIO;
}
- memcpy(&cfm_bond_cmd_info, (const void *)cmd_info, sizeof(struct hinic5_bond_cmd));
- err = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_CFM, msg_cmd_type,
- &cfm_bond_cmd_info, sizeof(cfm_bond_cmd_s),
- &cfm_bond_cmd_info, &out_size,
- HINIC5_BOND_MSG_TIMEOUT_MS, HINIC5_CHANNEL_NIC);
- if (err != 0 || out_size == 0 || cfm_bond_cmd_info.comm_head.status != 0) {
- bond_master_err(bdev->bond->dev,
- "bond msg cmd type: %u failed, err: %d, " \
- "cfm bond sts: %u, out size: %u\n",
- msg_cmd_type, err, cfm_bond_cmd_info.comm_head.status, out_size);
+ (void)memcpy_s(&cfm_bond_cmd_info, sizeof(cfm_bond_cmd_s),
+ (const void *)cmd_info, sizeof(struct hinic5_bond_cmd));
+ cfm_bond_cmd_info.bond_type = BOND_TYPE_HALF;
+ err = hinic5_msg_to_mgmt_sync(
+ lld_dev->hwdev, HINIC5_MOD_CFM, msg_cmd_type,
+ &cfm_bond_cmd_info, sizeof(cfm_bond_cmd_s), &cfm_bond_cmd_info,
+ &out_size, HINIC5_BOND_MSG_TIMEOUT_MS, HINIC5_CHANNEL_NIC);
+ if (err != 0 || out_size == 0 ||
+ cfm_bond_cmd_info.comm_head.status != 0) {
+ bond_master_err(
+ bdev->bond->dev,
+ "bond msg cmd type: %u failed, err: %d, cfm bond sts: %u, out size: %u\n",
+ msg_cmd_type, err, cfm_bond_cmd_info.comm_head.status,
+ out_size);
err = -EIO;
}
return err;
}
-static int bond_send_mpu_ovs_msg(struct hinic5_bond_dev *bdev, struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
+static int bond_send_mpu_ovs_msg(struct hinic5_bond_dev *bdev,
+ struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
{
int err = 0;
u16 msg_cmd_type = g_cmd_covert[cmd_type];
u16 out_size = sizeof(struct hinic5_bond_cmd);
- struct hinic5_lld_dev *lld_dev = hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
-
- if (!lld_dev) {
- bond_master_err(bdev->bond->dev,
- "no available hinic5 lld device(ovs), chip_name: %s\n",
- bdev->chip_name);
+ struct hinic5_lld_dev *lld_dev =
+ hinic5_get_lld_dev_by_chip_name(bdev->chip_name);
+ if (lld_dev == NULL) {
+ bond_master_err(
+ bdev->bond->dev,
+ "no available hinic5 lld device(ovs), chip_name: %s\n",
+ bdev->chip_name);
return -ENXIO;
}
- err = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_OVS, msg_cmd_type, cmd_info,
- sizeof(struct hinic5_bond_cmd), cmd_info, &out_size, 0,
- HINIC5_CHANNEL_NIC);
+ err = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_OVS,
+ msg_cmd_type, cmd_info,
+ sizeof(struct hinic5_bond_cmd), cmd_info,
+ &out_size, 0, HINIC5_CHANNEL_NIC);
if (err != 0 || out_size == 0 || cmd_info->comm_head.status != 0) {
- bond_master_err(bdev->bond->dev,
- "bond msg cmd type: %u failed, err: %d, sts: %u, out size: %u\n",
- msg_cmd_type, err, cmd_info->comm_head.status, out_size);
+ bond_master_err(
+ bdev->bond->dev,
+ "bond msg cmd type: %u failed, err: %d, sts: %u, out size: %u\n",
+ msg_cmd_type, err, cmd_info->comm_head.status,
+ out_size);
err = -EIO;
}
return err;
}
-static int bond_send_mpu_msg(struct hinic5_bond_dev *bdev, struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
+static int bond_send_mpu_msg(struct hinic5_bond_dev *bdev,
+ struct hinic5_bond_cmd *cmd_info, u8 cmd_type)
{
int err = 0;
-
if (bdev->service_en_bitmap == 0) {
err = bond_get_service_en_bitmap(bdev);
if (err != 0)
@@ -448,24 +518,40 @@ static int bond_send_mpu_msg(struct hinic5_bond_dev *bdev, struct hinic5_bond_cm
return bond_send_mpu_ovs_msg(bdev, cmd_info, cmd_type);
}
-static int bond_send_upcmd(struct hinic5_bond_dev *bdev, struct bond_attr *attr, u8 cmd_type)
+static int bond_send_upcmd(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr, u8 cmd_type)
{
- struct hinic5_bond_cmd cmd_info = {{0}, 0};
+ int err = 0;
+ struct hinic5_bond_cmd cmd_info = { { 0 }, 0 };
cmd_info.sub_cmd = 0;
cmd_info.comm_head.status = 0;
- if (attr)
- memcpy((void *)&cmd_info.attr, attr, sizeof(*attr));
- else
+ if (curr_attr != NULL) {
+ err = memcpy_s((void *)&cmd_info.attr, sizeof(cmd_info.attr),
+ curr_attr, sizeof(*curr_attr));
+ if (err != 0) {
+ bond_master_err(bdev->bond->dev,
+ "hinic5_bond: memcpy failed\n");
+ return -EIO;
+ }
+ } else {
cmd_info.attr.slaves = bdev->bond_attr.slaves;
-
+ }
/* cmd_info bond_id is chip bond id */
cmd_info.attr.bond_id = (u16)bdev->chip_bond_id;
if (cmd_type == BOND_CREATE_CMD) {
- strncpy((char *)cmd_info.attr.bond_name, bdev->name, sizeof(cmd_info.attr.bond_name));
- cmd_info.attr.bond_name[sizeof(cmd_info.attr.bond_name) - 1] = '\0';
+ err = strncpy_s((char *)cmd_info.attr.bond_name,
+ sizeof(cmd_info.attr.bond_name), bdev->name,
+ sizeof(cmd_info.attr.bond_name));
+ if (err != 0) {
+ bond_master_err(bdev->bond->dev,
+ "hinic5_bond: memcpy failed\n");
+ return -EIO;
+ }
+ cmd_info.attr.bond_name[sizeof(cmd_info.attr.bond_name) - 1] =
+ '\0';
}
return bond_send_mpu_msg(bdev, &cmd_info, cmd_type);
@@ -480,16 +566,19 @@ static int bond_upcmd_deactivate(struct hinic5_bond_dev *bdev)
spin_lock(&bdev->lock);
status = bdev->status;
spin_unlock(&bdev->lock);
- if (status == BOND_DEV_STATUS_IDLE)
+ if (status == BOND_DEV_STATUS_IDLE) {
return 0;
+ }
- bond_master_info(bdev->bond->dev, "hinic5_bond: deactivate bond: %u\n", bdev->bond_attr.bond_id);
+ bond_master_info(bdev->bond->dev, "hinic5_bond: deactivate bond: %u\n",
+ bdev->bond_attr.bond_id);
err = bond_send_upcmd(bdev, NULL, BOND_DELETE_CMD);
if (err == 0) {
spin_lock(&bdev->lock);
id_tmp = bdev->bond_attr.bond_id;
- memset(&bdev->bond_attr, 0, sizeof(bdev->bond_attr));
+ (void)memset_s(&bdev->bond_attr, sizeof(bdev->bond_attr), 0,
+ sizeof(bdev->bond_attr));
bdev->status = BOND_DEV_STATUS_IDLE;
bdev->bond_attr.bond_id = id_tmp;
spin_unlock(&bdev->lock);
@@ -498,103 +587,81 @@ static int bond_upcmd_deactivate(struct hinic5_bond_dev *bdev)
return err;
}
-static void bond_update_slave_info(struct hinic5_bond_dev *bdev, struct bond_attr *attr)
+void bond_print_bdev_attr(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr)
{
- struct net_device *ndev = NULL;
- u8 port_id;
-
- /* if bond dev down(ifconfig down), slave dev is up, should not set active slaves */
- if (!netif_running(bdev->bond->dev))
- return;
-
- if (attr->bond_mode == BOND_MODE_ACTIVEBACKUP) {
- rcu_read_lock();
- ndev = bond_option_active_slave_get_rcu(bdev->bond);
- rcu_read_unlock();
- }
-
- for (port_id = 0; port_id < BOND_PORT_MAX_NUM; port_id++) {
- if (bdev->tracker.netdev_state[port_id].tx_enabled == 0)
- continue;
-
- if (attr->bond_mode == BOND_MODE_8023AD) {
- BITMAP_SET(attr->active_slaves, port_id);
- BITMAP_SET(attr->lacp_collect_slaves, port_id);
- } else if (attr->bond_mode == BOND_MODE_XOR) {
- BITMAP_SET(attr->active_slaves, port_id);
- } else if (ndev && (ndev == bdev->tracker.ndev[port_id])) {
- /* BOND_MODE_ACTIVEBACKUP */
- BITMAP_SET(attr->active_slaves, port_id);
- }
- }
+ bond_master_info(
+ bdev->bond->dev,
+ "mode: %u, up_delay: %u, down_delay: %u, hash: %u, lacp_collect_slaves: %u, tracker cnt: %u\n",
+ curr_attr->bond_mode, curr_attr->up_delay,
+ curr_attr->down_delay, curr_attr->xmit_hash_policy,
+ curr_attr->lacp_collect_slaves, bdev->tracker.cnt);
+ bond_master_info(bdev->bond->dev, "slave ports bitmap: 0x%x\n",
+ curr_attr->slaves);
+ bond_master_info(bdev->bond->dev, "active slave ports bitmap: 0x%x\n",
+ curr_attr->active_slaves);
+ bond_master_info(bdev->bond->dev, "slave pf bitmap: 0x%x\n",
+ curr_attr->bond_pf_bitmap);
+ bond_master_info(bdev->bond->dev, "user bitmap: 0x%x\n",
+ curr_attr->user_bitmap);
}
-void bond_print_bdev_attr(struct hinic5_bond_dev *bdev, struct bond_attr *attr)
-{
- bond_master_info(bdev->bond->dev,
- "mode: %u, up_delay: %u, down_delay: %u, hash: %u, lacp_collect_slaves: %u, tracker cnt: %u\n",
- attr->bond_mode,
- attr->up_delay,
- attr->down_delay,
- attr->xmit_hash_policy,
- attr->lacp_collect_slaves,
- bdev->tracker.cnt);
- bond_master_info(bdev->bond->dev, "slave ports bitmap: 0x%x\n", attr->slaves);
- bond_master_info(bdev->bond->dev, "active slave ports bitmap: 0x%x\n", attr->active_slaves);
- bond_master_info(bdev->bond->dev, "slave pf bitmap: 0x%x\n", attr->bond_pf_bitmap);
- bond_master_info(bdev->bond->dev, "user bitmap: 0x%x\n", attr->user_bitmap);
-}
-
-static int bond_upcmd_config(struct hinic5_bond_dev *bdev, struct bond_attr *attr)
+static int bond_upcmd_config(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr)
{
int err;
- bond_update_slave_info(bdev, attr);
-
- if (memcmp(&bdev->bond_attr, attr, sizeof(struct bond_attr)) == 0)
+ if (memcmp(&bdev->bond_attr, curr_attr, sizeof(struct bond_attr)) == 0)
return 0;
- bond_master_info(bdev->bond->dev, "Config bond id: %u\n", attr->bond_id);
- bond_print_bdev_attr(bdev, attr);
+ bond_master_info(bdev->bond->dev, "Config bond id: %u\n",
+ curr_attr->bond_id);
+ bond_print_bdev_attr(bdev, curr_attr);
- err = bond_send_upcmd(bdev, attr, BOND_SET_CMD);
+ err = bond_send_upcmd(bdev, curr_attr, BOND_SET_CMD);
if (err == 0)
- memcpy(&bdev->bond_attr, attr, sizeof(struct bond_attr));
+ (void)memcpy_s(&bdev->bond_attr, sizeof(struct bond_attr),
+ curr_attr, sizeof(struct bond_attr));
return err;
}
-static int bond_upcmd_activate(struct hinic5_bond_dev *bdev, struct bond_attr *attr)
+static int bond_upcmd_activate(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr)
{
int err;
if (bond_dev_is_activated(bdev))
return 0;
- bond_update_slave_info(bdev, attr);
- bond_master_info(bdev->bond->dev, "Active bond id: %u\n", bdev->bond_attr.bond_id);
- bond_print_bdev_attr(bdev, attr);
+ bond_master_info(bdev->bond->dev, "Active bond id: %u\n",
+ bdev->bond_attr.bond_id);
+ bond_print_bdev_attr(bdev, curr_attr);
- err = bond_send_upcmd(bdev, attr, BOND_CREATE_CMD);
+ err = bond_send_upcmd(bdev, curr_attr, BOND_CREATE_CMD);
if (err == 0) {
spin_lock(&bdev->lock);
bdev->status = BOND_DEV_STATUS_ACTIVATED;
spin_unlock(&bdev->lock);
- err = bond_upcmd_config(bdev, attr); /* create first, then set, for compatibility with old firmware mpu processing flow */
+ err = bond_upcmd_config(
+ bdev,
+ curr_attr); /* 先create再set是为了兼容老固件mpu处理流程 */
}
return err;
}
-static void bond_call_service_func(struct hinic5_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int err)
+static void bond_call_service_func(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr,
+ enum bond_service_proc_pos pos, int err)
{
u32 user;
mutex_lock(&g_bond_event_func_mutex);
for (user = HINIC5_BOND_USER_OVS; user < HINIC5_BOND_USER_NUM; user++) {
if (g_bond_event_func[user][pos])
- g_bond_event_func[user][pos](bdev->name, attr, err);
+ g_bond_event_func[user][pos](bdev->name, curr_attr,
+ err);
}
mutex_unlock(&g_bond_event_func_mutex);
}
@@ -605,190 +672,161 @@ static u32 bond_get_user_bitmap(struct hinic5_bond_dev *bdev)
u32 user;
for (user = HINIC5_BOND_USER_OVS; user < HINIC5_BOND_USER_NUM; user++) {
- if (bdev->slot_used[user] == 1) {
+ if (bdev->slot_used[user] == 1)
BITMAP_SET(user_bitmap, user);
- }
}
return user_bitmap;
}
-static void bond_do_work(struct work_struct *work)
+void bond_do_work(struct work_struct *work)
{
bool is_bonded = 0;
- struct bond_attr attr;
- int is_in_kexec;
+ u32 user = 0;
+ int is_in_kexec = 0;
int err = 0;
struct delayed_work *delayed_work = to_delayed_work(work);
- struct hinic5_bond_dev *bdev = container_of(delayed_work, struct hinic5_bond_dev, bond_work);
+ struct hinic5_bond_work *bond_work =
+ container_of(delayed_work, struct hinic5_bond_work, work);
+ struct hinic5_bond_dev *bdev = bond_work->bdev;
+ struct bond_attr curr_attr = bond_work->curr_attr;
- is_in_kexec = hinic5_vram_get_kexec_flag();
+ destroy_work(&bond_work->work);
+ kfree(bond_work);
+
+ is_in_kexec = vram5_get_kexec_flag();
if (is_in_kexec != 0) {
- bond_master_info(bdev->bond->dev, "Skip changing bond status during os replace\n");
+ atomic_dec(&bdev->counter);
+ bond_master_info(
+ bdev->bond->dev,
+ "Skip changing bond status during os replace\n");
return;
}
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
- attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = bond_get_user_bitmap(bdev);
+ curr_attr.user_bitmap = bond_get_user_bitmap(bdev);
- bond_master_info(bdev->bond->dev,
- "bond_do_work is_bonded: %d, bond_dev_is_activated(bdev): %d\n",
- is_bonded, bond_dev_is_activated(bdev));
+ bond_master_info(
+ bdev->bond->dev,
+ "bond_do_work is_bonded: %d, bond_dev_is_activated(bdev): %d\n",
+ is_bonded, bond_dev_is_activated(bdev));
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
- bond_call_service_func(bdev, &attr, BOND_BEFORE_ACTIVE, 0);
- err = bond_upcmd_activate(bdev, &attr);
- bond_call_service_func(bdev, &attr, BOND_AFTER_ACTIVE, err);
+ bond_call_service_func(bdev, &curr_attr, BOND_BEFORE_ACTIVE, 0);
+ err = bond_upcmd_activate(bdev, &curr_attr);
+ bond_call_service_func(bdev, &curr_attr, BOND_AFTER_ACTIVE,
+ err);
} else if (is_bonded && bond_dev_is_activated(bdev)) {
- bond_call_service_func(bdev, &attr, BOND_BEFORE_MODIFY, 0);
- err = bond_upcmd_config(bdev, &attr);
- bond_call_service_func(bdev, &attr, BOND_AFTER_MODIFY, err);
+ bond_call_service_func(bdev, &curr_attr, BOND_BEFORE_MODIFY, 0);
+ err = bond_upcmd_config(bdev, &curr_attr);
+ bond_call_service_func(bdev, &curr_attr, BOND_AFTER_MODIFY,
+ err);
} else if (!is_bonded && bond_dev_is_activated(bdev)) {
- bond_call_service_func(bdev, &attr, BOND_BEFORE_DEACTIVE, 0);
+ bond_call_service_func(bdev, &curr_attr, BOND_BEFORE_DEACTIVE,
+ 0);
err = bond_upcmd_deactivate(bdev);
- bond_call_service_func(bdev, &attr, BOND_AFTER_DEACTIVE, err);
+ bond_call_service_func(bdev, &curr_attr, BOND_AFTER_DEACTIVE,
+ err);
}
-
if (err != 0)
- bond_master_err(bdev->bond->dev, "hinic5_bond: Do bond failed, err: %d\n", err);
-}
+ bond_master_err(bdev->bond->dev,
+ "hinic5_bond: Do bond failed, err: %d\n", err);
-static void bond_put_knl_bonding(struct bonding *bond)
-{
- dev_put(bond->dev);
+ hinic5_bond_detach_mutex_lock();
+ atomic_dec(&bdev->counter);
+ if (!bdev->tracker.is_bonded && atomic_read(&bdev->counter) == 0) {
+ for (user = HINIC5_BOND_USER_OVS; user < HINIC5_BOND_USER_NUM;
+ user++)
+ hinic5_bond_do_detach(user, bdev->bond_attr.bond_id);
+ }
+ hinic5_bond_detach_mutex_unlock();
}
static void bond_dev_deinit(struct hinic5_bond_dev *bdev)
{
- spin_lock(&bdev->lock);
- WRITE_ONCE(bdev->dead, true);
- spin_unlock(&bdev->lock);
-
- /* Block and wait for bond_work task to finish */
- cancel_delayed_work_sync(&bdev->bond_work);
- /* Block and wait for all srcu read operations to finish */
- synchronize_srcu(&bdev_srcu);
- if (bdev->wq) {
- destroy_workqueue(bdev->wq);
- }
if (bdev->bond != NULL) {
- bond_put_knl_bonding(bdev->bond);
+ bond_master_info(bdev->bond->dev,
+ "bond_dev_deinit, bond_id: %u\n",
+ bdev->bond_attr.bond_id);
+ dev_put(bdev->bond->dev);
bdev->bond = NULL;
}
kfree(bdev);
}
-static struct hinic5_bond_dev *bond_dev_init(struct bonding *bond, const char *name)
+static struct hinic5_bond_dev *bond_dev_init(struct bonding *bond,
+ const char *name)
{
struct hinic5_bond_dev *bdev = NULL;
+ int err = 0;
bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
if (bdev == NULL)
return NULL;
- bdev->wq = create_singlethread_workqueue("hinic5_bond_wq");
- if (!bdev->wq) {
- pr_err("hinic5_bond: Failed to create workqueue\n");
- goto bdev_wq_err;
- }
-
- if (strlen(name) >= sizeof(bdev->name)) {
- pr_err("hinic5_bond: bond name too long: %s (max %zu)\n",
- name, sizeof(bdev->name) - 1);
+ err = strncpy_s(bdev->name, sizeof(bdev->name), name, strlen(name));
+ if (err != 0) {
+ pr_err("hinic5_bond: Failed to init bond dev: %s\n", name);
goto bdev_name_err;
}
- strncpy(bdev->name, name, sizeof(bdev->name));
- INIT_DELAYED_WORK(&bdev->bond_work, bond_do_work);
+ atomic_set(&bdev->counter, 0);
bdev->status = BOND_DEV_STATUS_IDLE;
-
spin_lock_init(&bdev->lock);
-
dev_hold(bond->dev);
bdev->bond = bond;
-
return bdev;
-
bdev_name_err:
- destroy_workqueue(bdev->wq);
-bdev_wq_err:
kfree(bdev);
return NULL;
}
-static struct bonding *bond_get_knl_bonding(const char *name)
-{
- struct net_device *ndev_tmp = NULL;
-
- rtnl_lock();
- for_each_netdev(&init_net, ndev_tmp) {
- if (netif_is_bond_master(ndev_tmp) && (strcmp(ndev_tmp->name, name) == 0)) {
- dev_hold(ndev_tmp);
- rtnl_unlock();
- return netdev_priv(ndev_tmp);
- }
- }
- rtnl_unlock();
- return NULL;
-}
-
-static int bond_dev_release(struct hinic5_bond_dev *bdev)
+static void bond_dev_free(struct kref *ref)
{
- int err;
- u8 i;
+ u8 i = 0;
+ struct hinic5_bond_dev *bdev =
+ container_of(ref, struct hinic5_bond_dev, ref);
- err = bond_upcmd_deactivate(bdev);
- if (err != 0) {
- mutex_unlock(&g_bond_mutex);
- bond_master_err(bdev->bond->dev, "Failed to deactivate dev\n");
- return err;
- }
+ if (bond_upcmd_deactivate(bdev) != 0)
+ bond_master_warn(bdev->bond->dev, "Failed to deactivate dev\n");
for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- bond_master_info(bdev->bond->dev, "Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ bond_master_info(bdev->bond->dev,
+ "Free bond, id: %u mngr_cnt:%u\n", i,
+ bond_mngr.cnt);
break;
}
}
-
- mutex_unlock(&g_bond_mutex);
bond_dev_free_chip_bond_id(bdev);
bond_dev_deinit(bdev);
-
- return err;
+ bdev = NULL;
}
-static void bond_dev_free(struct kref *ref)
-{
- struct hinic5_bond_dev *bdev = NULL;
-
- bdev = container_of(ref, struct hinic5_bond_dev, ref);
- bond_dev_release(bdev);
-}
-
-static struct hinic5_bond_dev *bond_dev_alloc(const char *name, struct bonding *bond)
+static struct hinic5_bond_dev *bond_dev_alloc(const char *name,
+ struct bonding *bond)
{
struct hinic5_bond_dev *bdev = NULL;
u16 i;
bdev = bond_dev_init(bond, name);
- if (bdev == NULL) {
+ if (bdev == NULL)
return NULL;
- }
for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
- if ((bond_mngr.bond_dev != NULL) && (bond_mngr.bond_dev[i] == NULL)) {
+ if ((bond_mngr.bond_dev != NULL) &&
+ (bond_mngr.bond_dev[i] == NULL)) {
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- bond_master_info(bond->dev,
- "Create bond dev: %s, bond id: %u, bond cnt: %u\n",
- name, i, bond_mngr.cnt);
+ bond_master_info(
+ bond->dev,
+ "Create bond dev: %s, bond id: %u, bond cnt: %u\n",
+ name, i, bond_mngr.cnt);
break;
}
}
@@ -802,43 +840,14 @@ static struct hinic5_bond_dev *bond_dev_alloc(const char *name, struct bonding *
return bdev;
}
-static void bond_init_all_slave(struct hinic5_bond_dev *bdev, struct bonding *bond)
-{
- int i = 0, cnt = 0;
- struct slave *slave = NULL;
- struct list_head *iter = NULL;
- struct net_device *slave_ndev[BOND_PORT_MAX_NUM];
-
- rcu_read_lock();
- bond_for_each_slave_rcu(bond, slave, iter) {
- if (cnt >= BOND_PORT_MAX_NUM)
- break;
- slave_ndev[cnt] = slave->dev;
- dev_hold(slave_ndev[cnt++]);
- (void)iter;
- }
- rcu_read_unlock();
-
- /* TODO: Check if this flow is redundant, to be confirmed later */
- for (i = 0; i < cnt; ++i) {
- if (bond_dev_track_port(bdev, slave_ndev[i]) == PORT_INVALID_ID)
- continue;
- }
- for (i = 0; i < cnt; ++i)
- bond_handle_rtnl_event(slave_ndev[i]);
- bond_handle_rtnl_event(bond->dev);
-
- while (cnt != 0)
- dev_put(slave_ndev[--cnt]);
-}
-
-static struct hinic5_bond_dev *bond_dev_by_name(const char *name)
+static struct hinic5_bond_dev *hinic5_bond_get_dev_by_name(const char *name)
{
struct hinic5_bond_dev *bdev = NULL;
int i;
for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
- if (BDEV_IS_VALID(i) && (strcmp(bond_mngr.bond_dev[i]->name, name) == 0)) {
+ if (BDEV_IS_VALID(i) &&
+ (strcmp(bond_mngr.bond_dev[i]->name, name) == 0)) {
bdev = bond_mngr.bond_dev[i];
break;
}
@@ -847,74 +856,25 @@ static struct hinic5_bond_dev *bond_dev_by_name(const char *name)
return bdev;
}
-static void bond_dev_user_attach(struct hinic5_bond_dev *bdev, enum hinic5_bond_user user)
+static void bond_dev_attach_user(struct hinic5_bond_dev *bdev,
+ enum hinic5_bond_user user)
{
- u32 user_bitmap;
- if (user < 0 || user >= HINIC5_BOND_USER_NUM || bdev->slot_used[user] != 0) {
+ if (bdev->slot_used[user] != 0)
return;
- }
bdev->slot_used[user] = 1;
- if (kref_get_unless_zero(&bdev->ref) == 0) {
+ if (kref_get_unless_zero(&bdev->ref) == 0)
kref_init(&bdev->ref);
- } else {
- user_bitmap = bond_get_user_bitmap(bdev);
- bond_master_info(bdev->bond->dev, "Bond user %u attach bond %s, user_bitmap %#x\n",
- user, bdev->name, user_bitmap);
- queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
- }
}
-static void bond_dev_user_detach(struct hinic5_bond_dev *bdev,
- enum hinic5_bond_user user, bool *freed)
+static void bond_dev_detach_user(struct hinic5_bond_dev *bdev,
+ enum hinic5_bond_user user)
{
- u32 user_bitmap;
- if (user < 0 || user >= HINIC5_BOND_USER_NUM) {
+ if (bdev->slot_used[user] == 0)
return;
- }
-
- if (bdev->slot_used[user] != 0) {
- bdev->slot_used[user] = 0;
- if (kref_read(&bdev->ref) == 1)
- *freed = true;
- if (kref_put(&bdev->ref, bond_dev_free) == 0) {
- user_bitmap = bond_get_user_bitmap(bdev);
- bond_master_info(bdev->bond->dev, "Bond: user %u detach bond %s, " \
- "user_bitmap %#x\n", user, bdev->name, user_bitmap);
- queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
- }
- }
-}
-
-/* Bind bond when bond event is reported */
-int hinic5_bond_event_attach(struct bonding *bond, enum hinic5_bond_user user)
-{
- struct hinic5_bond_dev *bdev = NULL;
-
- if (bond->params.mode != BOND_MODE_8023AD &&
- bond->params.mode != BOND_MODE_XOR &&
- bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
- bond_master_err(bond->dev, "bond mode:%d is not supported\n", bond->params.mode);
- return -EINVAL;
- }
-
- mutex_lock(&g_bond_mutex);
- bdev = bond_dev_by_name(bond->dev->name);
- if (bdev == NULL) {
- bdev = bond_dev_alloc(bond->dev->name, bond);
- if (bdev == NULL) {
- mutex_unlock(&g_bond_mutex);
- return -ENODEV;
- }
- } else {
- bond_master_info(bdev->bond->dev,
- "Bond event attach %s already exist\n", bond->dev->name);
- }
- bond_dev_user_attach(bdev, user);
- mutex_unlock(&g_bond_mutex);
-
- return 0;
+ bdev->slot_used[user] = 0;
+ kref_put(&bdev->ref, bond_dev_free);
}
bool hinic5_bond_slave_is_match(struct bonding *bond)
@@ -922,53 +882,40 @@ bool hinic5_bond_slave_is_match(struct bonding *bond)
struct hinic5_lld_dev *lld_dev = NULL;
struct list_head *iter = NULL;
struct slave *slave = NULL;
- char chip_name[IFNAMSIZ] = {0};
- char tmp_name[IFNAMSIZ] = {0};
+ char chip_name[IFNAMSIZ] = { 0 };
+ char tmp_name[IFNAMSIZ] = { 0 };
int err = 0;
- if (!bond_has_slaves(bond)) {
- bond_master_info(bond->dev, "Have no slaves");
- return true;
- }
+ /* Have no slaves */
+ if (!bond_has_slaves(bond))
+ return false;
rcu_read_lock();
bond_for_each_slave_rcu(bond, slave, iter) {
+ /* Bond Slave device mismatch, is not hinic5 netdev */
lld_dev = hinic5_get_lld_dev_by_netdev(slave->dev);
- if (lld_dev == NULL) {
- bond_slave_warn(bond->dev, slave->dev, "Bond Slave device mismatch, is not hinic5 netdev\n");
+ if (lld_dev == NULL)
goto out;
- }
- /* If the function in bond group contains vf, print warning */
- if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
- bond_slave_warn(bond->dev, slave->dev, "Bond Slave device is VF\n");
- continue;;
- }
+ /* Bond Slave device is VF */
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF)
+ continue;
- err = hinic5_get_chip_name(lld_dev, tmp_name, sizeof(chip_name));
- if (err != 0) {
- bond_slave_err(bond->dev, slave->dev,
- "Bond Slave get chip name err %d\n", err);
+ /* Only support bond for same card */
+ err = hinic5_get_chip_name(lld_dev, tmp_name,
+ sizeof(chip_name));
+ if (err != 0)
goto out;
- }
-
if (strlen(chip_name) == 0) {
- memcpy(chip_name, tmp_name, sizeof(tmp_name));
+ (void)memcpy_s(chip_name, sizeof(chip_name), tmp_name,
+ sizeof(tmp_name));
continue;
}
-
- /* Only support bond for same card */
- if (strcmp(tmp_name, chip_name) != 0) {
- bond_slave_err(bond->dev, slave->dev,
- "Bond Slave not match err, bond dev chip_name %s, " \
- "slave chip name %s\n",
- chip_name, tmp_name);
+ if (strcmp(tmp_name, chip_name) != 0)
goto out;
- }
}
rcu_read_unlock();
return true;
-
out:
rcu_read_unlock();
return false;
@@ -983,152 +930,187 @@ int hinic5_bond_get_id_by_name(u8 *bond_name, u16 *bond_id)
return -EINVAL;
}
+ mutex_lock(&g_bond_mutex);
for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
- if (!BDEV_IS_VALID(i)) {
- continue;
- }
-
- if (strcmp(bond_name, bond_mngr.bond_dev[i]->name) == 0) {
+ if (BDEV_IS_VALID(i) &&
+ strcmp(bond_name, bond_mngr.bond_dev[i]->name) == 0) {
*bond_id = bond_mngr.bond_dev[i]->bond_attr.bond_id;
+ mutex_unlock(&g_bond_mutex);
return 0;
}
}
+ mutex_unlock(&g_bond_mutex);
return -EINVAL;
}
+EXPORT_SYMBOL(hinic5_bond_get_id_by_name);
-int hinic5_bond_attach(const char *name, enum hinic5_bond_user user, u16 *bond_id)
+/**
+ * @brief 进行bond解绑
+ * @param[in] user 上层业务类型
+ * @param[in] bond_id 表示bond的id号
+ * @return: void
+ */
+void hinic5_bond_do_detach(enum hinic5_bond_user user, u16 bond_id)
{
- struct hinic5_bond_dev *bdev = NULL;
- struct bonding *bond = NULL;
- bool is_new_dev = false;
+ mutex_lock(&g_bond_mutex);
+ if (BDEV_IS_VALID(bond_id))
+ bond_dev_detach_user(bond_mngr.bond_dev[bond_id], user);
+ mutex_unlock(&g_bond_mutex);
+}
- if (user >= HINIC5_BOND_USER_NUM)
- return -EINVAL;
+static int hinic5_bond_detach_sync(enum hinic5_bond_user user, u16 bond_id)
+{
+ ulong jiffies_end = 0;
- if (!name || !bond_id)
+ if (!HINIC5_BOND_ID_IS_VALID(bond_id)) {
+ pr_warn("hinic5_bond: user:%u Invalid bond id:%u to delete\n",
+ user, bond_id);
return -EINVAL;
-
- bond = bond_get_knl_bonding(name);
- if (bond == NULL) {
- pr_warn("hinic5_bond: Kernel bond %s not exist.\n", name);
- return -ENODEV;
}
- if (bond->params.mode != BOND_MODE_8023AD &&
- bond->params.mode != BOND_MODE_XOR &&
- bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
- bond_master_warn(bond->dev, "bond mode:%d is not supported\n", bond->params.mode);
+ jiffies_end =
+ jiffies + msecs_to_jiffies(HINIC5_BOND_DETACH_WAIT_TIMEOUT);
+ do {
+ if (time_after_eq(jiffies, jiffies_end)) {
+ pr_err("bond detach timeout: bond_id=%u\n", bond_id);
+ return -ETIMEDOUT;
+ }
+ hinic5_bond_detach_mutex_lock();
+ mutex_lock(&g_bond_mutex);
+ /* 排空异步bond_do_work */
+ if (!BDEV_IS_VALID(bond_id) ||
+ atomic_read(&bond_mngr.bond_dev[bond_id]->counter) == 0) {
+ mutex_unlock(&g_bond_mutex);
+ hinic5_bond_do_detach(user, bond_id);
+ hinic5_bond_detach_mutex_unlock();
+ return 0;
+ }
+ mutex_unlock(&g_bond_mutex);
+ hinic5_bond_detach_mutex_unlock();
+ usleep_range(HINIC5_BOND_DETACH_USLEEP_TIME_MIN,
+ HINIC5_BOND_DETACH_USLEEP_TIME_MAX);
+ } while (true);
+}
+
+int hinic5_bond_detach(u16 bond_id, enum hinic5_bond_user user)
+{
+ return hinic5_bond_detach_sync(user, bond_id);
+}
+EXPORT_SYMBOL(hinic5_bond_detach);
+
+int hinic5_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
+{
+ if (!HINIC5_BOND_ID_IS_VALID(bond_id) || !uplink_id) {
+ pr_warn("hinic5_bond: Invalid args, bond id: %u, uplink: %d\n",
+ bond_id, !!uplink_id);
+ return -EINVAL;
}
- /* Need to return bond id, so only print warning log */
- if (!hinic5_bond_slave_is_match(bond)) {
- bond_master_warn(bond->dev, "Bond attach slaves invalid or not exist\n");
+ mutex_lock(&g_bond_mutex);
+ if (BDEV_IS_VALID(bond_id))
+ *uplink_id = bond_gen_uplink_id(bond_mngr.bond_dev[bond_id]);
+ mutex_unlock(&g_bond_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic5_bond_get_uplink_id);
+
+/**
+ * @brief 进行bond绑定
+ * @param[in] user 上层业务类型
+ * @param[in] bond 协议栈 bond 指针
+ * @param[in] from_event true 表示监听协议栈时绑定bond,false 表示用户注册时绑定bond
+ * @return: 返回函数执行结果,0为成功,非0失败
+ */
+int hinic5_bond_do_attach(enum hinic5_bond_user user, struct bonding *bond,
+ bool from_event)
+{
+ struct hinic5_bond_dev *bdev = NULL;
+ bool is_new_dev = false;
+
+ dev_hold(bond->dev);
+ if (bond->params.mode != BOND_MODE_8023AD &&
+ bond->params.mode != BOND_MODE_XOR &&
+ bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
+ dev_put(bond->dev);
+ bond_master_warn(bond->dev, "bond mode:%d is not supported\n",
+ bond->params.mode);
+ return -EINVAL;
}
mutex_lock(&g_bond_mutex);
- bdev = bond_dev_by_name(name);
+ bdev = hinic5_bond_get_dev_by_name(bond->dev->name);
if (bdev == NULL) {
/* if bond_dev_alloc return success, will increment the bond netdev reference count. */
- bdev = bond_dev_alloc(name, bond);
+ bdev = bond_dev_alloc(bond->dev->name, bond);
if (bdev == NULL) {
mutex_unlock(&g_bond_mutex);
- bond_put_knl_bonding(bond);
+ dev_put(bond->dev);
return -ENODEV;
}
is_new_dev = true;
} else {
- bond_master_info(bdev->bond->dev, "Attach %s already exist\n", name);
+ bond_master_info(bdev->bond->dev, "Attach %s already exist\n",
+ bond->dev->name);
}
-
- bond_dev_user_attach(bdev, user);
+ bond_dev_attach_user(bdev, user);
mutex_unlock(&g_bond_mutex);
- if (is_new_dev) {
- bond_init_all_slave(bdev, bond);
- flush_delayed_work(&bdev->bond_work);
- }
-
- bond_put_knl_bonding(bond);
+ if (is_new_dev && !from_event)
+ bond_handle_rtnl_event(bond->dev); /* init slave device */
- *bond_id = bdev->bond_attr.bond_id;
+ dev_put(bond->dev);
return 0;
}
-EXPORT_SYMBOL(hinic5_bond_attach);
-int hinic5_bond_detach(u16 bond_id, enum hinic5_bond_user user)
+int hinic5_bond_attach(const char *name, enum hinic5_bond_user user,
+ u16 *bond_id)
{
- int err = 0;
- bool lock_freed = false;
- if (user >= HINIC5_BOND_USER_NUM) {
- pr_err("Bond attach user num error: %u\n", user);
- return -EINVAL;
- }
+ struct net_device *ndev = NULL;
+ struct bonding *bond = NULL;
+ int ret = 0;
- if (!HINIC5_BOND_ID_IS_VALID(bond_id)) {
- pr_warn("hinic5_bond: user:%u Invalid bond id:%u to delete\n", user, bond_id);
+ if (!name || user >= HINIC5_BOND_USER_NUM)
return -EINVAL;
- }
- mutex_lock(&g_bond_mutex);
- if (!BDEV_IS_VALID(bond_id))
- err = -ENODEV;
- else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
-
- if (!lock_freed)
- mutex_unlock(&g_bond_mutex);
- return err;
-}
-EXPORT_SYMBOL(hinic5_bond_detach);
-
-void hinic5_bond_clean_user(enum hinic5_bond_user user)
-{
- int i = 0;
- bool lock_freed = false;
-
- if (user >= HINIC5_BOND_USER_NUM) {
- pr_err("Bond clean user num error: %u\n", user);
- return;
- }
+ rtnl_lock();
+ for_each_netdev(&init_net, ndev) {
+ bond = netdev_priv(ndev);
+ if (!netif_is_bond_master(ndev) ||
+ strcmp(ndev->name, name) != 0 ||
+ !hinic5_bond_slave_is_match(bond))
+ continue;
- mutex_lock(&g_bond_mutex);
- for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
- if (BDEV_IS_VALID(i)) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
- if (lock_freed) {
- mutex_lock(&g_bond_mutex);
- lock_freed = false;
- }
+ hinic5_bond_detach_mutex_lock();
+ if (hinic5_bond_can_attach(user, bond)) {
+ bond_master_info(bond->dev,
+ "bond try attach user:%u, name: %s\n",
+ user, name);
+ ret = hinic5_bond_do_attach(user, bond, false);
+ if (ret != 0)
+ bond_master_err(bond->dev,
+ "Failed to attach bond\n");
}
+ hinic5_bond_detach_mutex_unlock();
+ break;
}
- if (!lock_freed)
- mutex_unlock(&g_bond_mutex);
+ rtnl_unlock();
+ if (ret == 0)
+ ret = hinic5_bond_get_id_by_name((u8 *)name, bond_id);
+ return ret;
}
-EXPORT_SYMBOL(hinic5_bond_clean_user);
+EXPORT_SYMBOL(hinic5_bond_attach);
-int hinic5_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
+int hinic5_bond_register(enum hinic5_bond_user user, struct bond_srv_func *func)
{
- if (!HINIC5_BOND_ID_IS_VALID(bond_id) || !uplink_id) {
- pr_warn("hinic5_bond: Invalid args, bond id: %u, uplink: %d\n",
- bond_id, !!uplink_id);
- return -EINVAL;
- }
-
- mutex_lock(&g_bond_mutex);
- if (BDEV_IS_VALID(bond_id))
- *uplink_id = bond_gen_uplink_id(bond_mngr.bond_dev[bond_id]);
- mutex_unlock(&g_bond_mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(hinic5_bond_get_uplink_id);
+ struct net_device *ndev = NULL;
+ struct bonding *bond = NULL;
+ int ret = 0;
-int hinic5_bond_register_service_func(enum hinic5_bond_user user, struct bond_srv_func *func)
-{
+ /* 用户user注册服务函数 */
if (user >= HINIC5_BOND_USER_NUM || func == NULL)
return -EINVAL;
-
mutex_lock(&g_bond_event_func_mutex);
g_bond_event_func[user][BOND_BEFORE_ACTIVE] = func->before_active;
g_bond_event_func[user][BOND_AFTER_ACTIVE] = func->after_active;
@@ -1142,15 +1124,42 @@ int hinic5_bond_register_service_func(enum hinic5_bond_user user, struct bond_sr
g_bond_attach_func[user] = func->can_attach;
mutex_unlock(&g_bond_attach_func_mutex);
+ /* 用户user绑定半卸载bond */
+ rtnl_lock();
+ for_each_netdev(&init_net, ndev) {
+ bond = netdev_priv(ndev);
+ if (!netif_is_bond_master(ndev) ||
+ !hinic5_bond_slave_is_match(bond))
+ continue;
+
+ hinic5_bond_detach_mutex_lock();
+ if (hinic5_bond_can_attach(user, bond)) {
+ bond_master_info(
+ bond->dev,
+ "bond srv try attach user:%u name %s\n", user,
+ bond->dev->name);
+ ret = hinic5_bond_do_attach(user, bond, false);
+ if (ret != 0)
+ bond_master_err(
+ bond->dev,
+ "Failed to attach bond for registration\n");
+ }
+ hinic5_bond_detach_mutex_unlock();
+ }
+ rtnl_unlock();
return 0;
}
-EXPORT_SYMBOL(hinic5_bond_register_service_func);
+EXPORT_SYMBOL(hinic5_bond_register);
-int hinic5_bond_unregister_service_func(enum hinic5_bond_user user)
+int hinic5_bond_unregister(enum hinic5_bond_user user)
{
- if (user >= HINIC5_BOND_USER_NUM) {
+ u16 bond_id = 0;
+ if (user >= HINIC5_BOND_USER_NUM)
return -EINVAL;
- }
+ /* 解绑当前user所有bond */
+ for (bond_id = HINIC5_BOND_START_ID; bond_id < HINIC5_MAX_BODN_ID_NUM;
+ bond_id++)
+ (void)hinic5_bond_detach_sync(user, bond_id);
mutex_lock(&g_bond_event_func_mutex);
g_bond_event_func[user][BOND_BEFORE_ACTIVE] = NULL;
@@ -1167,13 +1176,14 @@ int hinic5_bond_unregister_service_func(enum hinic5_bond_user user)
return 0;
}
-EXPORT_SYMBOL(hinic5_bond_unregister_service_func);
+EXPORT_SYMBOL(hinic5_bond_unregister);
int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info)
{
struct bond_tracker *tracker = NULL;
int size;
int i;
+ int err = 0;
if (!info || !HINIC5_BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic5_bond: Invalid args, info: %d, bond id: %u\n",
@@ -1183,8 +1193,7 @@ int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info)
size = ARRAY_LEN(info->slaves_name);
if (size < BOND_PORT_MAX_NUM) {
- pr_warn("hinic5_bond: Invalid args, size: %u\n",
- size);
+ pr_warn("hinic5_bond: Invalid args, size: %u\n", size);
return -EINVAL;
}
@@ -1198,14 +1207,18 @@ int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info)
info->cnt = 0;
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if ((BITMAP_JUDGE(info->slaves, i) != 0) && tracker->ndev[i]) {
- if (strlen(tracker->ndev[i]->name) >= sizeof(info->slaves_name[0])) {
- bond_master_err(bond_mngr.bond_dev[bond_id]->bond->dev,
- "hinic5_bond: port name too long: %s (max %zu)\n",
- tracker->ndev[i]->name, sizeof(info->slaves_name[0]) - 1);
+ err = strncpy_s(info->slaves_name[info->cnt],
+ sizeof(info->slaves_name[0]),
+ tracker->ndev[i]->name,
+ sizeof(info->slaves_name[0]) - 1);
+ if (err != 0) {
+ bond_master_err(
+ bond_mngr.bond_dev[bond_id]->bond->dev,
+ "hinic5_bond: port num %d strncpy failed\n",
+ i);
mutex_unlock(&g_bond_mutex);
return -EINVAL;
}
- strncpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, sizeof(info->slaves_name[0]));
info->cnt++;
}
}
@@ -1214,16 +1227,16 @@ int hinic5_bond_get_slaves(u16 bond_id, struct hinic5_bond_info_s *info)
}
EXPORT_SYMBOL(hinic5_bond_get_slaves);
-struct net_device *hinic5_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic5_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic5_bond_dev *bdev = NULL;
- if (!bond_name || port_id >= BOND_PORT_MAX_NUM) {
+ if (!bond_name || port_id >= BOND_PORT_MAX_NUM)
return NULL;
- }
mutex_lock(&g_bond_mutex);
- bdev = bond_dev_by_name(bond_name);
+ bdev = hinic5_bond_get_dev_by_name(bond_name);
if (bdev == NULL) {
mutex_unlock(&g_bond_mutex);
return NULL;
@@ -1233,7 +1246,8 @@ struct net_device *hinic5_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic5_bond_get_netdev_by_portid);
-int hinic5_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic5_bond_get_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic5_bond_dev *bdev = NULL;
int i;
@@ -1243,7 +1257,8 @@ int hinic5_get_bond_tracker_by_name(const char *name, struct bond_tracker *track
mutex_lock(&g_bond_mutex);
for (i = HINIC5_BOND_START_ID; i < HINIC5_MAX_BODN_ID_NUM; i++) {
- if (BDEV_IS_VALID(i) && (strcmp(bond_mngr.bond_dev[i]->name, name) == 0)) {
+ if (BDEV_IS_VALID(i) &&
+ (strcmp(bond_mngr.bond_dev[i]->name, name) == 0)) {
bdev = bond_mngr.bond_dev[i];
spin_lock(&bdev->lock);
*tracker = bdev->tracker;
@@ -1255,44 +1270,49 @@ int hinic5_get_bond_tracker_by_name(const char *name, struct bond_tracker *track
mutex_unlock(&g_bond_mutex);
return -ENODEV;
}
-EXPORT_SYMBOL(hinic5_get_bond_tracker_by_name);
+EXPORT_SYMBOL(hinic5_bond_get_tracker_by_name);
int hinic5_bond_init(void)
{
- int ret = init_srcu_struct(&bdev_srcu);
- if (ret != 0) {
- pr_err("Failed to initialize bdev_srcu\n");
- return -ENOMEM;
- }
+ int ret = 0;
- bond_mngr.bond_dev = kzalloc(sizeof(struct hinic5_bond_dev *) * HINIC5_MAX_BODN_ID_NUM, GFP_KERNEL);
+ bond_mngr.bond_dev = kzalloc(sizeof(struct hinic5_bond_dev *) *
+ HINIC5_MAX_BODN_ID_NUM,
+ GFP_KERNEL);
if (bond_mngr.bond_dev == NULL) {
pr_err("Bond dev kzalloc failed\n");
return -ENOMEM;
}
INIT_LIST_HEAD(&bond_mngr.bond_chip_list);
+ bond_mngr.wq = create_singlethread_workqueue("hinic5_bond_mngr_wq");
+ if (!bond_mngr.wq) {
+ pr_err("Failed to create hinic5 bond workqueue\n");
+ ret = -ENOMEM;
+ goto bond_dev_err;
+ }
+
ret = bond_enable_netdev_event();
if (ret != 0) {
pr_err("Bond enable netdev event err: %d\n", ret);
- goto bond_dev_err;
+ goto bond_wq_err;
}
-
return 0;
-
+bond_wq_err:
+ destroy_workqueue(bond_mngr.wq);
bond_dev_err:
kfree(bond_mngr.bond_dev);
bond_mngr.bond_dev = NULL;
-
return ret;
}
void hinic5_bond_deinit(void)
{
bond_disable_netdev_event();
+ if (bond_mngr.wq != NULL)
+ destroy_workqueue(bond_mngr.wq);
if (bond_mngr.bond_dev) {
kfree(bond_mngr.bond_dev);
bond_mngr.bond_dev = NULL;
}
- cleanup_srcu_struct(&bdev_srcu);
}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_event.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_event.c
index 8297345cc..a09fe4ff2 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_event.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_event.c
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bond_event.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [BOND]" fmt
@@ -18,16 +12,16 @@
#include <linux/net.h>
#include <linux/netdevice.h>
+#include "ossl_knl.h"
+#include "bond_common_defs.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
#include "hinic5_hw.h"
#include "hinic5_lld.h"
-#include "cfg_mgmt_mpu_cmd_defs.h"
#include "hinic5_srv_nic.h"
-#include "hinic5_nic_dev.h"
-#include "bond_common_defs.h"
-#include "hinic5_bond.h"
#include "hinic5_bond_inner.h"
-static u8 bond_get_slaves_bitmap(struct hinic5_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic5_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -38,9 +32,9 @@ static u8 bond_get_slaves_bitmap(struct hinic5_bond_dev *bdev, struct bonding *b
rcu_read_lock();
bond_for_each_slave_rcu(bond, slave, iter) {
lld_dev = hinic5_get_lld_dev_by_netdev(slave->dev);
- if (lld_dev == NULL || hinic5_func_type(lld_dev->hwdev) == TYPE_VF)
+ if (lld_dev == NULL ||
+ hinic5_func_type(lld_dev->hwdev) == TYPE_VF)
continue;
-
port_id = hinic5_physical_port_id(lld_dev->hwdev);
BITMAP_SET(bitmap, port_id);
(void)iter;
@@ -53,30 +47,33 @@ static u8 bond_get_slaves_bitmap(struct hinic5_bond_dev *bdev, struct bonding *b
static void bond_update_attr(struct hinic5_bond_dev *bdev, struct bonding *bond)
{
spin_lock(&bdev->lock);
- bdev->new_attr.bond_mode = (u16)bond->params.mode;
- bdev->new_attr.bond_id = bdev->bond_attr.bond_id;
- bdev->new_attr.up_delay = (u16)bond->params.updelay;
- bdev->new_attr.down_delay = (u16)bond->params.downdelay;
- bdev->new_attr.slaves = 0;
- bdev->new_attr.active_slaves = 0;
- bdev->new_attr.lacp_collect_slaves = 0;
- bdev->new_attr.first_roce_func = BOND_DEFAULT_ROCE_FUNC;
+ bdev->curr_attr.bond_mode = (u16)bond->params.mode;
+ bdev->curr_attr.bond_id = bdev->bond_attr.bond_id;
+ bdev->curr_attr.up_delay = (u16)bond->params.updelay;
+ bdev->curr_attr.down_delay = (u16)bond->params.downdelay;
+ bdev->curr_attr.slaves = 0;
+ bdev->curr_attr.active_slaves = 0;
+ bdev->curr_attr.lacp_collect_slaves = 0;
+ bdev->curr_attr.bond_pf_bitmap = 0;
+ bdev->curr_attr.first_roce_func = BOND_DEFAULT_ROCE_FUNC;
/* Only support L2/L34/L23 three policy */
if (bond->params.xmit_policy <= BOND_XMIT_POLICY_LAYER23) {
- bdev->new_attr.xmit_hash_policy = (u8)bond->params.xmit_policy;
+ bdev->curr_attr.xmit_hash_policy = (u8)bond->params.xmit_policy;
} else {
- bond_master_warn(bdev->bond->dev, "Invalid hash policy %u (not layer2/34/23), defaulting to layer2\n",
- (u8)bond->params.xmit_policy);
- bdev->new_attr.xmit_hash_policy = BOND_XMIT_POLICY_LAYER2;
+ bond_master_warn(
+ bdev->bond->dev,
+ "Invalid hash policy %u (not layer2/34/23), defaulting to layer2\n",
+ (u8)bond->params.xmit_policy);
+ bdev->curr_attr.xmit_hash_policy = BOND_XMIT_POLICY_LAYER2;
}
- bdev->new_attr.slaves = bond_get_slaves_bitmap(bdev, bond);
+ bdev->curr_attr.slaves = bond_get_slaves_bitmap(bdev, bond);
spin_unlock(&bdev->lock);
}
static u8 bond_get_netdev_idx(const struct hinic5_bond_dev *bdev,
- const struct net_device *ndev)
+ const struct net_device *ndev)
{
u8 i;
@@ -88,7 +85,8 @@ static u8 bond_get_netdev_idx(const struct hinic5_bond_dev *bdev,
return PORT_INVALID_ID;
}
-static void bond_pf_bitmap_set(struct hinic5_bond_dev *bdev, struct bond_attr *attr, u8 port_id)
+static void bond_pf_bitmap_set(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr, u8 port_id)
{
struct hinic5_lld_dev *lld_dev = NULL;
u8 pf_id;
@@ -100,31 +98,50 @@ static void bond_pf_bitmap_set(struct hinic5_bond_dev *bdev, struct bond_attr *a
}
pf_id = hinic5_pf_id_of_vf(lld_dev->hwdev);
- BITMAP_SET(attr->bond_pf_bitmap, pf_id);
+ BITMAP_SET(curr_attr->bond_pf_bitmap, pf_id);
+}
+
+static bool bond_eval_bonding_stats(const struct hinic5_bond_dev *bdev)
+{
+ return bdev->tracker.cnt > 0;
}
-static void bond_dev_untrack_port(struct hinic5_bond_dev *bdev, u8 port_id)
+static void bond_update_slave_info(struct hinic5_bond_dev *bdev,
+ struct bond_attr *curr_attr)
{
- u32 track_cnt = 0;
- const struct net_device *untrack_ndev = NULL;
+ struct net_device *ndev = NULL;
+ u8 port_id;
- spin_lock(&bdev->lock);
- if (bdev->tracker.ndev[port_id] != NULL) {
- untrack_ndev = bdev->tracker.ndev[port_id];
- track_cnt = --bdev->tracker.cnt;
- bdev->tracker.ndev[port_id] = NULL;
+ /* if bond dev down(ifconfig down), slave dev is up, should not set active slaves */
+ if (!netif_running(bdev->bond->dev))
+ return;
+
+ if (curr_attr->bond_mode == BOND_MODE_ACTIVEBACKUP) {
+ rcu_read_lock();
+ ndev = bond_option_active_slave_get_rcu(bdev->bond);
+ rcu_read_unlock();
+ }
+
+ for (port_id = 0; port_id < BOND_PORT_MAX_NUM; port_id++) {
+ if (bdev->tracker.netdev_state[port_id].tx_enabled == 0)
+ continue;
+
+ if (curr_attr->bond_mode == BOND_MODE_8023AD) {
+ BITMAP_SET(curr_attr->active_slaves, port_id);
+ BITMAP_SET(curr_attr->lacp_collect_slaves, port_id);
+ } else if (curr_attr->bond_mode == BOND_MODE_XOR) {
+ BITMAP_SET(curr_attr->active_slaves, port_id);
+ } else if (ndev && (ndev == bdev->tracker.ndev[port_id])) {
+ /* BOND_MODE_ACTIVEBACKUP */
+ BITMAP_SET(curr_attr->active_slaves, port_id);
+ }
}
- spin_unlock(&bdev->lock);
- if (track_cnt == 0)
- bond_dev_free_chip_bond_id(bdev);
- if (untrack_ndev)
- bond_master_info(bdev->bond->dev, "untrack port:%u, untrack ndev: %s, tracker cnt: %u\n",
- port_id, untrack_ndev->name, track_cnt);
}
static void bond_slave_event(struct hinic5_bond_dev *bdev, struct slave *slave)
{
- /* Compatible with low version kernel socket listen event dynamically adding slave PF */
+ struct hinic5_bond_work *bond_work = NULL;
+ /* 兼容低版本内核socket监听事件动态添加slave PF */
u8 port_id = bond_get_netdev_idx(bdev, slave->dev);
if (port_id == PORT_INVALID_ID)
port_id = bond_dev_track_port(bdev, slave->dev);
@@ -133,31 +150,43 @@ static void bond_slave_event(struct hinic5_bond_dev *bdev, struct slave *slave)
spin_lock(&bdev->lock);
bdev->tracker.netdev_state[port_id].link_up = bond_slave_is_up(slave);
- bdev->tracker.netdev_state[port_id].tx_enabled = bond_slave_is_up(slave) && bond_is_active_slave(slave);
+ bdev->tracker.netdev_state[port_id].tx_enabled =
+ bond_slave_is_up(slave) && bond_is_active_slave(slave);
spin_unlock(&bdev->lock);
- /* If bdev is dead, terminate the flow */
- if (unlikely(READ_ONCE(bdev->dead)))
- return;
- queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
-}
-static bool bond_eval_bonding_stats(const struct hinic5_bond_dev *bdev, struct bonding *bond)
-{
- return bdev->tracker.cnt > 0;
+ for (port_id = 0; port_id < BOND_PORT_MAX_NUM; port_id++) {
+ if (BITMAP_JUDGE(bdev->curr_attr.slaves, port_id) != 0)
+ bond_pf_bitmap_set(bdev, &bdev->curr_attr, port_id);
+ }
+
+ bond_update_slave_info(bdev, &bdev->curr_attr);
+
+ bond_work = kzalloc(sizeof(*bond_work), GFP_KERNEL);
+ if (!bond_work)
+ return;
+ bond_work->bdev = bdev;
+ bond_work->curr_attr = bdev->curr_attr;
+ INIT_DELAYED_WORK(&bond_work->work, bond_do_work);
+ atomic_inc(&bdev->counter);
+ queue_delayed_work(hinic5_bond_get_mngr_wq(), &bond_work->work, 0);
}
-static void bond_master_event(struct hinic5_bond_dev *bdev, struct bonding *bond)
+static void bond_master_event(struct hinic5_bond_dev *bdev,
+ struct bonding *bond)
{
u8 port_id = 0;
int i = 0, cnt = 0;
struct slave *slave = NULL;
struct list_head *iter = NULL;
+ struct hinic5_bond_work *bond_work = NULL;
- bool slave_is_up[BOND_PORT_MAX_NUM] = {false};
- bool slave_is_active[BOND_PORT_MAX_NUM] = {false};
- struct net_device *slave_ndev[BOND_PORT_MAX_NUM]; /* Temporarily store network device pointers*/
+ bool slave_is_up[BOND_PORT_MAX_NUM] = { false };
+ bool slave_is_active[BOND_PORT_MAX_NUM] = { false };
+ struct net_device *slave_ndev[BOND_PORT_MAX_NUM] = {
+ NULL
+ }; /* 暂存网卡设备指针 */
- /* No mutex allowed within rcu lock */
+ /* rcu锁内不能有mutex */
rcu_read_lock();
bond_for_each_slave_rcu(bond, slave, iter) {
if (cnt >= BOND_PORT_MAX_NUM)
@@ -170,7 +199,7 @@ static void bond_master_event(struct hinic5_bond_dev *bdev, struct bonding *bond
}
rcu_read_unlock();
- /* Dynamic add Slave PF scenario */
+ /* 添加 Slave PF 场景 */
for (i = 0; i < cnt; ++i) {
port_id = bond_get_netdev_idx(bdev, slave_ndev[i]);
if (port_id == PORT_INVALID_ID) {
@@ -179,7 +208,8 @@ static void bond_master_event(struct hinic5_bond_dev *bdev, struct bonding *bond
continue;
spin_lock(&bdev->lock);
- bdev->tracker.netdev_state[port_id].link_up = slave_is_up[i];
+ bdev->tracker.netdev_state[port_id].link_up =
+ slave_is_up[i];
bdev->tracker.netdev_state[port_id].tx_enabled =
slave_is_up[i] && slave_is_active[i];
spin_unlock(&bdev->lock);
@@ -187,28 +217,39 @@ static void bond_master_event(struct hinic5_bond_dev *bdev, struct bonding *bond
}
while (cnt != 0)
dev_put(slave_ndev[--cnt]);
- /* TODO: For logic completeness, spinlock modify bdev needs to check bdev->dead status,
- This issue will be uniformly modified when attach/detach new solution is modified */
- spin_lock(&bdev->lock);
- bdev->tracker.is_bonded = bond_eval_bonding_stats(bdev, bond);
- spin_unlock(&bdev->lock);
- /* Dynamic delete Slave PF scenario */
+ /* 删除 Slave PF 场景 */
for (port_id = 0; port_id < BOND_PORT_MAX_NUM; port_id++) {
- /* If new bond_attr has no slave pf but old bond_attr has slave pf,
- need to delete old bond_attr's slave PF */
- if (BITMAP_JUDGE(bdev->new_attr.slaves, port_id) == 0) {
- if (BITMAP_JUDGE(bdev->bond_attr.slaves, port_id) != 0) {
+ /* 新 bond_attr 没有 slave pf 但是旧 bond_attr 有 slave pf, 需要删除旧 bond_attr 的 slave PF */
+ if (BITMAP_JUDGE(bdev->curr_attr.slaves, port_id) == 0) {
+ if (BITMAP_JUDGE(bdev->prev_attr.slaves, port_id) !=
+ 0) {
bond_dev_untrack_port(bdev, port_id);
+
+ spin_lock(&bdev->lock);
+ bdev->tracker.netdev_state[port_id].link_up = 0;
+ bdev->tracker.netdev_state[port_id].tx_enabled =
+ 0;
+ spin_unlock(&bdev->lock);
}
continue;
}
- bond_pf_bitmap_set(bdev, &bdev->new_attr, port_id);
+ bond_pf_bitmap_set(bdev, &bdev->curr_attr, port_id);
}
- /* Terminate the flow if bdev is dead */
- if (unlikely(READ_ONCE(bdev->dead)))
+
+ spin_lock(&bdev->lock);
+ bdev->tracker.is_bonded = bond_eval_bonding_stats(bdev);
+ spin_unlock(&bdev->lock);
+ bond_update_slave_info(bdev, &bdev->curr_attr);
+
+ bond_work = kzalloc(sizeof(*bond_work), GFP_KERNEL);
+ if (!bond_work)
return;
- queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ bond_work->bdev = bdev;
+ bond_work->curr_attr = bdev->curr_attr;
+ INIT_DELAYED_WORK(&bond_work->work, bond_do_work);
+ atomic_inc(&bdev->counter);
+ queue_delayed_work(hinic5_bond_get_mngr_wq(), &bond_work->work, 0);
}
void bond_handle_rtnl_event(struct net_device *ndev)
@@ -217,14 +258,14 @@ void bond_handle_rtnl_event(struct net_device *ndev)
struct bonding *bond = NULL;
struct slave *slave = NULL;
struct hinic5_lld_dev *lld_dev = NULL;
- int srcu_idx = 0;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
lld_dev = hinic5_get_lld_dev_by_netdev(ndev);
- if (!lld_dev || hinic5_func_type(lld_dev->hwdev) == TYPE_VF)
+ if (lld_dev == NULL ||
+ hinic5_func_type(lld_dev->hwdev) == TYPE_VF)
return;
slave = bond_slave_get_rtnl(ndev);
if (slave) {
@@ -235,73 +276,60 @@ void bond_handle_rtnl_event(struct net_device *ndev)
if (bond == NULL || bdev == NULL)
return;
- /* TODO: Temporarily solve bdev async timing issue */
- srcu_idx = srcu_read_lock(&bdev_srcu);
- if (!bdev || unlikely(READ_ONCE(bdev->dead))) {
- srcu_read_unlock(&bdev_srcu, srcu_idx);
-
- return;
- }
-
bond_update_attr(bdev, bond);
if (slave)
bond_slave_event(bdev, slave);
else
bond_master_event(bdev, bond);
-
- srcu_read_unlock(&bdev_srcu, srcu_idx);
+ bdev->prev_attr = bdev->curr_attr;
}
-/* If service registers attach_func, it will try to bind bond */
+/* 如果服务注册了attach_func会尝试绑定bond */
void bond_try_attach_user(struct net_device *ndev)
{
u32 user;
+ int ret = 0;
struct bonding *bond = NULL;
struct hinic5_bond_dev *bdev = NULL;
- if (!netif_is_bond_master(ndev))
- return;
-
bond = netdev_priv(ndev);
- /* if slave invalid or not exist, don't alloc bdev */
- if (!hinic5_bond_slave_is_match(bond)) {
- bond_master_warn(ndev, "Bond try attach user slaves invalid or not exist\n");
+ if (!netif_is_bond_master(ndev) || !hinic5_bond_slave_is_match(bond))
return;
- }
- if (bond->params.mode != BOND_MODE_ACTIVEBACKUP &&
- bond->params.mode != BOND_MODE_XOR &&
- bond->params.mode != BOND_MODE_8023AD) {
- return;
- }
bdev = bond_get_bdev(bond);
for (user = HINIC5_BOND_USER_OVS; user < HINIC5_BOND_USER_NUM; user++) {
if (bdev && bdev->slot_used[user] != 0)
continue;
- if (bond_call_srv_attach_func(user, bond)) {
- bond_master_info(bond->dev, "bond try attach user:%d name %s\n",
- user, bond->dev->name);
- hinic5_bond_event_attach(bond, user);
+ if (hinic5_bond_can_attach(user, bond)) {
+ bond_master_info(bond->dev,
+ "bond try attach user:%u name %s\n",
+ user, bond->dev->name);
+ ret = hinic5_bond_do_attach(user, bond, true);
+ if (ret != 0)
+ bond_master_err(
+ bond->dev,
+ "Failed to attach bond for event monitor\n");
}
}
}
#if defined(HAVE_NETDEV_CHANGEUPPER)
-int bond_notifier_netdev_event(struct notifier_block *self, unsigned long event, void *ptr)
+int bond_notifier_netdev_event(struct notifier_block *self, unsigned long event,
+ void *ptr)
{
struct net_device *ndev = NULL;
struct netdev_notifier_changeupper_info *info = NULL;
struct net_device *upper_dev = NULL;
+ hinic5_bond_detach_mutex_lock();
switch ((u32)event) {
case NETDEV_CHANGEUPPER:
info = (struct netdev_notifier_changeupper_info *)ptr;
-
upper_dev = info->upper_dev;
- if (!virt_addr_valid((void *)upper_dev)) /* Low kernel version register callback but dev may not have completed registration scenario */
+ if (!virt_addr_valid((
+ void *)upper_dev)) /* 低内核版本注册回调但dev可能未完成注册的场景 */
break;
-
bond_try_attach_user(upper_dev);
bond_handle_rtnl_event(upper_dev);
break;
@@ -312,12 +340,12 @@ int bond_notifier_netdev_event(struct notifier_block *self, unsigned long event,
ndev = netdev_notifier_info_to_dev(ptr);
if (!virt_addr_valid((void *)ndev))
break;
-
bond_handle_rtnl_event(ndev);
break;
default:
- return NOTIFY_DONE;
+ break;
}
+ hinic5_bond_detach_mutex_unlock();
return NOTIFY_DONE;
}
@@ -328,14 +356,11 @@ struct notifier_block g_bond_nb = {
int bond_enable_netdev_event(void)
{
- int ret;
-
- ret = register_netdevice_notifier(&g_bond_nb);
+ int ret = register_netdevice_notifier(&g_bond_nb);
if (ret != 0) {
pr_err("bond register_netdevice_notifier failed\n");
return ret;
}
-
return 0;
}
@@ -363,20 +388,24 @@ void bond_rtnl_data_ready(struct sock *sk)
return;
hdr = (struct nlmsghdr *)skb->data;
- if (!hdr || !((skb->len > (sizeof(struct nlmsghdr) + sizeof(struct ifinfomsg))) &&
- hdr->nlmsg_len >= sizeof(struct nlmsghdr) && hdr->nlmsg_len <= skb->len) ||
- hdr->nlmsg_type != RTM_NEWLINK || rtnl_is_locked() == 0) {
+ if (!hdr ||
+ !((skb->len >
+ (sizeof(struct nlmsghdr) + sizeof(struct ifinfomsg))) &&
+ hdr->nlmsg_len >= sizeof(struct nlmsghdr) &&
+ hdr->nlmsg_len <= skb->len) ||
+ hdr->nlmsg_type != RTM_NEWLINK || rtnl_is_locked() == 0) {
goto free_skb;
}
ifinfo = nlmsg_data(hdr);
ndev = dev_get_by_index(&init_net, ifinfo->ifi_index);
if (ndev) {
+ hinic5_bond_detach_mutex_lock();
bond_try_attach_user(ndev);
bond_handle_rtnl_event(ndev);
+ hinic5_bond_detach_mutex_unlock();
dev_put(ndev);
}
-
free_skb:
kfree_skb(skb);
}
@@ -390,12 +419,12 @@ int bond_enable_netdev_event(void)
int err;
struct socket **rtnl_sock = hinic5_get_bond_mngr_sock_addr();
-#if defined (HAVE_SOCK_CREATE_KERN_NET)
+#if defined(HAVE_SOCK_CREATE_KERN_NET)
err = sock_create_kern(&init_net, AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
- rtnl_sock);
+ rtnl_sock);
#else
err = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
- rtnl_sock);
+ rtnl_sock);
#endif
if (err != 0) {
pr_err("hinic5_bond: Couldn't create rtnl socket.\n");
@@ -406,20 +435,19 @@ int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err != 0) {
pr_err("hinic5_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
*rtnl_sock = NULL;
}
-
return err;
}
void bond_disable_netdev_event(void)
{
struct socket *rtnl_sock = NULL;
-
rtnl_sock = hinic5_get_bond_mngr_sock();
if (rtnl_sock != NULL)
sock_release(rtnl_sock);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_inner.h
index 279c216cc..8c4cefd41 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_inner.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/bond/hinic5_bond_inner.h
@@ -1,11 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bond_inner.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
*/
#ifndef HINIC5_BOND_INNER_H
@@ -13,19 +7,22 @@
#include <net/bonding.h>
#include <linux/list.h>
-#include <linux/srcu.h>
-#include "hinic5_bond.h"
-
-extern struct srcu_struct bdev_srcu;
-
-#define bond_slave_info(bond_dev, slave_dev, fmt, ...) \
- netdev_info(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, ##__VA_ARGS__)
-#define bond_slave_warn(bond_dev, slave_dev, fmt, ...) \
- netdev_warn(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, ##__VA_ARGS__)
-#define bond_slave_dbg(bond_dev, slave_dev, fmt, ...) \
- netdev_dbg(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, ##__VA_ARGS__)
-#define bond_slave_err(bond_dev, slave_dev, fmt, ...) \
- netdev_err(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, ##__VA_ARGS__)
+#include <linux/atomic.h>
+
+#include "drv_bond_api.h"
+
+#define bond_slave_info(bond_dev, slave_dev, fmt, ...) \
+ netdev_info(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, \
+ ##__VA_ARGS__)
+#define bond_slave_warn(bond_dev, slave_dev, fmt, ...) \
+ netdev_warn(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, \
+ ##__VA_ARGS__)
+#define bond_slave_dbg(bond_dev, slave_dev, fmt, ...) \
+ netdev_dbg(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, \
+ ##__VA_ARGS__)
+#define bond_slave_err(bond_dev, slave_dev, fmt, ...) \
+ netdev_err(bond_dev, "[BOND] (slave %s): " fmt, (slave_dev)->name, \
+ ##__VA_ARGS__)
#define bond_master_info(bond_dev, fmt, ...) \
netdev_info(bond_dev, "[BOND]" fmt, ##__VA_ARGS__)
@@ -36,11 +33,11 @@ extern struct srcu_struct bdev_srcu;
#define bond_master_err(bond_dev, fmt, ...) \
netdev_err(bond_dev, "[BOND]" fmt, ##__VA_ARGS__)
-#define PORT_INVALID_ID 0xFF
+#define PORT_INVALID_ID 0xFF
-#define BITMAP_SET(bm, bit) ((bm) |= (typeof(bm))(1U << (bit)))
-#define BITMAP_CLR(bm, bit) ((bm) &= ~((typeof(bm))(1U << (bit))))
-#define BITMAP_JUDGE(bm, bit) ((bm) & (typeof(bm))(1U << (bit)))
+#define BITMAP_SET(bm, bit) ((bm) |= (typeof(bm))(1U << (bit)))
+#define BITMAP_CLR(bm, bit) ((bm) &= ~((typeof(bm))(1U << (bit))))
+#define BITMAP_JUDGE(bm, bit) ((bm) & (typeof(bm))(1U << (bit)))
enum bond_dev_status {
BOND_DEV_STATUS_IDLE,
@@ -50,29 +47,36 @@ enum bond_dev_status {
#ifndef IFNAMSIZ
#define IFNAMSIZ 16UL
#endif
-#define HINIC5_BOND_START_ID 1
+#define HINIC5_BOND_START_ID 1
#define HINIC5_MAX_BODN_ID_NUM 64 /* MAX BOND ID for driver */
+#define BOND_ID_NUM_DETACH 1
#define HINIC5_INVALID_BOND_ID 0xFF
-#define HINIC5_BOND_ID_IS_VALID(_id) (((_id) >= HINIC5_BOND_START_ID) && ((_id) < HINIC5_MAX_BODN_ID_NUM))
-#define HINIC5_BOND_ID_IS_INVALID(_id) (!(HINIC5_BOND_ID_IS_VALID(_id)))
+#define HINIC5_BOND_ID_IS_VALID(_id) \
+ (((_id) >= HINIC5_BOND_START_ID) && ((_id) < HINIC5_MAX_BODN_ID_NUM))
+#define HINIC5_BOND_ID_IS_INVALID(_id) (!(HINIC5_BOND_ID_IS_VALID(_id)))
struct hinic5_bond_dev {
char name[BOND_NAME_MAX_LEN];
char chip_name[IFNAMSIZ];
struct bond_attr bond_attr;
- struct bond_attr new_attr;
+ struct bond_attr curr_attr;
+ struct bond_attr prev_attr;
struct bonding *bond;
struct kref ref;
enum bond_dev_status status;
u8 slot_used[HINIC5_BOND_USER_NUM];
- struct workqueue_struct *wq;
- struct delayed_work bond_work;
struct bond_tracker tracker;
spinlock_t lock; /* lock for change status */
u32 service_en_bitmap;
u32 chip_bond_id;
- bool dead; /* check bdev liveness under SRCU */
+ atomic_t counter;
+};
+
+struct hinic5_bond_work {
+ struct delayed_work work;
+ struct hinic5_bond_dev *bdev;
+ struct bond_attr curr_attr;
};
#define HINIC5_MAX_BOND_ID_PER_CARD 5 /* MAX BOND ID for per chip */
@@ -89,12 +93,19 @@ int bond_enable_netdev_event(void);
struct socket **hinic5_get_bond_mngr_sock_addr(void);
struct socket *hinic5_get_bond_mngr_sock(void);
-int hinic5_bond_event_attach(struct bonding *bond, enum hinic5_bond_user user);
-bool bond_call_srv_attach_func(enum hinic5_bond_user user, struct bonding *bond);
+int hinic5_bond_do_attach(enum hinic5_bond_user user, struct bonding *bond,
+ bool from_event);
+void hinic5_bond_do_detach(enum hinic5_bond_user user, u16 bond_id);
+bool hinic5_bond_can_attach(enum hinic5_bond_user user, struct bonding *bond);
void bond_handle_rtnl_event(struct net_device *ndev);
u8 bond_dev_track_port(struct hinic5_bond_dev *bdev, struct net_device *ndev);
+void bond_dev_untrack_port(struct hinic5_bond_dev *bdev, u8 port_id);
struct hinic5_bond_dev *bond_get_bdev(const struct bonding *bond);
bool hinic5_bond_slave_is_match(struct bonding *bond);
void bond_dev_free_chip_bond_id(struct hinic5_bond_dev *bdev);
+void hinic5_bond_detach_mutex_lock(void);
+void hinic5_bond_detach_mutex_unlock(void);
+struct workqueue_struct *hinic5_bond_get_mngr_wq(void);
+void bond_do_work(struct work_struct *work);
#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg.c
index a4f1691ef..ee86246c9 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg.c
@@ -1,11 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fast_msg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : hisdk5_fast_msg.c
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: hisdk5_fast_msg.c
+ * Author: -
+ * Create:
*/
#include <linux/module.h>
@@ -19,7 +16,8 @@
#include "hinic5_fast_msg.h"
-int hinic5_fast_msg_register_cb(void *hwdev, u8 mod, hinic5_fast_msg_rq_cb callback, void *pri_data)
+int hinic5_fast_msg_register_cb(void *hwdev, u8 mod,
+ hinic5_fast_msg_rq_cb callback, void *pri_data)
{
struct hinic5_hwdev *dev = hwdev;
struct hisdk5_fast_msg_to_func *fast_msg_to_func = NULL;
@@ -32,7 +30,7 @@ int hinic5_fast_msg_register_cb(void *hwdev, u8 mod, hinic5_fast_msg_rq_cb callb
fast_msg_to_func = dev->fast_msg_to_func;
- if (!fast_msg_to_func->fast_msg_rq_cb[mod]) {
+ if (fast_msg_to_func->fast_msg_rq_cb[mod] == NULL) {
fast_msg_to_func->fast_msg_rq_cb[mod] = callback;
fast_msg_to_func->fast_msg_rq_data[mod] = pri_data;
}
@@ -53,7 +51,7 @@ void hinic5_fast_msg_unregister_cb(void *hwdev, u8 mod)
fast_msg_to_func = dev->fast_msg_to_func;
- if (fast_msg_to_func->fast_msg_rq_cb[mod]) {
+ if (fast_msg_to_func->fast_msg_rq_cb[mod] != NULL) {
fast_msg_to_func->fast_msg_rq_cb[mod] = NULL;
fast_msg_to_func->fast_msg_rq_data[mod] = NULL;
}
@@ -68,12 +66,13 @@ void hinic5_fast_msg_clear_bitmap(void *hwdev, u32 rq_offset)
u64 out_parm;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return;
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
- sdk_err(dev->dev_hdl, "Allocate clear bit map cmd buf failed\n");
+ if (cmd_buf == NULL) {
+ sdk_err(dev->dev_hdl,
+ "Allocate clear bit map cmd buf failed\n");
return;
}
fast_msg_buf = (struct hisdk5_fast_msg_buf *)cmd_buf->buf;
@@ -84,45 +83,55 @@ void hinic5_fast_msg_clear_bitmap(void *hwdev, u32 rq_offset)
cmd_buf->size = sizeof(u32);
err = hinic5_send_fast_msg_need_resp(hwdev, HINIC5_MOD_COMM,
- COMM_CMD_UCODE_FAST_MSG_CLEAR, cmd_buf, &out_parm);
- if (err != 0 || out_parm != 0) {
- sdk_err(dev->dev_hdl, "Failed to get fast msg cap, err = 0x%x, out_parm = 0x%llx\n",
+ COMM_CMD_UCODE_FAST_MSG_CLEAR,
+ cmd_buf, &out_parm);
+ if ((err != 0) || (out_parm != 0)) {
+ sdk_err(dev->dev_hdl,
+ "Failed to get fast msg cap, err = 0x%x, out_parm = 0x%llx\n",
err, out_parm);
}
hinic5_free_cmd_buf(hwdev, cmd_buf);
}
-static struct hisdk5_fast_msg_buf *hinic5_get_rq_msg(struct hisdk5_fast_msg_to_func *fast_msg, u32 rq_offset)
+static struct hisdk5_fast_msg_buf *
+hinic5_get_rq_msg(struct hisdk5_fast_msg_to_func *fast_msg, u32 rq_offset)
{
u32 msg_num_per_page;
u32 page_index;
u32 page_offset;
- msg_num_per_page = fast_msg->fast_msg_rq_page_size / FAST_MSG_ENTRY_SIZE;
+ msg_num_per_page =
+ fast_msg->fast_msg_rq_page_size / FAST_MSG_ENTRY_SIZE;
page_index = rq_offset / msg_num_per_page;
page_offset = rq_offset % msg_num_per_page;
- return (struct hisdk5_fast_msg_buf *)
- ((u8 *)fast_msg->rq_mem[page_index] + page_offset * FAST_MSG_ENTRY_SIZE_B);
+ return (struct hisdk5_fast_msg_buf
+ *)((u8 *)fast_msg->rq_mem[page_index] +
+ page_offset * FAST_MSG_ENTRY_SIZE_B);
}
-static void hinic5_fast_msg_recv_msg(struct hisdk5_fast_msg_to_func *fast_msg, u32 rq_offset)
+static void hinic5_fast_msg_recv_msg(struct hisdk5_fast_msg_to_func *fast_msg,
+ u32 rq_offset)
{
- struct hisdk5_fast_msg_buf *rq_msg = hinic5_get_rq_msg(fast_msg, rq_offset);
+ struct hisdk5_fast_msg_buf *rq_msg =
+ hinic5_get_rq_msg(fast_msg, rq_offset);
struct hinic5_hwdev *hwdev = fast_msg->hwdev;
u8 mod = rq_msg->fast_msg_header.mod;
- /* Head has already been converted in the upper half, only convert data here */
- hinic5_be32_to_cpu(rq_msg->fast_msg_data, rq_msg->fast_msg_header.data_len);
+ /* head已经在上半部转换过大小端,这里仅转换data */
+ hinic5_be32_to_cpu(rq_msg->fast_msg_data,
+ rq_msg->fast_msg_header.data_len);
- if (fast_msg->fast_msg_rq_cb[mod]) {
- fast_msg->fast_msg_rq_cb[mod](rq_msg, fast_msg->fast_msg_rq_data[mod]);
+ if (fast_msg->fast_msg_rq_cb[mod] != NULL) {
+ fast_msg->fast_msg_rq_cb[mod](rq_msg,
+ fast_msg->fast_msg_rq_data[mod]);
} else {
sdk_err(hwdev->dev_hdl,
- "fast_msg_rq_cb is NULL, src_func: 0x%x, mod: %u, cmd: %u, " \
+ "fast_msg_rq_cb is NULL, src_func: 0x%x, mod: %u, cmd: %u, "
"data_len: %u, data: 0x%llx\n",
rq_msg->fast_msg_header.src_func_id, mod,
- rq_msg->fast_msg_header.cmd, rq_msg->fast_msg_header.data_len,
+ rq_msg->fast_msg_header.cmd,
+ rq_msg->fast_msg_header.data_len,
*(u64 *)rq_msg->fast_msg_data);
}
@@ -143,12 +152,14 @@ void hinic5_fast_msg_recv_handler(struct work_struct *work)
spin_unlock_bh(&recv_work->lock);
if (entry->type == MSG_WORK_ENTRY_RECV_FAST_MSG) {
- hinic5_fast_msg_recv_msg(recv_work->fast_msg_to_func, entry->rq_offset);
+ hinic5_fast_msg_recv_msg(recv_work->fast_msg_to_func,
+ entry->rq_offset);
} else if (entry->type == MSG_WORK_ENTRY_FORWARDING) {
entry->forward_cb(entry->forward_data);
kfree(entry);
} else {
- sdk_err(hwdev->dev_hdl, "Invalid msg type: 0x%x\n", entry->type);
+ sdk_err(hwdev->dev_hdl, "Invalid msg type: 0x%x\n",
+ entry->type);
}
spin_lock_bh(&recv_work->lock);
@@ -164,37 +175,44 @@ void hinic5_fast_msg_rq_handler(void *pri_handle, u32 ceqe_data)
struct hinic5_hwdev *hwdev = NULL;
u32 rq_offset, work_id;
- if (!pri_handle)
+ if (pri_handle == NULL) {
return;
+ }
hwdev = fast_msg->hwdev;
rq_offset = ceqe_data & FAST_MSG_RQ_OFFSET_MASK;
if (rq_offset >= fast_msg->fast_msg_rq_depth) {
- sdk_err(hwdev->dev_hdl, "rq offset is invalid, rq_offset: 0x%x, depth: 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "rq offset is invalid, rq_offset: 0x%x, depth: 0x%x\n",
rq_offset, fast_msg->fast_msg_rq_depth);
return;
}
rq_msg = hinic5_get_rq_msg(fast_msg, rq_offset);
- /* Need to use src_func_id, first convert header */
- hinic5_be32_to_cpu(rq_msg, sizeof(hisdk5_fast_msg_header));
+ hinic5_be32_to_cpu(
+ rq_msg,
+ sizeof(hisdk5_fast_msg_header)); /* 需使用src_func_id,先转换header */
- work_id = rq_msg->fast_msg_header.src_func_id % fast_msg->num_concurrent_work;
+ work_id = rq_msg->fast_msg_header.src_func_id %
+ fast_msg->num_concurrent_work;
recv_work = &fast_msg->recv_concurrent_work[work_id];
spin_lock(&recv_work->lock);
if (list_empty(&fast_msg->recv_entries[rq_offset].entry) != 0) {
- list_add_tail(&fast_msg->recv_entries[rq_offset].entry, &recv_work->msg_head);
+ list_add_tail(&fast_msg->recv_entries[rq_offset].entry,
+ &recv_work->msg_head);
spin_unlock(&recv_work->lock);
queue_work(fast_msg->workq, &recv_work->work);
} else {
spin_unlock(&recv_work->lock);
- sdk_err(hwdev->dev_hdl, "rq offset 0x%x, already in process\n", rq_offset);
+ sdk_err(hwdev->dev_hdl, "rq offset 0x%x, already in process\n",
+ rq_offset);
}
}
-int hinic5_fast_msg_send(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out_parm)
+int hinic5_fast_msg_send(void *hwdev, struct hinic5_cmd_buf *cmd_buf,
+ u64 *out_parm)
{
struct hinic5_hwdev *dev = hwdev;
int err;
@@ -203,15 +221,18 @@ int hinic5_fast_msg_send(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out_p
return -EINVAL;
err = hinic5_send_fast_msg_need_resp(hwdev, HINIC5_MOD_COMM,
- COMM_CMD_UCODE_FAST_MSG_CMD, cmd_buf, out_parm);
+ COMM_CMD_UCODE_FAST_MSG_CMD,
+ cmd_buf, out_parm);
if (err != 0)
- sdk_err(dev->dev_hdl, "Failed to send fast msg, ret = 0x%x\n", err);
+ sdk_err(dev->dev_hdl, "Failed to send fast msg, ret = 0x%x\n",
+ err);
return err;
}
EXPORT_SYMBOL(hinic5_fast_msg_send);
-int hinic5_fast_msg_forward(void *hwdev, u16 src_func_id, void *data, hinic5_fast_msg_forward_cb callback)
+int hinic5_fast_msg_forward(void *hwdev, u16 src_func_id, void *data,
+ hinic5_fast_msg_forward_cb callback)
{
struct hisdk5_fast_msg_to_func *fast_msg = NULL;
struct hisdk5_fast_msg_recv_entry *recv_entry = NULL;
@@ -219,12 +240,15 @@ int hinic5_fast_msg_forward(void *hwdev, u16 src_func_id, void *data, hinic5_fas
struct hinic5_hwdev *dev = hwdev;
u32 work_id;
- if (!hwdev || !callback)
+ if (hwdev == NULL || callback == NULL) {
return -EINVAL;
+ }
recv_entry = kzalloc(sizeof(*recv_entry), GFP_KERNEL);
- if (!recv_entry)
+ if (recv_entry == NULL) {
+ sdk_err(dev->dev_hdl, "Failed to aloc entry\n");
return -ENOMEM;
+ }
INIT_LIST_HEAD(&recv_entry->entry);
recv_entry->type = MSG_WORK_ENTRY_FORWARDING;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg_init.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg_init.c
index 168cbb827..adfbe348e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg_init.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/cfm/fast_msg/hinic5_fast_msg_init.c
@@ -1,11 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fast_msg_init.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : hinic5_fast_msg_init.c
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: hinic5_fast_msg_init.c
+ * Author: -
+ * Create:
*/
#include "ossl_knl.h"
@@ -16,21 +13,28 @@
#include "hinic5_fast_msg.h"
#include "hinic5_fast_msg_init.h"
-int hinic5_fast_msg_cap_get(struct hinic5_hwdev *hwdev, hisdk5_fast_msg_caps *caps)
+int hinic5_fast_msg_cap_get(struct hinic5_hwdev *hwdev,
+ hisdk5_fast_msg_caps *caps)
{
int err;
struct comm_cmd_fast_msg_cap fast_msg_cap;
u16 out_size;
- memset(&fast_msg_cap, 0, sizeof(fast_msg_cap));
+ err = memset_s(&fast_msg_cap, sizeof(fast_msg_cap), 0,
+ sizeof(fast_msg_cap));
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl, "Failed to init memset fast_msg_cap\n");
+ return -EINVAL;
+ }
fast_msg_cap.func_id = hinic5_global_func_id(hwdev);
out_size = sizeof(struct comm_cmd_fast_msg_cap);
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_GET_FAST_MSG_CAP,
- &fast_msg_cap, out_size,
- &fast_msg_cap, &out_size, 0, HINIC5_CHANNEL_COMM);
- if (err != 0 || out_size == 0 || fast_msg_cap.head.status != 0) {
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_GET_FAST_MSG_CAP,
+ &fast_msg_cap, out_size, &fast_msg_cap,
+ &out_size, 0, HINIC5_CHANNEL_COMM);
+ if ((err != 0) || (out_size == 0) || (fast_msg_cap.head.status != 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to get fast msg cap, ret = %d, status: 0x%x, out size: 0x%x\n",
err, fast_msg_cap.head.status, out_size);
@@ -49,49 +53,53 @@ void hinic5_fast_msg_rq_buf_deinit(struct hinic5_hwdev *hwdev)
struct hisdk5_fast_msg_to_func *fast_msg_to_func = NULL;
u32 page_idx;
- if (!hwdev)
+ if (hwdev == NULL)
return;
- if (!hwdev->fast_msg_to_func)
+ if (hwdev->fast_msg_to_func == NULL)
return;
fast_msg_to_func = hwdev->fast_msg_to_func;
- for (page_idx = 0; page_idx < fast_msg_to_func->fast_msg_rq_page_num; page_idx++) {
- if (fast_msg_to_func->rq_mem[page_idx])
+ for (page_idx = 0; page_idx < fast_msg_to_func->fast_msg_rq_page_num;
+ page_idx++) {
+ if (fast_msg_to_func->rq_mem[page_idx] != NULL)
dma_free_coherent(
hwdev->dev_hdl,
- fast_msg_to_func->fast_msg_rq_page_size * FAST_MSG_ENTRY_UNIT,
+ fast_msg_to_func->fast_msg_rq_page_size *
+ FAST_MSG_ENTRY_UNIT,
fast_msg_to_func->rq_mem[page_idx],
- fast_msg_to_func->rq_mem_paddr[page_idx]
- );
+ fast_msg_to_func->rq_mem_paddr[page_idx]);
}
}
void hinic5_fast_msg_clear_sml_table(struct hinic5_hwdev *hwdev)
{
int err;
- struct comm_cmd_clear_fast_msg_sml_table clear_info = {0};
+ struct comm_cmd_clear_fast_msg_sml_table clear_info = { 0 };
u16 out_size = sizeof(struct comm_cmd_clear_fast_msg_sml_table);
clear_info.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_CLEAR_FAST_MSG_SML,
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_CLEAR_FAST_MSG_SML,
&clear_info, sizeof(clear_info),
- &clear_info, &out_size, 0, HINIC5_CHANNEL_COMM);
+ &clear_info, &out_size, 0,
+ HINIC5_CHANNEL_COMM);
if (clear_info.head.status == HINIC5_MGMT_CMD_UNSUPPORTED) {
- sdk_warn(hwdev->dev_hdl, "not support clear fastmsg sml table\n");
+ sdk_warn(hwdev->dev_hdl,
+ "not support clear fastmsg sml table\n");
return;
}
- if (err != 0 || out_size == 0 || clear_info.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (clear_info.head.status != 0)) {
sdk_err(hwdev->dev_hdl,
- "Failed to clear fast msg sml table, ret = %d, status: 0x%x, " \
- "out size: 0x%x\n",
+ "Failed to clear fast msg sml table, ret = %d, status: 0x%x, out size: 0x%x\n",
err, clear_info.head.status, out_size);
}
}
-int hinic5_fast_msg_rq_buf_init(struct hinic5_hwdev *hwdev, hisdk5_fast_msg_caps *caps)
+int hinic5_fast_msg_rq_buf_init(struct hinic5_hwdev *hwdev,
+ hisdk5_fast_msg_caps *caps)
{
int err;
struct comm_cmd_set_fast_msg_rq_addr rq_addr;
@@ -99,25 +107,31 @@ int hinic5_fast_msg_rq_buf_init(struct hinic5_hwdev *hwdev, hisdk5_fast_msg_caps
u32 page_idx;
void *page_vaddr = NULL;
dma_addr_t page_paddr;
- gfp_t gfp_hinic5_vram;
+ gfp_t gfp_vram;
- memset(&rq_addr, 0, sizeof(rq_addr));
+ err = memset_s(&rq_addr, sizeof(rq_addr), 0, sizeof(rq_addr));
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl, "Failed to init memset rq_addr\n");
+ return -EINVAL;
+ }
rq_addr.func_id = hinic5_global_func_id(hwdev);
- rq_addr.page_num = (caps->depth * FAST_MSG_ENTRY_SIZE) / caps->page_size;
+ rq_addr.page_num =
+ (caps->depth * FAST_MSG_ENTRY_SIZE) / caps->page_size;
hwdev->fast_msg_to_func->fast_msg_rq_page_num = rq_addr.page_num;
hwdev->fast_msg_to_func->fast_msg_rq_page_size = caps->page_size;
out_size = sizeof(struct comm_cmd_set_fast_msg_rq_addr);
- gfp_hinic5_vram = hinic5_hinic5_vram_get_gfp_hinic5_vram();
+ gfp_vram = hi5_vram_get_gfp_vram();
for (page_idx = 0; page_idx < rq_addr.page_num; page_idx++) {
- page_vaddr = dma_zalloc_coherent(hwdev->dev_hdl,
- caps->page_size * FAST_MSG_ENTRY_UNIT,
- &page_paddr, GFP_KERNEL | gfp_hinic5_vram);
- if (!page_vaddr) {
+ page_vaddr = dma_zalloc_coherent(
+ hwdev->dev_hdl, caps->page_size * FAST_MSG_ENTRY_UNIT,
+ &page_paddr, GFP_KERNEL | gfp_vram);
+ if (page_vaddr == NULL) {
sdk_err(hwdev->dev_hdl,
- "alloc fast msg rq mem failed, page_idx = 0x%x\n", page_idx);
+ "alloc fast msg rq mem failed, page_idx = 0x%x\n",
+ page_idx);
err = -ENOMEM;
goto err_handler;
}
@@ -127,10 +141,11 @@ int hinic5_fast_msg_rq_buf_init(struct hinic5_hwdev *hwdev, hisdk5_fast_msg_caps
rq_addr.page_addr[page_idx].rq_page_addr = (u64)page_paddr;
}
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_SET_FAST_MSG_RQ_ADDR,
- &rq_addr, out_size,
- &rq_addr, &out_size, 0, HINIC5_CHANNEL_COMM);
- if (err != 0 || out_size == 0 || rq_addr.head.status != 0) {
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_SET_FAST_MSG_RQ_ADDR,
+ &rq_addr, out_size, &rq_addr, &out_size,
+ 0, HINIC5_CHANNEL_COMM);
+ if ((err != 0) || (out_size == 0) || (rq_addr.head.status != 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to get fast msg cap, ret = %d, status: 0x%x, out size: 0x%x\n",
err, rq_addr.head.status, out_size);
@@ -158,7 +173,8 @@ static void recv_concurrent_work_init(struct hisdk5_fast_msg_to_func *fast_msg)
}
}
-int hinic5_fast_msg_recv_init(struct hinic5_hwdev *hwdev, struct hisdk5_fast_msg_to_func *fast_msg)
+int hinic5_fast_msg_recv_init(struct hinic5_hwdev *hwdev,
+ struct hisdk5_fast_msg_to_func *fast_msg)
{
u32 i;
int err;
@@ -166,20 +182,24 @@ int hinic5_fast_msg_recv_init(struct hinic5_hwdev *hwdev, struct hisdk5_fast_msg
err = hinic5_ceq_register_cb(hwdev, fast_msg, HINIC5_FAST_MSG_RQ,
hinic5_fast_msg_rq_handler);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Fail to register fast_msg_rq callback\n");
+ sdk_err(hwdev->dev_hdl,
+ "Fail to register fast_msg_rq callback\n");
return err;
}
- fast_msg->workq = alloc_workqueue(HINIC5_FAST_MSG_WQ_NAME, WQ_MEM_RECLAIM, 0);
- if (!fast_msg->workq) {
+ fast_msg->workq =
+ alloc_workqueue(HINIC5_FAST_MSG_WQ_NAME, WQ_MEM_RECLAIM, 0);
+ if (fast_msg->workq == NULL) {
sdk_err(hwdev->dev_hdl, "Fail to alloc fast_msg workq\n");
err = -EINVAL;
goto alloc_workq_err;
}
- fast_msg->recv_entries = kcalloc(fast_msg->fast_msg_rq_depth,
- sizeof(struct hisdk5_fast_msg_recv_entry), GFP_KERNEL);
- if (!fast_msg->recv_entries) {
+ fast_msg->recv_entries =
+ kcalloc(fast_msg->fast_msg_rq_depth,
+ sizeof(struct hisdk5_fast_msg_recv_entry), GFP_KERNEL);
+ if (fast_msg->recv_entries == NULL) {
+ sdk_err(hwdev->dev_hdl, "Fail to alloc fast_msg recv nodes\n");
err = -ENOMEM;
goto alloc_recv_node_err;
}
@@ -191,12 +211,11 @@ int hinic5_fast_msg_recv_init(struct hinic5_hwdev *hwdev, struct hisdk5_fast_msg
}
fast_msg->num_concurrent_work = FAST_MSG_RECV_MAX_CONCURRENT;
- fast_msg->recv_concurrent_work = kcalloc(
- fast_msg->num_concurrent_work,
- sizeof(struct hisdk5_fast_msg_recv_work),
- GFP_KERNEL
- );
- if (!fast_msg->recv_concurrent_work) {
+ fast_msg->recv_concurrent_work =
+ kcalloc(fast_msg->num_concurrent_work,
+ sizeof(struct hisdk5_fast_msg_recv_work), GFP_KERNEL);
+ if (fast_msg->recv_concurrent_work == NULL) {
+ sdk_err(hwdev->dev_hdl, "Fail to alloc fast_msg recv work\n");
err = -ENOMEM;
goto alloc_recv_work_err;
}
@@ -217,7 +236,8 @@ int hinic5_fast_msg_recv_init(struct hinic5_hwdev *hwdev, struct hisdk5_fast_msg
return err;
}
-void hinic5_fast_msg_recv_deinit(struct hinic5_hwdev *hwdev, struct hisdk5_fast_msg_to_func *fast_msg)
+void hinic5_fast_msg_recv_deinit(struct hinic5_hwdev *hwdev,
+ struct hisdk5_fast_msg_to_func *fast_msg)
{
struct hisdk5_fast_msg_recv_work *recv_work = NULL;
u32 i;
@@ -244,10 +264,16 @@ int hinic5_fast_msg_init(void *hwdev)
hisdk5_fast_msg_caps caps;
struct hisdk5_fast_msg_to_func *fast_msg_to_func = NULL;
- memset(&caps, 0, sizeof(caps));
+ err = memset_s(&caps, sizeof(caps), 0, sizeof(caps));
+ if (err != 0) {
+ sdk_err(dev->dev_hdl, "Failed to init memset fast_msg caps\n");
+ return -EINVAL;
+ }
- fast_msg_to_func = kzalloc(sizeof(struct hisdk5_fast_msg_to_func), GFP_KERNEL);
- if (!fast_msg_to_func) {
+ fast_msg_to_func =
+ kzalloc(sizeof(struct hisdk5_fast_msg_to_func), GFP_KERNEL);
+ if (fast_msg_to_func == NULL) {
+ sdk_err(dev->dev_hdl, "Failed to alloc fast_msg_to_func\n");
return -ENOMEM;
}
@@ -256,19 +282,22 @@ int hinic5_fast_msg_init(void *hwdev)
err = hinic5_fast_msg_cap_get(dev, &caps);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to get fast_msg cap, err: %d\n", err);
+ sdk_err(dev->dev_hdl, "Failed to get fast_msg cap, err: %d\n",
+ err);
goto err_get_cap;
}
err = hinic5_fast_msg_recv_init(dev, fast_msg_to_func);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to init fast_msg recv msg, err: %d\n", err);
+ sdk_err(dev->dev_hdl,
+ "Failed to init fast_msg recv msg, err: %d\n", err);
goto err_init_recv_msg;
}
err = hinic5_fast_msg_rq_buf_init(hwdev, &caps);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to init fast_msg rq, err: %d\n", err);
+ sdk_err(dev->dev_hdl, "Failed to init fast_msg rq, err: %d\n",
+ err);
goto err_rq_init;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/bond/hinic5_bond.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/bond/hinic5_bond.h
index 7ff82a8a1..fa95d0e98 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/bond/hinic5_bond.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/bond/hinic5_bond.h
@@ -1,45 +1,25 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bond.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/**< SPDX-License-Identifier: GPL-2.0 */
+/**< Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_BOND_H
#define HINIC5_BOND_H
-#include "nic_mpu_cmd_structs.h"
-#include "drv_bond_api.h"
-
/**
- * @brief Bond initialization interface
+ * @brief bond初始化接口
* @param[in] void
- * @details Called during nic initialization, used for bond module initialization
+ * @details nic初始化时调用,用于bond模块的初始化
* @attention N/A
- * @return Returns initialization result, 0 for success, non-zero for failure
+ * @return 返回初始化结果,0为成功,非0失败
**/
int hinic5_bond_init(void);
/**
- * @brief Bond deinitialization interface
+ * @brief bond去初始化接口
* @param[in] void
- * @details Called during nic driver unload, used for bond module deinitialization
+ * @details nic驱动卸载时调用,用于bond模块去初始化
* @attention N/A
* @return void
**/
void hinic5_bond_deinit(void);
-/**
- * @brief Get bond id by bond name
- * @param[in] bond_name bond name
- * @param[out] bond_id found bond id
- * @details The returned bond id is maintained by the driver side
- * @attention N/A
- * @return Returns get result, 0 for found, non-zero for not found
- **/
-int hinic5_bond_get_id_by_name(u8 *bond_name, u16 *bond_id);
-
#endif /**< HINIC5_BOND_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg.h
index 0ec8b9d4d..dc91af80b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fast_msg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
#ifndef HINIC5_FAST_MSG_H
#define HINIC5_FAST_MSG_H
@@ -17,23 +10,24 @@
#include "comm_defs.h"
#include "hinic5_hw.h"
-#define FAST_MSG_ENTRY_SIZE 2
-#define FAST_MSG_ENTRY_UNIT 1024
-#define FAST_MSG_ENTRY_SIZE_B (FAST_MSG_ENTRY_UNIT * FAST_MSG_ENTRY_SIZE)
-#define HISDK5_FAST_MSG_MAX_PAGE_NUM 32
-#define MAX_FAST_MSG_RQ_DEPTH 2048
-#define FAST_MSG_RQ_OFFSET_MASK 0xFFF
-#define FAST_MSG_RECV_MAX_CONCURRENT 10
+#define FAST_MSG_ENTRY_SIZE 2
+#define FAST_MSG_ENTRY_UNIT 1024
+#define FAST_MSG_ENTRY_SIZE_B (FAST_MSG_ENTRY_UNIT * FAST_MSG_ENTRY_SIZE)
+#define HISDK5_FAST_MSG_MAX_PAGE_NUM 32
+#define MAX_FAST_MSG_RQ_DEPTH 2048
+#define FAST_MSG_RQ_OFFSET_MASK 0xFFF
+#define FAST_MSG_RECV_MAX_CONCURRENT 10
-/* Indicate fast msg upper layer message format type */
+/* 标识fast msg上层承载消息格式类型 */
enum hisdk5_fast_msg_ulp_format {
HISDK5_FAST_MSG_ULP_FROMAT_NONE = 0,
HISDK5_FAST_MSG_ULP_FROMAT_MIG = 1,
- /* 4bit width, type must be less than 16 */
+ /* 4bit位宽,类型需小于16 */
HISDK5_FAST_MSG_ULP_FROMAT_MAX = 16
};
-typedef void (*hinic5_fast_msg_rq_cb)(hisdk5_fast_msg_buf *rq_msg, void *fast_msg_rq_data);
+typedef void (*hinic5_fast_msg_rq_cb)(hisdk5_fast_msg_buf *rq_msg,
+ void *fast_msg_rq_data);
typedef void (*hinic5_fast_msg_forward_cb)(void *data);
enum hisdk5_fast_msg_work_entry_type {
@@ -57,7 +51,7 @@ struct hisdk5_fast_msg_recv_work {
struct work_struct work;
struct hisdk5_fast_msg_to_func *fast_msg_to_func;
struct list_head msg_head;
- spinlock_t lock;/* spinlock protecting the msg_head and work queue data */
+ spinlock_t lock;
};
struct hisdk5_fast_msg_to_func {
@@ -83,32 +77,34 @@ struct hisdk5_fast_msg_to_func {
void hinic5_fast_msg_rq_handler(void *pri_handle, u32 ceqe_data);
void hinic5_fast_msg_recv_handler(struct work_struct *work);
-int hinic5_fast_msg_register_cb(void *hwdev, u8 mod, hinic5_fast_msg_rq_cb callback, void *pri_data);
+int hinic5_fast_msg_register_cb(void *hwdev, u8 mod,
+ hinic5_fast_msg_rq_cb callback, void *pri_data);
void hinic5_fast_msg_unregister_cb(void *hwdev, u8 mod);
-int hinic5_fast_msg_send(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out_parm);
+int hinic5_fast_msg_send(void *hwdev, struct hinic5_cmd_buf *cmd_buf,
+ u64 *out_parm);
/**
- * @brief fast msg message reorder execution
+ * @brief fast msg消息重新保序执行
*
- * @param hwdev SDK handle
- * @param src_func_id fastmsg message source function id
- * @param data callback function private data
- * @param callback callback function pointer
+ * @param hwdev SDK句柄
+ * @param src_func_id fastmsg消息的源function id
+ * @param data 回调函数的私有数据
+ * @param callback 回调函数指针
*
- * @details After a function receives a fastmsg message, if the message needs to wait for all previous messages
- * from another function to be processed, then fastmsg needs to be re-chained to ensure the message is
- * processed serially in the task of another function
+ * @details 某个function接收到fastmsg消息之后,若消息需要等另一个function前面的消息都处理完,
+ * 则fastmsg需要重新挂链确保消息在另一个function的任务里串行处理
*
- * @return: 0 - message added to list successfully, other - message added to list failed
+ * @return: 0 - 消息入链表成功, other - 消息入链失败
*/
-int hinic5_fast_msg_forward(void *hwdev, u16 src_func_id, void *data, hinic5_fast_msg_forward_cb callback);
+int hinic5_fast_msg_forward(void *hwdev, u16 src_func_id, void *data,
+ hinic5_fast_msg_forward_cb callback);
/**
- * @brief Check if current function supports fast msg
+ * @brief 获取本function是否支持fast msg
*
- * @param hwdev SDK handle
+ * @param hwdev SDK句柄
*
- * @return: true - supported, false - not supported.
+ * @return: true - 支持, false - 不支持.
*/
bool hinic5_support_fast_msg(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg_init.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg_init.h
index 26106bc72..8bb7ab50f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg_init.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/cfm/fast_msg/hinic5_fast_msg_init.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fast_msg_init.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
#ifndef HINIC5_FAST_MSG_INIT
#define HINIC5_FAST_MSG_INIT
@@ -18,7 +11,7 @@ typedef struct hisdk5_fast_msg_caps {
u32 page_size;
} hisdk5_fast_msg_caps;
-#define HINIC5_FAST_MSG_WQ_NAME "hinic5_fast_msg"
+#define HINIC5_FAST_MSG_WQ_NAME "hinic5_fast_msg"
int hinic5_fast_msg_init(void *hwdev);
void hinic5_fast_msg_deinit(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_hinic5_vram.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_hinic5_vram.h
deleted file mode 100644
index b24b42d32..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_hinic5_vram.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hinic5_vram.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_HINIC5_VRAM
-#define HINIC5_HINIC5_VRAM
-
-#include <linux/pci.h>
-#include <linux/pm.h>
-
-#include "mpu_inband_cmd_defs.h"
-
-typedef int (*hiudk_flush_fn)(void *priv_data);
-typedef struct hiudk_dev_flush_infos {
- void *lld_dev;
- hiudk_flush_fn flush_ops;
-
- /* private: Internal use */
- int ret;
-} hiudk_dev_flush_infos;
-
-typedef struct hiudk_async_ctrl {
- spinlock_t lock; /* spinlock protecting the hiudk_async_ctrl data structure */
-
- hiudk_dev_flush_infos flush_infos[CMD_MAX_MAX_PF_NUM];
-} hiudk_async_ctrl;
-
-int hinic5_wait_for_devices_flush(struct notifier_block *nb, unsigned long action, void *data);
-int hiudk5_register_flush_fn(void *lld_dev, hiudk_flush_fn fn);
-int hiudk5_unregister_flush_fn(void *lld_dev);
-int hisdk5_hinic5_vram_init(void);
-void hisdk5_hinic5_vram_deinit(void);
-
-#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_id_tbl.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_id_tbl.h
index bdd9c883a..8261612da 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_id_tbl.h
@@ -1,70 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_id_tbl.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_ID_TBL_H
#define HINIC5_ID_TBL_H
-#define HINIC5_VIRTIO_VNEDER_ID 0x1AF4
+#define HINIC5_VIRTIO_VNEDER_ID 0x1AF4
#ifdef CONFIG_SP_VID_DID
-#define PCI_VENDOR_ID_SPNIC 0x1F3F
-#define HINIC5_DEV_ID_STANDARD 0x9020
-#define HINIC5_DEV_ID_SDI_5_1_PF 0x9032
-#define HINIC5_DEV_ID_VF 0x9001
-#define HINIC5_DEV_ID_VF_HV 0x9002
-#define HINIC5_DEV_ID_SPU 0xAC00
+#define PCI_VENDOR_ID_SPNIC 0x1F3F
+#define HINIC5_DEV_ID_STANDARD 0x9020
+#define HINIC5_DEV_ID_SDI_5_1_PF 0x9032
+#define HINIC5_DEV_ID_VF 0x9001
+#define HINIC5_DEV_ID_VF_HV 0x9002
+#define HINIC5_DEV_ID_SPU 0xAC00
#else
-#define PCI_VENDOR_ID_HUAWEI 0x19e5
-#define HINIC5_DEV_ID_STANDARD 0x0222
-#define HINIC5_DEV_ID_SDI_5_1_PF 0x0226
-#define HINIC5_DEV_ID_SDI_5_0_PF 0x0225
-#define HINIC5_DEV_ID_DPU_STORGE_PF 0x0220
-#define HINIC5_DEV_ID_SDI_6_0_PF 0x0225
-#define HINIC5_DEV_ID_VF 0x375F
-#define HINIC5_DEV_ID_VF_HV 0x379F
-#define HINIC5_DEV_ID_SPU 0xAC00
+#define PCI_VENDOR_ID_HUAWEI 0x19e5
+#define HINIC5_DEV_ID_STANDARD 0x0222
+#define HINIC5_DEV_ID_SDI_5_1_PF 0x0226
+#define HINIC5_DEV_ID_SDI_5_0_PF 0x0225
+#define HINIC5_DEV_ID_DPU_STORGE_PF 0x0220
+#define HINIC5_DEV_ID_SDI_6_0_PF 0x0225
+#define HINIC5_DEV_ID_VF 0x375F
+#define HINIC5_DEV_ID_VF_HV 0x379F
+#define HINIC5_DEV_ID_SPU 0xAC00
-#define HINIC5_DEV_ID_TEMP 0x1823
-#define HINIC5_DEV_ID_1823_VF_TEMP 0x375E
-#define HINIC5_DEV_ID_1823_VF_HV_TEMP 0x379E
+#define HINIC5_DEV_ID_TEMP 0x1823
+#define HINIC5_DEV_ID_1823_VF_TEMP 0x375E
+#define HINIC5_DEV_ID_1823_VF_HV_TEMP 0x379E
/* Hi1872V100, SP233, SP235, SP235-O */
-#define HINIC5_DEV_ID_72V1_PF 0x0229
-#define HINIC5_DEV_ID_72V1_VF 0x022a
+#define HINIC5_DEV_ID_72V1_PF 0x0229
+#define HINIC5_DEV_ID_72V1_VF 0x022a
#endif /* CONFIG_SP_VID_DID */
-/* Hi1825V100 2X200G standard card, 1X400G standard card, 2X400G UBX UB carrier board UB EXP custom card, 2X200G 4X200G Tianqu 2.0 on-board card */
-#define HINIC5_DEV_ID_25V1_PF 0x0230
-#define HINIC5_DEV_ID_25V1_VF 0x0231
+/* Hi1825V100 2X200G标卡、1X400G标卡、2X400G UBX UB载板 UB EXP定制卡、2X200G 4X200G天衢2.0板载卡 */
+#define HINIC5_DEV_ID_25V1_PF 0x0230
+#define HINIC5_DEV_ID_25V1_VF 0x0231
-#define HINIC5_IS_VF_DEV(dev_id) (((dev_id) == HINIC5_DEV_ID_VF) || \
- ((dev_id) == HINIC5_DEV_ID_72V1_VF) || \
- ((dev_id) == HINIC5_DEV_ID_1823_VF_TEMP) || \
- ((dev_id) == HINIC5_DEV_ID_25V1_VF))
-#define HINIC5_IS_SPU_DEV(dev_id) (((dev_id) == HINIC5_DEV_ID_SPU) || \
- ((dev_id) == HINIC5_DEV_ID_SDI_5_0_PF))
+#define HINIC5_IS_VF_DEV(dev_id) \
+ (((dev_id) == HINIC5_DEV_ID_VF) || \
+ ((dev_id) == HINIC5_DEV_ID_72V1_VF) || \
+ ((dev_id) == HINIC5_DEV_ID_1823_VF_TEMP) || \
+ ((dev_id) == HINIC5_DEV_ID_25V1_VF))
+#define HINIC5_IS_SPU_DEV(dev_id) \
+ (((dev_id) == HINIC5_DEV_ID_SPU) || \
+ ((dev_id) == HINIC5_DEV_ID_SDI_5_0_PF))
-#define HINIC5_UDEV_VENDOR_ID_HUAWEI 0xCC08
-#define HINIC5_UDEV_VENDOR_ID_HUAWEI_E0FC 0xE0FC /* Old Vendor ID, to be deleted */
+#define HINIC5_UDEV_VENDOR_ID_HUAWEI 0xCC08
+#define HINIC5_UDEV_VENDOR_ID_HUAWEI_E0FC \
+ 0xE0FC /* Old Vendor ID, to be deleted */
-#define HINIC5_UDEV_DEVICE_ID_1825_PF 0x8200
-#define HINIC5_UDEV_DEVICE_ID_1825_VF 0x8201
-#define HINIC5_UDEV_DEVICE_ID_1825_TEMP 0x1825 /* For development */
+#define HINIC5_UDEV_DEVICE_ID_1825_PF 0x8200
+#define HINIC5_UDEV_DEVICE_ID_1825_VF 0x8201
+#define HINIC5_UDEV_DEVICE_ID_1825_TEMP 0x1825 /* For development */
-#define HINIC5_UDEV_DEVICE_ID_1872_PF 0x8100
-#define HINIC5_UDEV_DEVICE_ID_1872_VF 0x8101
+#define HINIC5_UDEV_DEVICE_ID_1872_PF 0x8100
+#define HINIC5_UDEV_DEVICE_ID_1872_VF 0x8101
-#define HINIC5_UDEV_CLASS_CODE_1825 0x0102
-#define HINIC5_UDEV_CLASS_CODE_1872 0x0102
+#define HINIC5_UDEV_CLASS_CODE_1825 0x0102
+#define HINIC5_UDEV_CLASS_CODE_1872 0x0102
-#define HINIC5_UDEV_CLASS_CODE_MASK 0xFFFF
+#define HINIC5_UDEV_CLASS_CODE_MASK 0xFFFF
#endif /* HINIC5_ID_TBL_H */
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram_common.h
deleted file mode 100644
index fed081fee..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/sdk/knldk/hinic5_vram_common.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_vram_common.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Header File, hinic5_vram common
- */
-#ifndef HINIC5_VRAM_COMMON_H
-#define HINIC5_VRAM_COMMON_H
-
-#if !defined(__UEFI__) && !defined(__WIN__)
-#include <linux/notifier.h>
-#include <linux/numa.h>
-#endif
-
-#define HINIC5_VRAM_BLOCK_SIZE_2M 0x200000UL
-#define KEXEC_SIGN "hinic-in-kexec"
-// now hinic5_vram_name max len is 14, when add other hinic5_vram, attention this value
-#define HINIC5_VRAM_NAME_SIZE 15
-#define HINIC5_VRAM_NAME_MAX_LEN 16
-
-#define HINIC5_VRAM_HINIC5_CQM_GLB_FUNC_BASE "F"
-#define HINIC5_VRAM_HINIC5_CQM_FAKE_MEM_BASE "FK"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_BASE "C"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_TYPE_BASE "T"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_SMF_BASE "M"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_COORD_X "X"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_COORD_Y "Y"
-#define HINIC5_VRAM_HINIC5_CQM_CLA_COORD_Z "Z"
-#define HINIC5_VRAM_HINIC5_CQM_BITMAP_BASE "B"
-
-#define HINIC5_VRAM_NIC_DCB "DCB"
-#define HINIC5_VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
-#define HINIC5_VRAM_NIC_HINIC5_VRAM "NIC_HINIC5_VRAM"
-#define HINIC5_VRAM_NIC_FUNC_BASE "NIC_F"
-
-#define HINIC5_VRAM_NIC_MQM "NM"
-
-#define HINIC5_VRAM_VBS_IOCB "IOCB"
-#define HINIC5_VRAM_VBS_RXQS_CQE "RCQE"
-#define HINIC5_VRAM_VBS_NAME_BASE "VBS_"
-#define HINIC5_VRAM_VBS_VOLQ_MTT "VOLQMTT"
-#define HINIC5_VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
-
-#define HINIC5_VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
-#define HINIC5_VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
-
-#define HINIC5_VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
-#define HINIC5_VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
-#define HINIC5_VRAM_VROCE_UUID "VROCE_UUID"
-#define HINIC5_VRAM_VROCE_VID "VROCE_VID"
-#define HINIC5_VRAM_VROCE_BASE "VROCE_BASE"
-#define HINIC5_VRAM_VROCE_DSCP "VROCE_DSCP"
-#define HINIC5_VRAM_VROCE_QOS "VROCE_QOS"
-#define HINIC5_VRAM_VROCE_DEV "VROCE_DEV"
-#define HINIC5_VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
-#define HINIC5_VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
-#define HINIC5_VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
-
-#define HINIC5_VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
-#define HINIC5_VRAM_DTOE_CARD_MEM "DTOE_CARD"
-#define HINIC5_VRAM_DTOE_CONN_MEM "DTOE_CONN"
-#define HINIC5_VRAM_DTOE_SUB_LEN 10
-
-#define HINIC5_VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
-#define HINIC5_VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
-
-#define MPU_OS_HOTREPLACE_FLAG 0x1
-
-#define USE_HINIC5_VRAM 1
-#define NO_USE_HINIC5_VRAM 0
-
-#define OS_HOT_REPLACE_DOING 1
-#define OS_HOT_REPLACE_DONE 0
-
-#define HINIC5_VRAM_NUMA_NODE_NUM 2
-
-/* Allocate from the CPU where runtime is located */
-#define HINIC5_VRAM_AFFINITY_NUMA 0xfe
-
-/* No NUMA specified, allocate from free NUMA */
-#define HINIC5_VRAM_NO_NUMA 0xff
-
-enum KUP_HOOK_POINT {
- PRE_FREEZE,
- FREEZE_TO_KILL,
- PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
- POST_UPDATE_KERNEL,
- UNFREEZE_TO_RUN,
- POST_RUN,
- KUP_HOOK_MAX,
-};
-
-#if defined(__UEFI__) || defined(__WIN__) || defined(__VMWARE__)
-#define hinic5_hinic5_vram_kalloc(name, size) 0
-#define hinic5_vram_get_kexec_flag() 0
-#define hinic5_hinic5_vram_get_gfp_hinic5_vram() 0
-#else
-
-typedef int (*register_nvwa_notifier_t)(int hook, struct notifier_block *nb);
-typedef int (*unregister_nvwa_notifier_t)(int hook, struct notifier_block *nb);
-typedef int (*register_euleros_reboot_notifier_t)(struct notifier_block *nb);
-typedef int (*unregister_euleros_reboot_notifier_t)(struct notifier_block *nb);
-typedef void __iomem *(*hinic5_vram_kalloc_t)(char *name, u64 size);
-typedef void __iomem *(*vpmem_kalloc_node_t)(char *name, u64 size, u8 numa);
-typedef void (*hinic5_vram_kfree_t)(void __iomem *vaddr, char *name, u64 size);
-typedef gfp_t (*hinic5_vram_get_gfp_hinic5_vram_t)(void);
-
-/**
- * @brief init hinic5_vram related symbols
- **/
-void lookup_hinic5_vram_related_symbols(void);
-/**
- * @brief register nvwa notifier
- * @param hook @ref enum KUP_HOOK_POINT
- * @param nb pointer of notifier block
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hi_register_nvwa_notifier(int hook, struct notifier_block *nb);
-/**
- * @brief unregister nvwa notifier
- * @param hook @ref enum KUP_HOOK_POINT
- * @param nb pointer of notifier block
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hi_unregister_nvwa_notifier(int hook, struct notifier_block *nb);
-/**
- * @brief register machine-shutdown notifier
- * @param nb pointer of notifier block
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hi_register_euleros_reboot_notifier(struct notifier_block *nb);
-/**
- * @brief unregister machine-shutdown notifier
- * @param nb pointer of notifier block
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hi_unregister_euleros_reboot_notifier(struct notifier_block *nb);
-/**
- * @brief alloc hinic5_vram memory
- * @param name name of hinic5_vram memory
- * @param size size of hinic5_vram memory
- **/
-void __iomem *hinic5_hinic5_vram_kalloc(char *name, u64 size);
-/**
- * @brief get gfp of hinic5_vram for dma
- * @return
- * - gfp_t from sdi_nanoos
- **/
-gfp_t hinic5_hinic5_vram_get_gfp_hinic5_vram(void);
-/**
- * @brief set kexec status
- * @param status 1 : doing kexec, 0 : done kexec
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hinic5_set_kexec_status(int status);
-/**
- * @brief get kexec status
- * @return
- * - Zero if successful. Non-zero otherwise.
- **/
-int hinic5_get_kexec_status(void);
-/**
- * @brief set use-hinic5_vram flag
- * @param flag: true : use hinic5_vram, false : don't use hinic5_vram
- **/
-void set_use_hinic5_vram_flag(bool flag);
-/**
- * @brief get kexec flag
- * @return
- * - 0: done kexec
- * - 1: doing kexec
- **/
-int hinic5_vram_get_kexec_flag(void);
-
-#endif
-
-#endif /* HINIC5_VRAM_COMMON_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/typedef.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/typedef.h
index 600459403..c5c6fbdf4 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/typedef.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/include/typedef.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : typedef.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef TYPEDEF_H
#define TYPEDEF_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.c
index b1fed282d..b5678cae1 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_cfg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -18,11 +11,11 @@
#include <linux/semaphore.h>
#include "ossl_knl.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_crm.h"
#include "hinic5_hw.h"
#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "comm_defs.h"
#include "cfg_mgmt_mpu_cmd.h"
#include "cfg_mgmt_mpu_cmd_defs.h"
@@ -35,28 +28,42 @@
static void parse_pub_res_cap_dfx(struct hinic5_hwdev *hwdev,
const struct service_cap *cap)
{
- sdk_info(hwdev->dev_hdl, "Get public resource capbility: svc_cap_en: 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "Get public resource capbility: svc_cap_en: 0x%x\n",
cap->svc_type);
- sdk_info(hwdev->dev_hdl, "Host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, port_id: 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "Host_id: 0x%x, ep_id: 0x%x, er_id: 0x%x, port_id: 0x%x\n",
cap->host_id, cap->ep_id, cap->er_id, cap->port_id);
- sdk_info(hwdev->dev_hdl, "cos_bitmap: 0x%x, flexq: 0x%x, virtio_vq_size: 0x%x\n",
- cap->cos_valid_bitmap, cap->flexq_en, cap->virtio_vq_size);
- sdk_info(hwdev->dev_hdl, "Host_total_function: 0x%x, host_oq_id_mask_val: 0x%x, max_vf: 0x%x\n",
- cap->host_total_function, cap->host_oq_id_mask_val,
- cap->max_vf);
- sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
- cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
-}
-
-static void parse_hinic5_cqm_res_cap(const struct hinic5_hwdev *hwdev, struct service_cap *cap,
- struct cfg_cmd_dev_cap *dev_cap)
+ "cos_bitmap: 0x%x, flexq: 0x%x, virtio_vq_size: 0x%x\n",
+ cap->cos_valid_bitmap, cap->flexq_en, cap->virtio_vq_size);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Host_total_function: 0x%x, host_oq_id_mask_val: 0x%x, max_vf: 0x%x\n",
+ cap->host_total_function, cap->host_oq_id_mask_val,
+ cap->max_vf);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
+ cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
+ sdk_info(
+ hwdev->dev_hdl,
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode);
+ sdk_info(
+ hwdev->dev_hdl,
+ "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(
+ hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+}
+
+static void parse_cqm_res_cap(const struct hinic5_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap)
{
struct dev_sf_svc_attr *attr = &cap->sf_svc_attr;
@@ -71,7 +78,8 @@ static void parse_hinic5_cqm_res_cap(const struct hinic5_hwdev *hwdev, struct se
cap->fake_vf_bfilter_len = dev_cap->fake_vf_bfilter_len;
if (COMM_SUPPORT_VIRTIO_VQ_SIZE(hwdev))
- cap->virtio_vq_size = (u16)(VIRTIO_BASE_VQ_SIZE << dev_cap->virtio_vq_size);
+ cap->virtio_vq_size =
+ (u16)(VIRTIO_BASE_VQ_SIZE << dev_cap->virtio_vq_size);
else
cap->virtio_vq_size = VIRTIO_DEFAULT_VQ_SIZE;
cap->virtio_vq_num = dev_cap->virtio_vq_num;
@@ -120,13 +128,16 @@ static void parse_pub_res_cap(struct hinic5_hwdev *hwdev,
cap->er_id = dev_cap->er_id;
cap->port_id = dev_cap->port_id;
- cap->svc_type = ((dev_cap->svc_cap_en) | (dev_cap->svc_cap_en_h << SVC_CAP_EN_OFFSET_BIT));
+ cap->svc_type = ((dev_cap->svc_cap_en) |
+ (dev_cap->svc_cap_en_h << SVC_CAP_EN_OFFSET_BIT));
cap->chip_svc_type = cap->svc_type;
cap->cos_valid_bitmap = (dev_cap->dev_cos_valid_bitmap == 0) ?
- dev_cap->valid_cos_bitmap : dev_cap->dev_cos_valid_bitmap;
+ dev_cap->valid_cos_bitmap :
+ dev_cap->dev_cos_valid_bitmap;
cap->cos_mask_mode = (dev_cap->cos_mask_mode == 0) ?
- COS_DEFAULT_MASK_MODE : dev_cap->cos_mask_mode;
+ COS_DEFAULT_MASK_MODE :
+ dev_cap->cos_mask_mode;
cap->dcb_state.default_cos = dev_cap->dev_default_cos;
cap->port_cos_valid_bitmap = dev_cap->port_cos_valid_bitmap;
cap->func_gpa_spu_en = dev_cap->func_gpa_spu_en;
@@ -147,7 +158,7 @@ static void parse_pub_res_cap(struct hinic5_hwdev *hwdev,
cap->max_vf = 0;
}
- parse_hinic5_cqm_res_cap(hwdev, cap, dev_cap);
+ parse_cqm_res_cap(hwdev, cap, dev_cap);
parse_pub_res_cap_dfx(hwdev, cap);
}
@@ -171,13 +182,15 @@ static void parse_l2nic_res_cap(struct hinic5_hwdev *hwdev,
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
- sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
if (nic_cap->max_sqs > HINIC5_CFG_MAX_QP ||
nic_cap->max_rqs > HINIC5_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
+ sdk_info(hwdev->dev_hdl,
+ "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
HINIC5_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
nic_cap->max_sqs = HINIC5_CFG_MAX_QP;
nic_cap->max_rqs = HINIC5_CFG_MAX_QP;
@@ -200,10 +213,11 @@ static void parse_fc_res_cap(struct hinic5_hwdev *hwdev,
fc_cap->vp_id_end = dev_cap->fc_vp_id_end;
sdk_info(hwdev->dev_hdl, "Get fc resource capbility\n");
- sdk_info(hwdev->dev_hdl,
- "Max_parent_qpc_num: 0x%x, scq_num: 0x%x, srq_num: 0x%x, max_child_qpc_num: 0x%x, child_qpc_id_start: 0x%x\n",
- fc_cap->max_parent_qpc_num, fc_cap->scq_num, fc_cap->srq_num,
- fc_cap->max_child_qpc_num, fc_cap->child_qpc_id_start);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Max_parent_qpc_num: 0x%x, scq_num: 0x%x, srq_num: 0x%x, max_child_qpc_num: 0x%x, child_qpc_id_start: 0x%x\n",
+ fc_cap->max_parent_qpc_num, fc_cap->scq_num, fc_cap->srq_num,
+ fc_cap->max_child_qpc_num, fc_cap->child_qpc_id_start);
sdk_info(hwdev->dev_hdl, "Vp_id_start: 0x%x, vp_id_end: 0x%x\n",
fc_cap->vp_id_start, fc_cap->vp_id_end);
}
@@ -226,17 +240,22 @@ static void parse_roce_res_cap(struct hinic5_hwdev *hwdev,
roce_cap->wqe_cl_end = dev_cap->roce_wqe_cl_end;
roce_cap->wqe_cl_sz = dev_cap->roce_wqe_cl_size;
roce_cap->qpc_entry_sz = (dev_cap->hyper_qpc_entry_size_en == 0) ?
- ROCE_QPC_ENTRY_SZ : HYPER_ROCE_QPC_ENTRY_SZ;
+ ROCE_QPC_ENTRY_SZ :
+ HYPER_ROCE_QPC_ENTRY_SZ;
sdk_info(hwdev->dev_hdl, "Get roce resource capbility, type: 0x%x\n",
type);
- sdk_info(hwdev->dev_hdl, "Max_qps: 0x%x, max_cqs: 0x%x, max_srqs: 0x%x, max_mpts: 0x%x, max_drcts: 0x%x\n",
- roce_cap->max_qps, roce_cap->max_cqs, roce_cap->max_srqs,
- roce_cap->max_mpts, roce_cap->max_drc_qps);
-
- sdk_info(hwdev->dev_hdl, "Wqe_start: 0x%x, wqe_end: 0x%x, wqe_sz: 0x%x. qpc_entry_sz:0x%x\n",
- roce_cap->wqe_cl_start, roce_cap->wqe_cl_end,
- roce_cap->wqe_cl_sz, roce_cap->qpc_entry_sz);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Max_qps: 0x%x, max_cqs: 0x%x, max_srqs: 0x%x, max_mpts: 0x%x, max_drcts: 0x%x\n",
+ roce_cap->max_qps, roce_cap->max_cqs, roce_cap->max_srqs,
+ roce_cap->max_mpts, roce_cap->max_drc_qps);
+
+ sdk_info(
+ hwdev->dev_hdl,
+ "Wqe_start: 0x%x, wqe_end: 0x%x, wqe_sz: 0x%x. qpc_entry_sz:0x%x\n",
+ roce_cap->wqe_cl_start, roce_cap->wqe_cl_end,
+ roce_cap->wqe_cl_sz, roce_cap->qpc_entry_sz);
if (roce_cap->max_qps == 0) {
if (type == TYPE_PF || type == TYPE_PPF) {
@@ -261,10 +280,12 @@ static void parse_roce_ext_res_cap(struct hinic5_hwdev *hwdev,
struct cfg_cmd_ext_dev_cap *ext_dev_cap,
struct service_cap *cap, u32 index)
{
- struct dev_roce_svc_own_cap *roce_cap = &cap->rdma_cap.dev_rdma_cap.roce_own_cap;
+ struct dev_roce_svc_own_cap *roce_cap =
+ &(cap->rdma_cap.dev_rdma_cap.roce_own_cap);
struct cfg_roce_ext_caps *roce_ext_caps = NULL;
- roce_ext_caps = (struct cfg_roce_ext_caps *)(&ext_dev_cap->ext_cap[index]);
+ roce_ext_caps =
+ (struct cfg_roce_ext_caps *)(&(ext_dev_cap->ext_cap[index]));
roce_cap->reserved_qps = roce_ext_caps->rsvd_qp;
roce_cap->reserved_qps_back = roce_ext_caps->rsvd_qp_back;
@@ -276,11 +297,18 @@ static void parse_roce_ext_res_cap(struct hinic5_hwdev *hwdev,
roce_cap->max_xrcd = roce_ext_caps->max_xrcd;
roce_cap->max_gid = roce_ext_caps->max_gid;
- sdk_info(hwdev->dev_hdl, "reserved_qps: 0x%x, reserved_qps_back: 0x%x, reserved_cqs: 0x%x\n",
- roce_cap->reserved_qps, roce_cap->reserved_qps_back, roce_cap->reserved_cqs);
- sdk_info(hwdev->dev_hdl, "reserved_cqs_back: 0x%x, reserved_srqs: 0x%x, reserved_srqs_back: 0x%x\n",
- roce_cap->reserved_cqs_back, roce_cap->reserved_srqs, roce_cap->reserved_srqs_back);
- sdk_info(hwdev->dev_hdl, "max_pd: 0x%x, max_xrcd: 0x%x, max_gid: 0x%x\n",
+ sdk_info(
+ hwdev->dev_hdl,
+ "reserved_qps: 0x%x, reserved_qps_back: 0x%x, reserved_cqs: 0x%x\n",
+ roce_cap->reserved_qps, roce_cap->reserved_qps_back,
+ roce_cap->reserved_cqs);
+ sdk_info(
+ hwdev->dev_hdl,
+ "reserved_cqs_back: 0x%x, reserved_srqs: 0x%x, reserved_srqs_back: 0x%x\n",
+ roce_cap->reserved_cqs_back, roce_cap->reserved_srqs,
+ roce_cap->reserved_srqs_back);
+ sdk_info(hwdev->dev_hdl,
+ "max_pd: 0x%x, max_xrcd: 0x%x, max_gid: 0x%x\n",
roce_cap->max_pd, roce_cap->max_xrcd, roce_cap->max_gid);
}
@@ -300,11 +328,14 @@ static void parse_rdma_res_cap(struct hinic5_hwdev *hwdev,
roce_cap->dmtt_cl_end = dev_cap->roce_dmtt_cl_end;
roce_cap->dmtt_cl_sz = dev_cap->roce_dmtt_cl_size;
- sdk_info(hwdev->dev_hdl, "Get rdma resource capbility, Cmtt_start: 0x%x, cmtt_end: 0x%x, cmtt_sz: 0x%x\n",
- roce_cap->cmtt_cl_start, roce_cap->cmtt_cl_end,
- roce_cap->cmtt_cl_sz);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get rdma resource capbility, Cmtt_start: 0x%x, cmtt_end: 0x%x, cmtt_sz: 0x%x\n",
+ roce_cap->cmtt_cl_start, roce_cap->cmtt_cl_end,
+ roce_cap->cmtt_cl_sz);
- sdk_info(hwdev->dev_hdl, "Dmtt_start: 0x%x, dmtt_end: 0x%x, dmtt_sz: 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "Dmtt_start: 0x%x, dmtt_end: 0x%x, dmtt_sz: 0x%x\n",
roce_cap->dmtt_cl_start, roce_cap->dmtt_cl_end,
roce_cap->dmtt_cl_sz);
}
@@ -322,13 +353,13 @@ static void parse_ovs_res_cap(struct hinic5_hwdev *hwdev,
ovs_cap->dev_ovs_cap.fake_vf_num = dev_cap->fake_vf_num;
ovs_cap->dev_ovs_cap.dynamic_qp_en = dev_cap->flexq_en;
- sdk_info(hwdev->dev_hdl,
- "Get ovs resource capbility, max_qpc: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x\n",
- ovs_cap->dev_ovs_cap.max_pctxs,
- ovs_cap->dev_ovs_cap.fake_vf_start_id,
- ovs_cap->dev_ovs_cap.fake_vf_num);
- sdk_info(hwdev->dev_hdl,
- "fake_vf_max_qpc: 0x%x, dynamic_qp_en: 0x%x\n",
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get ovs resource capbility, max_qpc: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x\n",
+ ovs_cap->dev_ovs_cap.max_pctxs,
+ ovs_cap->dev_ovs_cap.fake_vf_start_id,
+ ovs_cap->dev_ovs_cap.fake_vf_num);
+ sdk_info(hwdev->dev_hdl, "fake_vf_max_qpc: 0x%x, dynamic_qp_en: 0x%x\n",
ovs_cap->dev_ovs_cap.fake_vf_max_pctx,
ovs_cap->dev_ovs_cap.dynamic_qp_en);
}
@@ -345,11 +376,11 @@ static void parse_ppa_res_cap(struct hinic5_hwdev *hwdev,
dip_cap->qpc_fake_vf_num = dev_cap->fake_vf_num;
dip_cap->bloomfilter_en = (dev_cap->fake_vf_bfilter_len != 0) ? 1 : 0;
dip_cap->bloomfilter_length = dev_cap->fake_vf_bfilter_len;
- sdk_info(hwdev->dev_hdl,
- "Get ppa resource capbility, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_qpc: 0x%x\n",
- dip_cap->qpc_fake_vf_start,
- dip_cap->qpc_fake_vf_num,
- dip_cap->qpc_fake_vf_ctx_num);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get ppa resource capbility, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_qpc: 0x%x\n",
+ dip_cap->qpc_fake_vf_start, dip_cap->qpc_fake_vf_num,
+ dip_cap->qpc_fake_vf_ctx_num);
}
static void parse_toe_res_cap(struct hinic5_hwdev *hwdev,
@@ -366,10 +397,11 @@ static void parse_toe_res_cap(struct hinic5_hwdev *hwdev,
toe_cap->max_mpts = dev_cap->toe_max_mpt;
toe_cap->max_cctxt = dev_cap->toe_max_cctxt;
- sdk_info(hwdev->dev_hdl,
- "Get toe resource capbility, max_pctxs: 0x%x, max_cqs: 0x%x, max_srqs: 0x%x, srq_id_start: 0x%x, max_mpts: 0x%x\n",
- toe_cap->max_pctxs, toe_cap->max_cqs, toe_cap->max_srqs,
- toe_cap->srq_id_start, toe_cap->max_mpts);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get toe resource capbility, max_pctxs: 0x%x, max_cqs: 0x%x, max_srqs: 0x%x, srq_id_start: 0x%x, max_mpts: 0x%x\n",
+ toe_cap->max_pctxs, toe_cap->max_cqs, toe_cap->max_srqs,
+ toe_cap->srq_id_start, toe_cap->max_mpts);
}
static void parse_ipsec_res_cap(struct hinic5_hwdev *hwdev,
@@ -382,17 +414,20 @@ static void parse_ipsec_res_cap(struct hinic5_hwdev *hwdev,
ipsec_cap->dev_ipsec_cap.max_sactxs = dev_cap->ipsec_max_sactxs;
ipsec_cap->dev_ipsec_cap.max_spctxs = dev_cap->ipsec_max_spctxs;
ipsec_cap->dev_ipsec_cap.max_cqs = dev_cap->ipsec_max_cq;
- ipsec_cap->dev_ipsec_cap.sa_hash_bucket_num = dev_cap->ipsec_sa_hash_bucket_num;
- ipsec_cap->dev_ipsec_cap.sp_hash_bucket_num = dev_cap->ipsec_sp_hash_bucket_num;
+ ipsec_cap->dev_ipsec_cap.sa_hash_bucket_num =
+ dev_cap->ipsec_sa_hash_bucket_num;
+ ipsec_cap->dev_ipsec_cap.sp_hash_bucket_num =
+ dev_cap->ipsec_sp_hash_bucket_num;
- sdk_info(hwdev->dev_hdl,
+ sdk_info(
+ hwdev->dev_hdl,
"Get IPsec resource capbility, max_sactxs: 0x%x, sa hash bucket num: 0x%x\n",
dev_cap->ipsec_max_sactxs, dev_cap->ipsec_sa_hash_bucket_num);
- sdk_info(hwdev->dev_hdl,
- "Get IPsec resource capbility, max_spctxs: 0x%x, " \
- "sp hash bucket num: 0x%x, max cq: 0x%x\n",
- dev_cap->ipsec_max_spctxs, dev_cap->ipsec_sp_hash_bucket_num,
- dev_cap->ipsec_max_cq);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get IPsec resource capbility, max_spctxs: 0x%x, sp hash bucket num: 0x%x, max cq: 0x%x\n",
+ dev_cap->ipsec_max_spctxs, dev_cap->ipsec_sp_hash_bucket_num,
+ dev_cap->ipsec_max_cq);
}
static void parse_vbs_res_cap(struct hinic5_hwdev *hwdev,
@@ -407,12 +442,16 @@ static void parse_vbs_res_cap(struct hinic5_hwdev *hwdev,
vbs_cap->vbs_volq_cos = dev_cap->vbs_volq_cos;
vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
- vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable =
+ dev_cap->vbs_fushion_queue_pf_enable;
vbs_cap->vbs_child_ctx_num = dev_cap->vbs_child_ctx_num;
vbs_cap->vbs_hash_bucket_num = dev_cap->vbs_hash_bucket_num;
- sdk_info(hwdev->dev_hdl, "Get VBS resource capbility, vbs_max_volq: 0x%x, vbs_child_ctx_num: 0x%x, vbs_hash_bucket_num: 0x%x\n",
- dev_cap->vbs_max_volq, dev_cap->vbs_child_ctx_num, dev_cap->vbs_hash_bucket_num);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x, vbs_child_ctx_num: 0x%x, vbs_hash_bucket_num: 0x%x\n",
+ dev_cap->vbs_max_volq, dev_cap->vbs_child_ctx_num,
+ dev_cap->vbs_hash_bucket_num);
}
static void parse_jbof_res_cap(struct hinic5_hwdev *hwdev,
@@ -422,16 +461,18 @@ static void parse_jbof_res_cap(struct hinic5_hwdev *hwdev,
struct jbof_service_cap *jbof_cap = &cap->jbof_cap;
struct cfg_jbof_ext_caps *jbof_ext_caps = NULL;
- jbof_ext_caps = (struct cfg_jbof_ext_caps *)(&ext_dev_cap->ext_cap[index]);
+ jbof_ext_caps =
+ (struct cfg_jbof_ext_caps *)(&ext_dev_cap->ext_cap[index]);
jbof_cap->max_parent_qpc_num = jbof_ext_caps->jbof_max_pctx;
jbof_cap->max_child_qpc_num = jbof_ext_caps->jbof_max_cctx;
jbof_cap->hash_bucket_num = jbof_ext_caps->jbof_hash_bucket_num;
- sdk_info(hwdev->dev_hdl,
- "Get jbof resource capbility, max_parent_qpc_num: 0x%x max_child_qpc_num:0x%x, hash_bucket_num: 0x%x\n",
- jbof_cap->max_parent_qpc_num, jbof_cap->max_child_qpc_num,
- jbof_cap->hash_bucket_num);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get jbof resource capbility, max_parent_qpc_num: 0x%x max_child_qpc_num:0x%x, hash_bucket_num: 0x%x\n",
+ jbof_cap->max_parent_qpc_num, jbof_cap->max_child_qpc_num,
+ jbof_cap->hash_bucket_num);
}
static void parse_dmmu_res_cap(struct hinic5_hwdev *hwdev,
@@ -446,7 +487,8 @@ static void parse_dmmu_res_cap(struct hinic5_hwdev *hwdev,
dmmu_cap->cl_start = dev_cap->dmmu_cl_start;
dmmu_cap->cl_end = dev_cap->dmmu_cl_end;
- sdk_info(hwdev->dev_hdl, "Get DMMU resource capbility, pasid_max: 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "Get DMMU resource capbility, pasid_max: 0x%x\n",
dmmu_cap->pasid_max);
}
@@ -478,13 +520,18 @@ static void parse_ub_res_cap(struct hinic5_hwdev *dev,
ub_caps->net_dev_cap.max_mtu = ub_ext_caps->max_mtu; // 8192
ub_caps->net_dev_cap.vf_cnt = ub_ext_caps->vf_cnt;
- sdk_info(dev->dev_hdl, "Max_jfc: 0x%x, max_jfr: 0x%x, max_jetty: 0x%x, max_mpts: 0x%x, max_tp: 0x%x\n",
- ub_caps->sdk_res.max_jfc, ub_caps->sdk_res.max_jfr,
- ub_caps->sdk_res.max_jetty, ub_caps->sdk_res.max_mpts, ub_caps->sdk_res.max_tp);
+ sdk_info(
+ dev->dev_hdl,
+ "Max_jfc: 0x%x, max_jfr: 0x%x, max_jetty: 0x%x, max_mpts: 0x%x, max_tp: 0x%x\n",
+ ub_caps->sdk_res.max_jfc, ub_caps->sdk_res.max_jfr,
+ ub_caps->sdk_res.max_jetty, ub_caps->sdk_res.max_mpts,
+ ub_caps->sdk_res.max_tp);
- sdk_info(dev->dev_hdl, "cqc_entry_sz: 0x%x, srqc_entry_sz: 0x%x, qpc_entry_sz: 0x%x\n",
- ub_caps->sdk_res.cqc_entry_sz, ub_caps->sdk_res.srqc_entry_sz,
- ub_caps->sdk_res.qpc_entry_sz);
+ sdk_info(
+ dev->dev_hdl,
+ "cqc_entry_sz: 0x%x, srqc_entry_sz: 0x%x, qpc_entry_sz: 0x%x\n",
+ ub_caps->sdk_res.cqc_entry_sz, ub_caps->sdk_res.srqc_entry_sz,
+ ub_caps->sdk_res.qpc_entry_sz);
}
static void parse_fake_vf_ext_cap(struct hinic5_hwdev *hwdev,
@@ -495,49 +542,58 @@ static void parse_fake_vf_ext_cap(struct hinic5_hwdev *hwdev,
(struct cfg_fake_vf_ext_caps *)(&ext_dev_cap->ext_cap[index]);
cap->fake_vf_parent_func_id = ext_cap->fake_vf_parent_func_id;
- cap->fake_vf_lazy_init = ext_cap->fake_vf_lazy_init != 0;
+ cap->fake_vf_lazy_init = ext_cap->fake_vf_lazy_init != 0;
+ cap->fake_vf_bat_expanded = ext_cap->fake_vf_bat_expanded != 0;
cap->fake_vf_max_scqc_ctx = ext_cap->scqc_fake_vf_ctx_num;
cap->fake_vf_max_srqc_ctx = ext_cap->srqc_fake_vf_ctx_num;
cap->fake_vf_max_gid_ctx = ext_cap->gid_fake_vf_ctx_num;
cap->fake_vf_max_mpt_ctx = ext_cap->mpt_fake_vf_ctx_num;
cap->fake_vf_max_childc_ctx = ext_cap->childc_fake_vf_ctx_num;
- cap->fake_vf_qpc_ctx_size_en = ext_cap->qpc_fake_vf_ctx_size_order_en != 0;
+ cap->fake_vf_qpc_ctx_size_en = ext_cap->qpc_fake_vf_ctx_size_order_en !=
+ 0;
cap->fake_vf_qpc_ctx_size_order = ext_cap->qpc_fake_vf_ctx_size_order;
- sdk_info(hwdev->dev_hdl,
- "Get fake vf capbility, parent func id 0x%x, lazy init %u\n",
- cap->fake_vf_parent_func_id, ext_cap->fake_vf_lazy_init);
- sdk_info(hwdev->dev_hdl,
- "Get fake vf ctx max capbility, scqc 0x%x, srqc 0x%x, gid 0x%x, mpt 0x%x, childc 0x%x\n",
- cap->fake_vf_max_scqc_ctx, cap->fake_vf_max_srqc_ctx, cap->fake_vf_max_gid_ctx,
- cap->fake_vf_max_mpt_ctx, cap->fake_vf_max_childc_ctx);
- sdk_info(hwdev->dev_hdl,
- "Get fake vf ctx size capbility. qpc ctx size en %u, order %u\n",
- cap->fake_vf_qpc_ctx_size_en, cap->fake_vf_qpc_ctx_size_order);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get fake vf capbility, parent func id 0x%x, lazy init %u, bat expanded %d\n",
+ cap->fake_vf_parent_func_id, ext_cap->fake_vf_lazy_init,
+ ext_cap->fake_vf_bat_expanded);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get fake vf ctx max capbility, scqc 0x%x, srqc 0x%x, gid 0x%x, mpt 0x%x, childc 0x%x\n",
+ cap->fake_vf_max_scqc_ctx, cap->fake_vf_max_srqc_ctx,
+ cap->fake_vf_max_gid_ctx, cap->fake_vf_max_mpt_ctx,
+ cap->fake_vf_max_childc_ctx);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get fake vf ctx size capbility. qpc ctx size en %u, order %u\n",
+ cap->fake_vf_qpc_ctx_size_en, cap->fake_vf_qpc_ctx_size_order);
}
static void parse_fw_update_ext_cap(struct hinic5_hwdev *hwdev,
struct cfg_cmd_ext_dev_cap *ext_dev_cap,
struct service_cap *cap, u32 index)
{
- cfg_fw_update_ext_caps *ext_caps = (cfg_fw_update_ext_caps *)(&ext_dev_cap->ext_cap[index]);
+ cfg_fw_update_ext_caps *ext_caps =
+ (cfg_fw_update_ext_caps *)(&ext_dev_cap->ext_cap[index]);
*(&cap->fw_update_cap) = *ext_caps;
- sdk_info(hwdev->dev_hdl,
- "Get fw udpate capbility, fw_img_hdr_size 0x%x, fw_tile_text_size 0x%x\n",
- cap->fw_update_cap.fw_img_hdr_size, cap->fw_update_cap.fw_tile_text_size);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get fw udpate capbility, fw_img_hdr_size 0x%x, fw_tile_text_size 0x%x\n",
+ cap->fw_update_cap.fw_img_hdr_size,
+ cap->fw_update_cap.fw_tile_text_size);
}
static void parse_comm_info_ext_cap(struct hinic5_hwdev *hwdev,
struct cfg_cmd_ext_dev_cap *ext_dev_cap,
struct service_cap *cap, u32 index)
{
- struct comm_info_ext_cap *ext_caps;
+ struct comm_info_ext_cap *ext_caps =
+ (struct comm_info_ext_cap *)(&ext_dev_cap->ext_cap[index]);
struct cfm_service_cap *cfm_cap = &cap->cfm_cap;
- ext_caps = (struct comm_info_ext_cap *)(&ext_dev_cap->ext_cap[index]);
-
/* BAT capabilities */
cap->bat_cid_index_bit_width = ext_caps->bat_cid_index_bit_width;
@@ -547,16 +603,18 @@ static void parse_comm_info_ext_cap(struct hinic5_hwdev *hwdev,
/* SRIOV ext capabilities */
cap->vf_isolation = (ext_caps->vf_isolation != 0);
- sdk_info(hwdev->dev_hdl,
- "Get common ext cap: bat cid index bits %u, smf_max_num %u, vf iso %d\n",
- cap->bat_cid_index_bit_width, cap->smf_max_num,
- cap->vf_isolation);
+ sdk_info(
+ hwdev->dev_hdl,
+ "Get common ext cap: bat cid index bits %u, smf_max_num %u, vf iso %d\n",
+ cap->bat_cid_index_bit_width, cap->smf_max_num,
+ cap->vf_isolation);
/* CFM CCP capabilities */
- cfm_cap->ccp_child_ctx_sz = ext_caps->ccp_child_ctx_sz;
+ cfm_cap->ccp_child_ctx_sz = ext_caps->ccp_child_ctx_sz;
cfm_cap->ccp_max_child_ctx = ext_caps->ccp_max_child_ctx;
- sdk_info(hwdev->dev_hdl, "Get CFM CCP cap: childc basic size %u, max %u\n",
+ sdk_info(hwdev->dev_hdl,
+ "Get CFM CCP cap: childc basic size %u, max %u\n",
cfm_cap->ccp_child_ctx_sz, cfm_cap->ccp_max_child_ctx);
}
@@ -615,7 +673,7 @@ static void parse_all_res_cap(struct hinic5_hwdev *dev,
struct service_cap *cap, u32 type, u32 index)
{
switch (type) {
- // Different types between SERVICE_BIT_UB and EXT_CAP_FAKE_VF, to eliminate warning
+ // SERVICE_BIT_UB和EXT_CAP_FAKE_VF类型不同, 消除告警
case (u32)SERVICE_BIT_UB:
parse_ub_res_cap(dev, ext_dev_cap, cap, index);
break;
@@ -640,18 +698,21 @@ static void parse_all_res_cap(struct hinic5_hwdev *dev,
}
static void parse_ext_dev_cap(struct hinic5_hwdev *dev,
- struct cfg_cmd_ext_dev_cap *ext_dev_cap, enum func_type type)
+ struct cfg_cmd_ext_dev_cap *ext_dev_cap,
+ enum func_type type)
{
struct service_cap *cap = &dev->cfg_mgmt->svc_cap;
u32 index = 0;
struct cfg_cmd_tlv_hdr *tlv_hdr = NULL;
do {
- tlv_hdr = (struct cfg_cmd_tlv_hdr *)&ext_dev_cap->ext_cap[index];
- if (tlv_hdr->len == 0x0 || tlv_hdr->len % 0x4 != 0x0)
+ tlv_hdr =
+ (struct cfg_cmd_tlv_hdr *)&ext_dev_cap->ext_cap[index];
+ if ((tlv_hdr->len == 0x0) || (tlv_hdr->len % 0x4 != 0x0))
return;
- parse_all_res_cap(dev, ext_dev_cap, cap, tlv_hdr->type, index + sizeof(*tlv_hdr));
+ parse_all_res_cap(dev, ext_dev_cap, cap, tlv_hdr->type,
+ index + sizeof(*tlv_hdr));
index += (tlv_hdr->len + sizeof(*tlv_hdr));
} while (index < MAX_CAP_LEN_QWORD);
@@ -663,16 +724,16 @@ static int get_legacy_dev_cap(struct hinic5_hwdev *hwdev, enum func_type type)
u16 out_len = sizeof(dev_cap);
int err;
- memset(&dev_cap, 0, sizeof(dev_cap));
+ (void)memset_s(&dev_cap, sizeof(dev_cap), 0, sizeof(dev_cap));
dev_cap.func_id = hinic5_global_func_id(hwdev);
sdk_info(hwdev->dev_hdl, "Get cap from fw, func_idx: %u\n",
dev_cap.func_id);
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFGM, CFG_CMD_GET_DEV_CAP,
- &dev_cap, sizeof(dev_cap),
- &dev_cap, &out_len, 0,
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFGM,
+ CFG_CMD_GET_DEV_CAP, &dev_cap,
+ sizeof(dev_cap), &dev_cap, &out_len, 0,
HINIC5_CHANNEL_COMM);
- if (err != 0 || dev_cap.head.status != 0 || out_len == 0) {
+ if ((err != 0) || (dev_cap.head.status != 0) || (out_len == 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to get capability from FW, err: %d, status: 0x%x, out size: 0x%x\n",
err, dev_cap.head.status, out_len);
@@ -693,16 +754,17 @@ static int get_extend_dev_cap(struct hinic5_hwdev *hwdev, enum func_type type)
if (!COMM_SUPPORT_EXTEND_CAPBILITY(hwdev))
return 0;
- ext_dev_cap = (struct cfg_cmd_ext_dev_cap *)kzalloc(sizeof(*ext_dev_cap), GFP_KERNEL);
+ ext_dev_cap = (struct cfg_cmd_ext_dev_cap *)kzalloc(
+ sizeof(*ext_dev_cap), GFP_KERNEL);
if (!ext_dev_cap)
return -ENOMEM;
ext_dev_cap->func_id = hinic5_global_func_id(hwdev);
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFGM, CFG_CMD_GET_EXTEND_DEV_CAP,
- ext_dev_cap, sizeof(*ext_dev_cap),
- ext_dev_cap, &out_len, 0,
- HINIC5_CHANNEL_COMM);
- if (err != 0 || ext_dev_cap->head.status != 0 || out_len == 0) {
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFGM,
+ CFG_CMD_GET_EXTEND_DEV_CAP, ext_dev_cap,
+ sizeof(*ext_dev_cap), ext_dev_cap,
+ &out_len, 0, HINIC5_CHANNEL_COMM);
+ if ((err != 0) || (ext_dev_cap->head.status != 0) || (out_len == 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to get extern capability from FW, err: %d, status: 0x%x, out size: 0x%x\n",
err, ext_dev_cap->head.status, out_len);
@@ -718,7 +780,7 @@ static int get_extend_dev_cap(struct hinic5_hwdev *hwdev, enum func_type type)
STATIC int valid_smf_cap(struct service_cap *cap)
{
- const u8 smf_num_whitelist[] = {0x2, 0x4, 0x8};
+ const u8 smf_num_whitelist[] = { 0x2, 0x4, 0x8 };
const u8 smf_max_num = cap->smf_max_num;
u32 i;
@@ -736,12 +798,15 @@ static int get_smf_max_and_enabled_num(struct hinic5_hwdev *hwdev)
u8 smf_id, smf_enabled_num = 0;
int err;
- if (cap->smf_max_num == 0)
+ if (cap->smf_max_num == 0) {
cap->smf_max_num = CHIP_SMF_NUM_MIN;
+ }
err = valid_smf_cap(cap);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Not supported max number of SMFs: %u\n", cap->smf_max_num);
+ sdk_err(hwdev->dev_hdl,
+ "Not supported max number of SMFs: %u\n",
+ cap->smf_max_num);
return err;
}
@@ -752,8 +817,8 @@ static int get_smf_max_and_enabled_num(struct hinic5_hwdev *hwdev)
}
cap->smf_enabled_num = smf_enabled_num;
- sdk_info(hwdev->dev_hdl, "SMF cap: max %u, enabled %u\n", cap->smf_max_num,
- cap->smf_enabled_num);
+ sdk_info(hwdev->dev_hdl, "SMF cap: max %u, enabled %u\n",
+ cap->smf_max_num, cap->smf_enabled_num);
return 0;
}
@@ -790,7 +855,8 @@ int hinic5_get_dev_cap(void *hwdev)
case TYPE_VF:
err = get_cap_from_fw(dev, type);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to get PF/PPF capability\n");
+ sdk_err(dev->dev_hdl,
+ "Failed to get PF/PPF capability\n");
return err;
}
break;
@@ -811,56 +877,61 @@ STATIC int parse_host_timer_cfg(struct service_cap *cap,
struct timer_vf_info_fake *fake_info = &cfg->timer_vf_info.fake;
cap->timer_pf_id_start = cfg->timer_pf_id_start;
- cap->timer_pf_num = cfg->timer_pf_num;
+ cap->timer_pf_num = cfg->timer_pf_num;
cap->timer_vf_id_start = cfg->timer_vf_id_start;
- cap->timer_vf_num = cfg->timer_vf_num;
+ cap->timer_vf_num = cfg->timer_vf_num;
- memset(segs, 0, sizeof(cap->timer_vf_segs));
+ (void)memset_s(segs, sizeof(cap->timer_vf_segs), 0,
+ sizeof(cap->timer_vf_segs));
if (cfg->timer_vf_info_mode_segs != 0) {
- memcpy(segs,
- &cfg->timer_vf_info.segs,
- sizeof(cfg->timer_vf_info.segs));
+ return memcpy_s(segs, sizeof(cap->timer_vf_segs),
+ &cfg->timer_vf_info.segs,
+ sizeof(cfg->timer_vf_info.segs));
}
if (cfg->timer_vf_info_mode_fake != 0 &&
fake_info->timer_normal_vf_num != 0) {
- segs[0].start = cfg->timer_vf_id_start;
- segs[0].num = fake_info->timer_normal_vf_num;
+ segs[0].start = cfg->timer_vf_id_start;
+ segs[0].num = fake_info->timer_normal_vf_num;
segs[0x1].start = fake_info->timer_fake_vf_id_start;
- segs[0x1].num = fake_info->timer_fake_vf_num;
+ segs[0x1].num = fake_info->timer_fake_vf_num;
}
return 0;
}
-STATIC int check_host_timer_segments(struct service_cap *cap)
+STATIC int check_host_timer_segments(struct hinic5_hwdev *hwdev,
+ struct service_cap *cap)
{
struct timer_vf_info_seg *segs = cap->timer_vf_segs;
u16 vf_start = cap->timer_vf_id_start;
- u16 vf_end = cap->timer_vf_id_start + cap->timer_vf_num;
- u16 vf_last = vf_start;
+ u16 vf_end = cap->timer_vf_id_start + cap->timer_vf_num;
+ u16 vf_last = vf_start;
int i, err = 0;
for (i = 0; i < TIMER_VF_SEGS_NUM; i++) {
if (segs[i].start == 0)
break;
if (segs[i].num == 0) {
- pr_err("seg %d start is %u, but num is zero\n",
- i, segs[i].start);
+ sdk_err(hwdev->dev_hdl,
+ "seg %d start is %u, but num is zero\n", i,
+ segs[i].start);
err = -EINVAL;
goto fail;
}
if (segs[i].start < vf_last) {
- pr_err("seg %d conflict with last, seg start %u, last end %u\n",
- i, segs[i].start, vf_last);
+ sdk_err(hwdev->dev_hdl,
+ "seg %d conflict with last, seg start %u, last end %u\n",
+ i, segs[i].start, vf_last);
err = -EINVAL;
goto fail;
}
vf_last = segs[i].start + segs[i].num;
if (vf_last > vf_end) {
- pr_err("seg %d end %u > vf end %u", i, vf_last, vf_end);
+ sdk_err(hwdev->dev_hdl, "seg %d end %u > vf end %u", i,
+ vf_last, vf_end);
err = -ERANGE;
goto fail;
}
@@ -869,14 +940,16 @@ STATIC int check_host_timer_segments(struct service_cap *cap)
return 0;
fail:
- pr_err("vf timer segs: %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u\n",
- segs[0x0].start, segs[0x0].start + segs[0x0].num,
- segs[0x1].start, segs[0x1].start + segs[0x1].num,
- segs[0x2].start, segs[0x2].start + segs[0x2].num,
- segs[0x3].start, segs[0x3].start + segs[0x3].num,
- segs[0x4].start, segs[0x4].start + segs[0x4].num,
- segs[0x5].start, segs[0x5].start + segs[0x5].num,
- segs[0x6].start, segs[0x6].start + segs[0x6].num);
+ sdk_err(hwdev->dev_hdl,
+ "vf timer start %u, num %u, segs %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u\n",
+ cap->timer_vf_id_start, cap->timer_vf_num, segs[0x0].start,
+ segs[0x0].start + segs[0x0].num, segs[0x1].start,
+ segs[0x1].start + segs[0x1].num, segs[0x2].start,
+ segs[0x2].start + segs[0x2].num, segs[0x3].start,
+ segs[0x3].start + segs[0x3].num, segs[0x4].start,
+ segs[0x4].start + segs[0x4].num, segs[0x5].start,
+ segs[0x5].start + segs[0x5].num, segs[0x6].start,
+ segs[0x6].start + segs[0x6].num);
return err;
}
@@ -888,14 +961,15 @@ int hinic5_get_ppf_timer_cfg(void *hwdev)
u16 out_len = sizeof(cfg_host_timer);
int err;
- memset(&cfg_host_timer, 0, sizeof(cfg_host_timer));
+ (void)memset_s(&cfg_host_timer, sizeof(cfg_host_timer), 0,
+ sizeof(cfg_host_timer));
cfg_host_timer.host_id = dev->cfg_mgmt->svc_cap.host_id;
- err = hinic5_msg_to_mgmt_sync(dev, HINIC5_MOD_CFGM, CFG_CMD_GET_HOST_TIMER,
- &cfg_host_timer, sizeof(cfg_host_timer),
- &cfg_host_timer, &out_len, 0,
- HINIC5_CHANNEL_COMM);
- if (err != 0 || cfg_host_timer.head.status != 0 || out_len == 0) {
+ err = hinic5_msg_to_mgmt_sync(dev, HINIC5_MOD_CFGM,
+ CFG_CMD_GET_HOST_TIMER, &cfg_host_timer,
+ sizeof(cfg_host_timer), &cfg_host_timer,
+ &out_len, 0, HINIC5_CHANNEL_COMM);
+ if ((err != 0) || (cfg_host_timer.head.status != 0) || (out_len == 0)) {
sdk_err(dev->dev_hdl,
"Failed to get host timer cfg from FW, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg_host_timer.head.status, out_len);
@@ -909,11 +983,12 @@ int hinic5_get_ppf_timer_cfg(void *hwdev)
return err;
}
- sdk_info(dev->dev_hdl, "Get host timer cfg with vf info mode: segs %u, fake %u\n",
+ sdk_info(dev->dev_hdl,
+ "Get host timer cfg with vf info mode: segs %u, fake %u\n",
cfg_host_timer.timer_vf_info_mode_segs,
cfg_host_timer.timer_vf_info_mode_fake);
- err = check_host_timer_segments(cap);
+ err = check_host_timer_segments(dev, cap);
if (err != 0) {
sdk_err(dev->dev_hdl,
"Failed to check host timer config, err %d\n", err);
@@ -1006,14 +1081,11 @@ static void rdma_param_fix(struct hinic5_hwdev *dev)
rdma_param_fix_part(rdma_cap);
rdma_cap->num_comp_vectors = (u32)dev->cfg_mgmt->eq_info.num_ceq;
rdma_cap->page_size_cap = PAGE_SZ_CAP;
- rdma_cap->flags = (RDMA_BMME_FLAG_LOCAL_INV |
- RDMA_BMME_FLAG_REMOTE_INV |
- RDMA_BMME_FLAG_FAST_REG_WR |
- RDMA_DEV_CAP_FLAG_XRC |
- RDMA_DEV_CAP_FLAG_MEM_WINDOW |
- RDMA_BMME_FLAG_TYPE_2_WIN |
- RDMA_BMME_FLAG_WIN_TYPE_2B |
- RDMA_DEV_CAP_FLAG_ATOMIC);
+ rdma_cap->flags =
+ (RDMA_BMME_FLAG_LOCAL_INV | RDMA_BMME_FLAG_REMOTE_INV |
+ RDMA_BMME_FLAG_FAST_REG_WR | RDMA_DEV_CAP_FLAG_XRC |
+ RDMA_DEV_CAP_FLAG_MEM_WINDOW | RDMA_BMME_FLAG_TYPE_2_WIN |
+ RDMA_BMME_FLAG_WIN_TYPE_2B | RDMA_DEV_CAP_FLAG_ATOMIC);
rdma_cap->max_frpl_len = MAX_FRPL_LEN;
rdma_cap->max_pkeys = MAX_PKEYS;
}
@@ -1086,7 +1158,8 @@ static void ub_param_fix(struct hinic5_hwdev *dev)
ub_cap->sdk_res.dmtt_cl_end = UB_DMTT_CL_END;
ub_cap->sdk_res.dmtt_cl_sz = UB_DMTT_CL_SIZE;
- ub_cap->net_dev_cap.comp_vector_cnt = (u32)dev->cfg_mgmt->eq_info.num_ceq;
+ ub_cap->net_dev_cap.comp_vector_cnt =
+ (u32)dev->cfg_mgmt->eq_info.num_ceq;
ub_cap->net_dev_cap.port_cnt = 1;
}
@@ -1143,8 +1216,9 @@ static int cfg_init_eq(struct hinic5_hwdev *dev)
sdk_info(dev->dev_hdl, "Cfg mgmt: ceqs=0x%x, remain=0x%x\n",
cfg_mgmt->eq_info.num_ceq, cfg_mgmt->eq_info.num_ceq_remain);
- if (num_ceq == 0)
+ if (num_ceq == 0) {
return 0;
+ }
eq = kcalloc(num_ceq, sizeof(*eq), GFP_KERNEL);
if (!eq)
@@ -1183,14 +1257,22 @@ int hinic5_vector_to_eqn(void *hwdev, enum hinic5_service_type type, int vector)
cfg_mgmt = dev->cfg_mgmt;
if (!cfg_mgmt) {
- sdk_err(dev->dev_hdl, "Service type :%d, cfg_mgmt is null.\n", type);
+ sdk_err(dev->dev_hdl, "Service type :%d, cfg_mgmt is null.\n",
+ type);
+ return -EINVAL;
+ }
+
+ if (cfg_mgmt->eq_info.num_ceq == 0) {
+ sdk_err(dev->dev_hdl, "Get eqn fail, num ceq is zero\n");
return -EINVAL;
}
- vector_num = (vector_num % cfg_mgmt->eq_info.num_ceq) + CFG_RDMA_CEQ_BASE;
+ vector_num =
+ (vector_num % cfg_mgmt->eq_info.num_ceq) + CFG_RDMA_CEQ_BASE;
eq = cfg_mgmt->eq_info.eq;
- if (eq[vector_num].type == SERVICE_T_ROCE && eq[vector_num].free == CFG_BUSY)
+ if (eq[vector_num].type == SERVICE_T_ROCE &&
+ eq[vector_num].free == CFG_BUSY)
eqn = eq[vector_num].eqn;
return eqn;
@@ -1202,23 +1284,29 @@ static int cfg_init_interrupt(struct hinic5_hwdev *dev)
struct cfg_mgmt_info *cfg_mgmt = dev->cfg_mgmt;
struct cfg_irq_info *irq_info = &cfg_mgmt->irq_param_info;
u16 intr_num = dev->hwif->attr.num_irqs;
- u16 intr_needed = (dev->hwif->attr.msix_flex_en != 0) ? (dev->hwif->attr.num_aeqs +
- dev->hwif->attr.num_ceqs + dev->hwif->attr.num_sq) : intr_num;
+ u16 intr_needed =
+ (dev->hwif->attr.msix_flex_en != 0) ?
+ (dev->hwif->attr.num_aeqs + dev->hwif->attr.num_ceqs +
+ dev->hwif->attr.num_sq) :
+ intr_num;
if (intr_num == 0) {
- sdk_err(dev->dev_hdl, "Irq num cfg in fw is zero, msix_flex_en %d\n",
+ sdk_err(dev->dev_hdl,
+ "Irq num cfg in fw is zero, msix_flex_en %d\n",
dev->hwif->attr.msix_flex_en);
return -EFAULT;
}
if (intr_needed > intr_num) {
- sdk_warn(dev->dev_hdl, "Irq num cfg(%u) is less than the needed irq num(%u) msix_flex_en %u\n",
- intr_num, intr_needed, dev->hwif->attr.msix_flex_en);
+ sdk_warn(
+ dev->dev_hdl,
+ "Irq num cfg(%u) is less than the needed irq num(%u) msix_flex_en %u\n",
+ intr_num, intr_needed, dev->hwif->attr.msix_flex_en);
intr_needed = intr_num;
}
- irq_info->alloc_info = kcalloc(intr_num, sizeof(*irq_info->alloc_info),
- GFP_KERNEL);
+ irq_info->alloc_info =
+ kcalloc(intr_num, sizeof(*irq_info->alloc_info), GFP_KERNEL);
if (!irq_info->alloc_info)
return -ENOMEM;
@@ -1248,7 +1336,8 @@ static int cfg_enable_interrupt(struct hinic5_hwdev *dev)
switch (cfg_mgmt->svc_cap.interrupt_type) {
case INTR_TYPE_MSIX:
if (nreq == 0) {
- sdk_err(dev->dev_hdl, "Interrupt number cannot be zero\n");
+ sdk_err(dev->dev_hdl,
+ "Interrupt number cannot be zero\n");
return -EINVAL;
}
entry = kcalloc(nreq, sizeof(*entry), GFP_KERNEL);
@@ -1258,10 +1347,11 @@ static int cfg_enable_interrupt(struct hinic5_hwdev *dev)
for (i = 0; i < nreq; i++)
entry[i].entry = i;
- actual_irq = hinic5_adev_irq_vectors_alloc(dev->adapter_hdl, entry,
- VECTOR_THRESHOLD, nreq);
+ actual_irq = hinic5_adev_irq_vectors_alloc(
+ dev->adapter_hdl, entry, VECTOR_THRESHOLD, nreq);
if (actual_irq < 0) {
- sdk_err(dev->dev_hdl, "Alloc msix entries with threshold 2 failed. actual_irq: %d\n",
+ sdk_err(dev->dev_hdl,
+ "Alloc msix entries with threshold 2 failed. actual_irq: %d\n",
actual_irq);
kfree(entry);
return -ENOMEM;
@@ -1279,7 +1369,8 @@ static int cfg_enable_interrupt(struct hinic5_hwdev *dev)
/* u32 kernel uses to write allocated vector */
irq_id = hinic5_adev_irq_vector(dev->adapter_hdl, i);
if (irq_id < 0) {
- sdk_err(dev->dev_hdl, "Unable to get idx %d, irq %d\n", i,
+ sdk_err(dev->dev_hdl,
+ "Unable to get idx %d, irq %d\n", i,
irq_id);
hinic5_adev_irq_vectors_free(dev->adapter_hdl);
kfree(entry);
@@ -1316,7 +1407,7 @@ int hinic5_alloc_irqs(void *hwdev, enum hinic5_service_type type, u16 num,
if (!hwdev || !dev->cfg_mgmt || num == 0 || !irq_info_array || !act_num)
return -EINVAL;
- if (type > SERVICE_T_HINIC5_CQM) {
+ if (type > SERVICE_T_CQM) {
pr_err("type is out of bounds\n");
return -EINVAL;
}
@@ -1331,7 +1422,8 @@ int hinic5_alloc_irqs(void *hwdev, enum hinic5_service_type type, u16 num,
return -ENOMEM;
}
if (alloc_num > free_num_irq) {
- sdk_warn(dev->dev_hdl, "only %u irq resource in cfg mgmt.\n", free_num_irq);
+ sdk_warn(dev->dev_hdl, "only %u irq resource in cfg mgmt.\n",
+ free_num_irq);
alloc_num = free_num_irq;
}
@@ -1346,7 +1438,8 @@ int hinic5_alloc_irqs(void *hwdev, enum hinic5_service_type type, u16 num,
if (irq_info->num_irq_remain == 0) {
/* irq_info->num_irq_remain is not updated correctly */
- sdk_err(dev->dev_hdl, "No free irq resource in cfg mgmt\n");
+ sdk_err(dev->dev_hdl,
+ "No free irq resource in cfg mgmt\n");
mutex_unlock(&irq_info->irq_mutex);
return -EINVAL;
}
@@ -1399,7 +1492,8 @@ void hinic5_free_irq(void *hwdev, enum hinic5_service_type type, u32 irq_id)
alloc_info[i].free = CFG_FREE;
irq_info->num_irq_remain++;
if (irq_info->num_irq_remain > max_num_irq) {
- sdk_err(dev->dev_hdl, "Find target,but over range\n");
+ sdk_err(dev->dev_hdl,
+ "Find target,but over range\n");
mutex_unlock(&irq_info->irq_mutex);
return;
}
@@ -1435,7 +1529,8 @@ int hinic5_alloc_ceqs(void *hwdev, enum hinic5_service_type type, int num,
if (num > free_ceq) {
if (free_ceq <= 0) {
- sdk_err(dev->dev_hdl, "No free ceq resource in cfg mgmt\n");
+ sdk_err(dev->dev_hdl,
+ "No free ceq resource in cfg mgmt\n");
mutex_unlock(&eq->eq_mutex);
return -ENOMEM;
}
@@ -1449,7 +1544,8 @@ int hinic5_alloc_ceqs(void *hwdev, enum hinic5_service_type type, int num,
num_new = min(num_new, eq->num_ceq - CFG_RDMA_CEQ_BASE);
for (i = 0; i < num_new; i++) {
if (eq->num_ceq_remain == 0) {
- sdk_warn(dev->dev_hdl, "Alloc %d ceqs, less than required %d ceqs\n",
+ sdk_warn(dev->dev_hdl,
+ "Alloc %d ceqs, less than required %d ceqs\n",
*act_num, num_new);
mutex_unlock(&eq->eq_mutex);
return 0;
@@ -1490,7 +1586,8 @@ void hinic5_free_ceq(void *hwdev, enum hinic5_service_type type, int ceq_id)
mutex_lock(&eq->eq_mutex);
for (i = 0; i < num_ceq; i++) {
- if (ceq_id == eq->eq[i].eqn && type == cfg_mgmt->eq_info.eq[i].type) {
+ if (ceq_id == eq->eq[i].eqn &&
+ type == cfg_mgmt->eq_info.eq[i].type) {
if (eq->eq[i].free != CFG_BUSY)
continue;
@@ -1511,7 +1608,7 @@ void hinic5_free_ceq(void *hwdev, enum hinic5_service_type type, int ceq_id)
}
EXPORT_SYMBOL(hinic5_free_ceq);
-int hinic5_init_cfg_mgmt(struct hinic5_hwdev *dev)
+int init_cfg_mgmt(struct hinic5_hwdev *dev)
{
int err;
struct cfg_mgmt_info *cfg_mgmt = NULL;
@@ -1525,8 +1622,8 @@ int hinic5_init_cfg_mgmt(struct hinic5_hwdev *dev)
err = cfg_init_eq(dev);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to init cfg event queue, err: %d\n",
- err);
+ sdk_err(dev->dev_hdl,
+ "Failed to init cfg event queue, err: %d\n", err);
goto free_mgmt_mem;
}
@@ -1539,8 +1636,8 @@ int hinic5_init_cfg_mgmt(struct hinic5_hwdev *dev)
err = cfg_enable_interrupt(dev);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to enable cfg interrupt, err: %d\n",
- err);
+ sdk_err(dev->dev_hdl,
+ "Failed to enable cfg interrupt, err: %d\n", err);
goto free_interrupt_mem;
}
@@ -1562,15 +1659,16 @@ int hinic5_init_cfg_mgmt(struct hinic5_hwdev *dev)
return err;
}
-void hinic5_free_cfg_mgmt(struct hinic5_hwdev *dev)
+void free_cfg_mgmt(struct hinic5_hwdev *dev)
{
struct cfg_mgmt_info *cfg_mgmt = dev->cfg_mgmt;
/* if the allocated resource were recycled */
if (cfg_mgmt->irq_param_info.num_irq_remain !=
- cfg_mgmt->irq_param_info.num_total ||
+ cfg_mgmt->irq_param_info.num_total ||
cfg_mgmt->eq_info.num_ceq_remain != cfg_mgmt->eq_info.num_ceq)
- sdk_err(dev->dev_hdl, "Can't reclaim all irq and event queue, please check\n");
+ sdk_err(dev->dev_hdl,
+ "Can't reclaim all irq and event queue, please check\n");
hinic5_adev_irq_vectors_free(dev->adapter_hdl);
@@ -1587,7 +1685,7 @@ void hinic5_free_cfg_mgmt(struct hinic5_hwdev *dev)
kfree(cfg_mgmt);
}
-int hinic5_init_capability(struct hinic5_hwdev *dev)
+int init_capability(struct hinic5_hwdev *dev)
{
int err;
struct cfg_mgmt_info *cfg_mgmt = dev->cfg_mgmt;
@@ -1605,7 +1703,7 @@ int hinic5_init_capability(struct hinic5_hwdev *dev)
return 0;
}
-void hinic5_free_capability(struct hinic5_hwdev *dev)
+void free_capability(struct hinic5_hwdev *dev)
{
sdk_info(dev->dev_hdl, "Free capability success");
}
@@ -1621,8 +1719,9 @@ bool hinic5_support_nic(void *hwdev, struct nic_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.nic_cap,
- sizeof(struct nic_service_cap));
+ (void)memcpy_s(cap, sizeof(struct nic_service_cap),
+ &dev->cfg_mgmt->svc_cap.nic_cap,
+ sizeof(struct nic_service_cap));
return true;
}
@@ -1639,8 +1738,9 @@ bool hinic5_support_ppa(void *hwdev, struct ppa_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.ppa_cap,
- sizeof(struct ppa_service_cap));
+ (void)memcpy_s(cap, sizeof(struct ppa_service_cap),
+ &dev->cfg_mgmt->svc_cap.ppa_cap,
+ sizeof(struct ppa_service_cap));
return true;
}
@@ -1674,8 +1774,9 @@ bool hinic5_support_ipsec(void *hwdev, struct ipsec_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.ipsec_cap,
- sizeof(struct ipsec_service_cap));
+ (void)memcpy_s(cap, sizeof(struct ipsec_service_cap),
+ &dev->cfg_mgmt->svc_cap.ipsec_cap,
+ sizeof(struct ipsec_service_cap));
return true;
}
@@ -1706,8 +1807,9 @@ bool hinic5_support_roce(void *hwdev, struct rdma_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.rdma_cap,
- sizeof(struct rdma_service_cap));
+ (void)memcpy_s(cap, sizeof(struct rdma_service_cap),
+ &dev->cfg_mgmt->svc_cap.rdma_cap,
+ sizeof(struct rdma_service_cap));
return true;
}
@@ -1724,8 +1826,9 @@ bool hinic5_support_fc(void *hwdev, struct fc_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.fc_cap,
- sizeof(struct fc_service_cap));
+ (void)memcpy_s(cap, sizeof(struct fc_service_cap),
+ &dev->cfg_mgmt->svc_cap.fc_cap,
+ sizeof(struct fc_service_cap));
return true;
}
@@ -1742,8 +1845,9 @@ bool hinic5_support_rdma(void *hwdev, struct rdma_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.rdma_cap,
- sizeof(struct rdma_service_cap));
+ (void)memcpy_s(cap, sizeof(struct rdma_service_cap),
+ &dev->cfg_mgmt->svc_cap.rdma_cap,
+ sizeof(struct rdma_service_cap));
return true;
}
@@ -1753,14 +1857,16 @@ bool hinic5_is_rdma_en(void *hwdev, struct rdma_service_cap *cap)
{
struct hinic5_hwdev *dev = hwdev;
- if (!hwdev)
+ if (hwdev == NULL)
return false;
if (!IS_RDMA_ENABLE(dev))
return false;
- if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.rdma_cap, sizeof(struct rdma_service_cap));
+ if (cap != NULL)
+ (void)memcpy_s(cap, sizeof(struct rdma_service_cap),
+ &dev->cfg_mgmt->svc_cap.rdma_cap,
+ sizeof(struct rdma_service_cap));
return true;
}
@@ -1777,8 +1883,9 @@ bool hinic5_support_ovs(void *hwdev, struct ovs_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.ovs_cap,
- sizeof(struct ovs_service_cap));
+ (void)memcpy_s(cap, sizeof(struct ovs_service_cap),
+ &dev->cfg_mgmt->svc_cap.ovs_cap,
+ sizeof(struct ovs_service_cap));
return true;
}
@@ -1795,8 +1902,9 @@ bool hinic5_support_vbs(void *hwdev, struct vbs_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.vbs_cap,
- sizeof(struct vbs_service_cap));
+ (void)memcpy_s(cap, sizeof(struct vbs_service_cap),
+ &dev->cfg_mgmt->svc_cap.vbs_cap,
+ sizeof(struct vbs_service_cap));
return true;
}
@@ -1814,8 +1922,9 @@ bool hinic5_support_toe(void *hwdev, struct toe_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.toe_cap,
- sizeof(struct toe_service_cap));
+ (void)memcpy_s(cap, sizeof(struct toe_service_cap),
+ &dev->cfg_mgmt->svc_cap.toe_cap,
+ sizeof(struct toe_service_cap));
return true;
}
@@ -1834,8 +1943,9 @@ bool hinic5_support_ub(void *hwdev, struct ub_service_cap *cap)
}
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.ub_cap,
- sizeof(struct ub_service_cap));
+ (void)memcpy_s(cap, sizeof(struct ub_service_cap),
+ &dev->cfg_mgmt->svc_cap.ub_cap,
+ sizeof(struct ub_service_cap));
return true;
}
@@ -1854,8 +1964,9 @@ bool hinic5_support_jbof(void *hwdev, struct jbof_service_cap *cap)
}
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.jbof_cap,
- sizeof(struct jbof_service_cap));
+ (void)memcpy_s(cap, sizeof(struct jbof_service_cap),
+ &dev->cfg_mgmt->svc_cap.jbof_cap,
+ sizeof(struct jbof_service_cap));
return true;
}
@@ -1872,8 +1983,9 @@ bool hinic5_support_vroce(void *hwdev, struct rdma_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.rdma_cap,
- sizeof(struct rdma_service_cap));
+ (void)memcpy_s(cap, sizeof(struct rdma_service_cap),
+ &dev->cfg_mgmt->svc_cap.rdma_cap,
+ sizeof(struct rdma_service_cap));
return true;
}
@@ -1890,8 +2002,9 @@ bool hinic5_support_dmmu(void *hwdev, struct dmmu_service_cap *cap)
return false;
if (cap)
- memcpy(cap, &dev->cfg_mgmt->svc_cap.dmmu_cap,
- sizeof(struct dmmu_service_cap));
+ (void)memcpy_s(cap, sizeof(struct dmmu_service_cap),
+ &dev->cfg_mgmt->svc_cap.dmmu_cap,
+ sizeof(struct dmmu_service_cap));
return true;
}
@@ -2101,7 +2214,7 @@ void hinic5_shutdown_hwdev(void *hwdev)
return;
if (IS_SLAVE_HOST(dev) != 0)
- hinic5_set_slave_host_enable(hwdev, hinic5_pcie_itf_id(hwdev), false);
+ set_slave_host_enable(hwdev, hinic5_pcie_itf_id(hwdev), false);
}
u32 hinic5_host_pf_num(void *hwdev)
@@ -2187,23 +2300,25 @@ int hinic5_bat_get_l3i_entry_config(const struct hinic5_hwdev *hwdev,
bool ft_enable;
bool rdma_enable;
- if (!hwdev || !hwdev->hwif || !hwdev->cfg_mgmt || !entry_config)
+ if (hwdev == NULL || hwdev->hwif == NULL || hwdev->cfg_mgmt == NULL ||
+ entry_config == NULL)
return -EINVAL;
func_attr = &hwdev->hwif->attr;
- svc_cap = &hwdev->cfg_mgmt->svc_cap;
+ svc_cap = &hwdev->cfg_mgmt->svc_cap;
func_type = func_attr->func_type;
ft_enable = svc_cap->sf_svc_attr.ft_en;
rdma_enable = svc_cap->sf_svc_attr.rdma_en;
- if (func_type != TYPE_PF && func_type != TYPE_PPF) {
- entry_config->mapping = false;
+ if (func_type != TYPE_PF && func_type != TYPE_PPF &&
+ !COMM_SUPPORT_VF_BAT_EXPANDED(hwdev)) {
+ entry_config->mapping = false;
entry_config->bat_entry_offset = 0;
- entry_config->bat_entry_size = 0;
+ entry_config->bat_entry_size = 0;
return 0;
}
- entry_config->mapping = true;
+ entry_config->mapping = true;
entry_config->bat_entry_size = HINIC5_BAT_ENTRY_SIZE;
if (ft_enable && rdma_enable)
@@ -2224,22 +2339,26 @@ int hinic5_dcb_state_op(void *hwdev, enum hisdk5_dcb_state_op op,
struct hinic5_hwdev *dev = hwdev;
struct hisdk5_dcb_state *state = NULL;
- if (!dev || !dev->cfg_mgmt || !dcb_state) {
+ if ((!dev) || (!dev->cfg_mgmt) || (!dcb_state)) {
pr_err("Hwdev pointer or dcb_state pointer is NULL\n");
return -EINVAL;
}
state = &dev->cfg_mgmt->svc_cap.dcb_state;
- if (op == HISDK5_DCB_STATE_GET)
- memcpy(dcb_state, state, sizeof(struct hisdk5_dcb_state));
- else
- memcpy(state, dcb_state, sizeof(struct hisdk5_dcb_state));
+ if (op == HISDK5_DCB_STATE_GET) {
+ (void)memcpy_s(dcb_state, sizeof(struct hisdk5_dcb_state),
+ state, sizeof(struct hisdk5_dcb_state));
+ } else {
+ (void)memcpy_s(state, sizeof(struct hisdk5_dcb_state),
+ dcb_state, sizeof(struct hisdk5_dcb_state));
+ }
return 0;
}
EXPORT_SYMBOL(hinic5_dcb_state_op);
-int hinic5_get_port_info(void *hwdev, struct mag_port_info *port_info, u16 channel)
+int hinic5_get_port_info(void *hwdev, struct mag_port_info *port_info,
+ u16 channel)
{
struct mag_cmd_get_port_info port_msg = { 0 };
u16 out_size = sizeof(port_msg);
@@ -2251,9 +2370,16 @@ int hinic5_get_port_info(void *hwdev, struct mag_port_info *port_info, u16 chann
port_msg.port_id = hinic5_physical_port_id(hwdev);
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_HILINK, MAG_CMD_GET_PORT_INFO, &port_msg,
- sizeof(port_msg), &port_msg, &out_size, 0, channel);
- if (err != 0 || out_size == 0 || port_msg.head.status != 0) {
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_HILINK,
+ MAG_CMD_GET_PORT_INFO, &port_msg,
+ sizeof(port_msg), &port_msg, &out_size, 0,
+ channel);
+ if (err == 0 &&
+ port_msg.head.status ==
+ HINIC5_LOGICAL_OPTICAL_UNSUPPORTED) { /* ethtool,返回不支持 */
+ return -EOPNOTSUPP;
+ }
+ if ((err != 0) || (out_size == 0) || (port_msg.head.status != 0)) {
sdk_err(dev->dev_hdl,
"Failed to get port info, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, port_msg.head.status, out_size, channel);
@@ -2276,7 +2402,7 @@ EXPORT_SYMBOL(hinic5_get_port_info);
int hinic5_get_speed(void *hwdev, enum mag_cmd_port_speed *speed, u16 channel)
{
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
int err;
if (unlikely(!hwdev || !speed))
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.h
index 2f61b4461..09c72ba68 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_cfg.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_cfg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_HW_CFG_H
#define HINIC5_HW_CFG_H
@@ -16,161 +9,156 @@
#include "cfg_mgmt_mpu_cmd_defs.h"
#include "hinic5_hwdev.h"
-enum {
- CFG_FREE = 0,
- CFG_BUSY = 1
-};
+enum { CFG_FREE = 0, CFG_BUSY = 1 };
/* start position for CEQs allocation, Max number of CEQs is 32 */
-enum {
- CFG_RDMA_CEQ_BASE = 0
-};
+enum { CFG_RDMA_CEQ_BASE = 0 };
/* Public resources */
-#define CHIP_SMF_NUM_MIN 4 /* Min number of SMFs supported */
-#define CHIP_SMF_NUM_MAX 8 /* Max number of SMFs supported */
+#define CHIP_SMF_NUM_MIN 4 /* Min number of SMFs supported */
+#define CHIP_SMF_NUM_MAX 8 /* Max number of SMFs supported */
/* RDMA resource */
-#define K_UNIT BIT(10)
-#define M_UNIT BIT(20)
-#define G_UNIT BIT(30)
+#define K_UNIT BIT(10)
+#define M_UNIT BIT(20)
+#define G_UNIT BIT(30)
#define VIRTIO_BASE_VQ_SIZE 2048U
#define VIRTIO_DEFAULT_VQ_SIZE 8192U
/* L2NIC */
-#define HINIC5_CFG_MAX_QP 256
+#define HINIC5_CFG_MAX_QP 256
/* RDMA */
-#define RDMA_RSVD_QPS 2
-#define ROCE_MAX_WQES (8 * K_UNIT - 1)
-#define IWARP_MAX_WQES (8 * K_UNIT)
+#define RDMA_RSVD_QPS 2
+#define ROCE_MAX_WQES (8 * K_UNIT - 1)
+#define IWARP_MAX_WQES (8 * K_UNIT)
-#define RDMA_MAX_SQ_SGE 32
+#define RDMA_MAX_SQ_SGE 32
-#define ROCE_MAX_RQ_SGE 16
+#define ROCE_MAX_RQ_SGE 16
/* value changed should change ROCE_MAX_WQE_BB_PER_WR synchronously */
#define RDMA_MAX_SQ_DESC_SZ (256)
/* (256B(cache_line_len) - 16B(ctrl_seg_len) - 48B(max_task_seg_len)) */
-#define ROCE_MAX_SQ_INLINE_DATA_SZ 912
+#define ROCE_MAX_SQ_INLINE_DATA_SZ 912
-#define ROCE_MAX_RQ_DESC_SZ 256
+#define ROCE_MAX_RQ_DESC_SZ 256
-#define ROCE_QPC_ENTRY_SZ 512
+#define ROCE_QPC_ENTRY_SZ 512
#define HYPER_ROCE_QPC_ENTRY_SZ 1024
-#define WQEBB_SZ 64
+#define WQEBB_SZ 64
-#define ROCE_RDMARC_ENTRY_SZ 32
-#define ROCE_MAX_QP_INIT_RDMA 128
-#define ROCE_MAX_QP_DEST_RDMA 128
+#define ROCE_RDMARC_ENTRY_SZ 32
+#define ROCE_MAX_QP_INIT_RDMA 128
+#define ROCE_MAX_QP_DEST_RDMA 128
-#define ROCE_MAX_SRQ_WQES (16 * K_UNIT - 1)
-#define ROCE_MAX_SRQ_SGE 15
-#define ROCE_SRQC_ENTERY_SZ 64
+#define ROCE_MAX_SRQ_WQES (16 * K_UNIT - 1)
+#define ROCE_MAX_SRQ_SGE 15
+#define ROCE_SRQC_ENTERY_SZ 64
-#define RDMA_MAX_CQES (8 * M_UNIT - 1)
-#define RDMA_RSVD_CQS 0
+#define RDMA_MAX_CQES (8 * M_UNIT - 1)
+#define RDMA_RSVD_CQS 0
-#define RDMA_CQC_ENTRY_SZ 128
+#define RDMA_CQC_ENTRY_SZ 128
-#define RDMA_CQE_SZ 64
-#define RDMA_RSVD_MRWS 128
-#define RDMA_MPT_ENTRY_SZ 64
-#define RDMA_FRMR_MAP_NUM 0xff
-#define RDMA_NUM_MTTS (1 * G_UNIT)
-#define LOG_MTT_SEG 9
-#define MTT_ENTRY_SZ 8
-#define LOG_RDMARC_SEG 3
+#define RDMA_CQE_SZ 64
+#define RDMA_RSVD_MRWS 128
+#define RDMA_MPT_ENTRY_SZ 64
+#define RDMA_FRMR_MAP_NUM 0xff
+#define RDMA_NUM_MTTS (1 * G_UNIT)
+#define LOG_MTT_SEG 9
+#define MTT_ENTRY_SZ 8
+#define LOG_RDMARC_SEG 3
-#define LOCAL_ACK_DELAY 15
-#define RDMA_NUM_PORTS 1
-#define ROCE_MAX_MSG_SZ (2 * G_UNIT)
+#define LOCAL_ACK_DELAY 15
+#define RDMA_NUM_PORTS 1
+#define ROCE_MAX_MSG_SZ (2 * G_UNIT)
-#define DB_PAGE_SZ (4 * K_UNIT)
-#define DWQE_SZ 256
+#define DB_PAGE_SZ (4 * K_UNIT)
+#define DWQE_SZ 256
-#define NUM_PD (256 * K_UNIT)
-#define RSVD_PD 0
+#define NUM_PD (256 * K_UNIT)
+#define RSVD_PD 0
-#define MAX_XRCDS (64 * K_UNIT)
-#define RSVD_XRCDS 0
+#define MAX_XRCDS (64 * K_UNIT)
+#define RSVD_XRCDS 0
-#define MAX_GID_PER_PORT 128
-#define GID_ENTRY_SZ 32
-#define RSVD_LKEY ((RDMA_RSVD_MRWS - 1) << 8)
-#define NUM_COMP_VECTORS 32
-#define PAGE_SZ_CAP ((1UL << 12) | (1UL << 16) | (1UL << 21))
-#define ROCE_MODE 1
+#define MAX_GID_PER_PORT 128
+#define GID_ENTRY_SZ 32
+#define RSVD_LKEY ((RDMA_RSVD_MRWS - 1) << 8)
+#define NUM_COMP_VECTORS 32
+#define PAGE_SZ_CAP ((1UL << 12) | (1UL << 16) | (1UL << 21))
+#define ROCE_MODE 1
-#define MAX_FRPL_LEN 511
-#define MAX_PKEYS 1
+#define MAX_FRPL_LEN 511
+#define MAX_PKEYS 1
#define COS_DEFAULT_MASK_MODE 0xFF
/* ToE */
-#define TOE_PCTX_SZ 1024
-#define TOE_CQC_SZ 64
+#define TOE_PCTX_SZ 1024
+#define TOE_CQC_SZ 64
/* IoE */
-#define IOE_PCTX_SZ 512
+#define IOE_PCTX_SZ 512
/* FC */
-#define FC_PCTX_SZ 256
-#define FC_CCTX_SZ 256
-#define FC_SQE_SZ 128
-#define FC_SCQC_SZ 64
-#define FC_SCQE_SZ 64
-#define FC_SRQC_SZ 64
-#define FC_SRQE_SZ 32
+#define FC_PCTX_SZ 256
+#define FC_CCTX_SZ 256
+#define FC_SQE_SZ 128
+#define FC_SCQC_SZ 64
+#define FC_SCQE_SZ 64
+#define FC_SRQC_SZ 64
+#define FC_SRQE_SZ 32
/* OVS */
-#define OVS_PCTX_SZ 512
+#define OVS_PCTX_SZ 512
/* PPA */
-#define PPA_PCTX_SZ 512
+#define PPA_PCTX_SZ 512
/* IPsec */
-#define IPSEC_SACTX_SZ 512
+#define IPSEC_SACTX_SZ 512
/* UB */
-#define UB_CQC_ENTRY_SZ 128
-#define UB_QPC_ENTRY_SZ 1024
-#define UB_SRQC_ENTERY_SZ 64
-#define UB_DWQE_SZ 256
-#define UB_LOG_MTT_SEG 5
-#define UB_NUM_MTTS (1 * G_UNIT)
-#define UB_MTT_ENTRY_SZ 8
-#define UB_MPT_ENTRY_SZ 64
-#define MAX_JETTY_DEST_UB 128
-#define UB_RC_ENTRY_SZ 32
-#define LOG_UBRC_SEG 3
-#define UB_MAX_JFS_INLINE_DATA_SZ 192
-#define UB_MAX_MSG_SZ (2 * G_UNIT)
-#define UB_MAX_VTP (0x20000)
-
-#define UB_CMTT_CL_START 0x20
-#define UB_CMTT_CL_END 0x27
-#define UB_CMTT_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
-#define UB_WQE_CL_START 0x10
-#define UB_WQE_CL_END 0x1f
-#define UB_WQE_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
-
-#define UB_DMTT_CL_START 0x20
-#define UB_DMTT_CL_END 0x27
-#define UB_DMTT_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
+#define UB_CQC_ENTRY_SZ 128
+#define UB_QPC_ENTRY_SZ 1024
+#define UB_SRQC_ENTERY_SZ 64
+#define UB_DWQE_SZ 256
+#define UB_LOG_MTT_SEG 5
+#define UB_NUM_MTTS (1 * G_UNIT)
+#define UB_MTT_ENTRY_SZ 8
+#define UB_MPT_ENTRY_SZ 64
+#define MAX_JETTY_DEST_UB 128
+#define UB_RC_ENTRY_SZ 32
+#define LOG_UBRC_SEG 3
+#define UB_MAX_JFS_INLINE_DATA_SZ 192
+#define UB_MAX_MSG_SZ (2 * G_UNIT)
+#define UB_MAX_VTP (0x20000)
+
+#define UB_CMTT_CL_START 0x20
+#define UB_CMTT_CL_END 0x27
+#define UB_CMTT_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
+#define UB_WQE_CL_START 0x10
+#define UB_WQE_CL_END 0x1f
+#define UB_WQE_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
+
+#define UB_DMTT_CL_START 0x20
+#define UB_DMTT_CL_END 0x27
+#define UB_DMTT_CL_SIZE 0 // 0: 256B; 1: 512B; 2: 1024B
/* JBOF */
-#define JBOF_PCTX_SZ 256
-#define JBOF_CCTX_SZ 256
+#define JBOF_PCTX_SZ 256
+#define JBOF_CCTX_SZ 256
struct dev_sf_svc_attr {
- bool ft_en; /* business enable flag (not include RDMA) */
- bool ft_pf_en; /* In FPGA Test VF resource is in PF or not,
+ bool ft_en; /* business enable flag (not include RDMA) */
+ bool ft_pf_en; /* In FPGA Test VF resource is in PF or not,
* 0 - VF, 1 - PF, VF doesn't need this bit.
*/
bool rdma_en;
- bool rdma_pf_en;/* In FPGA Test VF RDMA resource is in PF or not,
+ bool rdma_pf_en; /* In FPGA Test VF RDMA resource is in PF or not,
* 0 - VF, 1 - PF, VF doesn't need this bit.
*/
};
@@ -188,13 +176,13 @@ enum intr_type {
/* device capability */
struct service_cap {
struct dev_sf_svc_attr sf_svc_attr;
- u32 svc_type; /* user input service type */
+ u32 svc_type; /* user input service type */
u32 chip_svc_type; /* HW supported service type, reference to servic_bit_define_e */
u8 host_id;
u8 ep_id;
- u8 er_id; /* PF/VF's ER */
- u8 port_id; /* PF/VF's physical port */
+ u8 er_id; /* PF/VF's ER */
+ u8 port_id; /* PF/VF's physical port */
/* Host global resources */
u16 host_total_function;
@@ -221,14 +209,15 @@ struct service_cap {
u8 cos_valid_bitmap;
u8 port_cos_valid_bitmap;
u8 func_gpa_spu_en;
- u16 max_vf; /* max VF number that PF supported */
+ u16 max_vf; /* max VF number that PF supported */
/* Fake VF capabilities */
u16 fake_vf_parent_func_id; /* Parent function id of the fake vf group */
u16 fake_vf_start_id;
- u16 fake_vf_num; /* fake vf number that PF supported */
- u16 fake_vf_num_cfg; /* fake vf number that PF configured */
+ u16 fake_vf_num; /* fake vf number that PF supported */
+ u16 fake_vf_num_cfg; /* fake vf number that PF configured */
bool fake_vf_lazy_init;
+ bool fake_vf_bat_expanded;
u32 fake_vf_max_pctx;
u32 fake_vf_max_scqc_ctx;
@@ -238,7 +227,7 @@ struct service_cap {
u32 fake_vf_max_childc_ctx;
bool fake_vf_qpc_ctx_size_en;
- u8 fake_vf_qpc_ctx_size_order;
+ u8 fake_vf_qpc_ctx_size_order;
u16 fake_vf_bfilter_start_addr;
u16 fake_vf_bfilter_len;
@@ -246,23 +235,23 @@ struct service_cap {
/* DO NOT get interrupt_type from firmware */
enum intr_type interrupt_type;
- bool sf_en; /* stateful business status */
- u8 timer_en; /* 0:disable, 1:enable */
+ bool sf_en; /* stateful business status */
+ u8 timer_en; /* 0:disable, 1:enable */
u8 bloomfilter_en; /* 0:disable, 1:enable */
/* SMF capabilities */
u8 lb_mode;
- u8 smf_pg; /* A bitmap indicating which SMFs are enabled.
- * The valid length of this bitmap is smf_max_num.
- */
- u8 smf_max_num; /* The Number of SMFs in the chip */
- u8 smf_enabled_num; /* The Number of SMFs currently enabled */
+ u8 smf_pg; /* A bitmap indicating which SMFs are enabled.
+ * The valid length of this bitmap is smf_max_num.
+ */
+ u8 smf_max_num; /* The Number of SMFs in the chip */
+ u8 smf_enabled_num; /* The Number of SMFs currently enabled */
/* SMF BAT capabilities */
u8 bat_cid_index_bit_width;
/* SRIOV capabilities */
- bool vf_isolation; /* The VF communicates directly with the Mgmt */
+ bool vf_isolation; /* The VF communicates directly with the Mgmt */
/* For test */
u32 test_mode;
@@ -303,19 +292,19 @@ struct service_cap {
struct hisdk5_dcb_state dcb_state;
- cfg_fw_update_ext_caps fw_update_cap; /* fw update capability */
- struct nic_service_cap nic_cap; /* NIC capability */
- struct rdma_service_cap rdma_cap; /* RDMA capability */
- struct fc_service_cap fc_cap; /* FC capability */
- struct toe_service_cap toe_cap; /* ToE capability */
- struct ovs_service_cap ovs_cap; /* OVS capability */
- struct ipsec_service_cap ipsec_cap; /* IPsec capability */
- struct ppa_service_cap ppa_cap; /* PPA capability */
- struct vbs_service_cap vbs_cap; /* VBS capability */
- struct ub_service_cap ub_cap; /* UB capability */
- struct jbof_service_cap jbof_cap; /* JBOF capability */
- struct dmmu_service_cap dmmu_cap; /* DMMU capability */
- struct cfm_service_cap cfm_cap; /* CFM capability */
+ cfg_fw_update_ext_caps fw_update_cap; /* fw update capability */
+ struct nic_service_cap nic_cap; /* NIC capability */
+ struct rdma_service_cap rdma_cap; /* RDMA capability */
+ struct fc_service_cap fc_cap; /* FC capability */
+ struct toe_service_cap toe_cap; /* ToE capability */
+ struct ovs_service_cap ovs_cap; /* OVS capability */
+ struct ipsec_service_cap ipsec_cap; /* IPsec capability */
+ struct ppa_service_cap ppa_cap; /* PPA capability */
+ struct vbs_service_cap vbs_cap; /* VBS capability */
+ struct ub_service_cap ub_cap; /* UB capability */
+ struct jbof_service_cap jbof_cap; /* JBOF capability */
+ struct dmmu_service_cap dmmu_cap; /* DMMU capability */
+ struct cfm_service_cap cfm_cap; /* CFM capability */
};
struct svc_cap_info {
@@ -342,7 +331,7 @@ struct cfg_eq_info {
struct irq_alloc_info_st {
enum hinic5_service_type type;
- int free; /* 1 - alocated, 0- freed */
+ int free; /* 1 - alocated, 0- freed */
struct irq_info info;
};
@@ -350,26 +339,27 @@ struct cfg_irq_info {
struct irq_alloc_info_st *alloc_info;
u16 num_total;
u16 num_irq_remain;
- u16 num_irq_hw; /* device max irq number */
+ u16 num_irq_hw; /* device max irq number */
/* mutex used for allocate EQs */
struct mutex irq_mutex;
};
-#define VECTOR_THRESHOLD 2
+#define VECTOR_THRESHOLD 2
struct cfg_mgmt_info {
struct hinic5_hwdev *hwdev;
- struct service_cap svc_cap;
- struct cfg_eq_info eq_info; /* EQ */
+ struct service_cap svc_cap;
+ struct cfg_eq_info eq_info; /* EQ */
struct cfg_irq_info irq_param_info; /* IRQ */
- u32 func_seq_num; /* temporary */
+ u32 func_seq_num; /* temporary */
};
-#define CFG_SERVICE_FT_EN (CFG_SERVICE_MASK_VBS | CFG_SERVICE_MASK_TOE | \
- CFG_SERVICE_MASK_IPSEC | CFG_SERVICE_MASK_FC | \
- CFG_SERVICE_MASK_VIRTIO | CFG_SERVICE_MASK_OVS)
-#define CFG_SERVICE_RDMA_EN CFG_SERVICE_MASK_ROCE
+#define CFG_SERVICE_FT_EN \
+ (CFG_SERVICE_MASK_VBS | CFG_SERVICE_MASK_TOE | \
+ CFG_SERVICE_MASK_IPSEC | CFG_SERVICE_MASK_FC | \
+ CFG_SERVICE_MASK_VIRTIO | CFG_SERVICE_MASK_OVS)
+#define CFG_SERVICE_RDMA_EN CFG_SERVICE_MASK_ROCE
#define IS_NIC_TYPE(dev) \
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_NIC)
@@ -381,8 +371,9 @@ struct cfg_mgmt_info {
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_TOE)
#define IS_IPSEC_TYPE(dev) \
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_IPSEC)
-#define IS_MACSEC_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MACSEC)
+#define IS_MACSEC_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & \
+ CFG_SERVICE_MASK_MACSEC)
#define IS_FC_TYPE(dev) \
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_FC)
#define IS_OVS_TYPE(dev) \
@@ -391,61 +382,60 @@ struct cfg_mgmt_info {
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_FT_EN)
#define IS_RDMA_TYPE(dev) \
(((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_RDMA_EN)
-#define IS_RDMA_ENABLE(dev) \
- ((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
-#define IS_FT_ENABLE(dev) \
- ((dev)->cfg_mgmt->svc_cap.sf_svc_attr.ft_en)
+#define IS_RDMA_ENABLE(dev) ((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
+#define IS_FT_ENABLE(dev) ((dev)->cfg_mgmt->svc_cap.sf_svc_attr.ft_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
-#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+#define IS_MIGR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & \
+ CFG_SERVICE_MASK_MIGRATE)
#define IS_UB_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_UB)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_UB)
#define IS_JBOF_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_JBOF)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_JBOF)
#define IS_VROCE_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_VROCE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_VROCE)
#define IS_DMMU_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_DMMU)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_DMMU)
#define IS_BIFUR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
#define IS_HIHTR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_HIHTR)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_HIHTR)
-int hinic5_init_cfg_mgmt(struct hinic5_hwdev *dev);
+int init_cfg_mgmt(struct hinic5_hwdev *dev);
-void hinic5_free_cfg_mgmt(struct hinic5_hwdev *dev);
+void free_cfg_mgmt(struct hinic5_hwdev *dev);
-int hinic5_init_capability(struct hinic5_hwdev *dev);
+int init_capability(struct hinic5_hwdev *dev);
-void hinic5_free_capability(struct hinic5_hwdev *dev);
+void free_capability(struct hinic5_hwdev *dev);
-/* Reference: hwsdk/hinic5_cqm/hinic5_cqm_bat_cla.h#HINIC5_CQM_BAT_ENTRY_MAX */
-#define HINIC5_BAT_ENTRY_MAX 16
-/* Reference: hwsdk/hinic5_cqm/hinic5_cqm_bat_cla.h#HINIC5_CQM_BAT_ENTRY_SIZE */
-#define HINIC5_BAT_ENTRY_SIZE 16
-#define HINIC5_BAT_MAX (HINIC5_BAT_ENTRY_MAX * HINIC5_BAT_ENTRY_SIZE)
+#define HINIC5_BAT_ENTRY_MAX \
+ 16 /* Reference: hwsdk/cqm/cqm_bat_cla.h#CQM_BAT_ENTRY_MAX */
+#define HINIC5_BAT_ENTRY_SIZE \
+ 16 /* Reference: hwsdk/cqm/cqm_bat_cla.h#CQM_BAT_ENTRY_SIZE */
+#define HINIC5_BAT_MAX (HINIC5_BAT_ENTRY_MAX * HINIC5_BAT_ENTRY_SIZE)
-#define HINIC5_BAT_L3I_OFF_FT_RDMA_PF (10 * HINIC5_BAT_ENTRY_SIZE)
-#define HINIC5_BAT_L3I_OFF_FT_PF (7 * HINIC5_BAT_ENTRY_SIZE)
-#define HINIC5_BAT_L3I_OFF_RDMA_PF (5 * HINIC5_BAT_ENTRY_SIZE)
-#define HINIC5_BAT_L3I_OFF_PF 0
+#define HINIC5_BAT_L3I_OFF_FT_RDMA_PF (10 * HINIC5_BAT_ENTRY_SIZE)
+#define HINIC5_BAT_L3I_OFF_FT_PF (7 * HINIC5_BAT_ENTRY_SIZE)
+#define HINIC5_BAT_L3I_OFF_RDMA_PF (5 * HINIC5_BAT_ENTRY_SIZE)
+#define HINIC5_BAT_L3I_OFF_PF 0
struct hinic5_bat_entry_config {
- bool mapping; /* Whether this entry should be mapped into
- * the function address space.
- */
- u32 bat_entry_offset; /* Offset of the entry in the BAT register file. */
- u32 bat_entry_size; /* Size of the entry in the BAT register file. */
+ bool mapping; /* Whether this entry should be mapped into
+ * the function address space. */
+ u32 bat_entry_offset; /* Offset of the entry in the BAT register file. */
+ u32 bat_entry_size; /* Size of the entry in the BAT register file. */
};
-int hinic5_bat_get_l3i_entry_config(const struct hinic5_hwdev *hwdev,
- struct hinic5_bat_entry_config *entry_config);
+int hinic5_bat_get_l3i_entry_config(
+ const struct hinic5_hwdev *hwdev,
+ struct hinic5_bat_entry_config *entry_config);
-static inline struct service_cap *get_device_capablity(const struct hinic5_hwdev *hwdev)
+static inline struct service_cap *
+get_device_capablity(const struct hinic5_hwdev *hwdev)
{
return &hwdev->cfg_mgmt->svc_cap;
}
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.c
index f16bc947c..b2f12c3af 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_comm.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include <linux/kernel.h>
#include <linux/msi.h>
@@ -22,42 +15,44 @@
#include "hinic5_common.h"
#include "hinic5_csr_inner.h"
#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_mgmt.h"
#include "hinic5_hw_cfg.h"
#include "hinic5_cmdq.h"
#include "mpu_inband_cmd_defs.h"
#include "mpu_inband_cmd.h"
-#include "hinic5_vram_common.h"
-#include "hinic5_hinic5_vram_api.h"
+#include "vram_common.h"
+#include "hinic5_vram_api.h"
#include "hinic5_hw_comm.h"
-unsigned char lowpower_mode;
-module_param(lowpower_mode, byte, 0644);
-MODULE_PARM_DESC(lowpower_mode, "Set lowpower test mode, 0-sml rd loop, 1-writeback ddr, 2-off");
+unsigned char lowpower_mode = 0;
+module_param(lowpower_mode, byte, 0444);
+MODULE_PARM_DESC(
+ lowpower_mode,
+ "Set lowpower test mode, 0-sml rd loop, 1-writeback ddr, 2-off");
-/* 1872 FT B505 temporary modification, to be removed after MQM fixes CMQ constraint */
-static unsigned char cmdq_cos_offset;
+/* 1872 FT B505临时修改方案,待MQM修复CMQ约束后删除 */
+static unsigned char cmdq_cos_offset = 0;
module_param(cmdq_cos_offset, byte, 0444);
MODULE_PARM_DESC(cmdq_cos_offset, "Set cmdq cos start offset");
-#define HINIC5_MSIX_CNT_LLI_TIMER_SHIFT 0
-#define HINIC5_MSIX_CNT_LLI_CREDIT_SHIFT 8
-#define HINIC5_MSIX_CNT_COALESC_TIMER_SHIFT 8
-#define HINIC5_MSIX_CNT_PENDING_SHIFT 8
-#define HINIC5_MSIX_CNT_RESEND_TIMER_SHIFT 29
+#define HINIC5_MSIX_CNT_LLI_TIMER_SHIFT 0
+#define HINIC5_MSIX_CNT_LLI_CREDIT_SHIFT 8
+#define HINIC5_MSIX_CNT_COALESC_TIMER_SHIFT 8
+#define HINIC5_MSIX_CNT_PENDING_SHIFT 8
+#define HINIC5_MSIX_CNT_RESEND_TIMER_SHIFT 29
-#define HINIC5_MSIX_CNT_LLI_TIMER_MASK 0xFFU
-#define HINIC5_MSIX_CNT_LLI_CREDIT_MASK 0xFFU
-#define HINIC5_MSIX_CNT_COALESC_TIMER_MASK 0xFFU
-#define HINIC5_MSIX_CNT_PENDING_MASK 0x1FU
-#define HINIC5_MSIX_CNT_RESEND_TIMER_MASK 0x7U
+#define HINIC5_MSIX_CNT_LLI_TIMER_MASK 0xFFU
+#define HINIC5_MSIX_CNT_LLI_CREDIT_MASK 0xFFU
+#define HINIC5_MSIX_CNT_COALESC_TIMER_MASK 0xFFU
+#define HINIC5_MSIX_CNT_PENDING_MASK 0x1FU
+#define HINIC5_MSIX_CNT_RESEND_TIMER_MASK 0x7U
-#define HINIC5_MSIX_CNT_SET(val, member) \
- (((val) & HINIC5_MSIX_CNT_##member##_MASK) << \
- HINIC5_MSIX_CNT_##member##_SHIFT)
+#define HINIC5_MSIX_CNT_SET(val, member) \
+ (((val)&HINIC5_MSIX_CNT_##member##_MASK) \
+ << HINIC5_MSIX_CNT_##member##_SHIFT)
-#define DEFAULT_RX_BUF_SIZE ((u16)0xB)
+#define DEFAULT_RX_BUF_SIZE ((u16)0xB)
#define HINIC5_HT_GPA_PAGE_LEN 1024
enum hinic5_rx_buf_size {
@@ -79,21 +74,33 @@ enum hinic5_rx_buf_size {
HINIC5_RX_BUF_SIZE_16K = 0x4000,
};
-static inline int comm_msg_to_mgmt_sync(struct hinic5_hwdev *hwdev, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size)
+static inline int comm_msg_to_mgmt_sync(struct hinic5_hwdev *hwdev, u16 cmd,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
{
return hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, cmd, buf_in,
in_size, buf_out, out_size, 0,
HINIC5_CHANNEL_COMM);
}
-static inline int comm_msg_to_mgmt_sync_ch(struct hinic5_hwdev *hwdev, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size, u16 channel)
+static inline int comm_msg_to_mgmt_sync_ch(struct hinic5_hwdev *hwdev, u16 cmd,
+ void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size,
+ u16 channel)
{
return hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, cmd, buf_in,
in_size, buf_out, out_size, 0, channel);
}
+static inline size_t get_bank_pg0_size(void)
+{
+ if (likely(lowpower_mode == 0)) {
+ return HINIC5_HT_GPA_PAGE_SIZE;
+ }
+
+ return HINIC5_HT_GPA_PAGE_SIZE * HINIC5_HT_GPA_PAGE_LEN;
+}
+
int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info,
u16 channel)
{
@@ -105,7 +112,7 @@ int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info,
if (!hwdev || !info)
return -EINVAL;
- memset(&msix_cfg, 0, sizeof(msix_cfg));
+ (void)memset_s(&msix_cfg, sizeof(msix_cfg), 0, sizeof(msix_cfg));
msix_cfg.func_id = hinic5_global_func_id(hwdev);
msix_cfg.msix_index = info->msix_index;
msix_cfg.opcode = MGMT_MSG_CMD_OP_GET;
@@ -113,8 +120,9 @@ int hinic5_get_interrupt_cfg(void *dev, struct interrupt_info *info,
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
&msix_cfg, sizeof(msix_cfg), &msix_cfg,
&out_size, channel);
- if (err != 0 || out_size == 0 || msix_cfg.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (msix_cfg.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, msix_cfg.head.status, out_size, channel);
return -EINVAL;
}
@@ -138,7 +146,7 @@ int hinic5_set_interrupt_cfg_direct(void *hwdev, struct interrupt_info *info,
if (!hwdev)
return -EINVAL;
- memset(&msix_cfg, 0, sizeof(msix_cfg));
+ (void)memset_s(&msix_cfg, sizeof(msix_cfg), 0, sizeof(msix_cfg));
msix_cfg.func_id = hinic5_global_func_id(hwdev);
msix_cfg.msix_index = info->msix_index;
msix_cfg.opcode = MGMT_MSG_CMD_OP_SET;
@@ -152,7 +160,7 @@ int hinic5_set_interrupt_cfg_direct(void *hwdev, struct interrupt_info *info,
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
&msix_cfg, sizeof(msix_cfg), &msix_cfg,
&out_size, channel);
- if (err != 0 || out_size == 0 || msix_cfg.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (msix_cfg.head.status) != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set interrupt config, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, msix_cfg.head.status, out_size, channel);
@@ -218,7 +226,8 @@ int hinic5_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size,
u16 out_size = sizeof(page_size_info);
int err;
- memset(&page_size_info, 0, sizeof(page_size_info));
+ (void)memset_s(&page_size_info, sizeof(page_size_info), 0,
+ sizeof(page_size_info));
page_size_info.func_id = func_idx;
page_size_info.page_size = HINIC5_PAGE_SIZE_HW(page_size);
page_size_info.opcode = MGMT_MSG_CMD_OP_SET;
@@ -226,7 +235,8 @@ int hinic5_set_wq_page_size(void *hwdev, u16 func_idx, u32 page_size,
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_CFG_PAGESIZE,
&page_size_info, sizeof(page_size_info),
&page_size_info, &out_size, channel);
- if (err != 0 || out_size == 0 || page_size_info.head.status != 0) {
+ if ((err != 0) || (out_size == 0) ||
+ (page_size_info.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set wq page size, err: %d, status: 0x%x, out_size: 0x%x, channel: 0x%x\n",
err, page_size_info.head.status, out_size, channel);
@@ -249,26 +259,27 @@ int hinic5_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
return -EINVAL;
}
- is_in_kexec = hinic5_vram_get_kexec_flag();
+ is_in_kexec = vram5_get_kexec_flag();
if (is_in_kexec != 0) {
sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
return 0;
}
- sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
- reset_flag, channel);
+ sdk_info(hwdev->dev_hdl,
+ "Function is reset, flag: 0x%llx, channel:0x%x\n", reset_flag,
+ channel);
- memset(&func_reset, 0, sizeof(func_reset));
+ (void)memset_s(&func_reset, sizeof(func_reset), 0, sizeof(func_reset));
func_reset.func_id = func_id;
func_reset.reset_flag = reset_flag;
- /* During func reset, chip may have OUTBOUND_FLUSH_DISABLED, skip abnormality check */
+ /* func reset时芯片会出现OUTBOUND_FLUSH_DISABLED, 不进行异常检测 */
atomic_inc(&hwdev->check_ob_flush_bypass_ref_cnt);
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_FUNC_RESET,
&func_reset, sizeof(func_reset),
&func_reset, &out_size, channel);
- if (err != 0 || out_size == 0 || func_reset.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (func_reset.head.status != 0)) {
sdk_err(hwdev->dev_hdl,
- "Failed to reset func resources, reset_flag 0x%llx, err: %d, " \
+ "Failed to reset func resources, reset_flag 0x%llx, err: %d, "
"status: 0x%x, out_size: 0x%x\n",
reset_flag, err, func_reset.head.status, out_size);
err = -EIO;
@@ -282,22 +293,14 @@ EXPORT_SYMBOL(hinic5_func_reset);
static u16 get_hw_rx_buf_size(const void *hwdev, u16 rx_buf_sz)
{
const int hinic5_hw_rx_buf_size[] = {
- HINIC5_RX_BUF_SIZE_32B,
- HINIC5_RX_BUF_SIZE_64B,
- HINIC5_RX_BUF_SIZE_96B,
- HINIC5_RX_BUF_SIZE_128B,
- HINIC5_RX_BUF_SIZE_192B,
- HINIC5_RX_BUF_SIZE_256B,
- HINIC5_RX_BUF_SIZE_384B,
- HINIC5_RX_BUF_SIZE_512B,
- HINIC5_RX_BUF_SIZE_768B,
- HINIC5_RX_BUF_SIZE_1K,
- HINIC5_RX_BUF_SIZE_1_5K,
- HINIC5_RX_BUF_SIZE_2K,
- HINIC5_RX_BUF_SIZE_3K,
- HINIC5_RX_BUF_SIZE_4K,
- HINIC5_RX_BUF_SIZE_8K,
- HINIC5_RX_BUF_SIZE_16K,
+ HINIC5_RX_BUF_SIZE_32B, HINIC5_RX_BUF_SIZE_64B,
+ HINIC5_RX_BUF_SIZE_96B, HINIC5_RX_BUF_SIZE_128B,
+ HINIC5_RX_BUF_SIZE_192B, HINIC5_RX_BUF_SIZE_256B,
+ HINIC5_RX_BUF_SIZE_384B, HINIC5_RX_BUF_SIZE_512B,
+ HINIC5_RX_BUF_SIZE_768B, HINIC5_RX_BUF_SIZE_1K,
+ HINIC5_RX_BUF_SIZE_1_5K, HINIC5_RX_BUF_SIZE_2K,
+ HINIC5_RX_BUF_SIZE_3K, HINIC5_RX_BUF_SIZE_4K,
+ HINIC5_RX_BUF_SIZE_8K, HINIC5_RX_BUF_SIZE_16K,
};
u16 num_hw_types;
u16 i;
@@ -326,7 +329,7 @@ int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz,
if (!hwdev)
return -EINVAL;
- memset(&root_ctxt, 0, sizeof(root_ctxt));
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
root_ctxt.func_id = hinic5_global_func_id(hwdev);
root_ctxt.set_cmdq_depth = 0;
@@ -334,19 +337,20 @@ int hinic5_set_root_ctxt(void *hwdev, u32 rq_depth, u32 sq_depth, u16 rx_buf_sz,
root_ctxt.lro_en = 1;
- root_ctxt.rq_depth = (u16)ilog2(rq_depth);
+ root_ctxt.rq_depth = (u16)ilog2(rq_depth);
root_ctxt.rx_buf_sz = get_hw_rx_buf_size(hwdev, rx_buf_sz);
- root_ctxt.sq_depth = (u16)ilog2(sq_depth);
+ root_ctxt.sq_depth = (u16)ilog2(sq_depth);
- err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_SET_VAT,
- &root_ctxt, sizeof(root_ctxt),
- &root_ctxt, &out_size, channel);
- if (err != 0 || out_size == 0 || root_ctxt.head.status != 0) {
+ err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_SET_VAT, &root_ctxt,
+ sizeof(root_ctxt), &root_ctxt, &out_size,
+ channel);
+ if ((err != 0) || (out_size == 0) || (root_ctxt.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set root context, err: %d, status: 0x%x, out_size: 0x%x, channel: 0x%x\n",
err, root_ctxt.head.status, out_size, channel);
return -EFAULT;
}
+
return 0;
}
EXPORT_SYMBOL(hinic5_set_root_ctxt);
@@ -360,13 +364,13 @@ int hinic5_clean_root_ctxt(void *hwdev, u16 channel)
if (!hwdev)
return -EINVAL;
- memset(&root_ctxt, 0, sizeof(root_ctxt));
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
root_ctxt.func_id = hinic5_global_func_id(hwdev);
- err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_SET_VAT,
- &root_ctxt, sizeof(root_ctxt),
- &root_ctxt, &out_size, channel);
- if (err != 0 || out_size == 0 || root_ctxt.head.status != 0) {
+ err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_SET_VAT, &root_ctxt,
+ sizeof(root_ctxt), &root_ctxt, &out_size,
+ channel);
+ if ((err != 0) || (out_size == 0) || (root_ctxt.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set root context, err: %d, status: 0x%x, out_size: 0x%x, channel: 0x%x\n",
err, root_ctxt.head.status, out_size, channel);
@@ -383,7 +387,7 @@ int hinic5_set_cmdq_depth(void *hwdev, u16 cmdq_depth)
u16 out_size = sizeof(root_ctxt);
int err;
- memset(&root_ctxt, 0, sizeof(root_ctxt));
+ (void)memset_s(&root_ctxt, sizeof(root_ctxt), 0, sizeof(root_ctxt));
root_ctxt.func_id = hinic5_global_func_id(hwdev);
root_ctxt.set_cmdq_depth = 1;
@@ -395,7 +399,7 @@ int hinic5_set_cmdq_depth(void *hwdev, u16 cmdq_depth)
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_VAT, &root_ctxt,
sizeof(root_ctxt), &root_ctxt, &out_size);
- if (err != 0 || out_size == 0 || root_ctxt.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (root_ctxt.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set cmdq depth, err: %d, status: 0x%x, out_size: 0x%x\n",
err, root_ctxt.head.status, out_size);
@@ -412,17 +416,18 @@ int hinic5_set_enhance_cmdq_ctxt(struct hinic5_hwdev *hwdev, u8 cmdq_id,
u16 out_size = sizeof(cmdq_ctxt);
int err;
- memset(&cmdq_ctxt, 0, sizeof(cmdq_ctxt));
- memcpy(&cmdq_ctxt.ctxt, ctxt, sizeof(*ctxt));
+ (void)memset_s(&cmdq_ctxt, sizeof(cmdq_ctxt), 0, sizeof(cmdq_ctxt));
+ (void)memcpy_s(&cmdq_ctxt.ctxt, sizeof(*ctxt), ctxt, sizeof(*ctxt));
cmdq_ctxt.func_id = hinic5_global_func_id(hwdev);
cmdq_ctxt.cmdq_id = cmdq_id | cmdq_cos_offset;
hwdev->cmdq_cos_offset = cmdq_cos_offset;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_ENHANCE_CMDQ_CTXT,
- &cmdq_ctxt, sizeof(cmdq_ctxt),
- &cmdq_ctxt, &out_size);
- if (err != 0 || out_size == 0 || cmdq_ctxt.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to set enhanced cmdq ctxt, err: %d, status: 0x%x, out_size: 0x%x\n",
+ &cmdq_ctxt, sizeof(cmdq_ctxt), &cmdq_ctxt,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (cmdq_ctxt.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to set enhanced cmdq ctxt, err: %d, status: 0x%x, out_size: 0x%x\n",
err, cmdq_ctxt.head.status, out_size);
return -EFAULT;
}
@@ -437,16 +442,17 @@ int hinic5_set_cmdq_ctxt(struct hinic5_hwdev *hwdev, u8 cmdq_id,
u16 out_size = sizeof(cmdq_ctxt);
int err;
- memset(&cmdq_ctxt, 0, sizeof(cmdq_ctxt));
- memcpy(&cmdq_ctxt.ctxt, ctxt, sizeof(*ctxt));
+ (void)memset_s(&cmdq_ctxt, sizeof(cmdq_ctxt), 0, sizeof(cmdq_ctxt));
+ (void)memcpy_s(&cmdq_ctxt.ctxt, sizeof(*ctxt), ctxt, sizeof(*ctxt));
cmdq_ctxt.func_id = hinic5_global_func_id(hwdev);
cmdq_ctxt.cmdq_id = cmdq_id;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_CMDQ_CTXT,
- &cmdq_ctxt, sizeof(cmdq_ctxt),
- &cmdq_ctxt, &out_size);
- if (err != 0 || out_size == 0 || cmdq_ctxt.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to set cmdq ctxt, err: %d, status: 0x%x, out_size: 0x%x\n",
+ &cmdq_ctxt, sizeof(cmdq_ctxt), &cmdq_ctxt,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (cmdq_ctxt.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to set cmdq ctxt, err: %d, status: 0x%x, out_size: 0x%x\n",
err, cmdq_ctxt.head.status, out_size);
return -EFAULT;
}
@@ -454,24 +460,25 @@ int hinic5_set_cmdq_ctxt(struct hinic5_hwdev *hwdev, u8 cmdq_id,
return 0;
}
-int hinic5_set_ceq_ctrl_reg(struct hinic5_hwdev *hwdev, u16 q_id,
- u32 ctrl0, u32 ctrl1)
+int hinic5_set_ceq_ctrl_reg(struct hinic5_hwdev *hwdev, u16 q_id, u32 ctrl0,
+ u32 ctrl1)
{
struct comm_cmd_ceq_ctrl_reg ceq_ctrl;
u16 out_size = sizeof(ceq_ctrl);
int err;
- memset(&ceq_ctrl, 0, sizeof(ceq_ctrl));
+ (void)memset_s(&ceq_ctrl, sizeof(ceq_ctrl), 0, sizeof(ceq_ctrl));
ceq_ctrl.func_id = hinic5_global_func_id(hwdev);
ceq_ctrl.q_id = q_id;
ceq_ctrl.ctrl0 = ctrl0;
ceq_ctrl.ctrl1 = ctrl1;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- &ceq_ctrl, sizeof(ceq_ctrl),
- &ceq_ctrl, &out_size);
- if (err != 0 || out_size == 0 || ceq_ctrl.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to set ceq %u ctrl reg, err: %d status: 0x%x, out_size: 0x%x\n",
+ &ceq_ctrl, sizeof(ceq_ctrl), &ceq_ctrl,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (ceq_ctrl.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to set ceq %u ctrl reg, err: %d status: 0x%x, out_size: 0x%x\n",
q_id, err, ceq_ctrl.head.status, out_size);
return -EFAULT;
}
@@ -479,14 +486,14 @@ int hinic5_set_ceq_ctrl_reg(struct hinic5_hwdev *hwdev, u16 q_id,
return 0;
}
-int hinic5_set_dma_attr_tbl(struct hinic5_hwdev *hwdev, u8 entry_idx, u8 st, u8 at, u8 ph,
- u8 no_snooping, u8 tph_en)
+int hinic5_set_dma_attr_tbl(struct hinic5_hwdev *hwdev, u8 entry_idx, u8 st,
+ u8 at, u8 ph, u8 no_snooping, u8 tph_en)
{
struct comm_cmd_dma_attr_config dma_attr;
u16 out_size = sizeof(dma_attr);
int err;
- memset(&dma_attr, 0, sizeof(dma_attr));
+ (void)memset_s(&dma_attr, sizeof(dma_attr), 0, sizeof(dma_attr));
dma_attr.func_id = hinic5_global_func_id(hwdev);
dma_attr.entry_idx = entry_idx;
dma_attr.st = st;
@@ -495,10 +502,12 @@ int hinic5_set_dma_attr_tbl(struct hinic5_hwdev *hwdev, u8 entry_idx, u8 st, u8
dma_attr.no_snooping = no_snooping;
dma_attr.tph_en = tph_en;
- err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_DMA_ATTR, &dma_attr, sizeof(dma_attr),
- &dma_attr, &out_size);
- if (err != 0 || out_size == 0 || dma_attr.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to set dma attr, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_DMA_ATTR,
+ &dma_attr, sizeof(dma_attr), &dma_attr,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (dma_attr.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to set dma attr, err: %d, status: 0x%x, out_size: 0x%x\n",
err, dma_attr.head.status, out_size);
return -EIO;
}
@@ -515,16 +524,16 @@ int hinic5_set_bdf_ctxt(void *hwdev, u8 bus, u8 device, u8 function)
if (!hwdev)
return -EINVAL;
- memset(&bdf_info, 0, sizeof(bdf_info));
+ (void)memset_s(&bdf_info, sizeof(bdf_info), 0, sizeof(bdf_info));
bdf_info.function_idx = hinic5_global_func_id(hwdev);
bdf_info.bus = bus;
bdf_info.device = device;
bdf_info.function = function;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SEND_BDF_INFO,
- &bdf_info, sizeof(bdf_info),
- &bdf_info, &out_size);
- if (err != 0 || out_size == 0 || bdf_info.head.status != 0) {
+ &bdf_info, sizeof(bdf_info), &bdf_info,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (bdf_info.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set bdf info to MPU, err: %d, status: 0x%x, out_size: 0x%x\n",
err, bdf_info.head.status, out_size);
@@ -540,11 +549,11 @@ int hinic5_sync_time(void *hwdev, u64 time)
u16 out_size = sizeof(time_info);
int err;
- memset(&time_info, 0, sizeof(time_info));
+ (void)memset_s(&time_info, sizeof(time_info), 0, sizeof(time_info));
time_info.mstime = time;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SYNC_TIME, &time_info,
sizeof(time_info), &time_info, &out_size);
- if (err != 0 || time_info.head.status != 0 || out_size == 0) {
+ if ((err != 0) || (time_info.head.status != 0) || (out_size == 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to sync time to mgmt, err: %d, status: 0x%x, out size: 0x%x\n",
err, time_info.head.status, out_size);
@@ -564,15 +573,17 @@ int hinic5_set_ppf_flr_type(void *hwdev, enum hinic5_ppf_flr_type flr_type)
if (!hwdev)
return -EINVAL;
- memset(&flr_type_set, 0, sizeof(flr_type_set));
+ (void)memset_s(&flr_type_set, sizeof(flr_type_set), 0,
+ sizeof(flr_type_set));
flr_type_set.func_id = hinic5_global_func_id(hwdev);
flr_type_set.ppf_flr_type = flr_type;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
&flr_type_set, sizeof(flr_type_set),
&flr_type_set, &out_size);
- if (err != 0 || out_size == 0 || flr_type_set.head.status != 0) {
- sdk_err(dev->dev_hdl, "Failed to set ppf flr type, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (flr_type_set.head.status != 0)) {
+ sdk_err(dev->dev_hdl,
+ "Failed to set ppf flr type, err: %d, status: 0x%x, out size: 0x%x\n",
err, flr_type_set.head.status, out_size);
return -EIO;
}
@@ -593,13 +604,15 @@ int hinic5_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
return -EINVAL;
}
- memset(&htr_info, 0, sizeof(htr_info));
+ (void)memset_s(&htr_info, sizeof(htr_info), 0, sizeof(htr_info));
htr_info.hotreplace_flag = flag;
ret = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_PPF_TBL_HTR_FLG,
- &htr_info, sizeof(htr_info), &htr_info, &out_size);
+ &htr_info, sizeof(htr_info), &htr_info,
+ &out_size);
if (ret != 0 || htr_info.head.status != 0) {
- sdk_err(dev->dev_hdl, "Send mbox to mpu failed in sdk, ret:%d, status:%u",
+ sdk_err(dev->dev_hdl,
+ "Send mbox to mpu failed in sdk, ret:%d, status:%hu",
ret, htr_info.head.status);
return -EIO;
}
@@ -608,8 +621,9 @@ int hinic5_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
}
EXPORT_SYMBOL(hinic5_set_ppf_tbl_hotreplace_flag);
-static int hinic5_get_fw_ver(struct hinic5_hwdev *hwdev, enum hinic5_fw_ver_type type,
- u8 *mgmt_ver, u8 version_size, u16 channel)
+static int hinic5_get_fw_ver(struct hinic5_hwdev *hwdev,
+ enum hinic5_fw_ver_type type, u8 *mgmt_ver,
+ u8 version_size, u16 channel)
{
struct comm_cmd_get_fw_version fw_ver;
u16 out_size = sizeof(fw_ver);
@@ -618,12 +632,12 @@ static int hinic5_get_fw_ver(struct hinic5_hwdev *hwdev, enum hinic5_fw_ver_type
if (!hwdev || !mgmt_ver)
return -EINVAL;
- memset(&fw_ver, 0, sizeof(fw_ver));
+ (void)memset_s(&fw_ver, sizeof(fw_ver), 0, sizeof(fw_ver));
fw_ver.fw_type = type;
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_GET_FW_VERSION,
&fw_ver, sizeof(fw_ver), &fw_ver,
&out_size, channel);
- if (err != 0 || out_size == 0 || fw_ver.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (fw_ver.head.status) != 0) {
sdk_err(hwdev->dev_hdl,
"Failed to get fw version, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, fw_ver.head.status, out_size, channel);
@@ -635,7 +649,11 @@ static int hinic5_get_fw_ver(struct hinic5_hwdev *hwdev, enum hinic5_fw_ver_type
return -ERANGE;
}
- memcpy(mgmt_ver, fw_ver.ver, version_size);
+ err = memcpy_s(mgmt_ver, version_size, fw_ver.ver, version_size);
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl, "Copy memory fail: Ret:0x%x.\n", err);
+ return -EIO;
+ }
return 0;
}
@@ -655,9 +673,8 @@ int hinic5_get_fw_version(void *hwdev, struct hinic5_fw_version *fw_ver,
if (!hwdev || !fw_ver)
return -EINVAL;
- err = hinic5_get_fw_ver(hwdev, HINIC5_FW_VER_TYPE_MPU,
- fw_ver->mgmt_ver, sizeof(fw_ver->mgmt_ver),
- channel);
+ err = hinic5_get_fw_ver(hwdev, HINIC5_FW_VER_TYPE_MPU, fw_ver->mgmt_ver,
+ sizeof(fw_ver->mgmt_ver), channel);
if (err != 0)
return err;
@@ -684,23 +701,39 @@ static int hinic5_comm_features_nego(void *hwdev, u8 opcode, u64 *s_feature,
if (!hwdev || !s_feature || size > COMM_MAX_FEATURE_QWORD)
return -EINVAL;
- memset(&feature_nego, 0, sizeof(feature_nego));
+ (void)memset_s(&feature_nego, sizeof(feature_nego), 0,
+ sizeof(feature_nego));
feature_nego.func_id = hinic5_global_func_id(hwdev);
feature_nego.opcode = opcode;
- if (opcode == MGMT_MSG_CMD_OP_SET)
- memcpy(feature_nego.s_feature, s_feature, (size * sizeof(u64)));
+ if (opcode == MGMT_MSG_CMD_OP_SET) {
+ if (memcpy_s(feature_nego.s_feature,
+ (COMM_MAX_FEATURE_QWORD * sizeof(u64)), s_feature,
+ (size * sizeof(u64))) != 0) {
+ sdk_err(dev->dev_hdl,
+ "Failed to copy negotiate feature.\n");
+ return -ENOMEM;
+ }
+ }
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_FEATURE_NEGO,
&feature_nego, sizeof(feature_nego),
&feature_nego, &out_size);
- if (err != 0 || out_size == 0 || feature_nego.head.status != 0) {
- sdk_err(dev->dev_hdl, "Failed to negotiate feature, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (feature_nego.head.status != 0)) {
+ sdk_err(dev->dev_hdl,
+ "Failed to negotiate feature, err: %d, status: 0x%x, out size: 0x%x\n",
err, feature_nego.head.status, out_size);
return -EINVAL;
}
- if (opcode == MGMT_MSG_CMD_OP_GET)
- memcpy(s_feature, feature_nego.s_feature, (COMM_MAX_FEATURE_QWORD * sizeof(u64)));
+ if (opcode == MGMT_MSG_CMD_OP_GET) {
+ if (memcpy_s(s_feature, (size * sizeof(u64)),
+ feature_nego.s_feature,
+ (COMM_MAX_FEATURE_QWORD * sizeof(u64))) != 0) {
+ sdk_err(dev->dev_hdl,
+ "Failed to copy negotiate feature.\n");
+ return -ENOMEM;
+ }
+ }
return 0;
}
@@ -726,14 +759,17 @@ int hinic5_comm_channel_detect(struct hinic5_hwdev *hwdev)
if (!hwdev)
return -EINVAL;
- memset(&channel_detect_info, 0, sizeof(channel_detect_info));
+ (void)memset_s(&channel_detect_info, sizeof(channel_detect_info), 0,
+ sizeof(channel_detect_info));
channel_detect_info.func_id = hinic5_global_func_id(hwdev);
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_CHANNEL_DETECT,
- &channel_detect_info, sizeof(channel_detect_info),
+ &channel_detect_info,
+ sizeof(channel_detect_info),
&channel_detect_info, &out_size);
- if ((channel_detect_info.head.status != HINIC5_MGMT_CMD_UNSUPPORTED &&
- channel_detect_info.head.status != 0) || err != 0 || out_size == 0) {
+ if (((channel_detect_info.head.status != HINIC5_MGMT_CMD_UNSUPPORTED) &&
+ (channel_detect_info.head.status != 0)) ||
+ (err != 0) || (out_size == 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to send channel detect, err: %d, status: 0x%x, out size: 0x%x\n",
err, channel_detect_info.head.status, out_size);
@@ -755,14 +791,15 @@ int hinic5_func_tmr_bitmap_set(void *hwdev, u16 func_id, bool en)
if (!hwdev)
return -EINVAL;
- memset(&bitmap_op, 0, sizeof(bitmap_op));
+ (void)memset_s(&bitmap_op, sizeof(bitmap_op), 0, sizeof(bitmap_op));
bitmap_op.func_id = func_id;
- bitmap_op.opcode = en ? FUNC_TMR_BITMAP_ENABLE : FUNC_TMR_BITMAP_DISABLE;
+ bitmap_op.opcode = en ? FUNC_TMR_BITMAP_ENABLE :
+ FUNC_TMR_BITMAP_DISABLE;
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- &bitmap_op, sizeof(bitmap_op),
- &bitmap_op, &out_size);
- if (err != 0 || out_size == 0 || bitmap_op.head.status != 0) {
+ &bitmap_op, sizeof(bitmap_op), &bitmap_op,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (bitmap_op.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set timer bitmap, err: %d, status: 0x%x, out_size: 0x%x\n",
err, bitmap_op.head.status, out_size);
@@ -782,40 +819,39 @@ int hinic5_func_vio_en(void *hwdev, bool en)
if (!hwdev)
return -EINVAL;
- memset(&cmd, 0, sizeof(cmd));
+ (void)memset_s(&cmd, sizeof(cmd), 0, sizeof(cmd));
cmd.msien_snap_2_virtio_en = en ? 0x1 : 0x0;
- err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_VIO_EN,
- &cmd, sizeof(cmd), &cmd, &out_size);
+ err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_VIO_EN, &cmd,
+ sizeof(cmd), &cmd, &out_size);
if (cmd.head.status == HINIC5_MGMT_CMD_UNSUPPORTED) {
sdk_warn(dev->dev_hdl, "not support vio en");
return 0;
}
- if (err != 0 || out_size == 0 || cmd.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (cmd.head.status != 0)) {
sdk_err(dev->dev_hdl,
"Failed to set vio %s, err: %d, status: 0x%x, out_size: 0x%x\n",
- (en ? "enable" : "disable"),
- err, cmd.head.status, out_size);
+ (en ? "enable" : "disable"), err, cmd.head.status,
+ out_size);
return -EFAULT;
}
return 0;
}
-static int alloc_bank_buf(struct hinic5_hwdev *hwdev, struct hinic5_page_addr *pg0,
- struct hinic5_page_addr *pg1, struct comm_cmd_ht_gpa *ht_gpa_set)
+static int alloc_bank_buf(struct hinic5_hwdev *hwdev,
+ struct hinic5_page_addr *pg0,
+ struct hinic5_page_addr *pg1,
+ struct comm_cmd_ht_gpa *ht_gpa_set)
{
- size_t page_len = HINIC5_HT_GPA_PAGE_SIZE * HINIC5_HT_GPA_PAGE_LEN;
-
+ pg0->virt_addr = dma_zalloc_coherent(hwdev->dev_hdl,
+ get_bank_pg0_size(),
+ &pg0->phys_addr, GFP_KERNEL);
if (lowpower_mode != 0) {
- pg0->virt_addr = dma_zalloc_coherent(hwdev->dev_hdl, page_len,
- &pg0->phys_addr, GFP_KERNEL);
ht_gpa_set->rsvd0[0] = lowpower_mode;
- sdk_info(hwdev->dev_hdl, "Alloc pg0 page addr len: 0x%lx, lowpower_mode=%u\n",
- page_len, lowpower_mode);
- } else {
- pg0->virt_addr = dma_zalloc_coherent(hwdev->dev_hdl, HINIC5_HT_GPA_PAGE_SIZE,
- &pg0->phys_addr, GFP_KERNEL);
+ sdk_info(hwdev->dev_hdl,
+ "Alloc pg0 page addr len: 0x%lx, lowpower_mode=%u\n",
+ get_bank_pg0_size(), lowpower_mode);
}
if (!pg0->virt_addr) {
@@ -841,7 +877,7 @@ static int ht_gpa_set(struct hinic5_hwdev *hwdev, struct hinic5_page_addr *pg0,
u16 out_size = sizeof(ht_gpa_set);
int ret;
- memset(&ht_gpa_set, 0, sizeof(ht_gpa_set));
+ (void)memset_s(&ht_gpa_set, sizeof(ht_gpa_set), 0, sizeof(ht_gpa_set));
ret = alloc_bank_buf(hwdev, pg0, pg1, &ht_gpa_set);
if (ret != 0)
return -EFAULT;
@@ -851,18 +887,22 @@ static int ht_gpa_set(struct hinic5_hwdev *hwdev, struct hinic5_page_addr *pg0,
ht_gpa_set.page_pa0 = pg0->phys_addr;
ht_gpa_set.page_pa1 = pg1->phys_addr;
#ifndef __VMWARE__
- sdk_info(hwdev->dev_hdl, "ht gpa set: page_addr0.pa=0x%llx, page_addr1.pa=0x%llx\n",
+ sdk_info(hwdev->dev_hdl,
+ "ht gpa set: page_addr0.pa=0x%llx, page_addr1.pa=0x%llx\n",
pg0->phys_addr, pg1->phys_addr);
#else
- sdk_info(hwdev->dev_hdl, "ht gpa set: page_addr0.pa=0x%lx, page_addr1.pa=0x%lx\n",
+ sdk_info(hwdev->dev_hdl,
+ "ht gpa set: page_addr0.pa=0x%lx, page_addr1.pa=0x%lx\n",
pg0->phys_addr, pg1->phys_addr);
#endif
ret = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_HT_GPA,
&ht_gpa_set, sizeof(ht_gpa_set),
&ht_gpa_set, &out_size);
- if (ret != 0 || out_size == 0 || ht_gpa_set.head.status != 0) {
- sdk_warn(hwdev->dev_hdl, "ht gpa set failed, ret: %d, status: 0x%x, out_size: 0x%x\n",
- ret, ht_gpa_set.head.status, out_size);
+ if ((ret != 0) || (out_size == 0) || (ht_gpa_set.head.status) != 0) {
+ sdk_warn(
+ hwdev->dev_hdl,
+ "ht gpa set unsuccessful, ret: %d, status: 0x%x, out_size: 0x%x\n",
+ ret, ht_gpa_set.head.status, out_size);
return -EFAULT;
}
@@ -877,8 +917,12 @@ static int ht_gpa_set(struct hinic5_hwdev *hwdev, struct hinic5_page_addr *pg0,
int hinic5_ht_gpa_init(struct hinic5_hwdev *hwdev)
{
- struct hinic5_page_addr page_addr0[HINIC5_HT_GPA_SET_RETRY_TIMES] = { 0 };
- struct hinic5_page_addr page_addr1[HINIC5_HT_GPA_SET_RETRY_TIMES] = { 0 };
+ struct hinic5_page_addr page_addr0[HINIC5_HT_GPA_SET_RETRY_TIMES] = {
+ 0
+ };
+ struct hinic5_page_addr page_addr1[HINIC5_HT_GPA_SET_RETRY_TIMES] = {
+ 0
+ };
int ret, i, j;
if (!hwdev) {
@@ -886,7 +930,8 @@ int hinic5_ht_gpa_init(struct hinic5_hwdev *hwdev)
return -EINVAL;
}
- if (hwdev->page_pa0.phys_addr != 0 || hwdev->page_pa1.phys_addr != 0) {
+ if ((hwdev->page_pa0.phys_addr != 0) ||
+ (hwdev->page_pa1.phys_addr != 0)) {
sdk_err(hwdev->dev_hdl, "ht gpa have be inited.\n");
return 0;
}
@@ -899,8 +944,7 @@ int hinic5_ht_gpa_init(struct hinic5_hwdev *hwdev)
for (j = 0; j < i; j++) {
if (page_addr0[j].virt_addr) {
- dma_free_coherent(hwdev->dev_hdl,
- HINIC5_HT_GPA_PAGE_SIZE,
+ dma_free_coherent(hwdev->dev_hdl, get_bank_pg0_size(),
page_addr0[j].virt_addr,
(dma_addr_t)page_addr0[j].phys_addr);
page_addr0[j].virt_addr = NULL;
@@ -929,7 +973,7 @@ static void ht_gpa_clear(struct hinic5_hwdev *hwdev)
u16 out_size = sizeof(ht_gpa_set);
int ret;
- memset(&ht_gpa_set, 0, sizeof(ht_gpa_set));
+ (void)memset_s(&ht_gpa_set, sizeof(ht_gpa_set), 0, sizeof(ht_gpa_set));
ht_gpa_set.host_id = hinic5_host_id(hwdev);
ht_gpa_set.opcode = HT_GPA_CLEAR;
@@ -939,10 +983,14 @@ static void ht_gpa_clear(struct hinic5_hwdev *hwdev)
ret = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_HT_GPA,
&ht_gpa_set, sizeof(ht_gpa_set),
&ht_gpa_set, &out_size);
- if (ret != 0 || out_size == 0 || ht_gpa_set.head.status != 0) {
- sdk_warn(hwdev->dev_hdl, "ht gpa set failed, ret: %d, status: 0x%x, out_size: 0x%x\n",
- ret, ht_gpa_set.head.status, out_size);
+ if ((ret != 0) || (out_size == 0) || (ht_gpa_set.head.status) != 0) {
+ sdk_warn(
+ hwdev->dev_hdl,
+ "ht gpa set failed, ret: %d, status: 0x%x, out_size: 0x%x\n",
+ ret, ht_gpa_set.head.status, out_size);
}
+
+ return;
}
void hinic5_ht_gpa_deinit(struct hinic5_hwdev *hwdev)
@@ -954,15 +1002,17 @@ void hinic5_ht_gpa_deinit(struct hinic5_hwdev *hwdev)
ht_gpa_clear(hwdev);
- if (hwdev->page_pa0.virt_addr && hwdev->page_pa0.phys_addr != 0) {
- dma_free_coherent(hwdev->dev_hdl, HINIC5_HT_GPA_PAGE_SIZE,
+ if ((hwdev->page_pa0.virt_addr != NULL) &&
+ (hwdev->page_pa0.phys_addr != 0)) {
+ dma_free_coherent(hwdev->dev_hdl, get_bank_pg0_size(),
hwdev->page_pa0.virt_addr,
(dma_addr_t)(hwdev->page_pa0.phys_addr));
hwdev->page_pa0.virt_addr = NULL;
hwdev->page_pa0.phys_addr = 0;
}
- if (hwdev->page_pa1.virt_addr && hwdev->page_pa1.phys_addr != 0) {
+ if ((hwdev->page_pa1.virt_addr != NULL) &&
+ (hwdev->page_pa1.phys_addr != 0)) {
dma_free_coherent(hwdev->dev_hdl, HINIC5_HT_GPA_PAGE_SIZE,
hwdev->page_pa1.virt_addr,
(dma_addr_t)hwdev->page_pa1.phys_addr);
@@ -981,7 +1031,7 @@ static int set_ppf_tmr_status(struct hinic5_hwdev *hwdev,
if (!hwdev)
return -EINVAL;
- memset(&op, 0, sizeof(op));
+ (void)memset_s(&op, sizeof(op), 0, sizeof(op));
if (hinic5_func_type(hwdev) != TYPE_PPF)
return -EFAULT;
@@ -991,8 +1041,9 @@ static int set_ppf_tmr_status(struct hinic5_hwdev *hwdev,
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_PPF_TMR, &op,
sizeof(op), &op, &out_size);
- if (err != 0 || out_size == 0 || op.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to set ppf timer, err: %d, status: 0x%x, out_size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (op.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to set ppf timer, err: %d, status: 0x%x, out_size: 0x%x\n",
err, op.head.status, out_size);
return -EFAULT;
}
@@ -1009,7 +1060,7 @@ int hinic5_ppf_tmr_start(void *hwdev)
return -EINVAL;
}
- is_in_kexec = hinic5_vram_get_kexec_flag();
+ is_in_kexec = vram5_get_kexec_flag();
if (is_in_kexec != 0) {
pr_info("Skip starting ppt timer during kexec");
return 0;
@@ -1030,17 +1081,18 @@ int hinic5_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic5_ppf_tmr_stop);
-static int hinic5_hinic5_vram_kalloc_align(struct hinic5_hwdev *hwdev, char *name, u32 page_size,
- u32 page_num, struct hinic5_dma_addr_align *mem_align)
+static int hi5_vram_kalloc_align(struct hinic5_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic5_dma_addr_align *mem_align)
{
void *vaddr = NULL, *align_vaddr = NULL;
dma_addr_t paddr, align_paddr;
u64 real_size = page_size;
u64 align = page_size;
- vaddr = (void *)hinic5_hinic5_vram_kalloc(name, real_size);
- if (!vaddr) {
- sdk_err(hwdev->dev_hdl, "hinic5_vram kalloc failed, name:%s.\n", name);
+ vaddr = (void *)hi5_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
return -ENOMEM;
}
@@ -1052,19 +1104,21 @@ static int hinic5_hinic5_vram_kalloc_align(struct hinic5_hwdev *hwdev, char *nam
goto out;
}
- hinic5_hinic5_vram_kfree((void *)vaddr, name, real_size);
+ hi5_vram_kfree((void *)vaddr, name, real_size);
/* realloc memory for align */
real_size = page_size + align;
- vaddr = (void *)hinic5_hinic5_vram_kalloc(name, real_size);
- if (!vaddr) {
- sdk_err(hwdev->dev_hdl, "hinic5_vram kalloc align failed, name:%s.\n", name);
+ vaddr = (void *)hi5_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n",
+ name);
return -ENOMEM;
}
paddr = (dma_addr_t)virt_to_phys(vaddr);
align_paddr = ALIGN(paddr, align);
- align_vaddr = (void *)(uintptr_t)((u64)(uintptr_t)vaddr + (align_paddr - paddr));
+ align_vaddr = (void *)(uintptr_t)((u64)(uintptr_t)vaddr +
+ (align_paddr - paddr));
out:
mem_align->real_size = (u32)real_size;
@@ -1080,62 +1134,71 @@ static void mqm_eqm_free_page_mem(struct hinic5_hwdev *hwdev)
{
struct hinic5_dma_addr_align *page_addr = NULL;
u32 i;
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
- struct mqm_eqm_hinic5_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_hinic5_vram_name;
+ int is_use_vram = get5_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name =
+ hwdev->mqm_eqm_vram_name;
page_addr = hwdev->mqm_att.brm_srch_page_addr;
for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- if (is_use_hinic5_vram != 0) {
- hinic5_hinic5_vram_kfree(page_addr->ori_vaddr,
- mqm_eqm_vram_name[i].hinic5_vram_name,
- page_addr->real_size);
+ if (is_use_vram != 0) {
+ hi5_vram_kfree(page_addr->ori_vaddr,
+ mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
} else {
- hinic5_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ hinic5_dma_free_coherent_align(hwdev->dev_hdl,
+ page_addr);
}
page_addr++;
}
kfree(mqm_eqm_vram_name);
- hwdev->mqm_eqm_hinic5_vram_name = NULL;
+ hwdev->mqm_eqm_vram_name = NULL;
}
static int mqm_eqm_try_alloc_mem(struct hinic5_hwdev *hwdev, u32 page_size,
u32 page_num)
{
- struct hinic5_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
- struct mqm_eqm_hinic5_vram_name_s *mqm_eqm_hinic5_vram_name = NULL;
+ struct hinic5_dma_addr_align *page_addr =
+ hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get5_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
u16 func_id;
- mqm_eqm_hinic5_vram_name = kzalloc(sizeof(struct mqm_eqm_hinic5_vram_name_s) * page_num, GFP_KERNEL);
- if (!mqm_eqm_hinic5_vram_name)
+ mqm_eqm_vram_name = kzalloc(
+ sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
return -ENOMEM;
+ }
- hwdev->mqm_eqm_hinic5_vram_name = mqm_eqm_hinic5_vram_name;
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
func_id = hinic5_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- if (is_use_hinic5_vram != 0) {
- err = snprintf(mqm_eqm_hinic5_vram_name[i].hinic5_vram_name,
- HINIC5_VRAM_NAME_MAX_LEN, "%s%hu%s%u",
- HINIC5_VRAM_NIC_FUNC_BASE, func_id,
- HINIC5_VRAM_NIC_MQM, i);
+ if (is_use_vram != 0) {
+ err = snprintf_s(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%hu%s%u",
+ VRAM_NIC_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
if (err < 0) {
sdk_err(hwdev->dev_hdl,
- "mqm eqm snprintf name fail, err:%d, index:%u\n", err, i);
+ "mqm eqm snprintf name fail, err:%d, index:%u\n",
+ err, i);
flag = 0;
break;
}
- err = hinic5_hinic5_vram_kalloc_align(hwdev,
- mqm_eqm_hinic5_vram_name[i].hinic5_vram_name,
- page_size, page_num, page_addr);
+ err = hi5_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
} else {
- err = hinic5_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ err = hinic5_dma_zalloc_coherent_align(
+ hwdev->dev_hdl, page_size, page_size,
+ GFP_KERNEL, page_addr);
}
if (err != 0) {
flag = 0;
@@ -1165,7 +1228,8 @@ static int mqm_eqm_alloc_page_mem(struct hinic5_hwdev *hwdev)
page_num = (hwdev->mqm_att.chunk_num + 0x3ff) >> 0xa;
ret = mqm_eqm_try_alloc_mem(hwdev, 0x2 * 0x400 * 0x400, page_num);
if (ret == 0) {
- sdk_info(hwdev->dev_hdl, "[mqm_eqm_init] Alloc page_size 2M OK\n");
+ sdk_info(hwdev->dev_hdl,
+ "[mqm_eqm_init] Alloc page_size 2M OK\n");
return 0;
}
@@ -1173,7 +1237,8 @@ static int mqm_eqm_alloc_page_mem(struct hinic5_hwdev *hwdev)
page_num = (hwdev->mqm_att.chunk_num + 0x1f) >> 0x5;
ret = mqm_eqm_try_alloc_mem(hwdev, 0x40 * 0x400, page_num);
if (ret == 0) {
- sdk_info(hwdev->dev_hdl, "[mqm_eqm_init] Alloc page_size 64K OK\n");
+ sdk_info(hwdev->dev_hdl,
+ "[mqm_eqm_init] Alloc page_size 64K OK\n");
return 0;
}
@@ -1181,7 +1246,8 @@ static int mqm_eqm_alloc_page_mem(struct hinic5_hwdev *hwdev)
page_num = (hwdev->mqm_att.chunk_num + 1) >> 1;
ret = mqm_eqm_try_alloc_mem(hwdev, 0x4 * 0x400, page_num);
if (ret == 0) {
- sdk_info(hwdev->dev_hdl, "[mqm_eqm_init] Alloc page_size 4K OK\n");
+ sdk_info(hwdev->dev_hdl,
+ "[mqm_eqm_init] Alloc page_size 4K OK\n");
return 0;
}
@@ -1194,7 +1260,8 @@ static int mqm_eqm_set_cfg_2_hw(struct hinic5_hwdev *hwdev, u8 valid)
u16 out_size = sizeof(info_eqm_cfg);
int err;
- memset(&info_eqm_cfg, 0, sizeof(info_eqm_cfg));
+ (void)memset_s(&info_eqm_cfg, sizeof(info_eqm_cfg), 0,
+ sizeof(info_eqm_cfg));
info_eqm_cfg.host_id = hinic5_host_id(hwdev);
info_eqm_cfg.page_size = hwdev->mqm_att.page_size;
@@ -1202,8 +1269,9 @@ static int mqm_eqm_set_cfg_2_hw(struct hinic5_hwdev *hwdev, u8 valid)
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_SET_MQM_CFG_INFO,
&info_eqm_cfg, sizeof(info_eqm_cfg),
&info_eqm_cfg, &out_size);
- if (err != 0 || out_size == 0 || info_eqm_cfg.head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to init func table, err: %d, status: 0x%x, out_size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (info_eqm_cfg.head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to init func table, err: %d, status: 0x%x, out_size: 0x%x\n",
err, info_eqm_cfg.head.status, out_size);
return -EFAULT;
}
@@ -1211,8 +1279,8 @@ static int mqm_eqm_set_cfg_2_hw(struct hinic5_hwdev *hwdev, u8 valid)
return 0;
}
-#define EQM_DATA_BUF_SIZE 1024
-#define MQM_ATT_PAGE_NUM 128
+#define EQM_DATA_BUF_SIZE 1024
+#define MQM_ATT_PAGE_NUM 128
static int mqm_eqm_set_page_2_hw(struct hinic5_hwdev *hwdev)
{
@@ -1224,10 +1292,10 @@ static int mqm_eqm_set_page_2_hw(struct hinic5_hwdev *hwdev)
u64 gpa;
u32 num, start_idx, i;
int err = 0;
- u8 cmd;
+ u8 cmd;
- send_buf_size = sizeof(struct comm_cmd_eqm_search_gpa) +
- EQM_DATA_BUF_SIZE;
+ send_buf_size =
+ sizeof(struct comm_cmd_eqm_search_gpa) + EQM_DATA_BUF_SIZE;
send_buf = kzalloc(send_buf_size, GFP_KERNEL);
if (!send_buf) {
sdk_err(hwdev->dev_hdl, "Alloc virtual mem failed\r\n");
@@ -1251,10 +1319,13 @@ static int mqm_eqm_set_page_2_hw(struct hinic5_hwdev *hwdev)
info->start_idx = start_idx;
info->host_id = hinic5_host_id(hwdev);
out_size = send_buf_size;
- err = comm_msg_to_mgmt_sync(hwdev, cmd, info, (u16)send_buf_size,
- info, &out_size);
- if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, info->head.status)) {
- sdk_err(hwdev->dev_hdl, "Set mqm srch gpa fail, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err = comm_msg_to_mgmt_sync(hwdev, cmd, info,
+ (u16)send_buf_size, info,
+ &out_size);
+ if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size,
+ info->head.status)) {
+ sdk_err(hwdev->dev_hdl,
+ "Set mqm srch gpa fail, err: %d, status: 0x%x, out_size: 0x%x\n",
err, info->head.status, out_size);
err = -EFAULT;
goto set_page_2_hw_end;
@@ -1272,9 +1343,12 @@ static int mqm_eqm_set_page_2_hw(struct hinic5_hwdev *hwdev)
info->start_idx = start_idx;
info->host_id = hinic5_host_id(hwdev);
out_size = send_buf_size;
- err = comm_msg_to_mgmt_sync(hwdev, cmd, info, (u16)send_buf_size, info, &out_size);
- if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, info->head.status)) {
- sdk_err(hwdev->dev_hdl, "Set mqm srch gpa fail, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err = comm_msg_to_mgmt_sync(
+ hwdev, cmd, info, (u16)send_buf_size, info, &out_size);
+ if (MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size,
+ info->head.status)) {
+ sdk_err(hwdev->dev_hdl,
+ "Set mqm srch gpa fail, err: %d, status: 0x%x, out_size: 0x%x\n",
err, info->head.status, out_size);
err = -EFAULT;
goto set_page_2_hw_end;
@@ -1286,22 +1360,27 @@ static int mqm_eqm_set_page_2_hw(struct hinic5_hwdev *hwdev)
return err;
}
-static int get_eqm_num(struct hinic5_hwdev *hwdev, struct comm_cmd_get_eqm_num *info_eqm_fix)
+static int get_eqm_num(struct hinic5_hwdev *hwdev,
+ struct comm_cmd_get_eqm_num *info_eqm_fix)
{
int ret;
u16 len = sizeof(*info_eqm_fix);
- memset(info_eqm_fix, 0, sizeof(*info_eqm_fix));
+ (void)memset_s(info_eqm_fix, sizeof(*info_eqm_fix), 0,
+ sizeof(*info_eqm_fix));
ret = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_GET_MQM_FIX_INFO,
- info_eqm_fix, sizeof(*info_eqm_fix), info_eqm_fix, &len);
- if (ret != 0 || len == 0 || info_eqm_fix->head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Get mqm fix info fail,err: %d, status: 0x%x, out_size: 0x%x\n",
+ info_eqm_fix, sizeof(*info_eqm_fix),
+ info_eqm_fix, &len);
+ if ((ret != 0) || (len == 0) || (info_eqm_fix->head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Get mqm fix info fail,err: %d, status: 0x%x, out_size: 0x%x\n",
ret, info_eqm_fix->head.status, len);
return -EFAULT;
}
- sdk_info(hwdev->dev_hdl, "get chunk_num: 0x%x, search_gpa_num: 0x%08x\n",
+ sdk_info(hwdev->dev_hdl,
+ "get chunk_num: 0x%x, search_gpa_num: 0x%08x\n",
info_eqm_fix->chunk_num, info_eqm_fix->search_gpa_num);
return 0;
@@ -1325,10 +1404,11 @@ static int mqm_eqm_init(struct hinic5_hwdev *hwdev)
hwdev->mqm_att.chunk_num = info_eqm_fix.chunk_num;
hwdev->mqm_att.search_gpa_num = info_eqm_fix.search_gpa_num;
hwdev->mqm_att.page_size = 0;
- hwdev->mqm_att.page_num = 0;
+ hwdev->mqm_att.page_num = 0;
hwdev->mqm_att.brm_srch_page_addr =
- kcalloc(hwdev->mqm_att.chunk_num, sizeof(struct hinic5_dma_addr_align), GFP_KERNEL);
+ kcalloc(hwdev->mqm_att.chunk_num,
+ sizeof(struct hinic5_dma_addr_align), GFP_KERNEL);
if (!(hwdev->mqm_att.brm_srch_page_addr)) {
sdk_err(hwdev->dev_hdl, "Alloc virtual mem failed\r\n");
return -EFAULT;
@@ -1380,8 +1460,8 @@ static void mqm_eqm_deinit(struct hinic5_hwdev *hwdev)
ret = mqm_eqm_set_cfg_2_hw(hwdev, 0);
if (ret != 0) {
- sdk_err(hwdev->dev_hdl, "Set mqm eqm cfg to chip fail! err: %d\n",
- ret);
+ sdk_err(hwdev->dev_hdl,
+ "Set mqm eqm cfg to chip fail! err: %d\n", ret);
return;
}
@@ -1432,17 +1512,18 @@ static enum hinic5_wait_return check_flr_finish_handler(void *priv_data)
return WAIT_PROCESS_WAITING;
}
-#define HINIC5_FLR_TIMEOUT 40000
+#define HINIC5_FLR_TIMEOUT 40000
static int wait_for_flr_finish(struct hinic5_hwif *hwif, u32 flr_timeout_ms)
{
- u32 flr_timeout = (flr_timeout_ms == 0) ? HINIC5_FLR_TIMEOUT : flr_timeout_ms;
+ u32 flr_timeout = (flr_timeout_ms == 0) ? HINIC5_FLR_TIMEOUT :
+ flr_timeout_ms;
return hinic5_wait_for_timeout(hwif, check_flr_finish_handler,
flr_timeout, 0xa * USEC_PER_MSEC);
}
-#define HINIC5_WAIT_CMDQ_IDLE_TIMEOUT 5000
+#define HINIC5_WAIT_CMDQ_IDLE_TIMEOUT 5000
static enum hinic5_wait_return check_cmdq_stop_handler(void *priv_data)
{
@@ -1491,8 +1572,8 @@ static int wait_cmdq_stop(struct hinic5_hwdev *hwdev)
return err;
}
-static int hinic5_rx_tx_flush(struct hinic5_hwdev *hwdev, u16 channel, bool wait_io,
- u32 flr_timeout_ms)
+static int hinic5_rx_tx_flush(struct hinic5_hwdev *hwdev, u16 channel,
+ bool wait_io, u32 flr_timeout_ms)
{
struct hinic5_hwif *hwif = hwdev->hwif;
struct comm_cmd_clear_doorbell clear_db;
@@ -1500,53 +1581,66 @@ static int hinic5_rx_tx_flush(struct hinic5_hwdev *hwdev, u16 channel, bool wait
u16 out_size;
int err;
- if (HINIC5_FUNC_TYPE(hwdev) != TYPE_VF && wait_io == true)
+ if ((HINIC5_FUNC_TYPE(hwdev) != TYPE_VF) && (wait_io == true))
msleep(100); /* wait ucode 100 ms stop I/O */
err = wait_cmdq_stop(hwdev);
- if (err != 0)
- sdk_warn(hwdev->dev_hdl, "CMDQ is still working, please check CMDQ timeout value is reasonable\n");
+ if (err != 0) {
+ sdk_warn(
+ hwdev->dev_hdl,
+ "CMDQ is still working, please check CMDQ timeout value is reasonable\n");
+ }
hinic5_disable_doorbell(hwif);
out_size = sizeof(clear_db);
- memset(&clear_db, 0, sizeof(clear_db));
+ (void)memset_s(&clear_db, sizeof(clear_db), 0, sizeof(clear_db));
clear_db.func_id = HINIC5_HWIF_GLOBAL_IDX(hwif);
- err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_FLUSH_DOORBELL, &clear_db,
- sizeof(clear_db), &clear_db, &out_size, channel);
- if (err != 0 || out_size == 0 || clear_db.head.status != 0) {
- sdk_warn(hwdev->dev_hdl, "Failed to flush doorbell, err: %d, status: 0x%x, out_size: 0x%x, channel: 0x%x\n",
- err, clear_db.head.status, out_size, channel);
+ err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_FLUSH_DOORBELL,
+ &clear_db, sizeof(clear_db), &clear_db,
+ &out_size, channel);
+ if ((err != 0) || (out_size == 0) || (clear_db.head.status != 0)) {
+ sdk_warn(
+ hwdev->dev_hdl,
+ "Failed to flush doorbell, err: %d, status: 0x%x, out_size: 0x%x, channel: 0x%x\n",
+ err, clear_db.head.status, out_size, channel);
}
hinic5_set_pf_status(hwif, HINIC5_PF_STATUS_FLR_START_FLAG);
- memset(&clr_res, 0, sizeof(clr_res));
+ (void)memset_s(&clr_res, sizeof(clr_res), 0, sizeof(clr_res));
clr_res.func_id = HINIC5_HWIF_GLOBAL_IDX(hwif);
- err = hinic5_msg_to_mgmt_no_ack(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_START_FLUSH, &clr_res,
+ err = hinic5_msg_to_mgmt_no_ack(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_START_FLUSH, &clr_res,
sizeof(clr_res), channel);
- if (err != 0)
- sdk_warn(hwdev->dev_hdl, "Failed to notice flush message, err: %d, channel: 0x%x\n",
- err, channel);
+ if (err != 0) {
+ sdk_warn(
+ hwdev->dev_hdl,
+ "Failed to notice flush message, err: %d, channel: 0x%x\n",
+ err, channel);
+ }
if (HINIC5_FUNC_TYPE(hwdev) != TYPE_VF) {
err = wait_for_flr_finish(hwif, flr_timeout_ms);
- if (err != 0)
+ if (err != 0) {
sdk_warn(hwdev->dev_hdl, "Wait firmware FLR timeout\n");
+ }
}
hinic5_enable_doorbell(hwif);
err = hinic5_reinit_cmdq_ctxts(hwdev);
- if (err != 0)
+ if (err != 0) {
sdk_warn(hwdev->dev_hdl, "Failed to reinit cmdq\n");
+ }
return err;
}
-int hinic5_func_rx_tx_flush(void *hwdev, u16 channel, bool wait_io, u32 flr_timeout_ms)
+int hinic5_func_rx_tx_flush(void *hwdev, u16 channel, bool wait_io,
+ u32 flr_timeout_ms)
{
struct hinic5_hwdev *dev = hwdev;
@@ -1570,18 +1664,18 @@ int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info,
if (!hwdev || !info)
return -EINVAL;
- memset(&board_info, 0, sizeof(board_info));
+ (void)memset_s(&board_info, sizeof(board_info), 0, sizeof(board_info));
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_GET_BOARD_INFO,
&board_info, sizeof(board_info),
&board_info, &out_size, channel);
- if (err != 0 || out_size == 0 || board_info.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (board_info.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to get board info, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, board_info.head.status, out_size, channel);
return -EIO;
}
- memcpy(info, &board_info.info, sizeof(*info));
+ (void)memcpy_s(info, sizeof(*info), &board_info.info, sizeof(*info));
return 0;
}
@@ -1602,9 +1696,9 @@ int hinic5_get_hw_pf_infos(void *hwdev, struct hinic5_hw_pf_infos *infos,
return -ENOMEM;
err = comm_msg_to_mgmt_sync_ch(hwdev, COMM_MGMT_CMD_GET_HW_PF_INFOS,
- pf_infos, sizeof(*pf_infos),
- pf_infos, &out_size, channel);
- if (err != 0 || out_size == 0 || pf_infos->head.status != 0) {
+ pf_infos, sizeof(*pf_infos), pf_infos,
+ &out_size, channel);
+ if ((err != 0) || (out_size == 0) || (pf_infos->head.status) != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to get hw pf information, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, pf_infos->head.status, out_size, channel);
@@ -1612,7 +1706,8 @@ int hinic5_get_hw_pf_infos(void *hwdev, struct hinic5_hw_pf_infos *infos,
goto free_buf;
}
- memcpy(infos, &pf_infos->infos, sizeof(struct hinic5_hw_pf_infos));
+ (void)memcpy_s(infos, sizeof(struct hinic5_hw_pf_infos),
+ &pf_infos->infos, sizeof(struct hinic5_hw_pf_infos));
free_buf:
kfree(pf_infos);
@@ -1629,14 +1724,15 @@ int hinic5_get_global_attr(void *hwdev, struct comm_global_attr *attr)
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_GET_GLOBAL_ATTR,
&get_attr, sizeof(get_attr), &get_attr,
&out_size);
- if (err != 0 || out_size == 0 || get_attr.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (get_attr.head.status) != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to get global attribute, err: %d, status: 0x%x, out size: 0x%x\n",
err, get_attr.head.status, out_size);
return -EIO;
}
- memcpy(attr, &get_attr.attr, sizeof(struct comm_global_attr));
+ (void)memcpy_s(attr, sizeof(struct comm_global_attr), &get_attr.attr,
+ sizeof(struct comm_global_attr));
return 0;
}
@@ -1651,7 +1747,7 @@ int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state,
if (!hwdev)
return -EINVAL;
- memset(&used_state, 0, sizeof(used_state));
+ (void)memset_s(&used_state, sizeof(used_state), 0, sizeof(used_state));
used_state.func_id = hinic5_global_func_id(hwdev);
used_state.svc_type = svc_type;
used_state.used_state = state;
@@ -1660,7 +1756,7 @@ int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state,
COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
&used_state, sizeof(used_state),
&used_state, &out_size, channel);
- if (err != 0 || out_size == 0 || used_state.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (used_state.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set func service used state, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n\n",
err, used_state.head.status, out_size, channel);
@@ -1671,10 +1767,11 @@ int hinic5_set_func_svc_used_state(void *hwdev, u16 svc_type, u8 state,
}
EXPORT_SYMBOL(hinic5_set_func_svc_used_state);
-int hinic5_get_sml_table_info(void *hwdev, u32 tbl_id, u8 *node_id, u8 *instance_id)
+int hinic5_get_sml_table_info(void *hwdev, u32 tbl_id, u8 *node_id,
+ u8 *instance_id)
{
- struct sml_table_id_info sml_table = {0};
- struct comm_cmd_get_sml_tbl_data sml_tbl = {0};
+ struct sml_table_id_info sml_table = { 0 };
+ struct comm_cmd_get_sml_tbl_data sml_tbl = { 0 };
u16 out_size = sizeof(sml_tbl);
int err;
@@ -1682,20 +1779,23 @@ int hinic5_get_sml_table_info(void *hwdev, u32 tbl_id, u8 *node_id, u8 *instance
return -EINVAL;
if (tbl_id != 0) {
- sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl, "sml table index is not 0");
+ sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "sml table index is not 0");
return -EINVAL;
}
err = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- &sml_tbl, sizeof(sml_tbl), &sml_tbl, &out_size);
- if (err != 0 || out_size == 0 || sml_tbl.head.status != 0) {
+ &sml_tbl, sizeof(sml_tbl), &sml_tbl,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (sml_tbl.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to get sml table information, err: %d, status: 0x%x, out size: 0x%x\n",
err, sml_tbl.head.status, out_size);
return -EIO;
}
- memcpy(&sml_table, sml_tbl.tbl_data, sizeof(sml_table));
+ (void)memcpy_s(&sml_table, sizeof(sml_table), sml_tbl.tbl_data,
+ sizeof(sml_table));
*node_id = sml_table.node_id;
*instance_id = sml_table.instance_id;
@@ -1715,21 +1815,26 @@ int hinic5_activate_firmware(void *hwdev, u8 cfg_index)
if (hinic5_func_type(hwdev) == TYPE_VF)
return -EOPNOTSUPP;
- memset(&activate_msg, 0, sizeof(activate_msg));
+ (void)memset_s(&activate_msg, sizeof(activate_msg), 0,
+ sizeof(activate_msg));
activate_msg.index = cfg_index;
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_ACTIVE_FW,
- &activate_msg, sizeof(activate_msg),
- &activate_msg, &out_size, FW_UPDATE_MGMT_TIMEOUT, 0);
- if (err != 0 || out_size == 0 || activate_msg.msg_head.status != 0) {
+ err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_ACTIVE_FW, &activate_msg,
+ sizeof(activate_msg), &activate_msg,
+ &out_size, FW_UPDATE_MGMT_TIMEOUT, 0);
+ if ((err != 0) || (out_size == 0) ||
+ (activate_msg.msg_head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to activate firmware, err: %d, status: 0x%x, out size: 0x%x\n",
err, activate_msg.msg_head.status, out_size);
- err = (activate_msg.msg_head.status != 0) ? activate_msg.msg_head.status : -EIO;
+ err = (activate_msg.msg_head.status != 0) ?
+ activate_msg.msg_head.status :
+ -EIO;
return err;
- } else {
- return 0;
}
+
+ return 0;
}
int hinic5_switch_config(void *hwdev, u8 cfg_index)
@@ -1747,50 +1852,55 @@ int hinic5_switch_config(void *hwdev, u8 cfg_index)
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&switch_cfg, 0, sizeof(switch_cfg));
+ (void)memset_s(&switch_cfg, sizeof(switch_cfg), 0, sizeof(switch_cfg));
switch_cfg.index = cfg_index;
- err = hinic5_pf_to_mgmt_sync(hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_SWITCH_CFG,
- &switch_cfg, sizeof(switch_cfg),
- &switch_cfg, &out_size, FW_UPDATE_MGMT_TIMEOUT);
- if (err != 0 || out_size == 0 || switch_cfg.msg_head.status != 0) {
+ err = hinic5_pf_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_SWITCH_CFG, &switch_cfg,
+ sizeof(switch_cfg), &switch_cfg, &out_size,
+ FW_UPDATE_MGMT_TIMEOUT);
+ if ((err != 0) || (out_size == 0) ||
+ (switch_cfg.msg_head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to switch cfg, err: %d, status: 0x%x, out size: 0x%x\n",
err, switch_cfg.msg_head.status, out_size);
- err = (switch_cfg.msg_head.status != 0) ? switch_cfg.msg_head.status : -EIO;
+ err = (switch_cfg.msg_head.status != 0) ?
+ switch_cfg.msg_head.status :
+ -EIO;
return err;
}
return 0;
}
-int hinic5_get_secure_mem_cfg(struct hinic5_hwdev *hwdev, dma_addr_t *gpa, u32 *len)
+int hinic5_get_secure_mem_cfg(struct hinic5_hwdev *hwdev, dma_addr_t *gpa,
+ u32 *len)
{
- struct hinic5_cqm_cmd_func_secure_mem mem_info;
+ struct cqm_cmd_func_secure_mem mem_info;
u16 out_size = sizeof(mem_info);
int ret;
if (!hwdev || !gpa || !len)
- return -EPERM;
+ return -EINVAL;
- memset(&mem_info, 0, sizeof(mem_info));
+ (void)memset_s(&mem_info, sizeof(mem_info), 0, sizeof(mem_info));
mem_info.func_id = hinic5_global_func_id((void *)hwdev);
ret = comm_msg_to_mgmt_sync(hwdev, COMM_MGMT_CMD_GET_FUNC_SECURE_MEM,
- &mem_info, sizeof(mem_info),
- &mem_info, &out_size);
+ &mem_info, sizeof(mem_info), &mem_info,
+ &out_size);
if (mem_info.head.status == HINIC5_MGMT_CMD_UNSUPPORTED)
- return -EPERM;
+ return -EOPNOTSUPP;
- if (ret != 0 || out_size == 0 || mem_info.head.status != 0) {
+ if ((ret != 0) || (out_size == 0) || (mem_info.head.status != 0)) {
sdk_err(hwdev->dev_hdl,
"Failed to get memsec info, ret: %d, status: 0x%x, out size: 0x%x\n",
ret, mem_info.head.status, out_size);
- return -EINVAL;
+ return -EFAULT;
}
if (mem_info.valid == 0)
- return -EPERM;
+ return -EOPNOTSUPP;
*len = mem_info.len;
*gpa = (dma_addr_t)MAKE_64BITS(mem_info.gpa_hi, mem_info.gpa_lo);
@@ -1801,7 +1911,8 @@ int hinic5_get_secure_mem_cfg(struct hinic5_hwdev *hwdev, dma_addr_t *gpa, u32 *
#define PLUG_SRV_GET 1
#define PLUG_SRV_SET 0
-int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 attach_en)
+int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 attach_en)
{
struct comm_cmd_plug_srv plug_srv;
u16 out_size = sizeof(plug_srv);
@@ -1810,15 +1921,15 @@ int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 attach_
if (!hwdev)
return -EPERM;
- memset(&plug_srv, 0, sizeof(plug_srv));
+ (void)memset_s(&plug_srv, sizeof(plug_srv), 0, sizeof(plug_srv));
plug_srv.func_id = func_id;
plug_srv.srv_type = srv_type;
plug_srv.attach_en = attach_en;
- ret = comm_msg_to_mgmt_sync((struct hinic5_hwdev *)hwdev, COMM_MGMT_CMD_SET_FUNC_PLUG_SRV,
- &plug_srv, sizeof(plug_srv),
- &plug_srv, &out_size);
- if (ret != 0 || out_size == 0 || plug_srv.head.status != 0) {
+ ret = comm_msg_to_mgmt_sync((struct hinic5_hwdev *)hwdev,
+ COMM_MGMT_CMD_SET_FUNC_PLUG_SRV, &plug_srv,
+ sizeof(plug_srv), &plug_srv, &out_size);
+ if ((ret != 0) || (out_size == 0) || (plug_srv.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to set plug srv_bitmap, ret: %d, status: 0x%x, out size: 0x%x\n",
ret, plug_srv.head.status, out_size);
@@ -1829,7 +1940,8 @@ int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 attach_
}
EXPORT_SYMBOL(hisdk5_set_plug_srv_bitmap);
-int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 *attach_en)
+int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 *attach_en)
{
struct comm_cmd_plug_srv plug_srv;
u16 out_size = sizeof(plug_srv);
@@ -1838,14 +1950,14 @@ int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 *attach
if (!hwdev)
return -EPERM;
- memset(&plug_srv, 0, sizeof(plug_srv));
+ (void)memset_s(&plug_srv, sizeof(plug_srv), 0, sizeof(plug_srv));
plug_srv.func_id = func_id;
plug_srv.srv_type = srv_type;
- ret = comm_msg_to_mgmt_sync((struct hinic5_hwdev *)hwdev, COMM_MGMT_CMD_GET_FUNC_PLUG_SRV,
- &plug_srv, sizeof(plug_srv),
- &plug_srv, &out_size);
- if (ret != 0 || out_size == 0 || plug_srv.head.status != 0) {
+ ret = comm_msg_to_mgmt_sync((struct hinic5_hwdev *)hwdev,
+ COMM_MGMT_CMD_GET_FUNC_PLUG_SRV, &plug_srv,
+ sizeof(plug_srv), &plug_srv, &out_size);
+ if ((ret != 0) || (out_size == 0) || (plug_srv.head.status != 0)) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Failed to get plug srv_bitmap, ret: %d, status: 0x%x, out size: 0x%x\n",
ret, plug_srv.head.status, out_size);
@@ -1856,4 +1968,4 @@ int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 *attach
return 0;
}
-EXPORT_SYMBOL(hisdk5_get_plug_srv_bitmap);
+EXPORT_SYMBOL(hisdk5_get_plug_srv_bitmap);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.h
index 96639add3..b7cabf0bd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hw_comm.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_comm.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_COMM_H
#define HINIC5_COMM_H
@@ -16,10 +9,10 @@
#include "mpu_inband_cmd_defs.h"
#include "hinic5_hwdev.h"
-#define MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, status) \
- (((err) != 0) || ((status) != 0) || ((out_size) == 0))
+#define MSG_TO_MGMT_SYNC_RETURN_ERR(err, out_size, status) \
+ (((err) != 0) || ((status) != 0) || ((out_size) == 0))
-#define HINIC5_PAGE_SIZE_HW(pg_size) ((u8)ilog2((u32)((pg_size) >> 12)))
+#define HINIC5_PAGE_SIZE_HW(pg_size) ((u8)ilog2((u32)((pg_size) >> 12)))
enum func_tmr_bitmap_status {
FUNC_TMR_BITMAP_DISABLE,
@@ -48,11 +41,11 @@ int hinic5_ppf_ext_db_init(struct hinic5_hwdev *hwdev);
int hinic5_ppf_ext_db_deinit(struct hinic5_hwdev *hwdev);
-int hinic5_set_ceq_ctrl_reg(struct hinic5_hwdev *hwdev, u16 q_id,
- u32 ctrl0, u32 ctrl1);
+int hinic5_set_ceq_ctrl_reg(struct hinic5_hwdev *hwdev, u16 q_id, u32 ctrl0,
+ u32 ctrl1);
-int hinic5_set_dma_attr_tbl(struct hinic5_hwdev *hwdev, u8 entry_idx, u8 st, u8 at, u8 ph,
- u8 no_snooping, u8 tph_en);
+int hinic5_set_dma_attr_tbl(struct hinic5_hwdev *hwdev, u8 entry_idx, u8 st,
+ u8 at, u8 ph, u8 no_snooping, u8 tph_en);
int hinic5_get_comm_features(void *hwdev, u64 *s_feature, u16 size);
int hinic5_set_comm_features(void *hwdev, u64 *s_feature, u16 size);
@@ -61,27 +54,34 @@ int hinic5_comm_channel_detect(struct hinic5_hwdev *hwdev);
int hinic5_get_global_attr(void *hwdev, struct comm_global_attr *attr);
-int hinic5_get_secure_mem_cfg(struct hinic5_hwdev *hwdev, dma_addr_t *gpa, u32 *len);
+int hinic5_get_secure_mem_cfg(struct hinic5_hwdev *hwdev, dma_addr_t *gpa,
+ u32 *len);
-int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 *attach_en);
-int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id, u8 attach_en);
+int hisdk5_get_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 *attach_en);
+int hisdk5_set_plug_srv_bitmap(void *hwdev, u8 srv_type, u16 func_id,
+ u8 attach_en);
-int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info, u16 channel);
+int hinic5_get_board_info(void *hwdev, struct hinic5_board_info *info,
+ u16 channel);
/**
- * @brief Initialize HT GPA
- * @param hwdev device handle
+ * @brief 初始化 HT GPA
+ * @param hwdev 设备句柄
*
- * @return whether success
+ * @return 是否成功
* @retval zero: success
* @retval non-zero: failure
*/
int hinic5_ht_gpa_init(struct hinic5_hwdev *hwdev);
/**
- * @brief Deinitialize HT GPA
- * @param hwdev device handle
+ * @brief 反初始化 HT GPA
+ * @param hwdev 设备句柄
*/
void hinic5_ht_gpa_deinit(struct hinic5_hwdev *hwdev);
+void pf_handle_mgmt_comm_event(void *handle, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hwdev.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hwdev.c
index f9278740c..7df61cc12 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_hwdev.c
@@ -1,18 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hwdev.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
-#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/rtc.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
@@ -27,8 +17,8 @@
#include "hinic5_hw.h"
#include "hinic5_common.h"
#include "hinic5_csr_inner.h"
-#include "hinic5_hwif_inner.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_hwif.h"
+#include "hisdk5_typedef.h"
#include "hinic5_eqs.h"
#include "hinic5_api_cmd.h"
#include "hinic5_mgmt.h"
@@ -36,13 +26,11 @@
#include "hinic5_cmdq.h"
#include "hinic5_hw_cfg.h"
#include "hinic5_hw_comm.h"
-#include "hinic5_hinic5_cqm.h"
+#include "hinic5_cqm.h"
#include "sdk_pub_cmd.h"
#if !defined(__WIN__)
-#include "hinic5_cqm_fast_msg.h"
#include "hinic5_devlink.h"
#endif
-#include "mpu_inband_cmd.h"
#if defined(__UEFI__) && !defined(__HIFC__)
#include "mpu_board_defs.h"
#endif
@@ -54,77 +42,76 @@
#include "hinic5_lld.h"
#include "hinic5_dev_mgmt.h"
#include "hinic5_micro_log.h"
+#include "securec.h"
#include "hinic5_non_ptp.h"
#endif
#include "hinic5_hwdev.h"
static unsigned int wq_page_order = HINIC5_MAX_WQ_PAGE_SIZE_ORDER;
module_param(wq_page_order, uint, 0444);
-MODULE_PARM_DESC(wq_page_order, "Set wq page size order, wq page size is 4K * " \
- "(2 ^ wq_page_order) - default is 8");
+MODULE_PARM_DESC(wq_page_order, "Set wq page size order, wq page size is 4K * "
+ "(2 ^ wq_page_order) - default is 8");
-static ulong perf_en_bitmap;
+static ulong perf_en_bitmap = 0;
module_param(perf_en_bitmap, ulong, 0644);
MODULE_PARM_DESC(perf_en_bitmap,
- "Set perf enable bitmap: 0-disable, 1-enable (bit(0)-cmdq, " \
+ "Set perf enable bitmap: 0-disable, 1-enable (bit(0)-cmdq, "
"bit(1)-mailbox) - default is 0");
-#define HINIC5_DMA_ATTR_INDIR_IDX_SHIFT 0
-#define UNKNOWN_LEN 7
-
-#define HINIC5_DMA_ATTR_INDIR_IDX_MASK 0x3FF
+#define HINIC5_DMA_ATTR_INDIR_IDX_SHIFT 0
+#define HINIC5_DMA_ATTR_INDIR_IDX_MASK 0x3FF
-#define HINIC5_DMA_ATTR_INDIR_IDX_SET(val, member) \
- (((u32)(val) & HINIC5_DMA_ATTR_INDIR_##member##_MASK) << \
- HINIC5_DMA_ATTR_INDIR_##member##_SHIFT)
+#define HINIC5_DMA_ATTR_INDIR_IDX_SET(val, member) \
+ (((u32)(val)&HINIC5_DMA_ATTR_INDIR_##member##_MASK) \
+ << HINIC5_DMA_ATTR_INDIR_##member##_SHIFT)
-#define HINIC5_DMA_ATTR_INDIR_IDX_CLEAR(val, member) \
- ((val) & (~(HINIC5_DMA_ATTR_INDIR_##member##_MASK \
- << HINIC5_DMA_ATTR_INDIR_##member##_SHIFT)))
+#define HINIC5_DMA_ATTR_INDIR_IDX_CLEAR(val, member) \
+ ((val) & (~(HINIC5_DMA_ATTR_INDIR_##member##_MASK \
+ << HINIC5_DMA_ATTR_INDIR_##member##_SHIFT)))
-#define HINIC5_DMA_ATTR_ENTRY_ST_SHIFT 0
-#define HINIC5_DMA_ATTR_ENTRY_AT_SHIFT 8
-#define HINIC5_DMA_ATTR_ENTRY_PH_SHIFT 10
-#define HINIC5_DMA_ATTR_ENTRY_NO_SNOOPING_SHIFT 12
-#define HINIC5_DMA_ATTR_ENTRY_TPH_EN_SHIFT 13
+#define HINIC5_DMA_ATTR_ENTRY_ST_SHIFT 0
+#define HINIC5_DMA_ATTR_ENTRY_AT_SHIFT 8
+#define HINIC5_DMA_ATTR_ENTRY_PH_SHIFT 10
+#define HINIC5_DMA_ATTR_ENTRY_NO_SNOOPING_SHIFT 12
+#define HINIC5_DMA_ATTR_ENTRY_TPH_EN_SHIFT 13
-#define HINIC5_DMA_ATTR_ENTRY_ST_MASK 0xFF
-#define HINIC5_DMA_ATTR_ENTRY_AT_MASK 0x3
-#define HINIC5_DMA_ATTR_ENTRY_PH_MASK 0x3
-#define HINIC5_DMA_ATTR_ENTRY_NO_SNOOPING_MASK 0x1
-#define HINIC5_DMA_ATTR_ENTRY_TPH_EN_MASK 0x1
+#define HINIC5_DMA_ATTR_ENTRY_ST_MASK 0xFF
+#define HINIC5_DMA_ATTR_ENTRY_AT_MASK 0x3
+#define HINIC5_DMA_ATTR_ENTRY_PH_MASK 0x3
+#define HINIC5_DMA_ATTR_ENTRY_NO_SNOOPING_MASK 0x1
+#define HINIC5_DMA_ATTR_ENTRY_TPH_EN_MASK 0x1
-#define HINIC5_DMA_ATTR_ENTRY_SET(val, member) \
- (((u32)(val) & HINIC5_DMA_ATTR_ENTRY_##member##_MASK) << \
- HINIC5_DMA_ATTR_ENTRY_##member##_SHIFT)
+#define HINIC5_DMA_ATTR_ENTRY_SET(val, member) \
+ (((u32)(val)&HINIC5_DMA_ATTR_ENTRY_##member##_MASK) \
+ << HINIC5_DMA_ATTR_ENTRY_##member##_SHIFT)
-#define HINIC5_DMA_ATTR_ENTRY_CLEAR(val, member) \
- ((val) & (~(HINIC5_DMA_ATTR_ENTRY_##member##_MASK \
- << HINIC5_DMA_ATTR_ENTRY_##member##_SHIFT)))
+#define HINIC5_DMA_ATTR_ENTRY_CLEAR(val, member) \
+ ((val) & (~(HINIC5_DMA_ATTR_ENTRY_##member##_MASK \
+ << HINIC5_DMA_ATTR_ENTRY_##member##_SHIFT)))
-#define HINIC5_PCIE_ST_DISABLE 0
-#define HINIC5_PCIE_AT_DISABLE 0
-#define HINIC5_PCIE_PH_DISABLE 0
+#define HINIC5_PCIE_ST_DISABLE 0
+#define HINIC5_PCIE_AT_DISABLE 0
+#define HINIC5_PCIE_PH_DISABLE 0
-#define PCIE_MSIX_ATTR_ENTRY 0
+#define PCIE_MSIX_ATTR_ENTRY 0
-#define HINIC5_DEAULT_EQ_MSIX_PENDING_LIMIT 0
-#define HINIC5_DEAULT_EQ_MSIX_COALESC_TIMER_CFG 0xFF
-#define HINIC5_DEAULT_EQ_MSIX_RESEND_TIMER_CFG 7
+#define HINIC5_DEAULT_EQ_MSIX_PENDING_LIMIT 0
+#define HINIC5_DEAULT_EQ_MSIX_COALESC_TIMER_CFG 0xFF
+#define HINIC5_DEAULT_EQ_MSIX_RESEND_TIMER_CFG 7
-#define HINIC5_HWDEV_WQ_NAME "hinic5_hardware"
-#define HINIC5_WQ_MAX_REQ 10
+#define HINIC5_HWDEV_WQ_NAME "hinic5_hardware"
+#define HINIC5_WQ_MAX_REQ 10
-#define SLAVE_HOST_STATUS_CLEAR(host_id, val) ((val) & (~(1U << (host_id))))
-#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
-#define SLAVE_HOST_STATUS_GET(host_id, val) (((val) & (1U << (host_id))) != 0)
+#define SLAVE_HOST_STATUS_CLEAR(host_id, val) ((val) & (~(1U << (host_id))))
+#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable)&1U) << (host_id))
+#define SLAVE_HOST_STATUS_GET(host_id, val) (((val) & (1U << (host_id))) != 0)
-#define HINIC5_COMM_RES \
- ((BIT(RES_TYPE_COMM)) | (BIT(RES_TYPE_COMM_CMD_CH)) | \
- (BIT(RES_TYPE_FLUSH_BIT)) | (BIT(RES_TYPE_MQM)) | \
- (BIT(RES_TYPE_SMF)) | (BIT(RES_TYPE_PF_BW_CFG)))
+#define HINIC5_COMM_RES \
+ ((BIT(RES_TYPE_COMM)) | (BIT(RES_TYPE_COMM_CMD_CH)) | \
+ (BIT(RES_TYPE_FLUSH_BIT)) | (BIT(RES_TYPE_MQM)) | \
+ (BIT(RES_TYPE_SMF)) | (BIT(RES_TYPE_PF_BW_CFG)))
-void hinic5_set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
+void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
@@ -132,11 +119,13 @@ void hinic5_set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
if (HINIC5_FUNC_TYPE(dev) != TYPE_PPF)
return;
- reg_val = hinic5_hwif_read_reg(dev->hwif, HINIC5_MULT_HOST_SLAVE_STATUS_ADDR);
+ reg_val = hinic5_hwif_read_reg(dev->hwif,
+ HINIC5_MULT_HOST_SLAVE_STATUS_ADDR);
reg_val = SLAVE_HOST_STATUS_CLEAR(host_id, reg_val);
reg_val |= SLAVE_HOST_STATUS_SET(host_id, enable);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_MULT_HOST_SLAVE_STATUS_ADDR, reg_val);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_MULT_HOST_SLAVE_STATUS_ADDR,
+ reg_val);
sdk_info(dev->dev_hdl, "Set slave host %u status %d, reg value: 0x%x\n",
host_id, enable, reg_val);
@@ -148,15 +137,17 @@ int hinic5_get_slave_host_enable(void *hwdev, u8 host_id, u8 *slave_en)
u32 reg_val;
- if (!hwdev || !slave_en)
+ if ((hwdev == NULL) || (slave_en == NULL)) {
return -EINVAL;
+ }
if (HINIC5_FUNC_TYPE(dev) != TYPE_PPF) {
sdk_warn(dev->dev_hdl, "hwdev should be ppf\n");
return -EINVAL;
}
- reg_val = hinic5_hwif_read_reg(dev->hwif, HINIC5_MULT_HOST_SLAVE_STATUS_ADDR);
+ reg_val = hinic5_hwif_read_reg(dev->hwif,
+ HINIC5_MULT_HOST_SLAVE_STATUS_ADDR);
*slave_en = SLAVE_HOST_STATUS_GET(host_id, reg_val);
return 0;
@@ -167,7 +158,6 @@ int hinic5_get_slave_bitmap(void *hwdev, u8 *slave_host_bitmap)
{
struct hinic5_hwdev *dev = hwdev;
struct service_cap *cap = NULL;
-
if (!dev || !dev->cfg_mgmt)
return -EINVAL;
cap = &dev->cfg_mgmt->svc_cap;
@@ -176,7 +166,8 @@ int hinic5_get_slave_bitmap(void *hwdev, u8 *slave_host_bitmap)
return -EINVAL;
}
- *slave_host_bitmap = cap->host_valid_bitmap & (~(1U << cap->master_host_id));
+ *slave_host_bitmap = cap->host_valid_bitmap &
+ (~(1U << cap->master_host_id));
return 0;
}
@@ -189,16 +180,18 @@ static void hinic5_init_host_mode_pre(struct hinic5_hwdev *hwdev)
switch (cap->srv_multi_host_mode) {
case HINIC5_SDI_MODE_BM:
- if (host_id == cap->master_host_id)
+ if (host_id == cap->master_host_id) {
hwdev->func_mode = FUNC_MOD_MULTI_BM_MASTER;
- else
+ } else {
hwdev->func_mode = FUNC_MOD_MULTI_BM_SLAVE;
+ }
break;
case HINIC5_SDI_MODE_VM:
- if (host_id == cap->master_host_id)
+ if (host_id == cap->master_host_id) {
hwdev->func_mode = FUNC_MOD_MULTI_VM_MASTER;
- else
+ } else {
hwdev->func_mode = FUNC_MOD_MULTI_VM_SLAVE;
+ }
break;
default:
hwdev->func_mode = FUNC_MOD_NORMAL_HOST;
@@ -213,7 +206,7 @@ STATIC int hinic5_multi_host_enable(struct hinic5_hwdev *hwdev, bool enable)
if (!IS_SLAVE_HOST(hwdev) || !HINIC5_IS_PPF(hwdev))
return 0;
- hinic5_set_slave_host_enable(hwdev, hinic5_pcie_itf_id(hwdev), enable);
+ set_slave_host_enable(hwdev, hinic5_pcie_itf_id(hwdev), enable);
return 0;
}
@@ -221,17 +214,9 @@ STATIC int hinic5_multi_host_enable(struct hinic5_hwdev *hwdev, bool enable)
static void hinic5_init_heartbeat_detect(struct hinic5_hwdev *hwdev);
static void hinic5_destroy_heartbeat_detect(struct hinic5_hwdev *hwdev);
-typedef void (*mgmt_event_cb)(void *handle, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
-
-struct mgmt_event_handle {
- u16 cmd;
- mgmt_event_cb proc;
-};
-
-static int pf_handle_vf_comm_mbox(void *pri_handle,
- u16 vf_id, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size)
+static int pf_handle_vf_comm_mbox(void *pri_handle, u16 vf_id, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size)
{
struct hinic5_hwdev *hwdev = pri_handle;
@@ -244,8 +229,7 @@ static int pf_handle_vf_comm_mbox(void *pri_handle,
return 0;
}
-static int vf_handle_pf_comm_mbox(void *pri_handle,
- u16 cmd, void *buf_in,
+static int vf_handle_pf_comm_mbox(void *pri_handle, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size)
{
struct hinic5_hwdev *hwdev = pri_handle;
@@ -258,693 +242,6 @@ static int vf_handle_pf_comm_mbox(void *pri_handle,
return 0;
}
-static void chip_fault_show(struct hinic5_hwdev *hwdev,
- struct hinic5_fault_event *event)
-{
- char fault_level[FAULT_LEVEL_MAX][FAULT_SHOW_STR_LEN + 1] = {
- "fatal", "reset", "host", "flr", "general", "suggestion"};
- char level_str[FAULT_SHOW_STR_LEN + 1];
- u8 level;
-
- memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
- level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level], sizeof(level_str));
- else
- strscpy(level_str, "Unknown", sizeof(level_str));
-
- if (level == FAULT_LEVEL_SERIOUS_FLR)
- dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
- level, level_str, event->event.chip.func_id);
-
- dev_err(hwdev->dev_hdl,
- "Module_id: 0x%x, err_type: 0x%x, err_level: %u[%s], err_csr_addr: 0x%08x, err_csr_value: 0x%08x\n",
- event->event.chip.node_id,
- event->event.chip.err_type, level, level_str,
- event->event.chip.err_csr_addr,
- event->event.chip.err_csr_value);
-}
-
-static void fault_report_show(struct hinic5_hwdev *hwdev,
- struct hinic5_fault_event *event)
-{
- char fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
- "chip", "ucode", "mem rd timeout", "mem wr timeout",
- "reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"
- };
- char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
- struct fault_event_stats *fault = NULL;
-
- sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
- hinic5_global_func_id(hwdev));
-
- fault = &hwdev->hw_stats.fault_event_stats;
-
- if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
- atomic_inc(&fault->fault_type_stat[event->type]);
- } else {
- strscpy(type_str, "Unknown", sizeof(type_str));
- }
-
- sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
- /* 0, 1, 2 and 3 word Represents array event->event.val index */
- sdk_err(hwdev->dev_hdl,
- "Fault val[0]: 0x%08x, val[1]: 0x%08x, val[2]: 0x%08x, val[3]: 0x%08x\n",
- event->event.val[0x0], event->event.val[0x1],
- event->event.val[0x2], event->event.val[0x3]);
-
- hinic5_show_chip_err_info(hwdev);
-
- switch (event->type) {
- case FAULT_TYPE_CHIP:
- chip_fault_show(hwdev, event);
- break;
- case FAULT_TYPE_UCODE:
- sdk_err(hwdev->dev_hdl, "Cause_id: %u, core_id: %u, c_id: %u, epc: 0x%08x\n",
- event->event.ucode.cause_id, event->event.ucode.core_id,
- event->event.ucode.c_id, event->event.ucode.epc);
- break;
- case FAULT_TYPE_MEM_RD_TIMEOUT:
- case FAULT_TYPE_MEM_WR_TIMEOUT:
- sdk_err(hwdev->dev_hdl,
- "Err_csr_ctrl: 0x%08x, err_csr_data: 0x%08x, ctrl_tab: 0x%08x, mem_index: 0x%08x\n",
- event->event.mem_timeout.err_csr_ctrl,
- event->event.mem_timeout.err_csr_data,
- event->event.mem_timeout.ctrl_tab, event->event.mem_timeout.mem_index);
- break;
- case FAULT_TYPE_REG_RD_TIMEOUT:
- case FAULT_TYPE_REG_WR_TIMEOUT:
- sdk_err(hwdev->dev_hdl, "Err_csr: 0x%08x\n", event->event.reg_timeout.err_csr);
- break;
- case FAULT_TYPE_PHY_FAULT:
- sdk_err(hwdev->dev_hdl,
- "Op_type: %u, port_id: %u, dev_ad: %u, csr_addr: 0x%08x, op_data: 0x%08x\n",
- event->event.phy_fault.op_type,
- event->event.phy_fault.port_id, event->event.phy_fault.dev_ad,
- event->event.phy_fault.csr_addr, event->event.phy_fault.op_data);
- break;
- default:
- break;
- }
-}
-
-static void fault_event_handler(void *dev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- struct hinic5_cmd_fault_event *fault_event = NULL;
- struct hinic5_fault_event *fault = NULL;
- struct hinic5_event_info event_info;
- struct hinic5_hwdev *hwdev = dev;
- struct card_node *chip_info = hwdev->chip_node;
- u8 fault_src = HINIC5_FAULT_SRC_TYPE_MAX;
- u8 fault_level;
-
- if (in_size != sizeof(*fault_event)) {
- sdk_err(hwdev->dev_hdl, "Invalid fault event report, length: %u, should be %lu\n",
- in_size, sizeof(*fault_event));
- return;
- }
-
- fault_event = buf_in;
- fault_report_show(hwdev, &fault_event->event);
-
- if (fault_event->event.type == FAULT_TYPE_CHIP)
- fault_level = fault_event->event.event.chip.err_level;
- else
- fault_level = FAULT_LEVEL_FATAL;
-
- if (fault_event->event.type == FAULT_TYPE_CHIP &&
- fault_level <= (u8)FAULT_LEVEL_SERIOUS_RESET) {
- chip_info->exception_flag = true;
- sdk_err(hwdev->dev_hdl, "Set card error due to chip fault, lvl %u\n",
- fault_level);
- }
-
- if (hwdev->event_callback) {
- event_info.service = EVENT_SRV_COMM;
- event_info.type = EVENT_COMM_FAULT;
- fault = (void *)event_info.event_data;
- memcpy(fault, &fault_event->event,
- sizeof(struct hinic5_fault_event));
- fault->fault_level = fault_level;
- hwdev->event_callback(hwdev->event_pri_handle, &event_info);
- }
-
- if (fault_event->event.type <= FAULT_TYPE_REG_WR_TIMEOUT)
- fault_src = fault_event->event.type;
- else if (fault_event->event.type == FAULT_TYPE_PHY_FAULT)
- fault_src = HINIC5_FAULT_SRC_HW_PHY_FAULT;
-
- hisdk5_fault_post_process(hwdev, fault_src, fault_level);
-}
-
-static void ffm_event_record(struct hinic5_hwdev *dev, struct dbgtool_k_glb_info *dbgtool_info,
- struct ffm_intr_info *intr)
-{
- struct rtc_time rctm;
- struct timeval txc;
- u32 ffm_idx;
- u32 last_err_csr_addr;
- u32 last_err_csr_value;
-
- ffm_idx = dbgtool_info->ffm->ffm_num;
- last_err_csr_addr = dbgtool_info->ffm->last_err_csr_addr;
- last_err_csr_value = dbgtool_info->ffm->last_err_csr_value;
- if (ffm_idx < FFM_RECORD_NUM_MAX) {
- if (intr->err_csr_addr == last_err_csr_addr &&
- intr->err_csr_value == last_err_csr_value) {
- dbgtool_info->ffm->ffm[ffm_idx - 1].times++;
- sdk_err(dev->dev_hdl, "Receive intr same, ffm_idx: %u\n", ffm_idx - 1);
- return;
- }
- sdk_err(dev->dev_hdl, "Receive intr, ffm_idx: %u\n", ffm_idx);
-
- dbgtool_info->ffm->ffm[ffm_idx].intr_info.node_id = intr->node_id;
- dbgtool_info->ffm->ffm[ffm_idx].intr_info.err_level = intr->err_level;
- dbgtool_info->ffm->ffm[ffm_idx].intr_info.err_type = intr->err_type;
- dbgtool_info->ffm->ffm[ffm_idx].intr_info.err_csr_addr = intr->err_csr_addr;
- dbgtool_info->ffm->ffm[ffm_idx].intr_info.err_csr_value = intr->err_csr_value;
- dbgtool_info->ffm->last_err_csr_addr = intr->err_csr_addr;
- dbgtool_info->ffm->last_err_csr_value = intr->err_csr_value;
- dbgtool_info->ffm->ffm[ffm_idx].times = 1;
-
- /* Obtain the current UTC time */
- do_gettimeofday(&txc);
-
- /* Calculate the time in date value to tm, i.e. GMT + 8, mutiplied by 60 * 60 */
- rtc_time_to_tm(txc.tv_sec + 60 * 60 * 8, &rctm);
-
- /* tm_year starts from 1900; 0->1900, 1->1901, and so on */
- dbgtool_info->ffm->ffm[ffm_idx].year = (u16)(rctm.tm_year + 1900);
- /* tm_mon starts from 0, 0 indicates January, and so on */
- dbgtool_info->ffm->ffm[ffm_idx].mon = (u8)rctm.tm_mon + 1;
- dbgtool_info->ffm->ffm[ffm_idx].mday = (u8)rctm.tm_mday;
- dbgtool_info->ffm->ffm[ffm_idx].hour = (u8)rctm.tm_hour;
- dbgtool_info->ffm->ffm[ffm_idx].min = (u8)rctm.tm_min;
- dbgtool_info->ffm->ffm[ffm_idx].sec = (u8)rctm.tm_sec;
-
- dbgtool_info->ffm->ffm_num++;
- }
-}
-
-static void ffm_event_msg_handler(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
-#if !defined(__VMWARE__) && !defined(__WIN__)
- struct dbgtool_k_glb_info *dbgtool_info = NULL;
- struct hinic5_hwdev *dev = hwdev;
- struct card_node *card_info = NULL;
- struct ffm_intr_info *intr = NULL;
- spinlock_t *lock = NULL;
-
- if (in_size != sizeof(*intr)) {
- sdk_err(dev->dev_hdl, "Invalid fault event report, length: %u, should be %ld.\n",
- in_size, sizeof(*intr));
- return;
- }
-
- intr = buf_in;
-
- sdk_err(dev->dev_hdl, "node_id: 0x%x, err_type: 0x%x, err_level: %u, err_csr_addr: 0x%08x, err_csr_value: 0x%08x\n",
- intr->node_id, intr->err_type, intr->err_level,
- intr->err_csr_addr, intr->err_csr_value);
-
- hinic5_show_chip_err_info(hwdev);
-
- card_info = dev->chip_node;
- dbgtool_info = card_info->dbgtool_info;
-
- *out_size = sizeof(*intr);
-
- if (!dbgtool_info)
- return;
-
- if (!dbgtool_info->ffm)
- return;
-
- lock = &card_info->dbgtool_info_lock;
- spin_lock(lock);
- ffm_event_record(dev, dbgtool_info, intr);
- spin_unlock(lock);
-#endif
-}
-
-#define X_CSR_INDEX 30
-
-static void sw_watchdog_timeout_info_show(struct hinic5_hwdev *hwdev,
- void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- struct comm_info_sw_watchdog *watchdog_info = buf_in;
- u32 stack_len, i, j, tmp;
- u32 *dump_addr = NULL;
- u64 *reg = NULL;
-
- if (in_size != sizeof(*watchdog_info)) {
- sdk_err(hwdev->dev_hdl, "Invalid mgmt watchdog report, length: %u, should be %ld\n",
- in_size, sizeof(*watchdog_info));
- return;
- }
-
- sdk_err(hwdev->dev_hdl, "Mgmt deadloop time: 0x%x 0x%x, task id: 0x%x, sp: 0x%llx\n",
- watchdog_info->curr_time_h, watchdog_info->curr_time_l,
- watchdog_info->task_id, watchdog_info->sp);
- sdk_err(hwdev->dev_hdl,
- "Stack current used: 0x%x, peak used: 0x%x, overflow flag: 0x%x, top: 0x%llx, bottom: 0x%llx\n",
- watchdog_info->curr_used, watchdog_info->peak_used,
- watchdog_info->is_overflow, watchdog_info->stack_top, watchdog_info->stack_bottom);
-
- sdk_err(hwdev->dev_hdl,
- "Mgmt pc: 0x%llx, elr: 0x%llx, spsr: 0x%llx, far: 0x%llx, esr: 0x%llx, xzr: 0x%llx\n",
- watchdog_info->pc, watchdog_info->reg_info.arm_reg.elr,
- watchdog_info->reg_info.arm_reg.spsr, watchdog_info->reg_info.arm_reg.far,
- watchdog_info->reg_info.arm_reg.esr, watchdog_info->reg_info.arm_reg.xzr);
-
- sdk_err(hwdev->dev_hdl, "Mgmt register info\n");
- reg = &watchdog_info->reg_info.arm_reg.x30;
- for (i = 0; i <= X_CSR_INDEX; i++)
- sdk_err(hwdev->dev_hdl, "x%02u:0x%llx\n",
- X_CSR_INDEX - i, reg[i]);
-
- if (watchdog_info->stack_actlen <= DATA_LEN_1K) {
- stack_len = watchdog_info->stack_actlen;
- } else {
- sdk_err(hwdev->dev_hdl, "Oops stack length: 0x%x is wrong\n",
- watchdog_info->stack_actlen);
- stack_len = DATA_LEN_1K;
- }
-
- sdk_err(hwdev->dev_hdl, "Mgmt dump stack, 16 bytes per line(start from sp)\n");
- for (i = 0; i < (stack_len / DUMP_16B_PER_LINE); i++) {
- dump_addr = (u32 *)(watchdog_info->stack_data + (u32)(i * DUMP_16B_PER_LINE));
- sdk_err(hwdev->dev_hdl, "0x%08x 0x%08x 0x%08x 0x%08x\n",
- *dump_addr, *(dump_addr + 0x1), *(dump_addr + 0x2), *(dump_addr + 0x3));
- }
-
- tmp = (stack_len % DUMP_16B_PER_LINE) / DUMP_4_VAR_PER_LINE;
- for (j = 0; j < tmp; j++) {
- dump_addr = (u32 *)(watchdog_info->stack_data +
- (u32)(i * DUMP_16B_PER_LINE + j * DUMP_4_VAR_PER_LINE));
- sdk_err(hwdev->dev_hdl, "0x%08x ", *dump_addr);
- }
-
- *out_size = sizeof(*watchdog_info);
- watchdog_info = buf_out;
- watchdog_info->head.status = 0;
-}
-
-static void mgmt_watchdog_timeout_event_handler(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- struct hinic5_event_info event_info = { 0 };
- struct hinic5_hwdev *dev = hwdev;
-
- sw_watchdog_timeout_info_show(dev, buf_in, in_size, buf_out, out_size);
-
- if (dev->event_callback) {
- event_info.type = EVENT_COMM_MGMT_WATCHDOG;
- dev->event_callback(dev->event_pri_handle, &event_info);
- }
-}
-
-static void show_exc_info(struct hinic5_hwdev *hwdev, const EXC_INFO_S *exc_info)
-{
- u32 i;
-
- /* key information */
- sdk_err(hwdev->dev_hdl, "==================== Exception Info Begin ====================\n");
- sdk_err(hwdev->dev_hdl, "Exception CpuTick : 0x%08x 0x%08x\n",
- exc_info->cpu_tick.cnt_hi, exc_info->cpu_tick.cnt_lo);
- sdk_err(hwdev->dev_hdl, "Exception Cause : %u\n", exc_info->exc_cause);
- sdk_err(hwdev->dev_hdl, "Os Version : %s\n", exc_info->os_ver);
- sdk_err(hwdev->dev_hdl, "App Version : %s\n", exc_info->app_ver);
- sdk_err(hwdev->dev_hdl, "CPU Type : 0x%08x\n", exc_info->cpu_type);
- sdk_err(hwdev->dev_hdl, "CPU ID : 0x%08x\n", exc_info->cpu_id);
- sdk_err(hwdev->dev_hdl, "Thread Type : 0x%08x\n", exc_info->thread_type);
- sdk_err(hwdev->dev_hdl, "Thread ID : 0x%08x\n", exc_info->thread_id);
- sdk_err(hwdev->dev_hdl, "Byte Order : 0x%08x\n", exc_info->byte_order);
- sdk_err(hwdev->dev_hdl, "Nest Count : 0x%08x\n", exc_info->nest_cnt);
- sdk_err(hwdev->dev_hdl, "Fatal Error Num : 0x%08x\n", exc_info->fatal_errno);
- sdk_err(hwdev->dev_hdl, "Current SP : 0x%016llx\n", exc_info->uw_sp);
- sdk_err(hwdev->dev_hdl, "Stack Bottom : 0x%016llx\n", exc_info->stack_bottom);
-
- /* register field */
- sdk_err(hwdev->dev_hdl, "Register contents when exception occur.\n");
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "TTBR0",
- exc_info->reg_info.ttbr0, "TTBR1", exc_info->reg_info.ttbr1);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "TCR",
- exc_info->reg_info.tcr, "MAIR", exc_info->reg_info.mair);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "SCTLR",
- exc_info->reg_info.sctlr, "VBAR", exc_info->reg_info.vbar);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "CURRENTE1",
- exc_info->reg_info.current_el, "SP", exc_info->reg_info.sp);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "ELR",
- exc_info->reg_info.elr, "SPSR", exc_info->reg_info.spsr);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx \t %-14s: 0x%016llx\n", "FAR",
- exc_info->reg_info.far_r, "ESR", exc_info->reg_info.esr);
- sdk_err(hwdev->dev_hdl, "%-14s: 0x%016llx\n", "XZR", exc_info->reg_info.xzr);
-
- for (i = 0; i < XREGS_NUM - 1; i += 0x2)
- sdk_err(hwdev->dev_hdl, "XREGS[%02u]%-5s: 0x%016llx \t XREGS[%02u]%-5s: 0x%016llx",
- i, " ", exc_info->reg_info.xregs[i],
- (u32)(i + 0x1U), " ", exc_info->reg_info.xregs[(u32)(i + 0x1U)]);
-
- sdk_err(hwdev->dev_hdl, "XREGS[%02u]%-5s: 0x%016llx \t ", XREGS_NUM - 1, " ",
- exc_info->reg_info.xregs[XREGS_NUM - 1]);
-}
-
-#define FOUR_REG_LEN 16
-
-static void mgmt_lastword_report_event_handler(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- comm_info_up_lastword_s *lastword_info = buf_in;
- EXC_INFO_S *exc_info = NULL;
- struct hinic5_hwdev *dev = hwdev;
- u32 *curr_reg = NULL;
- u32 reg_i, cnt, stack_len;
-
- if (in_size != sizeof(*lastword_info)) {
- sdk_err(dev->dev_hdl, "Invalid mgmt lastword, length: %u, should be %lu\n",
- in_size, sizeof(*lastword_info));
- return;
- }
- exc_info = &lastword_info->stack_info;
- stack_len = lastword_info->stack_actlen;
-
- if (stack_len > MPU_LASTWORD_SIZE) {
- sdk_err(dev->dev_hdl, "Invalid mgmt lastword, length: stack_len: %u, should less than %u\n",
- stack_len, MPU_LASTWORD_SIZE);
- return;
- }
-
- show_exc_info(dev, exc_info);
-
- /* call stack dump */
- sdk_err(dev->dev_hdl, "Dump stack when exceptioin occurs, 16Bytes per line.\n");
-
- cnt = stack_len / FOUR_REG_LEN;
- for (reg_i = 0; reg_i < cnt; reg_i++) {
- curr_reg = (u32 *)(lastword_info->stack_data + ((u64)(u32)(reg_i * FOUR_REG_LEN)));
- sdk_err(dev->dev_hdl, "0x%08x 0x%08x 0x%08x 0x%08x\n",
- *curr_reg, *(curr_reg + 0x1), *(curr_reg + 0x2), *(curr_reg + 0x3));
- }
-
- sdk_err(dev->dev_hdl, "==================== Exception Info End ====================\n");
-}
-
-#if !defined(__UEFI__) && !defined(__WIN__) && !defined(__VMWARE__)
-static int hisdk5_attach_vf_vroce(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- int err = 0;
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return -EINVAL;
-
- src_adev = to_hinic5_adev(lld_dev);
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return -EINVAL;
-
- err = hinic5_attach_service(&dst_adev->lld_dev, SERVICE_T_ROCE);
- return err;
-}
-
-static void hisdk5_detach_vf_vroce(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return;
-
- src_adev = to_hinic5_adev(lld_dev);
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return;
-
- hinic5_detach_service(&dst_adev->lld_dev, SERVICE_T_VROCE);
-}
-
-static int hisdk5_attach_vf_ub(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- int err = 0;
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return -EINVAL;
-
- src_adev = to_hinic5_adev(lld_dev);
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return -EINVAL;
-
- err = hinic5_attach_service(&dst_adev->lld_dev, SERVICE_T_UB);
- return err;
-}
-
-static void hisdk5_detach_vf_ub(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return;
-
- src_adev = to_hinic5_adev(lld_dev);
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return;
-
- hinic5_detach_service(&dst_adev->lld_dev, SERVICE_T_UB);
-}
-
-static int hisdk5_attach_vf_nic(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- int err = 0;
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return -EINVAL;
-
- src_adev = to_hinic5_adev(lld_dev);
-
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return -EINVAL;
-
- err = hinic5_set_func_en(dst_adev, true, func_id);
- return err;
-}
-
-static void hisdk5_detach_vf_nic(struct hinic5_lld_dev *lld_dev, u16 func_id)
-{
- struct hinic5_adev *src_adev = NULL;
- struct hinic5_adev *dst_adev = NULL;
-
- if (!lld_dev)
- return;
-
- src_adev = to_hinic5_adev(lld_dev);
- dst_adev = hinic5_get_vf_adev_by_pf((void *)src_adev, func_id);
- if (!dst_adev)
- return;
-
- (void)hinic5_set_func_en(dst_adev, false, func_id);
-}
-
-static void hisdk5_attach_plug_service(struct hinic5_lld_dev *lld_dev, u8 srv_type,
- struct hinic5_hwdev *dev, u16 func_id)
-{
- int err = 0;
-
- if (func_id < CMD_MAX_MAX_PF_NUM) {
- switch (srv_type) {
- case COMM_PLUG_SRV_NIC:
- err = hinic5_attach_service(lld_dev, SERVICE_T_NIC);
- break;
- case COMM_PLUG_SRV_VROCE:
- err = hinic5_attach_service(lld_dev, SERVICE_T_ROCE);
- break;
- case COMM_PLUG_SRV_UB:
- err = hinic5_attach_service(lld_dev, SERVICE_T_UB);
- break;
- default:
- sdk_err(dev->dev_hdl, "plug attach pf service type error.\n");
- }
- } else {
- switch (srv_type) {
- case COMM_PLUG_SRV_NIC:
- err = hisdk5_attach_vf_nic(lld_dev, func_id);
- break;
- case COMM_PLUG_SRV_VROCE:
- err = hisdk5_attach_vf_vroce(lld_dev, func_id);
- break;
- case COMM_PLUG_SRV_UB:
- err = hisdk5_attach_vf_ub(lld_dev, func_id);
- break;
- default:
- sdk_err(dev->dev_hdl, "plug attach vf service type error.\n");
- }
- }
-
- if (err != 0)
- sdk_err(dev->dev_hdl, "plug attach service failed.\n");
-}
-
-static void hisdk5_detach_plug_service(struct hinic5_lld_dev *lld_dev, u8 srv_type,
- struct hinic5_hwdev *dev, u16 func_id)
-{
- if (func_id < CMD_MAX_MAX_PF_NUM) {
- switch (srv_type) {
- case COMM_PLUG_SRV_NIC:
- hinic5_detach_service(lld_dev, SERVICE_T_NIC);
- break;
- case COMM_PLUG_SRV_VROCE:
- hinic5_detach_service(lld_dev, SERVICE_T_VROCE);
- break;
- case COMM_PLUG_SRV_UB:
- hinic5_detach_service(lld_dev, SERVICE_T_UB);
- break;
- default:
- sdk_err(dev->dev_hdl, "plug attach pf service type error.\n");
- }
- } else {
- switch (srv_type) {
- case COMM_PLUG_SRV_NIC:
- hisdk5_detach_vf_nic(lld_dev, func_id);
- break;
- case COMM_PLUG_SRV_VROCE:
- hisdk5_detach_vf_vroce(lld_dev, func_id);
- break;
- case COMM_PLUG_SRV_UB:
- hisdk5_detach_vf_ub(lld_dev, func_id);
- break;
- default:
- sdk_err(dev->dev_hdl, "plug detach vf service type error.\n");
- }
- }
-}
-
-static void hisdk5_plug_service_pre_handler(u8 srv_type, struct comm_cmd_plug_srv *plug_srv,
- struct hinic5_hwdev *dev)
-{
- if (srv_type == COMM_PLUG_SRV_NIC) {
- dev->cfg_mgmt->svc_cap.nic_cap.max_sqs = plug_srv->nic_cap.max_sqs;
- dev->cfg_mgmt->svc_cap.nic_cap.max_rqs = plug_srv->nic_cap.max_rqs;
- }
-}
-
-static void mgmt_plug_report_event_handler(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- struct comm_cmd_plug_srv *plug_srv = buf_in;
- struct hinic5_hwdev *dev = hwdev;
- struct hinic5_adev *adev = dev->adapter_hdl;
- struct hinic5_lld_dev *lld_dev = &adev->lld_dev;
- u16 func_id;
- u8 srv_type;
- u8 attach_en;
-
- if (in_size != sizeof(*plug_srv)) {
- sdk_err(dev->dev_hdl, "Invalid plug event report, length: %u, should be %ld.\n",
- in_size, sizeof(*plug_srv));
- return;
- }
-
- if (!IS_BMGW_SLAVE_HOST(dev)) {
- sdk_warn(dev->dev_hdl, "Discard plug event from unexpected function (mode %u).\n",
- dev->func_mode);
- return;
- }
-
- srv_type = plug_srv->srv_type;
- attach_en = plug_srv->attach_en;
- func_id = plug_srv->func_id;
- hisdk5_plug_service_pre_handler(srv_type, plug_srv, dev);
-
- if (attach_en != 0)
- hisdk5_attach_plug_service(lld_dev, srv_type, dev, func_id);
- else
- hisdk5_detach_plug_service(lld_dev, srv_type, dev, func_id);
-}
-#endif
-
-static void mgmt_reset_event_handler(void *dev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
-{
- struct hinic5_hwdev *hwdev = dev;
-
- sdk_err(hwdev->dev_hdl, "Event COMM_MGMT_CMD_MGMT_RESET from MPU\n");
-}
-
-const struct mgmt_event_handle hinic5_mgmt_event_proc[] = {
- {
- .cmd = COMM_MGMT_CMD_FAULT_REPORT,
- .proc = fault_event_handler,
- },
-
- {
- .cmd = COMM_MGMT_CMD_FFM_SET,
- .proc = ffm_event_msg_handler,
- },
-
- {
- .cmd = COMM_MGMT_CMD_WATCHDOG_INFO,
- .proc = mgmt_watchdog_timeout_event_handler,
- },
-
- {
- .cmd = COMM_MGMT_CMD_LASTWORD_GET,
- .proc = mgmt_lastword_report_event_handler,
- },
-
- {
- .cmd = COMM_MGMT_CMD_MGMT_RESET,
- .proc = mgmt_reset_event_handler,
- },
-
-#if !defined(__UEFI__) && !defined(__WIN__) && !defined(__VMWARE__)
- {
- .cmd = COMM_MGMT_CMD_SET_FUNC_PLUG_SRV,
- .proc = mgmt_plug_report_event_handler,
- },
-#endif
-};
-
-static void pf_handle_mgmt_comm_event(void *handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
-{
- struct hinic5_hwdev *hwdev = handle;
- u32 i, event_num = (u32)ARRAY_LEN(hinic5_mgmt_event_proc);
-
- if (!hwdev)
- return;
-
- for (i = 0; i < event_num; i++) {
- if (cmd == hinic5_mgmt_event_proc[i].cmd) {
- if (hinic5_mgmt_event_proc[i].proc)
- hinic5_mgmt_event_proc[i].proc(handle, buf_in, in_size,
- buf_out, out_size);
- else
- sdk_warn(hwdev->dev_hdl,
- "Mgmt event proc is not registered, cmd %u\n", cmd);
- return;
- }
- }
-
- sdk_warn(hwdev->dev_hdl, "Unsupported mgmt cpu event %u to process\n",
- cmd);
- *out_size = sizeof(struct mgmt_msg_head);
- ((struct mgmt_msg_head *)buf_out)->status = HINIC5_MGMT_CMD_UNSUPPORTED;
-}
-
static inline void hinic5_set_chip_present(struct hinic5_hwdev *hwdev)
{
hwdev->chip_present_flag = HINIC5_CHIP_PRESENT;
@@ -962,7 +259,8 @@ bool hinic5_check_htn_device_id(void *hwdev)
struct hinic5_adev *adev = dev->adapter_hdl;
if ((hinic5_adev_get_device_id(adev) != HINIC5_UDEV_DEVICE_ID_1872_PF &&
- hinic5_adev_get_device_id(adev) != HINIC5_UDEV_DEVICE_ID_1872_VF) ||
+ hinic5_adev_get_device_id(adev) !=
+ HINIC5_UDEV_DEVICE_ID_1872_VF) ||
adev->lld_dev.dev_type != HINIC5_DEVICE_T_UB) {
return false;
}
@@ -993,8 +291,9 @@ void hinic5_force_complete_all(void *dev)
struct hinic5_hwdev *hwdev = dev;
struct hinic5_mbox *func_to_func = NULL;
- if (!dev || !hwdev->pf_to_mgmt)
+ if (!dev || !hwdev->pf_to_mgmt) {
return;
+ }
spin_lock_bh(&hwdev->channel_lock);
if (test_bit(HINIC5_HWDEV_MGMT_INITED, &hwdev->func_state)) {
@@ -1026,7 +325,7 @@ void hinic5_detect_hw_present(void *hwdev)
{
struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
- if (!hinic5_get_card_present_state(dev)) {
+ if (!get_card_present_state(dev)) {
sdk_err(dev->dev_hdl, "Detect card absent.\n");
hinic5_set_chip_absent(hwdev);
hinic5_force_complete_all(hwdev);
@@ -1055,24 +354,25 @@ static int dma_attr_table_init(struct hinic5_hwdev *hwdev)
addr = HINIC5_CSR_DMA_ATTR_TBL_ADDR;
val = hinic5_hwif_read_reg(hwdev->hwif, addr);
- dst_attr = HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_ST_DISABLE, ST) |
- HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_AT_DISABLE, AT) |
- HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_PH_DISABLE, PH) |
- HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_SNOOP, NO_SNOOPING) |
- HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_TPH_DISABLE, TPH_EN);
+ dst_attr = HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_ST_DISABLE, ST) |
+ HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_AT_DISABLE, AT) |
+ HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_PH_DISABLE, PH) |
+ HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_SNOOP, NO_SNOOPING) |
+ HINIC5_DMA_ATTR_ENTRY_SET(HINIC5_PCIE_TPH_DISABLE, TPH_EN);
if (val == dst_attr)
return 0;
- return hinic5_set_dma_attr_tbl(hwdev, PCIE_MSIX_ATTR_ENTRY, HINIC5_PCIE_ST_DISABLE,
- HINIC5_PCIE_AT_DISABLE, HINIC5_PCIE_PH_DISABLE,
- HINIC5_PCIE_SNOOP, HINIC5_PCIE_TPH_DISABLE);
+ return hinic5_set_dma_attr_tbl(
+ hwdev, PCIE_MSIX_ATTR_ENTRY, HINIC5_PCIE_ST_DISABLE,
+ HINIC5_PCIE_AT_DISABLE, HINIC5_PCIE_PH_DISABLE,
+ HINIC5_PCIE_SNOOP, HINIC5_PCIE_TPH_DISABLE);
}
static int init_aeqs_msix_attr(struct hinic5_hwdev *hwdev)
{
struct hinic5_aeqs *aeqs = hwdev->aeqs;
- struct interrupt_info info = {0};
+ struct interrupt_info info = { 0 };
struct hinic5_eq *eq = NULL;
int q_id;
int err;
@@ -1089,8 +389,8 @@ static int init_aeqs_msix_attr(struct hinic5_hwdev *hwdev)
err = hinic5_set_interrupt_cfg_direct(hwdev, &info,
HINIC5_CHANNEL_COMM);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Set msix attr for aeq %d failed\n",
- q_id);
+ sdk_err(hwdev->dev_hdl,
+ "Set msix attr for aeq %d failed\n", q_id);
return -EFAULT;
}
}
@@ -1104,13 +404,14 @@ static int init_ceqs_msix_attr(struct hinic5_hwdev *hwdev)
return 0;
#endif
struct hinic5_ceqs *ceqs = hwdev->ceqs;
- struct interrupt_info info = {0};
+ struct interrupt_info info = { 0 };
struct hinic5_eq *eq = NULL;
u16 q_id;
int err;
- if (!ceqs)
+ if (!ceqs) {
return 0;
+ }
info.lli_set = 0;
info.interrupt_coalesc_set = 1;
@@ -1124,8 +425,8 @@ static int init_ceqs_msix_attr(struct hinic5_hwdev *hwdev)
err = hinic5_set_interrupt_cfg(hwdev, info,
HINIC5_CHANNEL_COMM);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Set msix attr for ceq %u failed\n",
- q_id);
+ sdk_err(hwdev->dev_hdl,
+ "Set msix attr for ceq %u failed\n", q_id);
return -EFAULT;
}
}
@@ -1170,8 +471,8 @@ static int hinic5_comm_aeqs_init(struct hinic5_hwdev *hwdev)
err = hinic5_alloc_irqs(hwdev, SERVICE_T_INTF, num_aeqs, aeq_irqs,
&resp_num_irq);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to alloc aeq irqs, num_aeqs: %u\n",
- num_aeqs);
+ sdk_err(hwdev->dev_hdl,
+ "Failed to alloc aeq irqs, num_aeqs: %u\n", num_aeqs);
return err;
}
@@ -1198,7 +499,7 @@ static int hinic5_comm_aeqs_init(struct hinic5_hwdev *hwdev)
static void hinic5_comm_aeqs_free(struct hinic5_hwdev *hwdev)
{
- struct irq_info aeq_irqs[HINIC5_MAX_AEQS] = {{0} };
+ struct irq_info aeq_irqs[HINIC5_MAX_AEQS] = { { 0 } };
struct irq_info *aeq_irq = &aeq_irqs[0];
u16 num_irqs, i;
@@ -1220,8 +521,9 @@ static int hinic5_comm_ceqs_init(struct hinic5_hwdev *hwdev)
int err;
num_ceqs = HINIC5_HWIF_NUM_CEQS(hwdev->hwif);
- if (num_ceqs == 0)
+ if (num_ceqs == 0) {
return 0;
+ }
if (num_ceqs > HINIC5_MAX_CEQS) {
sdk_warn(hwdev->dev_hdl, "Adjust ceq num to %d\n",
@@ -1232,8 +534,8 @@ static int hinic5_comm_ceqs_init(struct hinic5_hwdev *hwdev)
err = hinic5_alloc_irqs(hwdev, SERVICE_T_INTF, num_ceqs, ceq_irqs,
&resp_num_irq);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to alloc ceq irqs, num_ceqs: %u\n",
- num_ceqs);
+ sdk_err(hwdev->dev_hdl,
+ "Failed to alloc ceq irqs, num_ceqs: %u\n", num_ceqs);
return err;
}
@@ -1245,8 +547,7 @@ static int hinic5_comm_ceqs_init(struct hinic5_hwdev *hwdev)
err = hinic5_ceqs_init(hwdev, num_ceqs, ceq_irqs);
if (err != 0) {
- sdk_err(hwdev->dev_hdl,
- "Failed to init ceqs, err:%d\n", err);
+ sdk_err(hwdev->dev_hdl, "Failed to init ceqs, err:%d\n", err);
goto ceqs_init_err;
}
@@ -1269,31 +570,32 @@ static void hinic5_comm_ceqs_free(struct hinic5_hwdev *hwdev)
u16 num_irqs;
int i;
- if (!hwdev->ceqs)
+ if (!hwdev->ceqs) {
return;
+ }
hinic5_get_ceq_irqs(hwdev, ceq_irq, &num_irqs);
hinic5_ceqs_free(hwdev);
- for (i = 0; i < num_irqs; i++)
+ for (i = 0; i < num_irqs; i++) {
hinic5_free_irq(hwdev, SERVICE_T_INTF, ceq_irqs[i].irq_id);
+ }
}
/**
- * @brief Initialize communication between functions
+ * @brief 初始化function和function之间的通信功能
*
- * @param[in] hwdev device pointer
+ * @param[in] hwdev 设备指针
*
* @details
- * Note that mpu is a special function
- * Communication is implemented through mailbox
- * 1) Initialize mailbox related registers and resources
- * 2) Register callback for receiving mailbox data
+ * 注意mpu是一个特殊的function
+ * 这里的通信功能通过mailbox实现
+ * 1)初始化mailbox相关的寄存器和资源; 2)注册处理接收mailbox数据的回调
*
* @return:
- * @retval 0 success
- * @retval non-zero failure
+ * @retval 0 成功
+ * @retval 非0 失败
*/
static int hinic5_comm_func_to_func_init(struct hinic5_hwdev *hwdev)
{
@@ -1309,12 +611,10 @@ static int hinic5_comm_func_to_func_init(struct hinic5_hwdev *hwdev)
hinic5_mgmt_msg_aeqe_handler);
if (!HINIC5_IS_VF(hwdev))
- hinic5_register_pf_mbox_cb(hwdev, HINIC5_MOD_COMM,
- hwdev,
+ hinic5_register_pf_mbox_cb(hwdev, HINIC5_MOD_COMM, hwdev,
pf_handle_vf_comm_mbox);
else
- hinic5_register_vf_mbox_cb(hwdev, HINIC5_MOD_COMM,
- hwdev,
+ hinic5_register_vf_mbox_cb(hwdev, HINIC5_MOD_COMM, hwdev,
vf_handle_pf_comm_mbox);
set_bit(HINIC5_HWDEV_MBOX_INITED, &hwdev->func_state);
@@ -1331,10 +631,11 @@ static void hinic5_comm_func_to_func_free(struct hinic5_hwdev *hwdev)
hinic5_aeq_unregister_hw_cb(hwdev, HINIC5_MBX_FROM_FUNC);
hinic5_aeq_unregister_hw_cb(hwdev, HINIC5_MSG_FROM_MGMT_CPU);
- if (!HINIC5_IS_VF(hwdev))
+ if (!HINIC5_IS_VF(hwdev)) {
hinic5_unregister_pf_mbox_cb(hwdev, HINIC5_MOD_COMM);
- else
+ } else {
hinic5_unregister_vf_mbox_cb(hwdev, HINIC5_MOD_COMM);
+ }
hinic5_func_to_func_free(hwdev);
}
@@ -1376,7 +677,8 @@ static int hinic5_comm_cmdqs_init(struct hinic5_hwdev *hwdev)
return err;
}
- hinic5_ceq_register_cb(hwdev, hwdev, HINIC5_CMDQ, hinic5_cmdq_ceq_handler);
+ hinic5_ceq_register_cb(hwdev, hwdev, HINIC5_CMDQ,
+ hinic5_cmdq_ceq_handler);
err = hinic5_set_cmdq_depth(hwdev, HINIC5_CMDQ_DEPTH);
if (err != 0) {
@@ -1407,9 +709,9 @@ static void hinic5_comm_cmdqs_free(struct hinic5_hwdev *hwdev)
static void hinic5_sync_mgmt_func_state(struct hinic5_hwdev *hwdev)
{
#if defined(__UEFI__) && !defined(__HIFC__)
- hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_INIT);
+ hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_INIT);
#else
- hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_ACTIVE_FLAG);
+ hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_ACTIVE_FLAG);
#endif
}
@@ -1420,7 +722,8 @@ static void hinic5_unsync_mgmt_func_state(struct hinic5_hwdev *hwdev)
static int init_basic_attributes(struct hinic5_hwdev *hwdev)
{
- u64 drv_features[COMM_MAX_FEATURE_QWORD] = {HINIC5_DRV_FEATURE_QW0, 0, 0, 0};
+ u64 drv_features[COMM_MAX_FEATURE_QWORD] = { HINIC5_DRV_FEATURE_QW0, 0,
+ 0, 0 };
int err, i;
#if !defined(__UEFI__)
@@ -1440,7 +743,8 @@ static int init_basic_attributes(struct hinic5_hwdev *hwdev)
return err;
}
- sdk_info(hwdev->dev_hdl, "Comm hw features: 0x%llx, drv features: 0x%llx\n",
+ sdk_info(hwdev->dev_hdl,
+ "Comm hw features: 0x%llx, drv features: 0x%llx\n",
hwdev->features[0], drv_features[0]);
for (i = 0; i < COMM_MAX_FEATURE_QWORD; i++)
@@ -1452,12 +756,12 @@ static int init_basic_attributes(struct hinic5_hwdev *hwdev)
return err;
}
- sdk_info(hwdev->dev_hdl,
- "global attribute: max_host: 0x%x, max_pf: 0x%x, vf_id_start: 0x%x, mgmt node id: 0x%x, cmdq_num: 0x%x\n",
- hwdev->glb_attr.max_host_num, hwdev->glb_attr.max_pf_num,
- hwdev->glb_attr.vf_id_start,
- hwdev->glb_attr.mgmt_host_node_id,
- hwdev->glb_attr.cmdq_num);
+ sdk_info(
+ hwdev->dev_hdl,
+ "global attribute: max_host: 0x%x, max_pf: 0x%x, vf_id_start: 0x%x, mgmt node id: 0x%x, cmdq_num: 0x%x\n",
+ hwdev->glb_attr.max_host_num, hwdev->glb_attr.max_pf_num,
+ hwdev->glb_attr.vf_id_start, hwdev->glb_attr.mgmt_host_node_id,
+ hwdev->glb_attr.cmdq_num);
return 0;
}
@@ -1483,11 +787,7 @@ static int init_basic_mgmt_channel(struct hinic5_hwdev *hwdev)
sdk_err(hwdev->dev_hdl, "Failed to init aeqs msix attr\n");
goto aeqs_msix_attr_init_err;
}
-#if !defined(__UEFI__) && !defined(__WIN__) && !defined(__VMWARE__)
- err = hinic5_cqm_init_fast_msg(hwdev);
- if (err != 0)
- sdk_err(hwdev->dev_hdl, "Failed to init fast msg\n");
-#endif
+
return 0;
aeqs_msix_attr_init_err:
@@ -1541,7 +841,8 @@ static int init_mgmt_channel_post(struct hinic5_hwdev *hwdev)
if (HINIC5_IS_PPF(hwdev)) {
err = hinic5_mbox_init_host_msg_channel(hwdev);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to init mbox host channel\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to init mbox host channel\n");
return err;
}
}
@@ -1570,7 +871,8 @@ static int init_cmdqs_channel(struct hinic5_hwdev *hwdev)
err = hinic5_comm_ceqs_init(hwdev);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to init completion event queues\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to init completion event queues\n");
goto ceqs_init_err;
}
@@ -1582,7 +884,8 @@ static int init_cmdqs_channel(struct hinic5_hwdev *hwdev)
/* set default wq page_size */
if (wq_page_order > HINIC5_MAX_WQ_PAGE_SIZE_ORDER) {
- sdk_info(hwdev->dev_hdl, "wq_page_order exceed limit[0, %d], reset to %d\n",
+ sdk_info(hwdev->dev_hdl,
+ "wq_page_order exceed limit[0, %d], reset to %d\n",
HINIC5_MAX_WQ_PAGE_SIZE_ORDER,
HINIC5_MAX_WQ_PAGE_SIZE_ORDER);
wq_page_order = HINIC5_MAX_WQ_PAGE_SIZE_ORDER;
@@ -1606,8 +909,7 @@ static int init_cmdqs_channel(struct hinic5_hwdev *hwdev)
cmdq_init_err:
hinic5_set_wq_page_size(hwdev, hinic5_global_func_id(hwdev),
- HINIC5_HW_WQ_PAGE_SIZE,
- HINIC5_CHANNEL_COMM);
+ HINIC5_HW_WQ_PAGE_SIZE, HINIC5_CHANNEL_COMM);
init_wq_pg_size_err:
init_ceq_msix_err:
hinic5_comm_ceqs_free(hwdev);
@@ -1655,7 +957,8 @@ static int hinic5_init_comm_ch(struct hinic5_hwdev *hwdev)
goto init_cmdqs_channel_err;
}
- err = hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 1, HINIC5_CHANNEL_COMM);
+ err = hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 1,
+ HINIC5_CHANNEL_COMM);
if (err != 0)
goto set_used_state_err;
@@ -1667,16 +970,15 @@ static int hinic5_init_comm_ch(struct hinic5_hwdev *hwdev)
}
err = hinic5_init_stateless_aeqs(hwdev);
if (err != 0) {
- sdk_err(hwdev->dev_hdl,
- "Failed to init stateless aeqs\n");
+ sdk_err(hwdev->dev_hdl, "Failed to init stateless aeqs\n");
goto init_stateless_aeqs_err;
}
- err = hinic5_aeq_register_swe_cb(hwdev, hwdev, HINIC5_STATELESS_EVENT,
- (hinic5_aeq_swe_cb)hinic5_nic_sw_aeqe_handler);
+ err = hinic5_aeq_register_swe_cb(
+ hwdev, hwdev, HINIC5_STATELESS_EVENT,
+ (hinic5_aeq_swe_cb)hinic5_nic_sw_aeqe_handler);
if (err != 0) {
- sdk_err(hwdev->dev_hdl,
- "Failed to register sw aeqe handler\n");
+ sdk_err(hwdev->dev_hdl, "Failed to register sw aeqe handler\n");
goto register_ucode_aeqe_err;
}
@@ -1686,7 +988,8 @@ static int hinic5_init_comm_ch(struct hinic5_hwdev *hwdev)
hinic5_stateless_aeqs_free(hwdev);
init_stateless_aeqs_err:
hinic5_unsync_mgmt_func_state(hwdev);
- hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 0, HINIC5_CHANNEL_COMM);
+ hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 0,
+ HINIC5_CHANNEL_COMM);
set_used_state_err:
hinic5_free_cmdqs_channel(hwdev);
init_cmdqs_channel_err:
@@ -1707,14 +1010,13 @@ static void hinic5_uninit_comm_ch(struct hinic5_hwdev *hwdev)
hinic5_unsync_mgmt_func_state(hwdev);
- hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 0, HINIC5_CHANNEL_COMM);
+ hinic5_set_func_svc_used_state(hwdev, SVC_T_COMM, 0,
+ HINIC5_CHANNEL_COMM);
hinic5_free_cmdqs_channel(hwdev);
free_mgmt_msg_channel_post(hwdev);
-#if !defined(__UEFI__) && !defined(__WIN__) && !defined(__VMWARE__)
- hinic5_cqm_deinit_fast_msg(hwdev);
-#endif
+
free_base_mgmt_channel(hwdev);
}
@@ -1722,12 +1024,14 @@ static void hinic5_uninit_comm_ch(struct hinic5_hwdev *hwdev)
static void hinic5_auto_sync_time_work(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_hwdev *hwdev = container_of(delay, struct hinic5_hwdev, sync_time_task);
+ struct hinic5_hwdev *hwdev =
+ container_of(delay, struct hinic5_hwdev, sync_time_task);
int err;
- err = hinic5_sync_time(hwdev, hinic5_ossl_get_real_time());
+ err = hinic5_sync_time(hwdev, ossl_get_real_time());
if (err != 0)
- sdk_err(hwdev->dev_hdl, "Synchronize UTC time to firmware failed, errno:%d.\n",
+ sdk_err(hwdev->dev_hdl,
+ "Synchronize UTC time to firmware failed, errno:%d.\n",
err);
queue_delayed_work(hwdev->workq, &hwdev->sync_time_task,
@@ -1737,10 +1041,12 @@ static void hinic5_auto_sync_time_work(struct work_struct *work)
static void hinic5_auto_channel_detect_work(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_hwdev *hwdev = container_of(delay, struct hinic5_hwdev, channel_detect_task);
+ struct hinic5_hwdev *hwdev =
+ container_of(delay, struct hinic5_hwdev, channel_detect_task);
if (!hinic5_is_chip_present(hwdev)) {
- sdk_warn(hwdev->dev_hdl, "Detect card absent, stop channel detect.\n");
+ sdk_warn(hwdev->dev_hdl,
+ "Detect card absent, stop channel detect.\n");
return;
}
@@ -1748,30 +1054,33 @@ static void hinic5_auto_channel_detect_work(struct work_struct *work)
/* reschedule self */
if (!hinic5_channel_detect_should_stop(hwdev))
- queue_delayed_work(hwdev->workq, &hwdev->channel_detect_task,
- msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
+ queue_delayed_work(
+ hwdev->workq, &hwdev->channel_detect_task,
+ msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
}
void hinic5_kernel_sync_time_work(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_hwdev *hwdev = container_of(delay, struct hinic5_hwdev,
- sync_kernel_time_task);
+ struct hinic5_hwdev *hwdev =
+ container_of(delay, struct hinic5_hwdev, sync_kernel_time_task);
int err;
struct card_node *chip_node = (struct card_node *)(hwdev->chip_node);
-
- if (!chip_node || !chip_node->non_ptp_info ||
+ if ((chip_node == NULL) || (chip_node->non_ptp_info == NULL) ||
(chip_node->non_ptp_info->non_ptp_time_diff_enable == 0)) {
return;
}
err = hinic5_sync_kernel_time(hwdev);
if (err != 0)
- sdk_err(hwdev->dev_hdl, "Synchronize kernel time failed, errno:%d.\n", err);
+ sdk_err(hwdev->dev_hdl,
+ "Synchronize kernel time failed, errno:%d.\n", err);
- queue_delayed_work(hwdev->workq, &hwdev->sync_kernel_time_task,
- msecs_to_jiffies(HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD));
+ queue_delayed_work(
+ hwdev->workq, &hwdev->sync_kernel_time_task,
+ msecs_to_jiffies(HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD));
+ return;
}
static int hinic5_init_ppf_work(struct hinic5_hwdev *hwdev)
@@ -1788,25 +1097,29 @@ static int hinic5_init_ppf_work(struct hinic5_hwdev *hwdev)
if (COMM_SUPPORT_CHANNEL_DETECT(hwdev) != 0) {
INIT_DELAYED_WORK(&hwdev->channel_detect_task,
hinic5_auto_channel_detect_work);
- queue_delayed_work(hwdev->workq, &hwdev->channel_detect_task,
- msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
+ queue_delayed_work(
+ hwdev->workq, &hwdev->channel_detect_task,
+ msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
}
if (COMM_SUPPORT_NON_PTP_SYNC(hwdev) != 0) {
err = hinic5_non_ptp_cdev_init(hwdev);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to init non_ptp char dev\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to init non_ptp char dev\n");
goto init_non_ptp_err;
}
- /* Register delayed task, initialized as disable */
- INIT_DELAYED_WORK(&hwdev->sync_kernel_time_task, hinic5_kernel_sync_time_work);
+ /* 注册延时任务, 并初始化为disable */
+ INIT_DELAYED_WORK(&hwdev->sync_kernel_time_task,
+ hinic5_kernel_sync_time_work);
hinic5_set_non_ptp_time_diff_en(hwdev, false);
}
if (!COMM_SUPPORT_HTN_CMD(hwdev)) {
err = hinic5_comm_micro_log_init(hwdev);
- if (err != 0)
+ if (err != 0) {
sdk_warn(hwdev->dev_hdl, "Failed to init micro log\n");
+ }
}
return 0;
@@ -1909,12 +1222,14 @@ STATIC void hinic5_hwdev_init_timeout(struct hinic5_hwdev *hwdev, u8 hw_type)
u8 temp_hw_type = hw_type;
if (temp_hw_type > HINIC5_HW_TYPE_EDA) {
- sdk_warn(hwdev->dev_hdl, "No available timeout info for type(%d), use default type(%d)\n",
- temp_hw_type, HINIC5_HW_TYPE_FPGA);
+ sdk_warn(
+ hwdev->dev_hdl,
+ "No available timeout info for type(%d), use default type(%d)\n",
+ temp_hw_type, HINIC5_HW_TYPE_FPGA);
temp_hw_type = HINIC5_HW_TYPE_FPGA;
}
- hwdev->timeout_info = &g_sdk_timeout_info[temp_hw_type];
+ hwdev->timeout_info = &(g_sdk_timeout_info[temp_hw_type]);
}
static int init_hwdev(struct hinic5_init_para *para)
@@ -1942,7 +1257,8 @@ static int init_hwdev(struct hinic5_init_para *para)
goto alloc_chip_fault_stats_err;
hwdev->stateful_ref_cnt = 0;
- memset(hwdev->features, 0, sizeof(hwdev->features));
+ (void)memset_s(hwdev->features, sizeof(hwdev->features), 0,
+ sizeof(hwdev->features));
hinic5_hwdev_init_timeout(hwdev, HINIC5_HW_TYPE_ASIC);
@@ -1954,7 +1270,7 @@ static int init_hwdev(struct hinic5_init_para *para)
alloc_chip_fault_stats_err:
kfree(hwdev);
*para->hwdev = NULL;
- return -EFAULT;
+ return -EFAULT;
}
static void deinit_hwdev(struct hinic5_hwdev *hwdev)
@@ -1968,11 +1284,12 @@ static void deinit_hwdev(struct hinic5_hwdev *hwdev)
static inline void hinic5_init_max_aeq_busy_cnt(struct hinic5_hwdev *hwdev)
{
- hwdev->max_aeq_busy_cnt = hwdev->timeout_info->mbox_timeout / MSEC_PER_SEC;
+ hwdev->max_aeq_busy_cnt =
+ hwdev->timeout_info->mbox_timeout / MSEC_PER_SEC;
}
-#define HINIC5_HEARTBEAT_PERIOD 1000
-#define DETECT_PCIE_LINK_DOWN_RETRY 2
+#define HINIC5_HEARTBEAT_PERIOD 1000
+#define DETECT_PCIE_LINK_DOWN_RETRY 2
int hinic5_init_hwdev(struct hinic5_init_para *para)
{
@@ -1986,8 +1303,9 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
hwdev = *para->hwdev;
- err = hinic5_init_hwif(hwdev, para->fers2_reg_base, para->cfg_reg_base, para->intr_reg_base,
- para->mgmt_reg_base, para->db_base_phy, para->db_base,
+ err = hinic5_init_hwif(hwdev, para->fers2_reg_base, para->cfg_reg_base,
+ para->intr_reg_base, para->mgmt_reg_base,
+ para->db_base_phy, para->db_base,
para->db_dwqe_len);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init hwif\n");
@@ -2006,25 +1324,28 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
goto init_prof_adapter_err;
}
- hwdev->workq = alloc_workqueue(HINIC5_HWDEV_WQ_NAME, WQ_MEM_RECLAIM, HINIC5_WQ_MAX_REQ);
+ hwdev->workq = alloc_workqueue(HINIC5_HWDEV_WQ_NAME, WQ_MEM_RECLAIM,
+ HINIC5_WQ_MAX_REQ);
if (!hwdev->workq) {
sdk_err(hwdev->dev_hdl, "Failed to alloc hardware workq\n");
goto alloc_workq_err;
}
- (void)hinic5_set_heartbeat_period_and_linkdown_cnt((void *)hwdev, HINIC5_HEARTBEAT_PERIOD,
- DETECT_PCIE_LINK_DOWN_RETRY);
+ (void)hinic5_set_heartbeat_period_and_linkdown_cnt(
+ (void *)hwdev, HINIC5_HEARTBEAT_PERIOD,
+ DETECT_PCIE_LINK_DOWN_RETRY);
hinic5_init_heartbeat_detect(hwdev);
- err = hinic5_init_cfg_mgmt(hwdev);
+ err = init_cfg_mgmt(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init config mgmt\n");
- goto hinic5_init_cfg_mgmt_err;
+ goto init_cfg_mgmt_err;
}
err = hinic5_init_comm_ch(hwdev);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to init communication channel\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to init communication channel\n");
goto init_comm_ch_err;
}
@@ -2036,7 +1357,7 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
}
#endif
- err = hinic5_init_capability(hwdev);
+ err = init_capability(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init capability\n");
goto init_cap_err;
@@ -2054,7 +1375,8 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
if (err != 0)
goto init_ppf_work_fail;
- err = hinic5_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
+ err = hinic5_set_comm_features(hwdev, hwdev->features,
+ COMM_MAX_FEATURE_QWORD);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to set comm features\n");
goto set_feature_err;
@@ -2069,7 +1391,7 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
hinic5_multi_host_enable(hwdev, false);
init_multi_host_fail:
- hinic5_free_capability(hwdev);
+ free_capability(hwdev);
init_cap_err:
#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS
@@ -2080,9 +1402,9 @@ int hinic5_init_hwdev(struct hinic5_init_para *para)
hinic5_uninit_comm_ch(hwdev);
init_comm_ch_err:
- hinic5_free_cfg_mgmt(hwdev);
+ free_cfg_mgmt(hwdev);
-hinic5_init_cfg_mgmt_err:
+init_cfg_mgmt_err:
hinic5_destroy_heartbeat_detect(hwdev);
destroy_workqueue(hwdev->workq);
@@ -2104,7 +1426,8 @@ void hinic5_free_hwdev(void *hwdev)
struct hinic5_hwdev *dev = hwdev;
u64 drv_features[COMM_MAX_FEATURE_QWORD];
- memset(drv_features, 0, sizeof(drv_features));
+ (void)memset_s(drv_features, sizeof(drv_features), 0,
+ sizeof(drv_features));
hinic5_set_comm_features(hwdev, drv_features, COMM_MAX_FEATURE_QWORD);
hinic5_free_ppf_work(dev);
@@ -2113,7 +1436,7 @@ void hinic5_free_hwdev(void *hwdev)
hinic5_func_rx_tx_flush(hwdev, HINIC5_CHANNEL_COMM, true, 0);
- hinic5_free_capability(dev);
+ free_capability(dev);
#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS
hinic5_uninit_devlink(dev);
@@ -2121,7 +1444,7 @@ void hinic5_free_hwdev(void *hwdev)
hinic5_uninit_comm_ch(dev);
- hinic5_free_cfg_mgmt(dev);
+ free_cfg_mgmt(dev);
hinic5_destroy_heartbeat_detect(hwdev);
destroy_workqueue(dev->workq);
@@ -2164,16 +1487,19 @@ void *hinic5_get_service_adapter(void *hwdev, enum hinic5_service_type type)
{
struct hinic5_hwdev *dev = hwdev;
- if (!hwdev || type < SERVICE_T_NIC || type >= SERVICE_T_MAX)
+ if (!hwdev || type < SERVICE_T_NIC || type >= SERVICE_T_MAX) {
return NULL;
+ }
return dev->service_adapter[type];
}
EXPORT_SYMBOL(hinic5_get_service_adapter);
-int hinic5_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats, const u32 *out_size)
+int hinic5_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats,
+ const u32 *out_size)
{
- struct hinic5_hw_stats *tmp_hw_stats = (struct hinic5_hw_stats *)hw_stats;
+ struct hinic5_hw_stats *tmp_hw_stats =
+ (struct hinic5_hw_stats *)hw_stats;
struct card_node *chip_node = NULL;
if (!hwdev)
@@ -2185,8 +1511,9 @@ int hinic5_dbg_get_hw_stats(const void *hwdev, u8 *hw_stats, const u32 *out_size
return -EFAULT;
}
- memcpy(hw_stats, &((struct hinic5_hwdev *)hwdev)->hw_stats,
- sizeof(struct hinic5_hw_stats));
+ (void)memcpy_s(hw_stats, sizeof(struct hinic5_hw_stats),
+ &((struct hinic5_hwdev *)hwdev)->hw_stats,
+ sizeof(struct hinic5_hw_stats));
chip_node = ((struct hinic5_hwdev *)hwdev)->chip_node;
@@ -2209,7 +1536,8 @@ static int check_cmdq_args(struct hinic5_hwdev *hwdev, u16 cmdq_id)
return 0;
}
-int hinic5_dump_cmdq_wq(struct hinic5_hwdev *hwdev, u16 cmdq_id, struct hinic5_wq *wq)
+int hinic5_dump_cmdq_wq(struct hinic5_hwdev *hwdev, u16 cmdq_id,
+ struct hinic5_wq *wq)
{
int err;
@@ -2220,7 +1548,13 @@ int hinic5_dump_cmdq_wq(struct hinic5_hwdev *hwdev, u16 cmdq_id, struct hinic5_w
if (unlikely(err != 0))
return err;
- memcpy(wq, &hwdev->cmdqs->cmdq[cmdq_id].wq, sizeof(struct hinic5_wq));
+ err = memcpy_s(wq, sizeof(struct hinic5_wq),
+ &(hwdev->cmdqs->cmdq[cmdq_id].wq),
+ sizeof(struct hinic5_wq));
+ if (unlikely(err != 0)) {
+ sdk_err(hwdev->dev_hdl, "memcpy_s failed, err %d\n", err);
+ return -EFAULT;
+ }
return 0;
}
@@ -2243,13 +1577,20 @@ int hinic5_dump_cmdq_wqebb(struct hinic5_hwdev *hwdev, u16 cmdq_id, u16 wqe_idx,
wq = &hwdev->cmdqs->cmdq[cmdq_id].wq;
wqebb_size = wq->wqebb_size;
if (unlikely(wqebb_size > sizeof(wqe_desc->data)))
- dev_warn_once(hwdev->dev_hdl, "WARN: out wqebb size too small\n");
+ dev_warn_once(hwdev->dev_hdl,
+ "WARN: out wqebb size too small\n");
wqe_idx_masked = WQ_MASK_IDX(wq, wqe_idx);
wqebb = hinic5_wq_wqebb_addr(wq, wqe_idx_masked);
- memset((void *)wqe_desc->data, 0, sizeof(wqe_desc->data));
- memcpy((void *)wqe_desc->data, wqebb, wqebb_size);
+ (void)memset_s((void *)wqe_desc->data, sizeof(wqe_desc->data), 0,
+ sizeof(wqe_desc->data));
+ err = memcpy_s((void *)wqe_desc->data, sizeof(wqe_desc->data), wqebb,
+ wqebb_size);
+ if (unlikely(err != 0)) {
+ sdk_err(hwdev->dev_hdl, "memcpy_s failed, err %d\n", err);
+ return -EFAULT;
+ }
wqe_desc->wqebb_size = wqebb_size;
return 0;
@@ -2260,16 +1601,20 @@ u16 hinic5_dbg_clear_hw_stats(void *hwdev)
struct card_node *chip_node = NULL;
struct hinic5_hwdev *dev = hwdev;
- memset((void *)&dev->hw_stats, 0, sizeof(struct hinic5_hw_stats));
- memset((void *)dev->chip_fault_stats, 0, HINIC5_CHIP_FAULT_SIZE);
+ (void)memset_s((void *)&dev->hw_stats, sizeof(struct hinic5_hw_stats),
+ 0, sizeof(struct hinic5_hw_stats));
+ (void)memset_s((void *)dev->chip_fault_stats, HINIC5_CHIP_FAULT_SIZE, 0,
+ HINIC5_CHIP_FAULT_SIZE);
chip_node = dev->chip_node;
- if (COMM_SUPPORT_CHANNEL_DETECT(dev) && (atomic_read(&chip_node->channel_busy_cnt) != 0)) {
+ if (COMM_SUPPORT_CHANNEL_DETECT(dev) &&
+ (atomic_read(&chip_node->channel_busy_cnt) != 0)) {
atomic_set(&chip_node->channel_busy_cnt, 0);
dev->aeq_busy_cnt = 0;
#if !defined(__UEFI__) && !defined(__VMWARE__) && !defined(__WIN__)
- queue_delayed_work(dev->workq, &dev->channel_detect_task,
- msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
+ queue_delayed_work(
+ dev->workq, &dev->channel_detect_task,
+ msecs_to_jiffies(HINIC5_CHANNEL_DETECT_PERIOD));
#endif
}
@@ -2279,6 +1624,7 @@ u16 hinic5_dbg_clear_hw_stats(void *hwdev)
void hinic5_get_chip_fault_stats(const void *hwdev, u8 *chip_fault_stats,
u32 offset)
{
+ int ret;
u32 chip_fault_len;
if (offset >= HINIC5_CHIP_FAULT_SIZE) {
@@ -2290,11 +1636,20 @@ void hinic5_get_chip_fault_stats(const void *hwdev, u8 *chip_fault_stats,
chip_fault_len = MAX_DRV_BUF_SIZE;
else
chip_fault_len = HINIC5_CHIP_FAULT_SIZE - offset;
- memcpy(chip_fault_stats,
- ((struct hinic5_hwdev *)hwdev)->chip_fault_stats + offset, chip_fault_len);
+ ret = memcpy_s(chip_fault_stats, MAX_DRV_BUF_SIZE,
+ ((struct hinic5_hwdev *)hwdev)->chip_fault_stats +
+ offset,
+ chip_fault_len);
+ if (ret != 0) {
+ pr_err("Memcpy to chip_fault_stats failed: errcode is %d, offset is %u, "
+ "chip_fault_len is %u\n",
+ ret, offset, chip_fault_len);
+ return;
+ }
}
-int hinic5_event_register(void *dev, void *pri_handle, hinic5_event_handler callback)
+int hinic5_event_register(void *dev, void *pri_handle,
+ hinic5_event_handler callback)
{
struct hinic5_hwdev *hwdev = dev;
@@ -2336,7 +1691,8 @@ void hinic5_event_callback(void *hwdev, struct hinic5_event_info *event)
}
if (!dev->event_callback) {
- sdk_info(dev->dev_hdl, "Event callback function not register\n");
+ sdk_info(dev->dev_hdl,
+ "Event callback function not register\n");
return;
}
@@ -2380,34 +1736,35 @@ bool hinic5_need_init_stateful_default(void *hwdev)
if (lowpower_mode != 0)
return true;
- /* Current virtio net have to init hinic5_cqm in PPF. */
+ /* Current virtio net have to init cqm in PPF. */
if ((hinic5_func_type(hwdev) == TYPE_PPF) &&
((chip_svc_type & CFG_SERVICE_MASK_VIRTIO) != 0)) {
- sdk_info(dev->dev_hdl, "sdk init ppf resource, chip_svc_type: 0x%x\n",
+ sdk_info(dev->dev_hdl,
+ "sdk init ppf resource, chip_svc_type: 0x%x\n",
chip_svc_type);
return true;
}
- /* vroce have to init hinic5_cqm */
+ /* vroce have to init cqm */
if (IS_MASTER_HOST(dev) && (hinic5_func_type(hwdev) != TYPE_PPF) &&
(((chip_svc_type & CFG_SERVICE_MASK_VROCE) != 0)))
return true;
- /* Other service type will init hinic5_cqm when uld call. */
+ /* Other service type will init cqm when uld call. */
return false;
}
static bool hinic5_ext_db_en(struct hinic5_hwdev *dev)
{
u32 stateful_en = IS_FT_TYPE(dev) | IS_RDMA_TYPE(dev);
-
return (((stateful_en != 0) || IS_RDMA_ENABLE(dev) ||
- IS_FT_ENABLE(dev)) && HINIC5_IS_PPF(dev));
+ IS_FT_ENABLE(dev)) &&
+ HINIC5_IS_PPF(dev));
}
static inline void stateful_uninit(struct hinic5_hwdev *hwdev)
{
- hinic5_cqm_uninit(hwdev);
+ cqm5_uninit(hwdev);
if (hinic5_ext_db_en(hwdev))
hinic5_ppf_ext_db_deinit(hwdev);
@@ -2440,10 +1797,10 @@ int hinic5_stateful_init(void *hwdev)
goto out;
}
- err = hinic5_cqm_init(dev);
+ err = cqm5_init(dev);
if (err != 0) {
- sdk_err(dev->dev_hdl, "Failed to init hinic5_cqm, err: %d\n", err);
- goto init_hinic5_cqm_err;
+ sdk_err(dev->dev_hdl, "Failed to init cqm, err: %d\n", err);
+ goto init_cqm_err;
}
mutex_unlock(&dev->stateful_mutex);
@@ -2451,7 +1808,7 @@ int hinic5_stateful_init(void *hwdev)
return 0;
-init_hinic5_cqm_err:
+init_cqm_err:
if (ext_db_en)
hinic5_ppf_ext_db_deinit(dev);
@@ -2487,12 +1844,16 @@ void hinic5_free_stateful(void *hwdev)
{
struct hinic5_hwdev *dev = hwdev;
- if (!dev || !hinic5_get_stateful_enable(dev) || dev->stateful_ref_cnt == 0)
+ if (!dev || !hinic5_get_stateful_enable(dev) ||
+ (dev->stateful_ref_cnt == 0))
return;
- if (!hinic5_need_init_stateful_default(hwdev) || dev->stateful_ref_cnt > 1)
- sdk_info(dev->dev_hdl, "Current stateful resource ref is incorrect, ref_cnt:%u\n",
- dev->stateful_ref_cnt);
+ if (!hinic5_need_init_stateful_default(hwdev) ||
+ dev->stateful_ref_cnt > 1)
+ sdk_info(
+ dev->dev_hdl,
+ "Current stateful resource ref is incorrect, ref_cnt:%u\n",
+ dev->stateful_ref_cnt);
stateful_uninit(hwdev);
@@ -2500,23 +1861,22 @@ void hinic5_free_stateful(void *hwdev)
}
#endif /* __VMWARE__ */
-int hinic5_hinic5_get_card_present_state(void *hwdev, bool *card_present_state)
+int hinic5_get_card_present_state(void *hwdev, bool *card_present_state)
{
struct hinic5_hwdev *dev = hwdev;
if (!hwdev || !card_present_state)
return -EINVAL;
- *card_present_state = hinic5_get_card_present_state(dev);
+ *card_present_state = get_card_present_state(dev);
return 0;
}
-EXPORT_SYMBOL(hinic5_hinic5_get_card_present_state);
+EXPORT_SYMBOL(hinic5_get_card_present_state);
void hinic5_link_event_stats(void *dev, u8 link)
{
struct hinic5_hwdev *hwdev = dev;
-
if (!hwdev) {
pr_err("hwdev is null\n");
return;
@@ -2532,11 +1892,12 @@ EXPORT_SYMBOL(hinic5_link_event_stats);
int hinic5_get_link_down_cnt(void *dev, int *link_down_cnt)
{
struct hinic5_hwdev *hwdev = dev;
-
- if (!hwdev || !link_down_cnt)
+ if (!hwdev || !link_down_cnt) {
return -EINVAL;
+ }
- *link_down_cnt = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+ *link_down_cnt =
+ hwdev->hw_stats.link_event_stats.link_down_stats.counter;
return 0;
}
@@ -2556,8 +1917,8 @@ void hinic5_fault_event_report(void *hwdev, u16 src, u16 level)
if (!hwdev)
return;
- sdk_info(((struct hinic5_hwdev *)hwdev)->dev_hdl, "Fault event report, src: %u, level: %u\n",
- src, level);
+ sdk_info(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "Fault event report, src: %u, level: %u\n", src, level);
hisdk5_fault_post_process(hwdev, src, level);
}
@@ -2578,12 +1939,14 @@ static void hinic5_update_channel_status(struct hinic5_hwdev *hwdev)
if (!chip_node)
return;
- if ((hinic5_func_type(hwdev) != TYPE_PPF) || !COMM_SUPPORT_CHANNEL_DETECT(hwdev) ||
+ if ((hinic5_func_type(hwdev) != TYPE_PPF) ||
+ !COMM_SUPPORT_CHANNEL_DETECT(hwdev) ||
hinic5_channel_detect_should_stop(hwdev))
return;
- if (test_bit(HINIC5_HWDEV_MBOX_INITED, &hwdev->func_state) == 0)
+ if (test_bit(HINIC5_HWDEV_MBOX_INITED, &hwdev->func_state) == 0) {
return;
+ }
if (hwdev->last_recv_aeq_cnt != hwdev->cur_recv_aeq_cnt) {
hwdev->aeq_busy_cnt = 0;
@@ -2603,17 +1966,17 @@ static void hinic5_update_channel_status(struct hinic5_hwdev *hwdev)
static void hinic5_heartbeat_lost_handler(struct work_struct *work)
{
struct hinic5_event_info event_info = { 0 };
- struct hinic5_hwdev *hwdev = container_of(work, struct hinic5_hwdev,
- heartbeat_lost_work);
+ struct hinic5_hwdev *hwdev =
+ container_of(work, struct hinic5_hwdev, heartbeat_lost_work);
u16 src, level;
atomic_inc(&hwdev->hw_stats.heart_lost_stats);
if (hwdev->event_callback) {
event_info.service = EVENT_SRV_COMM;
- event_info.type =
- (atomic_read(&hwdev->bus_link_down) != 0) ? EVENT_COMM_PCIE_LINK_DOWN :
- EVENT_COMM_HEART_LOST;
+ event_info.type = (atomic_read(&hwdev->bus_link_down) != 0) ?
+ EVENT_COMM_PCIE_LINK_DOWN :
+ EVENT_COMM_HEART_LOST;
hwdev->event_callback(hwdev->event_pri_handle, &event_info);
}
@@ -2624,7 +1987,8 @@ static void hinic5_heartbeat_lost_handler(struct work_struct *work)
} else {
src = HINIC5_FAULT_SRC_HOST_HEARTBEAT_LOST;
level = FAULT_LEVEL_FATAL;
- sdk_err(hwdev->dev_hdl, "Heart lost report received, func_id: %u\n",
+ sdk_err(hwdev->dev_hdl,
+ "Heart lost report received, func_id: %hu\n",
hinic5_global_func_id(hwdev));
}
@@ -2633,9 +1997,9 @@ static void hinic5_heartbeat_lost_handler(struct work_struct *work)
hisdk5_fault_post_process(hwdev, src, level);
}
-#define HINIC5_HEARTBEAT_START_EXPIRE 5000
+#define HINIC5_HEARTBEAT_START_EXPIRE 5000
-/* Check if the current function is in available state */
+/* 判断当前function是否处于可用状态 */
bool hinic5_is_function_active(struct hinic5_hwdev *hwdev)
{
return (atomic_read(&hwdev->bus_link_down) == 0 &&
@@ -2655,7 +2019,8 @@ static bool hinic5_is_hw_abnormal(struct hinic5_hwdev *hwdev)
sdk_warn(hwdev->dev_hdl, "Detect BAR register read failed\n");
hwdev->rd_bar_err_cnt++;
if (hwdev->rd_bar_err_cnt >= hwdev->linkdown_threshold) {
- sdk_err(hwdev->dev_hdl, "Set card absent due to bus link down\n");
+ sdk_err(hwdev->dev_hdl,
+ "Set card absent due to bus link down\n");
hinic5_set_chip_absent(hwdev);
hinic5_force_complete_all(hwdev);
atomic_set(&hwdev->bus_link_down, true);
@@ -2668,7 +2033,8 @@ static bool hinic5_is_hw_abnormal(struct hinic5_hwdev *hwdev)
if (status != 0) {
atomic_set(&hwdev->heartbeat_lost, true);
chip_info->exception_flag = true;
- sdk_err(hwdev->dev_hdl, "Set card error due to heartbeat lost\n");
+ sdk_err(hwdev->dev_hdl,
+ "Set card error due to heartbeat lost\n");
return true;
}
@@ -2677,24 +2043,26 @@ static bool hinic5_is_hw_abnormal(struct hinic5_hwdev *hwdev)
return false;
}
-int hinic5_set_heartbeat_period_and_linkdown_cnt(void *hwdev, u32 heartbeat_period,
+int hinic5_set_heartbeat_period_and_linkdown_cnt(void *hwdev,
+ u32 heartbeat_period,
u32 linkdown_threshold)
{
struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
-
- if (!hwdev) {
+ if (hwdev == NULL) {
pr_err("Hwdev is NULL\n");
return -EINVAL;
}
- if (heartbeat_period == 0 && linkdown_threshold == 0) {
- sdk_err(dev->dev_hdl, "heartbeat_period and linkdown_threshold is 0\n");
+ if ((heartbeat_period == 0) && (linkdown_threshold == 0)) {
+ sdk_err(dev->dev_hdl,
+ "heartbeat_period and linkdown_threshold is 0\n");
return -EINVAL;
}
if (heartbeat_period != 0) {
dev->heartbeat_period = heartbeat_period;
- sdk_info(dev->dev_hdl, "heartbeat_period modify to %d\n", dev->heartbeat_period);
+ sdk_info(dev->dev_hdl, "heartbeat_period modify to %d\n",
+ dev->heartbeat_period);
}
if (linkdown_threshold != 0) {
@@ -2720,7 +2088,7 @@ static void hinic5_heartbeat_timer_handler(ulong data)
#endif
if (hinic5_is_hw_abnormal(hwdev)) {
- hinic5_stop_timer(&hwdev->heartbeat_timer);
+ stop_timer(&hwdev->heartbeat_timer);
queue_work(hwdev->workq, &hwdev->heartbeat_lost_work);
} else {
mod_timer(&hwdev->heartbeat_timer,
@@ -2745,14 +2113,14 @@ static void hinic5_init_heartbeat_detect(struct hinic5_hwdev *hwdev)
INIT_WORK(&hwdev->heartbeat_lost_work, hinic5_heartbeat_lost_handler);
- hinic5_add_to_timer(&hwdev->heartbeat_timer, hwdev->heartbeat_period);
+ add_to_timer(&hwdev->heartbeat_timer, hwdev->heartbeat_period);
}
static void hinic5_destroy_heartbeat_detect(struct hinic5_hwdev *hwdev)
{
destroy_work(&hwdev->heartbeat_lost_work);
- hinic5_stop_timer(&hwdev->heartbeat_timer);
- hinic5_delete_timer(&hwdev->heartbeat_timer);
+ stop_timer(&hwdev->heartbeat_timer);
+ delete_timer(&hwdev->heartbeat_timer);
}
void hinic5_set_api_stop(void *hwdev)
@@ -2765,10 +2133,54 @@ void hinic5_set_api_stop(void *hwdev)
sdk_info(dev->dev_hdl, "Set card absent\n");
hinic5_set_chip_absent(dev);
hinic5_force_complete_all(dev);
- sdk_info(dev->dev_hdl, "All messages interacting with the chip will stop\n");
+ sdk_info(dev->dev_hdl,
+ "All messages interacting with the chip will stop\n");
}
bool hinic5_get_perf_en(enum hinic5_perf_bitmap perf_bit)
{
return test_bit(perf_bit, (void *)&perf_en_bitmap);
}
+
+struct device *hinic5_get_device(void *hwdev)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (unlikely(!dev))
+ return NULL;
+
+ return dev->dev_hdl;
+}
+
+int hinic5_get_bus_type(void *hwdev, enum hinic5_dev_type *type)
+{
+ struct hinic5_hwdev *dev = hwdev;
+
+ if (unlikely(!dev || !type))
+ return -EINVAL;
+
+#if defined(__LINUX__)
+ if (unlikely(!dev->adapter_hdl))
+ return -EAGAIN;
+ *type = hinic5_adev_get_bus_type(dev->adapter_hdl);
+#else
+ *type = HINIC5_DEVICE_T_PCI;
+#endif
+
+ return 0;
+}
+
+int hinic5_get_chip_node_id_by_hwdev(void *hwdev, u64 *chip_node_id)
+{
+ struct hinic5_hwdev *dev = hwdev;
+ struct card_node *chip_node = NULL;
+
+ if (unlikely(!dev || !(dev->chip_node) || !chip_node_id))
+ return -EINVAL;
+
+ chip_node = dev->chip_node;
+ *chip_node_id = chip_node->id;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic5_get_chip_node_id_by_hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.c
index 152e67066..7d9f0763d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_prof_adap.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [PROF]" fmt
@@ -19,8 +12,8 @@
#include "hinic5_profile.h"
#include "hinic5_prof_adap.h"
-__weak
-const struct hinic5_prof_adapter *hinic5_get_prof_adapter(void *hwdev)
+__attribute__((weak)) const struct hinic5_prof_adapter *
+hinic5_get_prof_adapter(void *hwdev)
{
return NULL;
}
@@ -34,7 +27,8 @@ int hisdk5_init_profile_adapter(struct hinic5_hwdev *hwdev)
sdk_info(hwdev->dev_hdl, "No profile adapter\n");
return 0;
}
- sdk_info(hwdev->dev_hdl, "Find profile adapter type: %d\n", adapter->type);
+ sdk_info(hwdev->dev_hdl, "Find profile adapter type: %d\n",
+ adapter->type);
if (!hinic5_verify_prof_adapter(adapter)) {
sdk_err(hwdev->dev_hdl, "Invalid profile adapter\n");
@@ -64,7 +58,7 @@ struct hinic5_prof_attr *hinic5_get_prof_attr(void *hwdev)
{
struct hinic5_hwdev *dev = (struct hinic5_hwdev *)hwdev;
- if (!hwdev) {
+ if (hwdev == NULL) {
pr_err("hwdev is NULL\n");
return NULL;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.h
index a920f581e..0ea31e19a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/crm/hinic5_prof_adap.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_prof_adap.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_PROF_ADAP_H
#define HINIC5_PROF_ADAP_H
@@ -28,8 +21,8 @@ enum hisdk5_sw_features {
HISDK5_SW_F_CHANNEL_LOCK = BIT(0),
};
-#define GET_PROF_ATTR_OPS(hwdev) \
- ((hwdev)->prof_attr ? (hwdev)->prof_attr->ops : NULL)
+#define GET_PROF_ATTR_OPS(hwdev) \
+ ((hwdev)->prof_attr ? (hwdev)->prof_attr->ops : NULL)
static inline int hisdk5_get_work_cpu_affinity(struct hinic5_hwdev *hwdev,
enum cpu_affinity_work_type type)
@@ -37,7 +30,8 @@ static inline int hisdk5_get_work_cpu_affinity(struct hinic5_hwdev *hwdev,
struct hinic5_prof_ops *ops = GET_PROF_ATTR_OPS(hwdev);
if (ops && ops->get_work_cpu_affinity)
- return ops->get_work_cpu_affinity(hwdev->prof_attr->priv_data, type);
+ return ops->get_work_cpu_affinity(hwdev->prof_attr->priv_data,
+ type);
return WORK_CPU_UNBOUND;
}
@@ -66,7 +60,7 @@ static inline bool hisdk5_sw_feature_en(const struct hinic5_hwdev *hwdev,
return false;
return ((hwdev->prof_attr->sw_feature_cap & feature_bit) != 0) &&
- ((hwdev->prof_attr->dft_sw_feature & feature_bit) != 0);
+ ((hwdev->prof_attr->dft_sw_feature & feature_bit) != 0);
}
#ifdef CONFIG_MODULE_PROF
@@ -83,14 +77,14 @@ static inline void hisdk5_remove_pre_process(struct hinic5_hwdev *hwdev)
ops->remove_pre_handle(hwdev);
}
#else
-static inline void hisdk5_remove_pre_process(struct hinic5_hwdev *hwdev) {};
+static inline void hisdk5_remove_pre_process(struct hinic5_hwdev *hwdev){};
#endif
-#define SW_FEATURE_EN(hwdev, f_bit) \
- hisdk5_sw_feature_en(hwdev, HISDK5_SW_F_##f_bit)
-#define HISDK5_F_CHANNEL_LOCK_EN(hwdev) SW_FEATURE_EN(hwdev, CHANNEL_LOCK)
+#define SW_FEATURE_EN(hwdev, f_bit) \
+ hisdk5_sw_feature_en(hwdev, HISDK5_SW_F_##f_bit)
+#define HISDK5_F_CHANNEL_LOCK_EN(hwdev) SW_FEATURE_EN(hwdev, CHANNEL_LOCK)
-int hisdk5_init_profile_adapter(struct hinic5_hwdev *hwdev);
+int hisdk5_init_profile_adapter(struct hinic5_hwdev *hwdev);
void hisdk5_deinit_profile_adapter(struct hinic5_hwdev *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.c
deleted file mode 100644
index f23eec90c..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_182x_cmdq_ops.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include "ossl_knl.h"
-#include "hinic5_hinic5_cqm.h"
-#include "hinic5_cqm_npu_cmd.h"
-#include "hinic5_cqm_cmdq.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-#include "hinic5_cqm_182x_cmdq_ops.h"
-
-static s32 prepare_cmd_buf_bat_update(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_bat_update_param *param,
- u8 *cmd)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_cqm_182x_bat_update_cmd *cmd_data = buf_in->buf;
- u8 *bat = NULL;
-
- cmd_data->offset = param->bat_offset / HINIC5_CQM_BAT_ENTRY_SIZE;
- cmd_data->byte_len = param->update_size;
- cmd_data->smf_id = param->smf_id;
- cmd_data->func_id = param->func_id;
-
- bat = bat_table->bat + param->bat_offset;
- memcpy(cmd_data->data, bat, param->update_size);
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- sizeof(struct hinic5_cqm_182x_bat_update_cmd) >> HINIC5_CQM_DW_SHIFT);
- *cmd = (u8)HINIC5_CQM_CMD_T_BAT_UPDATE;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void prepare_cmd_buf_cla_update(hinic5_cqm_cla_update_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u8 *cmd)
-{
- struct hinic5_cqm_182x_cla_update_cmd *cmd_data = buf_in->buf;
-
- cmd_data->gpa_h = cmd_info->gpa_h;
- cmd_data->gpa_l = cmd_info->gpa_l;
- cmd_data->value_h = cmd_info->value_h;
- cmd_data->value_l = cmd_info->value_l;
- cmd_data->smf_id = cmd_info->smf_id;
- cmd_data->func_id = cmd_info->func_id;
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- (sizeof(struct hinic5_cqm_182x_cla_update_cmd) >> HINIC5_CQM_DW_SHIFT));
- *cmd = (u8)HINIC5_CQM_CMD_T_CLA_UPDATE;
-}
-
-static void prepare_cmd_cache_invalidate(hinic5_cqm_cla_cache_invalid_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u8 *cmd)
-{
- struct hinic5_cqm_182x_cla_cache_invalid_cmd *cmd_data = buf_in->buf;
-
- cmd_data->gpa_h = cmd_info->gpa_h;
- cmd_data->gpa_l = cmd_info->gpa_l;
- cmd_data->cache_size = cmd_info->cache_size;
- cmd_data->smf_id = cmd_info->smf_id;
- cmd_data->func_id = cmd_info->func_id;
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- /* shift 2 bits by right to get length of dw(4B) */
- (sizeof(struct hinic5_cqm_182x_cla_cache_invalid_cmd) >> HINIC5_CQM_DW_SHIFT));
- *cmd = (u8)HINIC5_CQM_CMD_T_CLA_CACHE_INVALID;
-}
-
-struct hinic5_cqm_cmdq_ops *hinic5_cqm_cmdq_get_182x_ops(void)
-{
- static struct hinic5_cqm_cmdq_ops cmdq_182x_ops = {
- .prepare_cmd_buf_bat_update = prepare_cmd_buf_bat_update,
- .prepare_cmd_buf_cla_update = prepare_cmd_buf_cla_update,
- .prepare_cmd_cache_invalidate = prepare_cmd_cache_invalidate,
- };
-
- return &cmdq_182x_ops;
-};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.h
deleted file mode 100644
index e98b2c9ca..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_182x_cmdq_ops.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef _HINIC5_CQM_182X_CMDQ_PRIVATE_H_
-#define _HINIC5_CQM_182X_CMDQ_PRIVATE_H_
-
-#include "ossl_knl.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-
-struct hinic5_cqm_182x_bat_update_cmd {
- u32 offset; /* byte offset,16Byte aligned */
- u32 byte_len; /* max size: 256byte */
- u8 data[HINIC5_CQM_BAT_MAX_SIZE];
- u32 smf_id;
- u32 func_id;
-};
-
-struct hinic5_cqm_182x_cla_update_cmd {
- /* Gpa address to be updated */
- u32 gpa_h; /* byte addr */
- u32 gpa_l; /* byte addr */
-
- /* Updated Value */
- u32 value_h;
- u32 value_l;
-
- u32 smf_id;
- u32 func_id;
-};
-
-struct hinic5_cqm_182x_cla_cache_invalid_cmd {
- u32 gpa_h;
- u32 gpa_l;
-
- u32 cache_size; /* CLA cache size=4096B */
-
- u32 smf_id;
- u32 func_id;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.c
deleted file mode 100644
index 8d23f2e52..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_187x_cmdq_ops.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include "ossl_knl.h"
-#include "hinic5_hinic5_cqm.h"
-#include "hinic5_cqm_cmdq.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-#include "hinic5_cqm_187x_cmdq_ops.h"
-
-static s32 prepare_cmd_buf_bat_update(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_bat_update_param *param,
- u8 *cmd)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_cqm_187x_bat_update_cmd *cmd_data = buf_in->buf;
- u8 *bat = NULL;
-
- cmd_data->offset = param->bat_offset / HINIC5_CQM_BAT_ENTRY_SIZE;
- cmd_data->byte_len = param->update_size;
- cmd_data->smf_id = param->smf_id;
- cmd_data->func_id = (u16)param->func_id;
-
- bat = bat_table->bat + param->bat_offset;
- memcpy(cmd_data->data, bat, param->update_size);
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- sizeof(struct hinic5_cqm_187x_bat_update_cmd) >> HINIC5_CQM_DW_SHIFT);
- *cmd = (u8)HINIC5_CQM_HTN_CMD_T_BAT_UPDATE;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void prepare_cmd_buf_cla_update(hinic5_cqm_cla_update_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u8 *cmd)
-{
- struct hinic5_cqm_187x_cla_update_cmd *cmd_data = buf_in->buf;
-
- cmd_data->gpa_h = cmd_info->gpa_h;
- cmd_data->gpa_l = cmd_info->gpa_l;
- cmd_data->value_h = cmd_info->value_h;
- cmd_data->value_l = cmd_info->value_l;
- cmd_data->smf_id = cmd_info->smf_id;
- cmd_data->func_id = (u16)cmd_info->func_id;
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- (sizeof(struct hinic5_cqm_187x_cla_update_cmd) >> HINIC5_CQM_DW_SHIFT));
- *cmd = (u8)HINIC5_CQM_HTN_CMD_T_CLA_UPDATE;
-}
-
-static void prepare_cmd_cache_invalidate(hinic5_cqm_cla_cache_invalid_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u8 *cmd)
-{
- struct hinic5_cqm_187x_cla_cache_invalid_cmd *cmd_data = buf_in->buf;
-
- cmd_data->gpa_h = cmd_info->gpa_h;
- cmd_data->gpa_l = cmd_info->gpa_l;
- cmd_data->cache_size = cmd_info->cache_size;
- cmd_data->smf_id = cmd_info->smf_id;
- cmd_data->func_id = (u16)cmd_info->func_id;
-
- hinic5_cqm_swab32((u8 *)cmd_data,
- /* shift 2 bits by right to get length of dw(4B) */
- (sizeof(struct hinic5_cqm_187x_cla_cache_invalid_cmd) >> 2));
- *cmd = (u8)HINIC5_CQM_HTN_CMD_T_CLA_CACHE_INVALID;
-}
-
-struct hinic5_cqm_cmdq_ops *hinic5_cqm_cmdq_get_187x_ops(void)
-{
- static struct hinic5_cqm_cmdq_ops cmdq_187x_ops = {
- .prepare_cmd_buf_bat_update = prepare_cmd_buf_bat_update,
- .prepare_cmd_buf_cla_update = prepare_cmd_buf_cla_update,
- .prepare_cmd_cache_invalidate = prepare_cmd_cache_invalidate,
- };
-
- return &cmdq_187x_ops;
-};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.h
deleted file mode 100644
index f61144b21..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_187x_cmdq_ops.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef _HINIC5_CQM_187X_CMDQ_PRIVATE_H_
-#define _HINIC5_CQM_187X_CMDQ_PRIVATE_H_
-
-#include "ossl_knl.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-
-struct hinic5_cqm_187x_bat_update_cmd {
- u32 rsv[2];
- u32 smf_id : 4; /* set as 0xffff, HTN_CMDQ use func_id in metadata */
- u32 byte_len : 10; /* max size: 256byte, min size: 16byte, 16Byte aligned */
- u32 offset : 18; /* byte offset, 16Byte aligned */
- u16 rsv1;
- u16 func_id;
- u8 data[HINIC5_CQM_BAT_MAX_SIZE];
-};
-
-struct hinic5_cqm_187x_cla_update_cmd {
- u32 rsv[2];
- u32 smf_id : 4;
- u32 rsv1 : 28;
- u16 rsv2;
- u16 func_id; /* set as 0xffff, HTN_CMDQ use func_id in metadata */
-
- /* Gpa address to be updated */
- u32 gpa_h; /* byte addr */
- u32 gpa_l;
-
- /* Updated Value */
- u32 value_h;
- u32 value_l;
-};
-
-struct hinic5_cqm_187x_cla_cache_invalid_cmd {
- u32 gpa_h;
- u32 gpa_l;
-
- u32 smf_id : 4;
- u32 cache_size : 19; /* CLA cache size=4096B */
- u32 rsv : 9;
- u16 rsv2;
- u16 func_id; /* set as 0xffff, HTN_CMDQ use func_id in metadata */
-};
-
-/* HINIC5_CQM HTN CMD */
-enum hinic5_cqm_htn_cmd {
- HINIC5_CQM_HTN_CMD_T_CLA_CACHE_INVALID = 0x20,
- HINIC5_CQM_HTN_CMD_T_BAT_UPDATE,
- HINIC5_CQM_HTN_CMD_T_CLA_UPDATE
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.c
deleted file mode 100644
index fbc7b7fee..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.c
+++ /dev/null
@@ -1,2864 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bat_cla.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/gfp.h>
-
-#ifdef __LINUX__
-#include <linux/mmzone.h>
-#endif
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
-#include "hinic5_hw_comm.h"
-#include "hinic5_hw_cfg.h"
-#include "hinic5_hinic5_vram_api.h"
-#include "hinic5_typedef_inner.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_cmd.h"
-#include "hinic5_cqm_object_intern.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_bat_cla.h"
-
-#include "comm_defs.h"
-#include "hinic5_cqm_npu_cmd.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-#include "hinic5_cqm_cmdq.h"
-
-#include "hinic5_vram_common.h"
-
-static unsigned char hinic5_cqm_ver = 8;
-module_param(hinic5_cqm_ver, byte, 0444);
-MODULE_PARM_DESC(hinic5_cqm_ver, "for hinic5_cqm version control (default=8)");
-
-static bool hinic5_cqm_cla_hugepage_hint;
-module_param(hinic5_cqm_cla_hugepage_hint, bool, 0444);
-MODULE_PARM_DESC(hinic5_cqm_cla_hugepage_hint,
- "Hint for hugepage alloc to improve TLB locality (default false). " \
- "This option only impacts QPC and Timer Spoke Lists.");
-
-#ifdef __HINIC5_CQM_DEBUG__
-bool hinic5_cqm_verbose;
-module_param(hinic5_cqm_verbose, bool, 0644);
-#endif
-
-bool secure_mem_en = true;
-
-static inline u32 get_cacheline_size(u32 entry_type)
-{
- /* The cacheline of the timer is changed to 512. */
- if (entry_type == HINIC5_CQM_BAT_ENTRY_T_TIMER && hinic5_cqm_ver == 0x8)
- return HINIC5_CQM_CHIP_TIMER_CACHELINE;
-
- return HINIC5_CQM_CHIP_CACHELINE;
-}
-
-static void hinic5_cqm_bat_fill_cla_common_gpa(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_bat_entry_standerd *bat_entry_standerd)
-{
- u8 gpa_check_enable = hinic5_cqm_handle->func_capability.gpa_check_enable;
- struct hinic5_func_attr *func_attr = NULL;
- struct tag_hinic5_cqm_bat_entry_vf2pf gpa = {0};
- u32 cla_gpa_h = 0;
- dma_addr_t pa;
-
- if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_0)
- pa = cla_table->cla_z_buf.buf_list[0].pa;
- else if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_1)
- pa = cla_table->cla_y_buf.buf_list[0].pa;
- else
- pa = cla_table->cla_x_buf.buf_list[0].pa;
-
- gpa.cla_gpa_h = HINIC5_CQM_ADDR_HI(pa) & HINIC5_CQM_CHIP_GPA_HIMASK;
- gpa.acs_spu_en = hinic5_cqm_get_acs_spu_en(hinic5_cqm_handle);
-
- /* In fake mode, fake_vf_en in the GPA address of the BAT
- * must be set to 1.
- */
- if (HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle)) {
- gpa.fake_vf_en = 1;
- func_attr = &hinic5_cqm_handle->parent_hinic5_cqm_handle->func_attribute;
- gpa.pf_id = func_attr->func_global_idx;
- } else {
- gpa.fake_vf_en = 0;
- }
-
- memcpy(&cla_gpa_h, &gpa, sizeof(u32));
- bat_entry_standerd->cla_gpa_h = cla_gpa_h;
-
- /* GPA is valid when gpa[0] = 1.
- * HINIC5_CQM_BAT_ENTRY_T_REORDER does not support GPA validity check.
- */
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_REORDER)
- bat_entry_standerd->cla_gpa_l = HINIC5_CQM_ADDR_LW(pa);
- else
- bat_entry_standerd->cla_gpa_l = HINIC5_CQM_ADDR_LW(pa) |
- gpa_check_enable;
-
- hinic5_cqm_info(hinic5_cqm_handle->dev, "Bat fill: cla_type %u, pa 0x%llx, gpa 0x%x-0x%x, level %u\n",
- cla_table->type, pa, bat_entry_standerd->cla_gpa_h, bat_entry_standerd->cla_gpa_l,
- bat_entry_standerd->cla_level);
-}
-
-static void hinic5_cqm_bat_fill_cla_common(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u8 *entry_base_addr)
-{
- struct tag_hinic5_cqm_bat_entry_standerd *bat_entry_standerd = NULL;
- u32 cache_line = get_cacheline_size(cla_table->type);
-
- if (cla_table->obj_num == 0) {
- hinic5_cqm_dbg(hinic5_cqm_handle->dev,
- "Bat fill: cla_type %u, obj_num=0, don't init bat entry\n",
- cla_table->type);
- return;
- }
-
- bat_entry_standerd = (struct tag_hinic5_cqm_bat_entry_standerd *)entry_base_addr;
-
- /* The QPC value is 256/512/1024 and the timer value is 512.
- * The other cacheline value is 256B.
- * The conversion operation is performed inside the chip.
- */
- if (cla_table->obj_size > cache_line) {
- if (cla_table->obj_size == HINIC5_CQM_OBJECT_512)
- bat_entry_standerd->entry_size = HINIC5_CQM_BAT_ENTRY_SIZE_512;
- else
- bat_entry_standerd->entry_size =
- HINIC5_CQM_BAT_ENTRY_SIZE_1024;
- bat_entry_standerd->max_number = cla_table->max_buffer_size /
- cla_table->obj_size;
- } else {
- if (cache_line == HINIC5_CQM_CHIP_CACHELINE) {
- bat_entry_standerd->entry_size = HINIC5_CQM_BAT_ENTRY_SIZE_256;
- bat_entry_standerd->max_number =
- cla_table->max_buffer_size / cache_line;
- } else {
- bat_entry_standerd->entry_size = HINIC5_CQM_BAT_ENTRY_SIZE_512;
- bat_entry_standerd->max_number =
- cla_table->max_buffer_size / cache_line;
- }
- }
-
- bat_entry_standerd->max_number = bat_entry_standerd->max_number - 1;
-
- bat_entry_standerd->bypass = HINIC5_CQM_BAT_NO_BYPASS_CACHE;
- bat_entry_standerd->z = cla_table->cacheline_z;
- bat_entry_standerd->y = cla_table->cacheline_y;
- bat_entry_standerd->x = cla_table->cacheline_x;
- bat_entry_standerd->cla_level = cla_table->cla_lvl;
-
- hinic5_cqm_bat_fill_cla_common_gpa(hinic5_cqm_handle, cla_table, bat_entry_standerd);
-}
-
-static void hinic5_cqm_bat_fill_cla_cfg(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_bat_entry_cfg *bat_entry_cfg = NULL;
-
- bat_entry_cfg = (struct tag_hinic5_cqm_bat_entry_cfg *)(*entry_base_addr);
- bat_entry_cfg->cur_conn_cache = 0;
- bat_entry_cfg->max_conn_cache =
- func_cap->flow_table_based_conn_cache_number;
- bat_entry_cfg->cur_conn_num_h_4 = 0;
- bat_entry_cfg->cur_conn_num_l_16 = 0;
- bat_entry_cfg->max_conn_num = func_cap->flow_table_based_conn_number;
-
- /* Aligns with 64 buckets and shifts rightward by 6 bits.
- * The maximum value of this field is 16 bits. A maximum of 4M buckets
- * can be supported. The value is subtracted by 1. It is used for &hash
- * value.
- */
- if ((func_cap->hash_number >> HINIC5_CQM_HASH_NUMBER_UNIT) != 0) {
- bat_entry_cfg->bucket_num = ((func_cap->hash_number >>
- HINIC5_CQM_HASH_NUMBER_UNIT) - 1);
- }
- if (func_cap->bloomfilter_length != 0) {
- bat_entry_cfg->bloom_filter_len = func_cap->bloomfilter_length -
- 1;
- bat_entry_cfg->bloom_filter_addr = func_cap->bloomfilter_addr;
- }
-
- (*entry_base_addr) += sizeof(struct tag_hinic5_cqm_bat_entry_cfg);
-}
-
-static void hinic5_cqm_bat_fill_cla_other(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- hinic5_cqm_bat_fill_cla_common(hinic5_cqm_handle, cla_table, *entry_base_addr);
-
- (*entry_base_addr) += sizeof(struct tag_hinic5_cqm_bat_entry_standerd);
-}
-
-static void hinic5_cqm_bat_fill_cla_taskmap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- const struct tag_hinic5_cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- struct tag_hinic5_cqm_bat_entry_taskmap *bat_entry_taskmap = NULL;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- int i;
-
- if (hinic5_cqm_handle->func_capability.taskmap_number != 0) {
- bat_entry_taskmap =
- (struct tag_hinic5_cqm_bat_entry_taskmap *)(*entry_base_addr);
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_TASKMAP_NUM; i++) {
- bat_entry_taskmap->addr[i].gpa_h =
- (u32)(cla_table->cla_z_buf.buf_list[i].pa >>
- HINIC5_CQM_CHIP_GPA_HSHIFT);
- bat_entry_taskmap->addr[i].gpa_l =
- (u32)(cla_table->cla_z_buf.buf_list[i].pa &
- HINIC5_CQM_CHIP_GPA_LOMASK);
- hinic5_cqm_info(handle->dev_hdl,
- "Cla alloc: taskmap bat entry: 0x%x 0x%x\n",
- bat_entry_taskmap->addr[i].gpa_h,
- bat_entry_taskmap->addr[i].gpa_l);
- }
- }
-
- (*entry_base_addr) += sizeof(struct tag_hinic5_cqm_bat_entry_taskmap);
-}
-
-static void hinic5_cqm_bat_fill_cla_timer(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- /* Only the PPF allocates timer resources. */
- if (!HINIC5_CQM_IS_PPF(hinic5_cqm_handle)) {
- (*entry_base_addr) += HINIC5_CQM_BAT_ENTRY_SIZE;
- } else {
- hinic5_cqm_bat_fill_cla_common(hinic5_cqm_handle, cla_table,
- *entry_base_addr);
-
- (*entry_base_addr) += sizeof(struct tag_hinic5_cqm_bat_entry_standerd);
- }
-}
-
-static void hinic5_cqm_bat_fill_cla_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u8 **entry_base_addr)
-{
- (*entry_base_addr) += HINIC5_CQM_BAT_ENTRY_SIZE;
-}
-
-/**
- * Prototype : hinic5_cqm_bat_fill_cla
- * Description : Fill the base address of the CLA table into the BAT table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-static void hinic5_cqm_bat_fill_cla(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- u32 entry_type = HINIC5_CQM_BAT_ENTRY_T_INVALID;
- u8 *entry_base_addr = NULL;
- u32 i = 0;
-
- /* Fills each item in the BAT table according to the BAT format. */
- entry_base_addr = bat_table->bat;
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, hinic5_cqm_handle->dev,
- "entry_base_addr = %p\n", entry_base_addr);
- entry_type = bat_table->bat_entry_type[i];
- cla_table = &bat_table->entry[i];
-
- if (entry_type == HINIC5_CQM_BAT_ENTRY_T_CFG) {
- hinic5_cqm_bat_fill_cla_cfg(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_TASKMAP) {
- hinic5_cqm_bat_fill_cla_taskmap(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_INVALID) {
- hinic5_cqm_bat_fill_cla_invalid(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_TIMER) {
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle) && HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- /* The fill of Timer Entry is delayed,
- * because it needs to be based on a specific SMF. */
- entry_base_addr += sizeof(struct tag_hinic5_cqm_bat_entry_standerd);
- continue;
- }
-
- hinic5_cqm_bat_fill_cla_timer(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_HASH) {
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- /* The fill of Hash Entry is delayed,
- * because it needs to be based on a specific SMF. */
- entry_base_addr += sizeof(struct tag_hinic5_cqm_bat_entry_standerd);
- continue;
- }
-
- hinic5_cqm_bat_fill_cla_other(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_XID2CID) {
- if (COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) && HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- /* The fill of XID2CID Entry is delayed,
- * because it needs to be based on a specific SMF. */
- entry_base_addr += sizeof(struct tag_hinic5_cqm_bat_entry_standerd);
- continue;
- }
-
- hinic5_cqm_bat_fill_cla_other(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else {
- hinic5_cqm_bat_fill_cla_other(hinic5_cqm_handle, cla_table, &entry_base_addr);
- }
-
- /* Check whether entry_base_addr is out-of-bounds array. */
- if (entry_base_addr >=
- (bat_table->bat + HINIC5_CQM_BAT_ENTRY_MAX * HINIC5_CQM_BAT_ENTRY_SIZE))
- break;
- }
-}
-
-u32 hinic5_cqm_lb0_get_smf_id(const struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 smf_sel, funcid, smf_pg_partial, smf_id;
- /* SMFID is selected based on SMF_PG[1:0] and SMF_Selection(0-1) */
- u32 smfsel_smfid01[4][2] = { {0, 0}, {0, 0}, {1, 1}, {0, 1} };
- /* SMFID is selected based on SMF_PG[3:2] and SMF_Selection(2-4) */
- u32 smfsel_smfid23[4][2] = { {2, 2}, {2, 2}, {3, 3}, {2, 3} };
-
- /* SMF_Selection is selected based on
- * the lower two bits of the function id
- */
- funcid = hinic5_cqm_handle->func_attribute.func_global_idx & 0x3;
- /* if smf2 and smf3 are disabled, only select smf0/smf1 */
- if ((hinic5_cqm_handle->func_capability.smf_pg >> 2) == 0) {
- u32 lbf_smfsel[4] = {0, 1, 0, 1};
- smf_sel = lbf_smfsel[funcid];
- } else {
- u32 lbf_smfsel[4] = {0, 2, 1, 3};
- smf_sel = lbf_smfsel[funcid];
- }
-
- if (smf_sel < 0x2) {
- smf_pg_partial = hinic5_cqm_handle->func_capability.smf_pg & 0x3;
- smf_id = smfsel_smfid01[smf_pg_partial][smf_sel];
- } else {
- smf_pg_partial =
- /* shift to right by 2 bits */
- (hinic5_cqm_handle->func_capability.smf_pg >> 2) & 0x3;
- smf_id = smfsel_smfid23[smf_pg_partial][smf_sel - 0x2];
- }
-
- return smf_id;
-}
-
-/* MUST be used when LB is disabled OR in LB mode 0 */
-u32 hinic5_cqm_funcid2smfid(const struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- /* When the LB mode is disabled, SMF0 is always returned. */
- if (HINIC5_CQM_IS_LB_MODE_NORMAL(hinic5_cqm_handle))
- return 0;
- if (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle))
- return hinic5_cqm_lb0_get_smf_id(hinic5_cqm_handle);
- WARN_ON_ONCE(true);
- return 0;
-}
-
-/* This function is used in LB mode 1/2. Some BAT entries
- * of independent space needs to be configured for all enabled SMFs.
- */
-static void hinic5_cqm_update_bat_gpa(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 smf_id)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- u32 entry_type = HINIC5_CQM_BAT_ENTRY_T_INVALID;
- u8 *entry_base_addr = bat_table->bat;
- u32 i = 0;
-
- if (!HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle))
- return;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- entry_type = bat_table->bat_entry_type[i];
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle) &&
- entry_type == HINIC5_CQM_BAT_ENTRY_T_TIMER) {
- cla_table = &bat_table->timer_entry[smf_id];
- hinic5_cqm_bat_fill_cla_timer(hinic5_cqm_handle, cla_table,
- &entry_base_addr);
- } else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_HASH) {
- cla_table = &bat_table->hash_entry[smf_id];
- hinic5_cqm_bat_fill_cla_other(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else if (COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) &&
- entry_type == HINIC5_CQM_BAT_ENTRY_T_XID2CID) {
- cla_table = &bat_table->xid2cid_entry[smf_id];
- hinic5_cqm_bat_fill_cla_other(hinic5_cqm_handle, cla_table, &entry_base_addr);
- } else {
- if (entry_type == HINIC5_CQM_BAT_ENTRY_T_TASKMAP)
- entry_base_addr += sizeof(struct tag_hinic5_cqm_bat_entry_taskmap);
- else
- entry_base_addr += HINIC5_CQM_BAT_ENTRY_SIZE;
- }
-
- /* Check whether entry_base_addr is out-of-bounds array. */
- if (entry_base_addr >=
- (bat_table->bat + HINIC5_CQM_BAT_ENTRY_MAX * HINIC5_CQM_BAT_ENTRY_SIZE))
- break;
- }
-}
-
-static s32 hinic5_cqm_bat_update_smf_cmd(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_bat_update_param *param)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_cqm_cmdq_ops *ops = hinic5_cqm_handle->cmdq_ops;
- u8 cmd;
- bool illegal_args = true;
- s32 ret = HINIC5_CQM_FAIL;
-
- illegal_args = (param->bat_offset % HINIC5_CQM_BAT_ENTRY_SIZE != 0) ||
- (param->update_size % HINIC5_CQM_BAT_ENTRY_SIZE != 0) ||
- (param->update_size == 0) ||
- (param->bat_offset + param->update_size > bat_table->bat_size);
- if (unlikely(illegal_args)) {
- hinic5_cqm_err(handle->dev_hdl,
- "Bat update: invalid args, bat_offset %u, update_size %u.",
- param->bat_offset, param->update_size);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_info(handle->dev_hdl,
- "Bat update: smf_id %u, func_id %u, bat_offset %u, update_size %u.",
- param->smf_id, param->func_id,
- param->bat_offset, param->update_size);
-
- ret = ops->prepare_cmd_buf_bat_update(hinic5_cqm_handle, buf_in, param, &cmd);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(prepare_cmd_buf_bat_update));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_dbg_byte_print(handle->dev_hdl, (u32 *)bat_table->bat, sizeof(bat_table->bat));
-
- ret = hinic5_cqm_send_cmd_box((void *)(handle), HINIC5_CQM_MOD_HINIC5_CQM,
- cmd, buf_in, NULL, NULL,
- HINIC5_CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- hinic5_cqm_err(handle->dev_hdl, "%s: send_cmd_box ret=%d\n", __func__,
- ret);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_bat_update_smf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u32 smf_id, u32 func_id)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_bat_update_param param = { 0 };
- struct hinic5_bat_entry_config l3i_config = { 0 };
- int is_in_kexec;
- s32 ret = HINIC5_CQM_FAIL;
-
- is_in_kexec = hinic5_vram_get_kexec_flag();
- if (is_in_kexec != 0) {
- hinic5_cqm_info(handle->dev_hdl, "Skip updating the hinic5_cqm_bat to chip during kexec!");
- return HINIC5_CQM_SUCCESS;
- }
-
- if (bat_table->bat_size > HINIC5_CQM_BAT_MAX_SIZE) {
- hinic5_cqm_err(handle->dev_hdl, "bat_size = %u, which is more than %d.",
- bat_table->bat_size, HINIC5_CQM_BAT_MAX_SIZE);
- return HINIC5_CQM_FAIL;
- }
-
- ret = hinic5_bat_get_l3i_entry_config(handle, &l3i_config);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_bat_get_l3i_entry_config));
- return ret;
- }
-
- param.smf_id = smf_id;
- param.func_id = func_id;
-
- /* The L3I entry is not managed by HINIC5_CQM */
- if (l3i_config.mapping &&
- bat_table->bat_size > l3i_config.bat_entry_offset) {
- /* update bat entries before L3I */
- param.bat_offset = 0;
- param.update_size = l3i_config.bat_entry_offset;
- ret = hinic5_cqm_bat_update_smf_cmd(hinic5_cqm_handle, buf_in, ¶m);
- if (ret != HINIC5_CQM_SUCCESS)
- goto cmd_err;
-
- /* update bat entries after L3I */
- param.bat_offset = l3i_config.bat_entry_offset + l3i_config.bat_entry_size;
- if (bat_table->bat_size > param.bat_offset) {
- param.update_size = bat_table->bat_size - param.bat_offset;
- ret = hinic5_cqm_bat_update_smf_cmd(hinic5_cqm_handle, buf_in, ¶m);
- if (ret != HINIC5_CQM_SUCCESS)
- goto cmd_err;
- }
- } else {
- /* update all bat entries */
- param.bat_offset = 0;
- param.update_size = bat_table->bat_size;
- ret = hinic5_cqm_bat_update_smf_cmd(hinic5_cqm_handle, buf_in, ¶m);
- if (ret != HINIC5_CQM_SUCCESS)
- goto cmd_err;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-cmd_err:
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bat_update_smf_cmd));
- return ret;
-}
-
-static s32 hinic5_cqm_bat_update_all_smf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u32 func_id)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- u32 smf_id = 0;
- s32 ret = HINIC5_CQM_SUCCESS;
-
- for (smf_id = 0; smf_id < func_cap->smf_max_num; smf_id++) {
- if ((func_cap->smf_pg & (1U << smf_id)) == 0)
- continue;
-
- hinic5_cqm_update_bat_gpa(hinic5_cqm_handle, smf_id);
- ret = hinic5_cqm_bat_update_smf(hinic5_cqm_handle, buf_in, smf_id, func_id);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
- }
-
- return ret;
-}
-
-/**
- * The LB scenario is supported.
- * - The normal mode is the traditional mode and is configured on SMF0.
- * - In mode 0, load is balanced to all SMFs based on the func ID (except
- * the PPF func ID). The PPF in mode 0 needs to be configured on all SMFs,
- * so the timer resources can be shared by the all timer engine.
- * - Mode 1/2 is load balanced to all SMFs by flow. Therefore, one function
- * needs to be configured to all SMFs.
- */
-static s32 hinic5_cqm_bat_update_lb(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- u32 func_id)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- u32 smf_id;
-
- if (HINIC5_CQM_IS_LB_MODE_NORMAL(hinic5_cqm_handle)) {
- smf_id = hinic5_cqm_funcid2smfid(hinic5_cqm_handle);
- return hinic5_cqm_bat_update_smf(hinic5_cqm_handle, buf_in, smf_id, func_id);
- }
-
- if (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle)) {
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle))
- return hinic5_cqm_bat_update_all_smf(hinic5_cqm_handle, buf_in, func_id);
- smf_id = hinic5_cqm_funcid2smfid(hinic5_cqm_handle);
- return hinic5_cqm_bat_update_smf(hinic5_cqm_handle, buf_in, smf_id, func_id);
- }
-
- if (HINIC5_CQM_IS_LB_MODE_1(hinic5_cqm_handle) || HINIC5_CQM_IS_LB_MODE_2(hinic5_cqm_handle))
- return hinic5_cqm_bat_update_all_smf(hinic5_cqm_handle, buf_in, func_id);
-
- hinic5_cqm_err(hwdev->dev_hdl, "Bat update: unsupported lb mode=%u\n",
- hinic5_cqm_handle->func_capability.lb_mode);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_bat_update
- * Description : Send a command to tile to update the BAT table through cmdq.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-static s32 hinic5_cqm_bat_update(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- s32 ret = HINIC5_CQM_FAIL;
- u32 func_id = 0;
-
- /* The BAT is maintained by the parent function. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- hinic5_cqm_err(hwdev->dev_hdl, "Bat update: unsupported for fake child\n");
- return HINIC5_CQM_FAIL;
- }
-
- buf_in = hinic5_cqm_cmd_alloc((void *)(hinic5_cqm_handle->ex_handle));
- if (unlikely((buf_in) == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- /* In non-fake mode, func_id is set to 0xffff, indicating the current
- * func. In fake mode, the value of func_id is specified. This is a fake
- * func_id.
- */
- if (HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle))
- func_id = hinic5_cqm_handle->func_attribute.func_global_idx;
- else
- func_id = 0xffff;
-
- ret = hinic5_cqm_bat_update_lb(hinic5_cqm_handle, buf_in, func_id);
-
- hinic5_cqm_cmd_free((void *)(hinic5_cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-static s32 hinic5_cqm_bat_init_ft(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_bat_table *bat_table,
- enum func_type function_type)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i = 0;
-
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX0] = HINIC5_CQM_BAT_ENTRY_T_CFG;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX1] = HINIC5_CQM_BAT_ENTRY_T_HASH;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX2] = HINIC5_CQM_BAT_ENTRY_T_QPC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX3] = HINIC5_CQM_BAT_ENTRY_T_SCQC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX4] = HINIC5_CQM_BAT_ENTRY_T_LUN;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX5] = HINIC5_CQM_BAT_ENTRY_T_TASKMAP;
-
- if (function_type == HINIC5_CQM_PF || function_type == HINIC5_CQM_PPF) {
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX6] = HINIC5_CQM_BAT_ENTRY_T_L3I;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX7] = HINIC5_CQM_BAT_ENTRY_T_CHILDC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX8] = HINIC5_CQM_BAT_ENTRY_T_TIMER;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX9] = HINIC5_CQM_BAT_ENTRY_T_XID2CID;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX10] = HINIC5_CQM_BAT_ENTRY_T_REORDER;
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_FT_PF;
- } else if (function_type == HINIC5_CQM_VF) {
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_FT_VF;
- } else {
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = HINIC5_CQM_BAT_ENTRY_T_INVALID;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(function_type));
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_bat_init_rdma(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_bat_table *bat_table,
- enum func_type function_type)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i = 0;
-
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX0] = HINIC5_CQM_BAT_ENTRY_T_QPC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX1] = HINIC5_CQM_BAT_ENTRY_T_SCQC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX2] = HINIC5_CQM_BAT_ENTRY_T_SRQC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX3] = HINIC5_CQM_BAT_ENTRY_T_MPT;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX4] = HINIC5_CQM_BAT_ENTRY_T_GID;
-
- if (function_type == HINIC5_CQM_PF || function_type == HINIC5_CQM_PPF) {
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX5] = HINIC5_CQM_BAT_ENTRY_T_L3I;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX6] =
- HINIC5_CQM_BAT_ENTRY_T_CHILDC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX7] =
- HINIC5_CQM_BAT_ENTRY_T_TIMER;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX8] =
- HINIC5_CQM_BAT_ENTRY_T_XID2CID;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX9] =
- HINIC5_CQM_BAT_ENTRY_T_REORDER;
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_RDMA_PF;
- } else if (function_type == HINIC5_CQM_VF) {
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_RDMA_VF;
- } else {
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = HINIC5_CQM_BAT_ENTRY_T_INVALID;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(function_type));
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_bat_init_ft_rdma(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_bat_table *bat_table,
- enum func_type function_type)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i = 0;
-
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX0] = HINIC5_CQM_BAT_ENTRY_T_CFG;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX1] = HINIC5_CQM_BAT_ENTRY_T_HASH;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX2] = HINIC5_CQM_BAT_ENTRY_T_QPC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX3] = HINIC5_CQM_BAT_ENTRY_T_SCQC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX4] = HINIC5_CQM_BAT_ENTRY_T_SRQC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX5] = HINIC5_CQM_BAT_ENTRY_T_MPT;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX6] = HINIC5_CQM_BAT_ENTRY_T_GID;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX7] = HINIC5_CQM_BAT_ENTRY_T_LUN;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX8] = HINIC5_CQM_BAT_ENTRY_T_TASKMAP;
-
- if (function_type == HINIC5_CQM_PF || function_type == HINIC5_CQM_PPF) {
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX9] = HINIC5_CQM_BAT_ENTRY_T_L3I;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX10] =
- HINIC5_CQM_BAT_ENTRY_T_CHILDC;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX11] =
- HINIC5_CQM_BAT_ENTRY_T_TIMER;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX12] =
- HINIC5_CQM_BAT_ENTRY_T_XID2CID;
- bat_table->bat_entry_type[HINIC5_CQM_BAT_INDEX13] =
- HINIC5_CQM_BAT_ENTRY_T_REORDER;
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_FT_RDMA_PF;
- } else if (function_type == HINIC5_CQM_VF) {
- bat_table->bat_size = HINIC5_CQM_BAT_SIZE_FT_RDMA_VF;
- } else {
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = HINIC5_CQM_BAT_ENTRY_T_INVALID;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(function_type));
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_bat_init
- * Description : Initialize the BAT table. Only the items to be initialized and
- * the entry sequence are selected. The content of the BAT entry
- * is filled after the CLA is allocated.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-s32 hinic5_cqm_bat_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- enum func_type function_type = hinic5_cqm_handle->func_attribute.func_type;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- u32 i;
-
- memset(bat_table, 0, sizeof(struct tag_hinic5_cqm_bat_table));
-
- /* Initialize the type of each bat entry. */
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = HINIC5_CQM_BAT_ENTRY_T_INVALID;
-
- /* Select BATs based on service types. Currently,
- * feature-related resources of the VF are stored in the BATs of the VF.
- */
- if (capability->ft_enable && capability->rdma_enable)
- return hinic5_cqm_bat_init_ft_rdma(hinic5_cqm_handle, bat_table, function_type);
- else if (capability->ft_enable)
- return hinic5_cqm_bat_init_ft(hinic5_cqm_handle, bat_table, function_type);
- else if (capability->rdma_enable)
- return hinic5_cqm_bat_init_rdma(hinic5_cqm_handle, bat_table, function_type);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-STATIC s32 hinic5_cqm_cla_reset(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- struct tag_hinic5_cqm_cla_reset_cmd *cmd_data = NULL;
- int ret = HINIC5_CQM_SUCCESS;
-
- buf_in = hinic5_cqm_cmd_alloc(handle);
- if (unlikely(!buf_in)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- cmd_data = buf_in->buf;
- memset(cmd_data, 0, sizeof(*cmd_data));
-
- cmd_data->func_id = hinic5_global_func_id(handle);
- hinic5_cqm_swab32((u8 *)cmd_data, sizeof(struct tag_hinic5_cqm_cla_reset_cmd) >> HINIC5_CQM_DW_SHIFT);
- ret = hinic5_cqm_send_cmd_box(handle, HINIC5_CQM_MOD_HINIC5_CQM, HINIC5_CQM_CMD_T_CLA_RESET,
- buf_in, NULL, NULL,
- HINIC5_CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- }
-
- return ret;
-}
-
-/**
- * Prototype : hinic5_cqm_bat_uninit
- * Description : Deinitialize the BAT table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-void hinic5_cqm_bat_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++)
- bat_table->bat_entry_type[i] = HINIC5_CQM_BAT_ENTRY_T_INVALID;
-
- /* The BAT is maintained by the parent function.
- Reset CLA instead of clear BAT. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- hinic5_cqm_cla_reset(hinic5_cqm_handle);
- return;
- }
-
- memset(bat_table->bat, 0, HINIC5_CQM_BAT_ENTRY_MAX * HINIC5_CQM_BAT_ENTRY_SIZE);
- /* Instruct the chip to update the BAT table. */
- if (hinic5_cqm_bat_update(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS)
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bat_update));
-}
-
-static u64 hinic5_cqm_cla_chip_gpa_flags(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u8 gpa_check_enable)
-{
- struct hinic5_func_attr *func_attr = NULL;
- u64 fake_en, spu_en, pf_id;
-
- spu_en = ((u64)hinic5_cqm_get_acs_spu_en(hinic5_cqm_handle)) << 0x3F;
-
- /* fake enable */
- fake_en = 0;
- pf_id = 0;
- if (HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle)) {
- fake_en = 1ULL << 0x3E;
- func_attr = &hinic5_cqm_handle->parent_hinic5_cqm_handle->func_attribute;
- pf_id = (u64)(func_attr->func_global_idx & 0x1f) << 0x39;
- }
-
- return spu_en | fake_en | pf_id | gpa_check_enable;
-}
-
-/**
- * Create mapping from cla_base_buf to cla_sub_buf.
- * The pointer in cla_base_buf is mapped from base_offset, and the target buf
- * in cla_sub_buf is used from sub_offset.
- */
-static s32 hinic5_cqm_cla_map_buf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_buf *cla_base_buf,
- const struct tag_hinic5_cqm_buf *cla_sub_buf,
- u32 base_offset, u32 sub_offset, u32 num,
- u8 gpa_check_enable)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 buf_addr_cap, base_addr_cap;
- u64 gpa_flags = 0;
- u32 i, base_buf_index, base_buf_offset, index_base_offset, index_sub_offset;
- dma_addr_t *base = NULL;
-
- buf_addr_cap = cla_base_buf->buf_size / sizeof(dma_addr_t);
- base_addr_cap = cla_base_buf->buf_number * buf_addr_cap;
-
- if (unlikely(num == 0 || (base_offset + num > base_addr_cap) ||
- (sub_offset + num > cla_sub_buf->buf_number))) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla alloc: truncate! mapping num %u, base off %u, sub cap %u, sub offset %u, sub cap %u",
- num, base_offset, base_addr_cap, sub_offset, cla_sub_buf->buf_number);
- return HINIC5_CQM_FAIL;
- }
-
- gpa_flags = hinic5_cqm_cla_chip_gpa_flags(hinic5_cqm_handle, gpa_check_enable);
-
- hinic5_cqm_dbg(handle->dev_hdl,
- "hinic5_cqm_cla_map_buf: mapping num %u, base off %u, sub cap %u, sub offset %u, sub cap %u, gpa_flags 0x%llX\n",
- num, base_offset, base_addr_cap, sub_offset, cla_sub_buf->buf_number, gpa_flags);
-
- index_base_offset = base_offset;
- index_sub_offset = sub_offset;
- for (i = 0; i < num; i++) {
- base_buf_index = index_base_offset / buf_addr_cap;
- base_buf_offset = index_base_offset % buf_addr_cap;
- base = (dma_addr_t *)(cla_base_buf->buf_list[base_buf_index].va);
- base += base_buf_offset;
-
-#define HINIC5_CQM_TIMER_FUNC_BUF_NUM 64
- hinic5_cqm_dbg_on(i % HINIC5_CQM_TIMER_FUNC_BUF_NUM == 0, handle->dev_hdl,
- "hinic5_cqm_cla_map_buf: mapping %4u, pointer(va 0x%lX, base_buf+%03u) --> sub_buf(idx %4u, pa 0x%lX), using base_buf(idx %3u, pa 0x%lX, va 0x%lX).\n",
- i, (uintptr_t)base, base_buf_offset,
- index_sub_offset, (uintptr_t)cla_sub_buf->buf_list[index_sub_offset].pa,
- base_buf_index, (uintptr_t)cla_base_buf->buf_list[base_buf_index].pa,
- (uintptr_t)cla_base_buf->buf_list[base_buf_index].va);
-
- *base = (dma_addr_t)(((u64)(cla_sub_buf->buf_list[index_sub_offset].pa) & HINIC5_CQM_CHIP_GPA_MASK)
- | gpa_flags);
- hinic5_cqm_swab64((u8 *)base, 1);
-
- index_base_offset++;
- index_sub_offset++;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_fill_buf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *cla_base_buf,
- struct tag_hinic5_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- dma_addr_t *base = NULL;
- u64 gpa_flags = 0;
- u32 i = 0;
- u32 addr_num;
- u32 buf_index = 0;
- s32 ret;
-
- /* Apply for space for base_buf */
- if (!cla_base_buf->buf_list) {
- ret = hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_base_buf, false);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(cla_base_buf));
- return ret;
- }
- }
-
- /* Apply for space for sub_buf */
- if (!cla_sub_buf->buf_list) {
- ret = hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_sub_buf, false);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(cla_sub_buf));
- hinic5_cqm_buf_free(cla_base_buf, hinic5_cqm_handle->dev);
- return ret;
- }
- }
-
- gpa_flags = hinic5_cqm_cla_chip_gpa_flags(hinic5_cqm_handle, gpa_check_enable);
- hinic5_cqm_dbg(handle->dev_hdl, "hinic5_cqm_cla_fill_buf: gpa_flags 0x%llX\n", gpa_flags);
-
- /* Fill base_buff with the gpa of sub_buf */
- addr_num = cla_base_buf->buf_size / sizeof(dma_addr_t);
- base = (dma_addr_t *)(cla_base_buf->buf_list[0].va);
- for (i = 0; i < cla_sub_buf->buf_number; i++) {
- *base = (dma_addr_t)(((u64)(cla_sub_buf->buf_list[i].pa) & HINIC5_CQM_CHIP_GPA_MASK)
- | gpa_flags);
-
- hinic5_cqm_swab64((u8 *)base, 1);
- if ((i + 1) % addr_num == 0) {
- buf_index++;
- if (buf_index < cla_base_buf->buf_number)
- base = cla_base_buf->buf_list[buf_index].va;
- } else {
- base++;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_apply_new_buf(struct tag_hinic5_cqm_buf *cla_buf, u32 buf_size, u32 buf_num, u32 buf_order)
-{
- cla_buf->buf_size = buf_size;
- cla_buf->buf_number = buf_num;
- cla_buf->page_number = cla_buf->buf_number << buf_order;
-}
-
-static s32 hinic5_cqm_cla_secure_mem_buf_alloc(struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_buf *buf)
-{
- /* Applying for the buffer list descriptor space */
- buf->buf_list = vmalloc(buf->buf_number * sizeof(struct tag_hinic5_cqm_buf_list));
- if (unlikely(buf->buf_list == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(secure_mem_buf_alloc));
- return HINIC5_CQM_FAIL;
- }
- memset(buf->buf_list,
- 0, buf->buf_number * sizeof(struct tag_hinic5_cqm_buf_list));
-
- buf->buf_list->va = cla_table->secure_mem.va;
- buf->buf_list->pa = cla_table->secure_mem.pa;
- buf->secure_mem_flag = HINIC5_CQM_SECURE_BUFFER_EN;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_xyz_lvl0(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table, u32 trunk_size)
-{
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- s32 ret;
-
- cla_table->cla_lvl = HINIC5_CQM_CLA_LVL_0;
-
- cla_table->z = cla_table->max_index_bit;
- cla_table->y = 0;
- cla_table->x = 0;
-
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
-
- /* Applying for CLA_Z_BUF Space */
- cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = 1;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
-
- if (secure_mem_en && HINIC5_CQM_IS_VF(hinic5_cqm_handle) && HINIC5_CQM_CLA_IS_SECURE_MEM(cla_table->type))
- return hinic5_cqm_cla_secure_mem_buf_alloc(cla_table, cla_z_buf);
-
- ret = hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_z_buf, false);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_warn(hinic5_cqm_handle->dev,
- "lvl_0_z_buf alloc fail. buf size 0x%x, ret %d.\n",
- trunk_size, ret);
- return ret;
-}
-
-static s32 hinic5_cqm_cla_xyz_lvl1(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table, u32 trunk_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- u32 shift = 0, z_buf_num;
- u8 gpa_check_enable = hinic5_cqm_handle->func_capability.gpa_check_enable;
- u32 cache_line = get_cacheline_size(cla_table->type);
- s32 ret;
-
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_REORDER)
- gpa_check_enable = 0;
-
- cla_table->cla_lvl = HINIC5_CQM_CLA_LVL_1;
-
- shift = hinic5_cqm_shift(trunk_size / cla_table->obj_size);
- cla_table->z = ((shift != 0) ? (shift - 1) : (shift));
- cla_table->y = cla_table->max_index_bit;
- cla_table->x = 0;
-
- if (cla_table->obj_size >= cache_line) {
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
- } else {
- shift = hinic5_cqm_shift(trunk_size / cache_line);
- cla_table->cacheline_z = ((shift != 0) ? (shift - 1) : (shift));
- cla_table->cacheline_y = cla_table->max_index_bit;
- cla_table->cacheline_x = 0;
- }
-
- /* Applying for CLA_Y_BUF Space */
- hinic5_cqm_apply_new_buf(cla_y_buf, trunk_size, 1, cla_table->trunk_order);
- ret = hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_y_buf, false);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(hinic5_cqm_handle->dev,
- "lvl_1_y_buf alloc fail. buf size 0x%x, ret %d.\n",
- trunk_size, ret);
- return ret;
- }
-
- /* Applying for CLA_Z_BUF Space */
- z_buf_num = ALIGN(cla_table->max_buffer_size, trunk_size) / trunk_size;
- hinic5_cqm_apply_new_buf(cla_z_buf, trunk_size, z_buf_num, cla_table->trunk_order);
- /* All buffer space must be statically allocated. */
- if (cla_table->alloc_static) {
- ret = hinic5_cqm_cla_fill_buf(hinic5_cqm_handle, cla_y_buf, cla_z_buf, gpa_check_enable);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_fill_buf));
- /* cla_y_buf freed by hinic5_cqm_cla_fill_buf() */
- return ret;
- }
- } else { /* Only the buffer list space is initialized. The buffer space
- * is dynamically allocated in services.
- */
- ret = hinic5_cqm_buf_list_alloc(cla_z_buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_1_z_buf));
- hinic5_cqm_buf_free(cla_y_buf, hinic5_cqm_handle->dev);
- return ret;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_cla_xyz_lvl2_param_init(struct tag_hinic5_cqm_cla_table *cla_table, u32 trunk_size)
-{
- u32 shift = 0;
- u32 cache_line = get_cacheline_size(cla_table->type);
-
- cla_table->cla_lvl = HINIC5_CQM_CLA_LVL_2;
-
- shift = hinic5_cqm_shift(trunk_size / cla_table->obj_size);
- cla_table->z = ((shift != 0) ? (shift - 1) : (shift));
- shift = hinic5_cqm_shift(trunk_size / sizeof(dma_addr_t));
- cla_table->y = cla_table->z + shift;
- cla_table->x = cla_table->max_index_bit;
-
- if (cla_table->obj_size >= cache_line) {
- cla_table->cacheline_z = cla_table->z;
- cla_table->cacheline_y = cla_table->y;
- cla_table->cacheline_x = cla_table->x;
- } else {
- shift = hinic5_cqm_shift(trunk_size / cache_line);
- cla_table->cacheline_z = ((shift != 0) ? (shift - 1) : (shift));
- shift = hinic5_cqm_shift(trunk_size / sizeof(dma_addr_t));
- cla_table->cacheline_y = cla_table->cacheline_z + shift;
- cla_table->cacheline_x = cla_table->max_index_bit;
- }
-}
-
-static s32 hinic5_cqm_cla_xyz_lvl2_xyz_apply(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table, u32 trunk_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- s32 ret;
-
- /* Apply for CLA_X_BUF Space */
- cla_x_buf->buf_size = trunk_size;
- cla_x_buf->buf_number = 1;
- cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
- cla_x_buf->buf_info.use_hinic5_vram = get_use_hinic5_vram_flag();
- ret = hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_x_buf, false);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_2_x_buf));
- return ret;
- }
-
- /* Apply for CLA_Z_BUF and CLA_Y_BUF Space */
- cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
-
- cla_y_buf->buf_size = trunk_size;
- cla_y_buf->buf_number =
- (u32)(ALIGN(cla_z_buf->buf_number * sizeof(dma_addr_t), trunk_size)) / trunk_size;
- cla_y_buf->page_number = cla_y_buf->buf_number << cla_table->trunk_order;
-
- return 0;
-}
-
-static s32 hinic5_cqm_cla_xyz_hinic5_vram_name_init(struct tag_hinic5_cqm_cla_table *cla_table,
- struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- const int use_hinic5_vram = get_use_hinic5_vram_flag();
- int ret;
-
- cla_x_buf->buf_info.use_hinic5_vram = use_hinic5_vram;
- ret = snprintf(cla_x_buf->buf_info.buf_hinic5_vram_name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s", cla_table->name, HINIC5_VRAM_HINIC5_CQM_CLA_COORD_X);
- if (ret < 0) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm cla x hinic5_vram name snprintf_s failed, cla_table->name:%s", cla_table->name);
- return HINIC5_CQM_FAIL;
- }
-
- cla_y_buf->buf_info.use_hinic5_vram = use_hinic5_vram;
- ret = snprintf(cla_y_buf->buf_info.buf_hinic5_vram_name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s", cla_table->name, HINIC5_VRAM_HINIC5_CQM_CLA_COORD_Y);
- if (ret < 0) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm cla y hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
-
- cla_z_buf->buf_info.use_hinic5_vram = use_hinic5_vram;
- ret = snprintf(cla_z_buf->buf_info.buf_hinic5_vram_name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s", cla_table->name, HINIC5_VRAM_HINIC5_CQM_CLA_COORD_Z);
- if (ret < 0) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm cla z hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_xyz_lvl2(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table, u32 trunk_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- s32 ret = HINIC5_CQM_FAIL;
- u8 gpa_check_enable = hinic5_cqm_handle->func_capability.gpa_check_enable;
-
- hinic5_cqm_cla_xyz_lvl2_param_init(cla_table, trunk_size);
-
- ret = hinic5_cqm_cla_xyz_lvl2_xyz_apply(hinic5_cqm_handle, cla_table, trunk_size);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
-
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_REORDER)
- gpa_check_enable = 0;
-
- /* All buffer space must be statically allocated. */
- if (cla_table->alloc_static) {
- /* Apply for y buf and z buf, and fill the gpa of z buf list in y buf */
- ret = hinic5_cqm_cla_fill_buf(hinic5_cqm_handle, cla_y_buf, cla_z_buf,
- gpa_check_enable);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_fill_buf));
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return ret;
- }
-
- /* Fill the gpa with the y buf list into the x buf.
- * After the x and y bufs are applied for, this function will not fail.
- * Use void to forcibly convert the return of the function.
- */
- (void)hinic5_cqm_cla_fill_buf(hinic5_cqm_handle, cla_x_buf, cla_y_buf, gpa_check_enable);
- } else { /* Only the buffer list space is initialized. The buffer space
- * is dynamically allocated in services.
- */
- ret = hinic5_cqm_buf_list_alloc(cla_z_buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_2_z_buf));
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return ret;
- }
-
- ret = hinic5_cqm_buf_list_alloc(cla_y_buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_2_y_buf));
- hinic5_cqm_buf_free(cla_z_buf, hinic5_cqm_handle->dev);
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return ret;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_xyz_lvl2_timer_xyz_apply(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 trunk_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_func_capability *cap = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- u32 timer_func_num, timer_number, actual_buffer_size;
- s32 ret;
-
- ret = hinic5_cqm_cla_xyz_lvl2_xyz_apply(hinic5_cqm_handle, cla_table, trunk_size);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
-
- /* Apply for space for CLA_Y_BUF */
- if (unlikely(hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_y_buf, false) != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_2_y_buf));
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return HINIC5_CQM_FAIL;
- }
-
- /* Ref: hinic5_cqm_capability_init_timer() */
- timer_func_num = cap->timer_pf_num + cap->timer_vf_num_actual;
- timer_number = HINIC5_CQM_TIMER_ALIGN_SCALE_NUM * timer_func_num;
- /* Ref: hinic5_cqm_bat_entry_init_timer() */
- actual_buffer_size = timer_number * cap->timer_basic_size;
-
- /* Ref: hinic5_cqm_cla_xyz_lvl2_xyz_apply() */
- cla_z_buf->buf_number = (ALIGN(actual_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
-
- /* Apply for space for CLA_Z_BUF */
- if (unlikely(hinic5_cqm_buf_alloc(hinic5_cqm_handle, cla_z_buf, false) != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(lvl_2_z_buf));
- hinic5_cqm_buf_free(cla_y_buf, hinic5_cqm_handle->dev);
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_dbg(handle->dev_hdl,
- "timer xyz apply: x buf va 0x%lX, pa 0x%lX. y buf num %u, z buf num %u\n",
- (uintptr_t)cla_x_buf->buf_list[0].va, (uintptr_t)cla_x_buf->buf_list[0].pa,
- cla_y_buf->buf_number, cla_z_buf->buf_number);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Level-2 CLA for timer
- * Allocates CLA_X_BUF, CLA_Y_BUF, and CLA_Z_BUF during initialization.
- *
- * SMF Timer accesses VF's spokes by offset based on timer_vf_id_start.
- * Some VF may not require initialization, the allocation is based on VF segments.
- *
- * The mapping from 1st CLA (Y buf) to 2nd CLA (Z buf) is as follows:
- *
- * <pre>
- * ▯ Empty buffer ▮ Buffer with pointer to Z buffer
- *
- * Ptr to first timer PF Ptr to VF seg N start
- * (timer_pf_id_start) (timer_vf_id_start) (timer_vf_segs[N].start)
- * | | |
- * 1st CLA ▮▮▮▮▮▮▮▮▮▮▮▮▮▯▯▯▯▯▮▮▮..▮▮▮▯▯▯▯▯▯▯▮▮▮▮▮
- * ┊ ┊ ╰───────╮ ╰────╮ ┊╭───────────╯ ┊
- * ┊ Ptr to VF seg 0 start ╰─────╮┊ ┊┊ ┊
- * ┊ (timer_vf_segs[0].start) ┊┊ ┊┊ ┊
- * ↓ ↓ ↓↓ ↓↓ ↓
- * 2nd CLA ▯▯▯▯...▯▯▯▯▯▯▯▯▯....▯▯▯▯▯▯▯▯▯▯▯▯▯.......▯▯▯▯
- * \______________/\____________________/\______/\____________________/
- * timer_pf_num timer_vf_segs[0].num .... timer_vf_segs[N].num
- * </pre>
- */
-static s32 hinic5_cqm_cla_xyz_lvl2_timer(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 trunk_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- u8 gpa_check_enable = hinic5_cqm_handle->func_capability.gpa_check_enable;
- u32 func_timer_size, func_z_buf_num;
- u32 base_idx, sub_idx, func_num;
- int i;
-
- if (!cla_table->alloc_static ||
- func_cap->timer_vf_num == func_cap->timer_vf_num_actual)
- return hinic5_cqm_cla_xyz_lvl2(hinic5_cqm_handle, cla_table, trunk_size);
-
- func_cap->timer_vf_deploy_with_segs = true;
-
- hinic5_cqm_cla_xyz_lvl2_param_init(cla_table, trunk_size);
-
- if (hinic5_cqm_cla_xyz_lvl2_timer_xyz_apply(hinic5_cqm_handle, cla_table, trunk_size) != HINIC5_CQM_SUCCESS)
- return HINIC5_CQM_FAIL;
-
- func_timer_size = HINIC5_CQM_TIMER_ALIGN_SCALE_NUM * func_cap->timer_basic_size;
- func_z_buf_num = func_timer_size / trunk_size;
-
- /* Fill the gpa with the z buf list into the y buf for PF. */
- base_idx = 0;
- sub_idx = 0;
- func_num = func_cap->timer_pf_num;
- if (hinic5_cqm_cla_map_buf(hinic5_cqm_handle, cla_y_buf, cla_z_buf,
- base_idx * func_z_buf_num,
- sub_idx * func_z_buf_num,
- func_num * func_z_buf_num,
- gpa_check_enable) == HINIC5_CQM_FAIL)
- goto mapping_buf_fail;
-
- /* Fill the gpa with the z buf list into the y buf for VF. */
- for (i = 0; i < ARRAY_SIZE(func_cap->timer_vf_segs); i++) {
- u16 seg_start = func_cap->timer_vf_segs[i].start;
- if (seg_start == 0)
- break;
-
- base_idx = func_cap->timer_pf_num +
- (seg_start - func_cap->timer_vf_id_start);
- sub_idx += func_num;
- func_num = func_cap->timer_vf_segs[i].num;
- if (hinic5_cqm_cla_map_buf(hinic5_cqm_handle, cla_y_buf, cla_z_buf,
- base_idx * func_z_buf_num,
- sub_idx * func_z_buf_num,
- func_num * func_z_buf_num,
- gpa_check_enable) == HINIC5_CQM_FAIL)
- goto mapping_buf_fail;
- }
-
- /* Fill the gpa with the y buf list into the x buf.
- * After the x and y bufs are applied for, this function will not fail.
- * Use void to forcibly convert the return of the function.
- */
- (void)hinic5_cqm_cla_fill_buf(hinic5_cqm_handle, cla_x_buf, cla_y_buf, gpa_check_enable);
-
- return HINIC5_CQM_SUCCESS;
-
-mapping_buf_fail:
- hinic5_cqm_err(handle->dev_hdl,
- "Failed to create mapping from Y buf to Z buf. base_idx %u, sub_idx %u, func_num %u",
- base_idx, sub_idx, func_num);
- hinic5_cqm_buf_free(cla_z_buf, hinic5_cqm_handle->dev);
- hinic5_cqm_buf_free(cla_y_buf, hinic5_cqm_handle->dev);
- hinic5_cqm_buf_free(cla_x_buf, hinic5_cqm_handle->dev);
- return HINIC5_CQM_FAIL;
-}
-
-static inline int min_order_for_cla_obj(struct tag_hinic5_cqm_cla_table *cla_table)
-{
- return get_order(cla_table->obj_size);
-}
-
-static u32 calc_cla_lvl(u64 max_size, u32 order)
-{
- const u64 buf_size = (u64)PAGE_SIZE << order;
- const u64 buf_addr_cap = buf_size / sizeof(dma_addr_t);
-
- if (max_size <= buf_size)
- return HINIC5_CQM_CLA_LVL_0;
- if (max_size <= buf_size * buf_addr_cap)
- return HINIC5_CQM_CLA_LVL_1;
- if (max_size <= buf_size * buf_addr_cap * buf_addr_cap)
- return HINIC5_CQM_CLA_LVL_2;
- return HINIC5_CQM_CLA_LVL_UNSUPPORT;
-}
-
-static s32 hinic5_cqm_cla_xyz_alloc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 order)
-{
- const u32 cla_lvl = calc_cla_lvl(cla_table->max_buffer_size, order);
- const u32 buf_size = (u32)(PAGE_SIZE << order);
- s32 ret;
-
- /* Level-0 CLA occupies a small space.
- * Only CLA_Z_BUF can be allocated during initialization.
- */
- if (cla_lvl == HINIC5_CQM_CLA_LVL_0) {
- ret = hinic5_cqm_cla_xyz_lvl0(hinic5_cqm_handle, cla_table, buf_size);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_warn(hinic5_cqm_handle->dev, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_xyz_lvl0));
- return ret;
- }
-
- /* Level-1 CLA
- * Allocates CLA_Y_BUF and CLA_Z_BUF during initialization.
- */
- if (cla_lvl == HINIC5_CQM_CLA_LVL_1) {
- ret = hinic5_cqm_cla_xyz_lvl1(hinic5_cqm_handle, cla_table, buf_size);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_warn(hinic5_cqm_handle->dev, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_xyz_lvl1));
- return ret;
- }
-
- /* Level-2 CLA
- * Allocates CLA_X_BUF, CLA_Y_BUF, and CLA_Z_BUF during initialization.
- */
- if (cla_lvl == HINIC5_CQM_CLA_LVL_2) {
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_TIMER) {
- ret = hinic5_cqm_cla_xyz_lvl2_timer(hinic5_cqm_handle, cla_table, buf_size);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_warn(hinic5_cqm_handle->dev, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_xyz_lvl2_timer));
- return ret;
- } else {
- ret = hinic5_cqm_cla_xyz_lvl2(hinic5_cqm_handle, cla_table, buf_size);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_warn(hinic5_cqm_handle->dev, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_xyz_lvl2));
- return ret;
- }
- }
-
- /* The current memory management mode does not support such a large
- * buffer addressing. The order value needs to be increased.
- */
- hinic5_cqm_err(hinic5_cqm_handle->dev,
- "Cla alloc: cla max_buffer_size 0x%x exceeds support range\n",
- cla_table->max_buffer_size);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Try hugepages for CLA tables, fallback to 4K pages.
- * Fallback is limited to alloc_pages() failures during CLA buffers init.
- */
-static s32 hinic5_cqm_cla_xyz_hugepage(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table)
-{
- const u32 max_size = cla_table->max_buffer_size;
- int min_order, max_order, order, ret;
-
- min_order = min_order_for_cla_obj(cla_table);
- max_order = get_order(max_size);
- if (max_order > MAX_ORDER)
- max_order = MAX_ORDER;
-
- hinic5_cqm_dbg(hinic5_cqm_handle->dev,
- "Cla alloc: try hugepage, size 0x%x, order %d - %d.\n",
- max_size, min_order, max_order);
-
- for (order = max_order; order >= min_order; order--) {
- ret = hinic5_cqm_cla_xyz_alloc(hinic5_cqm_handle, cla_table, (u32)order);
- if (ret == HINIC5_CQM_BUF_ALLOC_BUDDY_PAGES_FAIL) {
- hinic5_cqm_warn(hinic5_cqm_handle->dev,
- "Cla alloc: insufficient pages (order %d).\n",
- order);
- continue;
- }
-
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- hinic5_cqm_err(hinic5_cqm_handle->dev, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_xyz_alloc));
- return ret;
- }
-
- return HINIC5_CQM_FAIL;
-}
-
-static s32 hinic5_cqm_cla_xyz_check(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- /* Check whether obj_size is 2^n-aligned. An error is reported when
- * obj_size is 0 or 1.
- */
- if (!hinic5_cqm_check_align(cla_table->obj_size)) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_size 0x%x is not align on 2^n\n",
- cla_table->type, cla_table->obj_size);
- return HINIC5_CQM_FAIL;
- }
-
- if (min_order_for_cla_obj(cla_table) > MAX_ORDER) {
- hinic5_cqm_err(hinic5_cqm_handle->dev,
- "Cla alloc: cla_type %u, obj_size 0x%x is too big\n",
- cla_table->type, cla_table->obj_size);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_xyz
- * Description : Calculate the number of levels of CLA tables and allocate
- * space for each level of CLA table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * struct tag_hinic5_cqm_cla_table *cla_table
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-STATIC s32 hinic5_cqm_cla_xyz(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret = HINIC5_CQM_FAIL;
-
- /* The BAT and CLA of the Fake VF are maintained by the parent function. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- hinic5_cqm_dbg(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num 0x%x, fake child func skip alloc\n",
- cla_table->type, cla_table->obj_num);
- return HINIC5_CQM_SUCCESS;
- }
-
- /* If the capability(obj_num) is set to 0, the CLA does not need to be
- * initialized and exits directly.
- */
- if (cla_table->obj_num == 0) {
- hinic5_cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num 0, don't alloc buffer\n",
- cla_table->type);
- return HINIC5_CQM_SUCCESS;
- }
-
- hinic5_cqm_info(handle->dev_hdl,
- "Cla alloc: cla_type %u, obj_num 0x%x, hugetable_hint %d\n",
- cla_table->type, cla_table->obj_num, cla_table->hugepage_hint);
-
- ret = hinic5_cqm_cla_xyz_check(hinic5_cqm_handle, cla_table);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
-
- ret = hinic5_cqm_cla_xyz_hinic5_vram_name_init(cla_table, handle);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
-
- /* Try hugepages for CLA tables. */
- if (unlikely(cla_table->hugepage_hint))
- return hinic5_cqm_cla_xyz_hugepage(hinic5_cqm_handle, cla_table);
-
- /* Build CLA tables with specified page order. */
- if ((int)cla_table->trunk_order < min_order_for_cla_obj(cla_table)) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla alloc: cla type %u, obj_size 0x%x is out of a CLA buffer(order %u)\n",
- cla_table->type, cla_table->obj_size, cla_table->trunk_order);
- return HINIC5_CQM_FAIL;
- }
- return hinic5_cqm_cla_xyz_alloc(hinic5_cqm_handle, cla_table, cla_table->trunk_order);
-}
-
-static void update_entry_cap_for_secure_mem(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- if (!secure_mem_en || !HINIC5_CQM_IS_VF(hinic5_cqm_handle))
- return;
-
- /* No multi-level CLA and dynamic allocation
- * when Secure Memory is enabled. */
- cla_table->trunk_order = (u32)get_order(cla_table->max_buffer_size);
- cla_table->hugepage_hint = false;
- cla_table->alloc_static = true;
- hinic5_cqm_info(handle->dev_hdl, "Secure mem: cla_type=%u, max_buffer_size=0x%x, order=%u\n",
- cla_table->type, cla_table->max_buffer_size, cla_table->trunk_order);
-}
-
-static void init_hash_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->hash_basic_size;
- cla_table->obj_num = capability->hash_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = true;
-}
-
-static void init_qpc_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->qpc_basic_size;
- cla_table->obj_num = capability->qpc_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = capability->qpc_alloc_static;
-
- if (hinic5_cqm_cla_hugepage_hint)
- cla_table->hugepage_hint = true;
-
- update_entry_cap_for_secure_mem(hinic5_cqm_handle, cla_table, capability);
-}
-
-static void init_scqc_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->scqc_basic_size;
- cla_table->obj_num = capability->scqc_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = capability->scqc_alloc_static;
-
- update_entry_cap_for_secure_mem(hinic5_cqm_handle, cla_table, capability);
-}
-
-static void init_srqc_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->srqc_basic_size;
- cla_table->obj_num = capability->srqc_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = capability->srqc_alloc_static;
-
- update_entry_cap_for_secure_mem(hinic5_cqm_handle, cla_table, capability);
-}
-
-static void init_mpt_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->max_buffer_size = capability->mpt_number * capability->mpt_basic_size;
- cla_table->obj_size = capability->mpt_basic_size;
- cla_table->obj_num = capability->mpt_number;
- /* CCB decided. MPT uses only static application scenarios. */
- cla_table->alloc_static = true;
-
- update_entry_cap_for_secure_mem(hinic5_cqm_handle, cla_table, capability);
-}
-
-static void init_gid_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- /* Level-0 CLA table required */
- cla_table->obj_size = capability->gid_basic_size;
- cla_table->obj_num = capability->gid_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = hinic5_cqm_shift(ALIGN(cla_table->max_buffer_size, PAGE_SIZE) / PAGE_SIZE);
- cla_table->alloc_static = true;
-}
-
-static void init_lun_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->lun_basic_size;
- cla_table->obj_num = capability->lun_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = CLA_TABLE_PAGE_ORDER;
- cla_table->alloc_static = true;
-}
-
-static void init_taskmap_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->taskmap_basic_size;
- cla_table->obj_num = capability->taskmap_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = HINIC5_CQM_4K_PAGE_ORDER;
- cla_table->alloc_static = true;
-}
-
-static void init_l3i_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->l3i_basic_size;
- cla_table->obj_num = capability->l3i_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = CLA_TABLE_PAGE_ORDER;
- cla_table->alloc_static = true;
-}
-
-static void init_childc_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->childc_basic_size;
- cla_table->obj_num = capability->childc_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = true;
-}
-
-static void init_timer_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- /* Ensure that the basic size of the timer buffer page does not
- * exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
- * the function is complex.
- */
- cla_table->obj_size = capability->timer_basic_size;
- cla_table->obj_num = capability->timer_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = HINIC5_CQM_8K_PAGE_ORDER;
- cla_table->alloc_static = true;
-
- if (hinic5_cqm_cla_hugepage_hint)
- cla_table->hugepage_hint = true;
-}
-
-static void init_xid2cid_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->obj_size = capability->xid2cid_basic_size;
- cla_table->obj_num = capability->xid2cid_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = HINIC5_CQM_8K_PAGE_ORDER;
- cla_table->alloc_static = true;
-
- if (capability->bat_cid_index_bit_width > 0)
- cla_table->max_index_bit = capability->bat_cid_index_bit_width - 1;
-}
-
-static void init_reorder_entry_cap(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- /* This entry supports only IWARP and doesn't support GPA validity check. */
- cla_table->obj_size = capability->reorder_basic_size;
- cla_table->obj_num = capability->reorder_number;
- cla_table->max_buffer_size = cla_table->obj_size * cla_table->obj_num;
- cla_table->trunk_order = capability->pagesize_reorder;
- cla_table->alloc_static = true;
-}
-
-typedef void (*init_entry_cap)(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability);
-
-static const init_entry_cap init_entry_cap_funcs[HINIC5_CQM_BAT_ENTRY_T_MAX] = {
- NULL, /* HINIC5_CQM_BAT_ENTRY_T_CFG */
- init_hash_entry_cap,
- init_qpc_entry_cap,
- init_scqc_entry_cap,
- init_srqc_entry_cap,
- init_mpt_entry_cap,
- init_gid_entry_cap,
- init_lun_entry_cap,
- init_taskmap_entry_cap,
- init_l3i_entry_cap,
- init_childc_entry_cap,
- init_timer_entry_cap,
- init_xid2cid_entry_cap,
- init_reorder_entry_cap,
- NULL, /* HINIC5_CQM_BAT_ENTRY_T_INVALID */
-};
-
-static void hinic5_cqm_cla_init_entry_capability(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- cla_table->max_index_bit = HINIC5_CQM_MAX_INDEX_BIT_DEFAULT;
-
- if (cla_table->type < ARRAY_SIZE(init_entry_cap_funcs) &&
- init_entry_cap_funcs[cla_table->type])
- init_entry_cap_funcs[cla_table->type](hinic5_cqm_handle, cla_table, capability);
-}
-
-static s32 hinic5_cqm_cla_init_entry_memory(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 entry_idx)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = &bat_table->entry[entry_idx];
- struct tag_hinic5_cqm_cla_table *cla_table_tmp = NULL;
- u32 entry_type = cla_table->type;
- u32 i;
- int ret;
-
- /* When the SMF API LB is mode 1 or 2, some entries need to be
- * configured for all enabled SMFs and the address space is independent.
- */
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) &&
- (entry_type == HINIC5_CQM_BAT_ENTRY_T_TIMER || entry_type == HINIC5_CQM_BAT_ENTRY_T_HASH ||
- (entry_type == HINIC5_CQM_BAT_ENTRY_T_XID2CID && COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev)))) {
- for (i = 0; i < hinic5_cqm_handle->func_capability.smf_max_num; i++) {
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_TIMER)
- cla_table_tmp = &bat_table->timer_entry[i];
- else if (entry_type == HINIC5_CQM_BAT_ENTRY_T_HASH)
- cla_table_tmp = &bat_table->hash_entry[i];
- else
- cla_table_tmp = &bat_table->xid2cid_entry[i];
-
- memcpy(cla_table_tmp,
- cla_table, sizeof(struct tag_hinic5_cqm_cla_table));
-
- ret = snprintf(cla_table_tmp->name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s%01u", cla_table->name,
- HINIC5_VRAM_HINIC5_CQM_CLA_SMF_BASE, i);
- if (ret < 0) {
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl,
- "hinic5_cqm cla timer hinic5_vram name snprintf_s failed");
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, entry_idx);
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_cla_xyz(hinic5_cqm_handle, cla_table_tmp) ==
- HINIC5_CQM_FAIL) {
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, entry_idx);
- return HINIC5_CQM_FAIL;
- }
- }
- return HINIC5_CQM_SUCCESS;
- }
-
- if (hinic5_cqm_cla_xyz(hinic5_cqm_handle, cla_table) == HINIC5_CQM_FAIL) {
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, entry_idx);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_init_entry(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- s32 ret;
- u32 i = 0;
- int err;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- cla_table->type = bat_table->bat_entry_type[i];
-
- err = snprintf(cla_table->name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s%s%02u", hinic5_cqm_handle->name, HINIC5_VRAM_HINIC5_CQM_CLA_BASE,
- HINIC5_VRAM_HINIC5_CQM_CLA_TYPE_BASE, cla_table->type);
- if (err < 0) {
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl,
- "hinic5_cqm cla table hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
-
- mutex_init(&cla_table->lock);
-
- hinic5_cqm_cla_init_entry_capability(hinic5_cqm_handle, cla_table, capability);
-
- /* Those entries don't need to alloc memory */
- if (cla_table->type < HINIC5_CQM_BAT_ENTRY_T_HASH ||
- cla_table->type > HINIC5_CQM_BAT_ENTRY_T_REORDER) {
- continue;
- }
-
- /* Timer entry is only deployed in PPF */
- if (cla_table->type == HINIC5_CQM_BAT_ENTRY_T_TIMER &&
- !HINIC5_CQM_IS_PPF(hinic5_cqm_handle))
- continue;
-
- ret = hinic5_cqm_cla_init_entry_memory(hinic5_cqm_handle, i);
- if (ret != HINIC5_CQM_SUCCESS)
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static u32 hinic5_cqm_cla_get_ctx_mem_size(struct tag_hinic5_cqm_func_capability *capability, u32 cla_type)
-{
- u32 basic_size;
- u32 num;
-
- switch (cla_type) {
- case HINIC5_CQM_BAT_ENTRY_T_SCQC:
- basic_size = capability->scqc_basic_size;
- num = capability->scqc_number;
- break;
-
- case HINIC5_CQM_BAT_ENTRY_T_SRQC:
- basic_size = capability->srqc_basic_size;
- num = capability->srqc_number;
- break;
- case HINIC5_CQM_BAT_ENTRY_T_QPC:
- basic_size = capability->qpc_basic_size;
- num = capability->qpc_number;
- break;
- case HINIC5_CQM_BAT_ENTRY_T_MPT:
- basic_size = capability->mpt_basic_size;
- num = capability->mpt_number;
- break;
- default:
- return 0;
- }
-
- return basic_size * num;
-}
-
-#if defined(__UEFI__) || defined(SECURE_MEM_STUB)
-static s32 hinic5_cqm_stub_get_func_secure_mem_size(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_func_capability *capability,
- u32 *total_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 cla_type[] = { HINIC5_CQM_BAT_ENTRY_T_SCQC,
- HINIC5_CQM_BAT_ENTRY_T_QPC,
- HINIC5_CQM_BAT_ENTRY_T_MPT,
- HINIC5_CQM_BAT_ENTRY_T_SRQC };
- u32 cla_num = sizeof(cla_type) / sizeof(cla_type[0]);
- u32 mem_size, i;
-
- /* mem size check */
- for (i = 0; i < cla_num; i++) {
- mem_size = hinic5_cqm_cla_get_ctx_mem_size(capability, cla_type[i]);
- if (!HINIC5_CQM_IS_SECURE_MEMSIZE_VALID(mem_size)) {
- hinic5_cqm_err(handle->dev_hdl,
- "%s: mem check failed, type=%d, mem_size=0x%x\n",
- __func__, cla_type[i], mem_size);
- return HINIC5_CQM_FAIL;
- }
- *total_size += mem_size;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/* Currently secure mem stub is allocated by SDK; for production, it will be allocated by QEMU and read from SML table */
-static s32 hinic5_cqm_stub_alloc_secure_mem(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_func_capability *capability)
-{
- struct hinic5_cqm_secure_mem_info *secure_mem_info = &hinic5_cqm_handle->bat_table.func_secure_mem;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct device *dev = hinic5_cqm_handle->dev;
- u32 secure_mem_size = 0;
- u32 ret, order, map_size;
-
- ret = hinic5_cqm_stub_get_func_secure_mem_size(hinic5_cqm_handle, capability, &secure_mem_size);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
-
- order = (u32)get_order(secure_mem_size);
- /* map total mem size(2^n) */
- map_size = 1 << (order + PAGE_SHIFT);
- hinic5_cqm_info(handle->dev_hdl, "total_mem_size=0x%x, map_size=0x%x, order=%d\n",
- secure_mem_size, map_size, order);
- secure_mem_info->addr.va = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!secure_mem_info->addr.va) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(secure_mem));
- return HINIC5_CQM_FAIL;
- }
-
- secure_mem_info->len = map_size;
- secure_mem_info->addr.pa = dma_map_single(dev, secure_mem_info->addr.va, map_size,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(dev, secure_mem_info->addr.pa)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(secure_mem));
- free_pages((ulong)secure_mem_info->addr.va, order);
- return HINIC5_CQM_FAIL;
- }
- return HINIC5_CQM_SUCCESS;
-}
-
-#else
-
-/* Get VF secure memory address from SML table and do mapping */
-static s32 hinic5_cqm_cla_get_secure_mem(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_cqm_secure_mem_info *secure_mem_info = &hinic5_cqm_handle->bat_table.func_secure_mem;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret;
-
- ret = hinic5_get_secure_mem_cfg(handle, &secure_mem_info->addr.pa, &secure_mem_info->len);
- if (ret == HINIC5_CQM_CONTINUE) {
- secure_mem_en = false;
- return HINIC5_CQM_SUCCESS;
- } else if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "failed to get secure mem, ret: %d, func_id %hu\n",
- ret, hinic5_global_func_id((void *)handle));
- return HINIC5_CQM_FAIL;
- }
-
- secure_mem_info->addr.va = ioremap(secure_mem_info->addr.pa, secure_mem_info->len);
- if (!secure_mem_info->addr.va) {
- hinic5_cqm_err(handle->dev_hdl,
- "failed to remap secure mem, func_id %u, gpa=0x%llx, len=0x%x\n",
- hinic5_global_func_id((void *)handle), (u64)secure_mem_info->addr.pa,
- secure_mem_info->len);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_info(handle->dev_hdl,
- "get secure mem: func_id=0x%x, gpa=0x%llx, va=0x%lx, len=0x%x\n",
- hinic5_global_func_id((void *)handle), (u64)secure_mem_info->addr.pa,
- (uintptr_t)secure_mem_info->addr.va, secure_mem_info->len);
- return HINIC5_CQM_SUCCESS;
-}
-#endif
-
-#if defined(__UEFI__) || defined(SECURE_MEM_STUB)
-/* Currently secure mem stub is allocated by SDK, memory is freed if ctx size is invalid; for production, Qemu will free it */
-static void hinic5_cqm_free_secure_mem(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_cqm_secure_mem_info *secure_mem_info = &hinic5_cqm_handle->bat_table.func_secure_mem;
- struct device *dev = hinic5_cqm_handle->dev;
- u32 order;
-
- if (secure_mem_info->addr.va) {
- order = (u32)get_order(secure_mem_info->len);
- dma_unmap_single(dev, secure_mem_info->addr.pa,
- secure_mem_info->len,
- DMA_BIDIRECTIONAL);
- free_pages((ulong)(secure_mem_info->addr.va), order);
- secure_mem_info->addr.va = NULL;
- }
-}
-#else
-static void hinic5_cqm_free_secure_mem(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_cqm_secure_mem_info *secure_mem_info = &hinic5_cqm_handle->bat_table.func_secure_mem;
-
- if (secure_mem_en && secure_mem_info->addr.va != NULL) {
- iounmap(secure_mem_info->addr.va);
- secure_mem_info->addr.va = NULL;
- }
-}
-#endif
-
-static struct tag_hinic5_cqm_cla_table *hinic5_cqm_cla_get_entry(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 cla_type)
-{
- u32 *bat_entry_type = hinic5_cqm_handle->bat_table.bat_entry_type;
- struct tag_hinic5_cqm_cla_table *cla_entry = hinic5_cqm_handle->bat_table.entry;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- if (bat_entry_type[i] == cla_type)
- return &cla_entry[i];
- }
-
- return NULL;
-}
-
-static s32 hinic5_cqm_cla_secure_mem_assign(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_func_capability *capability,
- u32 cla_type, u32 *mem_offset)
-{
- struct hinic5_cqm_secure_mem_info *secure_mem_info = &hinic5_cqm_handle->bat_table.func_secure_mem;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cla_table *cla_entry = NULL;
- u32 cla_mem_size;
-
- cla_entry = hinic5_cqm_cla_get_entry(hinic5_cqm_handle, cla_type);
- if (!cla_entry) {
- hinic5_cqm_err(handle->dev_hdl, "Get cla entry failed: cla_type=%u\n", cla_type);
- return HINIC5_CQM_FAIL;
- }
- cla_entry->secure_mem.va = secure_mem_info->addr.va + *mem_offset;
- cla_entry->secure_mem.pa = secure_mem_info->addr.pa + *mem_offset;
-
- cla_mem_size = hinic5_cqm_cla_get_ctx_mem_size(capability, cla_type);
-
- *mem_offset += cla_mem_size;
- if (*mem_offset >= secure_mem_info->len) {
- hinic5_cqm_err(handle->dev_hdl, "Mem size exceeds: mem_offset=0x%x, max_size=0x%x\n",
- *mem_offset, secure_mem_info->len);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_secure_mem_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- /* SCQC must be first (UB-VTP Table Use SCQC) */
- u32 cla_type[] = { HINIC5_CQM_BAT_ENTRY_T_SCQC,
- HINIC5_CQM_BAT_ENTRY_T_QPC,
- HINIC5_CQM_BAT_ENTRY_T_MPT,
- HINIC5_CQM_BAT_ENTRY_T_SRQC };
- u32 cla_num = sizeof(cla_type) / sizeof(cla_type[0]);
- u32 mem_offset = 0;
- s32 ret;
- u32 i;
-
- /* Currently secure mem stub is allocated by SDK; for production, it will be allocated by QEMU and read from VF BAR space */
-#if defined(__UEFI__) || defined(SECURE_MEM_STUB)
- if (hinic5_cqm_stub_alloc_secure_mem(hinic5_cqm_handle, capability) != HINIC5_CQM_SUCCESS)
-#else
- if ((hinic5_cqm_cla_get_secure_mem(hinic5_cqm_handle)) != HINIC5_CQM_SUCCESS)
-#endif
- return HINIC5_CQM_FAIL;
-
- if (!secure_mem_en) {
- return HINIC5_CQM_SUCCESS;
- }
-
- for (i = 0; i < cla_num; i++) {
- ret = hinic5_cqm_cla_secure_mem_assign(hinic5_cqm_handle, capability, cla_type[i], &mem_offset);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Cla secure mem assign failed: cla_type=%u\n", cla_type[i]);
- hinic5_cqm_free_secure_mem(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_init
- * Description : Initialize the CLA table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-s32 hinic5_cqm_cla_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret;
-
- if (secure_mem_en && HINIC5_CQM_IS_VF(hinic5_cqm_handle)) {
- if (unlikely(hinic5_cqm_cla_secure_mem_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(secure_mem_init));
- return HINIC5_CQM_FAIL;
- }
- }
-
- /* Applying for CLA Entries */
- if (hinic5_cqm_cla_init_entry(hinic5_cqm_handle, capability) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_init_entry));
- return HINIC5_CQM_FAIL;
- }
-
- /* The BAT and CLA of the Fake VF are maintained by the parent function. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- return hinic5_cqm_cla_reset(hinic5_cqm_handle);
- }
-
- /* After the CLA entry is applied, the address is filled
- * in the BAT table.
- */
- hinic5_cqm_bat_fill_cla(hinic5_cqm_handle);
-
- /* Instruct the chip to update the BAT table. */
- if (hinic5_cqm_bat_update(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bat_update));
- goto err;
- }
-
- hinic5_cqm_info(handle->dev_hdl, "Timer start: func_type=%d, timer_enable=%u\n",
- hinic5_cqm_handle->func_attribute.func_type,
- hinic5_cqm_handle->func_capability.timer_enable);
-
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle) &&
- hinic5_cqm_handle->func_capability.timer_enable == HINIC5_CQM_TIMER_ENABLE) {
- /* Enable the timer after the timer resources are applied for */
- ret = hinic5_ppf_tmr_start(handle);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "PPF timer start failed, err %d\n", ret);
- goto err;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, HINIC5_CQM_BAT_ENTRY_MAX);
- return HINIC5_CQM_FAIL;
-}
-
-/* Inverse operation of hinic5_cqm_cla_xyz() */
-static void hinic5_cqm_cla_table_free_cache_inv(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- s32 *inv_flag)
-{
- /* The CLA memory are maintained by the parent function. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle))
- return;
-
- hinic5_cqm_buf_free_cache_inv(hinic5_cqm_handle, &cla_table->cla_x_buf, inv_flag);
- hinic5_cqm_buf_free_cache_inv(hinic5_cqm_handle, &cla_table->cla_y_buf, inv_flag);
- hinic5_cqm_buf_free_cache_inv(hinic5_cqm_handle, &cla_table->cla_z_buf, inv_flag);
-}
-
-STATIC INLINE void hinic5_cqm_cla_uninit_entry(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- s32 *inv_flag)
-{
- if (cla_table->type != HINIC5_CQM_BAT_ENTRY_T_INVALID)
- hinic5_cqm_cla_table_free_cache_inv(hinic5_cqm_handle, cla_table, inv_flag);
- mutex_deinit(&cla_table->lock);
-}
-
-/**
- * Prototype : hinic5_cqm_cla_uninit
- * Description : Deinitialize the CLA table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-void hinic5_cqm_cla_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 entry_numb)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- s32 inv_flag = 0;
- u32 i;
-
- for (i = 0; i < entry_numb; i++) {
- cla_table = &bat_table->entry[i];
- hinic5_cqm_cla_uninit_entry(hinic5_cqm_handle, cla_table, &inv_flag);
- }
-
- /* When the lb mode is 1/2, the following entries allocated to all SMFs
- * needs to be released.
- */
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) && HINIC5_CQM_IS_PPF(hinic5_cqm_handle)) {
- for (i = 0; i < hinic5_cqm_handle->func_capability.smf_max_num; i++) {
- cla_table = &bat_table->timer_entry[i];
- hinic5_cqm_cla_uninit_entry(hinic5_cqm_handle, cla_table, &inv_flag);
- }
- }
-
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- for (i = 0; i < hinic5_cqm_handle->func_capability.smf_max_num; i++) {
- cla_table = &bat_table->hash_entry[i];
- hinic5_cqm_cla_uninit_entry(hinic5_cqm_handle, cla_table, &inv_flag);
- }
- }
-
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) && COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev)) {
- for (i = 0; i < hinic5_cqm_handle->func_capability.smf_max_num; i++) {
- cla_table = &bat_table->xid2cid_entry[i];
- hinic5_cqm_cla_uninit_entry(hinic5_cqm_handle, cla_table, &inv_flag);
- }
- }
-
- /* Free secure memory. For production, Qemu will free it */
- hinic5_cqm_free_secure_mem(hinic5_cqm_handle);
-}
-
-static s32 hinic5_cqm_cla_update_cmd(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- hinic5_cqm_cla_update_cmd_s *cmd_info)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret = HINIC5_CQM_FAIL;
- u8 cmd;
-
- hinic5_cqm_handle->cmdq_ops->prepare_cmd_buf_cla_update(cmd_info, buf_in, &cmd);
- ret = hinic5_cqm_send_cmd_box((void *)(hinic5_cqm_handle->ex_handle), HINIC5_CQM_MOD_HINIC5_CQM,
- cmd, buf_in, NULL, NULL,
- HINIC5_CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- hinic5_cqm_err(handle->dev_hdl, "Cla alloc: hinic5_cqm_cla_update, hinic5_cqm_send_cmd_box_ret=%d\n",
- ret);
- hinic5_cqm_err(handle->dev_hdl, "Cla alloc: hinic5_cqm_cla_update, cla_update_cmd: 0x%x 0x%x 0x%x 0x%x\n",
- cmd_info->gpa_h, cmd_info->gpa_l, cmd_info->value_h, cmd_info->value_l);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_cla_cmd_init(hinic5_cqm_cla_update_cmd_s *cmd, struct tag_hinic5_cqm_handle *hinic5_cqm_handle, dma_addr_t parant_pa,
- dma_addr_t child_pa, u8 cla_update_mode)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u64 spu_en = 0;
- dma_addr_t pa = 0;
- u8 gpa_check_enable = hinic5_cqm_handle->func_capability.gpa_check_enable;
-
- spu_en = ((u64)hinic5_cqm_get_acs_spu_en(hinic5_cqm_handle)) << 0x3F;
-
- pa = (parant_pa | spu_en);
- cmd->gpa_h = HINIC5_CQM_ADDR_HI(pa);
- cmd->gpa_l = HINIC5_CQM_ADDR_LW(pa);
-
- pa = (child_pa | spu_en);
- cmd->value_h = HINIC5_CQM_ADDR_HI(pa);
- cmd->value_l = HINIC5_CQM_ADDR_LW(pa);
-
- /* current CLA GPA CHECK */
- if (gpa_check_enable != 0) {
- switch (cla_update_mode) {
- /* gpa[0]=1 means this GPA is valid */
- case HINIC5_CQM_CLA_RECORD_NEW_GPA:
- cmd->value_l |= 1;
- break;
- /* gpa[0]=0 means this GPA is valid */
- case HINIC5_CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID:
- case HINIC5_CQM_CLA_DEL_GPA_WITH_CACHE_INVALID:
- cmd->value_l &= (~1);
- break;
- default:
- hinic5_cqm_err(handle->dev_hdl, "Cla alloc: %s, wrong cla_update_mode=%u\n", __func__, cla_update_mode);
- break;
- }
- }
-}
-
-static s32 hinic5_cqm_cla_update_all_smf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- hinic5_cqm_cla_update_cmd_s *cmd,
- struct tag_hinic5_cqm_cmd_buf *buf_in)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- u32 i = 0;
- s32 ret = HINIC5_CQM_FAIL;
-
- for (i = 0; i < func_cap->smf_max_num; i++) {
- if ((func_cap->smf_pg & (1U << i)) != 0) {
- cmd->smf_id = i;
- ret = hinic5_cqm_cla_update_cmd(hinic5_cqm_handle, buf_in, cmd);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
- }
- }
- return ret;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_update
- * Description : Send a command to update the CLA table.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- * struct tag_hinic5_cqm_buf_list *buf_node_parent parent node of the content to
- * be updated
- * struct tag_hinic5_cqm_buf_list *buf_node_child Subnode for which the buffer
- * is to be applied
- * u32 child_index Index of a child node.
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-STATIC s32 hinic5_cqm_cla_update(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, const struct tag_hinic5_cqm_buf_list *buf_node_parent,
- const struct tag_hinic5_cqm_buf_list *buf_node_child, u32 child_index, u8 cla_update_mode)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- hinic5_cqm_cla_update_cmd_s cmd;
- s32 ret = HINIC5_CQM_FAIL;
-
- buf_in = hinic5_cqm_cmd_alloc(hinic5_cqm_handle->ex_handle);
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- /* Fill command format, convert to big endian. */
- hinic5_cqm_cla_cmd_init(&cmd, hinic5_cqm_handle, (buf_node_parent->pa + (child_index * sizeof(dma_addr_t))), buf_node_child->pa,
- cla_update_mode);
-
- hinic5_cqm_dbg(handle->dev_hdl,
- "Cla alloc: %s, gpa=0x%x 0x%x, value=0x%x 0x%x, cla_update_mode=0x%x\n",
- __func__, cmd.gpa_h, cmd.gpa_l, cmd.value_h, cmd.value_l, cla_update_mode);
-
- /* In non-fake mode, set func_id to 0xffff.
- * Indicates the current func fake mode, set func_id to the
- * specified value, This is a fake func_id.
- */
- if (HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle))
- cmd.func_id = hinic5_cqm_handle->func_attribute.func_global_idx;
- else
- cmd.func_id = 0xffff;
-
- /* Normal mode is 1822 traditional mode and is configured on SMF0. */
- /* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */
- if (HINIC5_CQM_IS_LB_MODE_NORMAL(hinic5_cqm_handle) ||
- (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle) && !HINIC5_CQM_IS_PPF(hinic5_cqm_handle))) {
- cmd.smf_id = hinic5_cqm_funcid2smfid(hinic5_cqm_handle);
- ret = hinic5_cqm_cla_update_cmd(hinic5_cqm_handle, buf_in, &cmd);
- /* Modes 1/2 are allocated to four SMF engines by flow.
- * Therefore, one function needs to be allocated to four SMF engines.
- */
- /* Mode 0 PPF needs to be configured on 4 engines,
- * and the timer resources need to be shared by the 4 engines.
- */
- } else if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) ||
- (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle) && HINIC5_CQM_IS_PPF(hinic5_cqm_handle))) {
- ret = hinic5_cqm_cla_update_all_smf(hinic5_cqm_handle, &cmd, buf_in);
- } else {
- hinic5_cqm_err(handle->dev_hdl, "Cla update: unsupported lb mode=%u\n", hinic5_cqm_handle->func_capability.lb_mode);
- ret = HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_cmd_free((void *)(hinic5_cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_alloc
- * Description : Trunk page for applying for a CLA.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- * struct tag_hinic5_cqm_cla_table *cla_table,
- * struct tag_hinic5_cqm_buf_list *buf_node_parent parent node of the content to
- * be updated
- * struct tag_hinic5_cqm_buf_list *buf_node_child subnode for which the buffer
- * is to be applied
- * u32 child_index index of a child node
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-static s32 hinic5_cqm_cla_alloc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_buf_list *buf_node_parent,
- struct tag_hinic5_cqm_buf_list *buf_node_child, u32 child_index)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret = HINIC5_CQM_FAIL;
-
- /* Apply for trunk page */
- buf_node_child->va = (u8 *)(uintptr_t)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
- cla_table->trunk_order);
- if (unlikely(buf_node_child->va == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(va));
- return HINIC5_CQM_FAIL;
- }
- /* PCI mapping */
- buf_node_child->pa = dma_map_single(hinic5_cqm_handle->dev, buf_node_child->va,
- PAGE_SIZE << cla_table->trunk_order,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev, buf_node_child->pa) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(buf_node_child->pa));
- goto err1;
- }
-
- /* Notify the chip of trunk_pa so that the chip fills in cla entry */
- ret = hinic5_cqm_cla_update(hinic5_cqm_handle, buf_node_parent, buf_node_child,
- child_index, HINIC5_CQM_CLA_RECORD_NEW_GPA);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_update));
- goto err2;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err2:
- dma_unmap_single(hinic5_cqm_handle->dev, buf_node_child->pa,
- PAGE_SIZE << cla_table->trunk_order,
- DMA_BIDIRECTIONAL);
-err1:
- free_pages((ulong)(uintptr_t)(buf_node_child->va), cla_table->trunk_order);
- buf_node_child->va = NULL;
- return HINIC5_CQM_FAIL;
-}
-
-static void hinic5_cqm_unmap_and_free_pages(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf_list *buf_node, u32 order)
-{
- /* Remove PCI mapping from the trunk page */
- dma_unmap_single(hinic5_cqm_handle->dev, buf_node->pa, PAGE_SIZE << order, DMA_BIDIRECTIONAL);
-
- /* Release trunk page */
- free_pages((ulong)(uintptr_t)(buf_node->va), order);
- buf_node->va = NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_free_without_cache_invalid
- * Description : Release trunk page of a CLA
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * struct tag_hinic5_cqm_cla_table *cla_table
- * struct tag_hinic5_cqm_buf_list *buf_node
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/15
- * Modification : Created function
- */
-static void hinic5_cqm_cla_free_without_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_buf_list *buf_node_parent,
- struct tag_hinic5_cqm_buf_list *buf_node_child,
- u32 child_index)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- if (hinic5_cqm_cla_update(hinic5_cqm_handle, buf_node_parent, buf_node_child,
- child_index, HINIC5_CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_update));
- return;
- }
- /* Remove PCI mapping from the trunk page and Release trunk page */
- hinic5_cqm_unmap_and_free_pages(hinic5_cqm_handle, buf_node_child, cla_table->trunk_order);
-}
-
-STATIC void hinic5_cqm_cla_free_with_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_buf_list *buf_node_parent,
- struct tag_hinic5_cqm_buf_list *buf_node_child,
- u32 child_index)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 trunk_size;
-
- if (hinic5_cqm_cla_update(hinic5_cqm_handle, buf_node_parent, buf_node_child,
- child_index, HINIC5_CQM_CLA_DEL_GPA_WITH_CACHE_INVALID) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_update));
- return;
- }
-
- /* invalid cache */
- trunk_size = (u32)(PAGE_SIZE << cla_table->trunk_order);
- if (hinic5_cqm_cla_cache_invalid(hinic5_cqm_handle, buf_node_child->pa, trunk_size) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_cache_invalid));
- return;
- }
-
- /* Remove PCI mapping from the trunk page and Release trunk page */
- hinic5_cqm_unmap_and_free_pages(hinic5_cqm_handle, buf_node_child, cla_table->trunk_order);
-}
-
-static inline u8 *hinic5_cqm_cla_do_get_lvl0(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- u32 offset = 0;
-
- /* Level 0 CLA pages are statically allocated. */
- offset = index * cla_table->obj_size;
- *pa = cla_z_buf->buf_list->pa + offset;
- return (u8 *)(cla_z_buf->buf_list->va) + offset;
-}
-
-static inline u8 *hinic5_cqm_cla_do_get_lvl1(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf_list *buf_node_y = NULL;
- struct tag_hinic5_cqm_buf_list *buf_node_z = NULL;
- u32 y_index = 0;
- u32 z_index = 0;
- u8 *ret_addr = NULL;
- u32 offset = 0;
-
- z_index = index & ((1U << (cla_table->z + 1)) - 1);
- y_index = index >> (cla_table->z + 1);
-
- if (y_index >= cla_z_buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla get: index exceeds buf_number, y_index %u, z_buf_number %u\n",
- y_index, cla_z_buf->buf_number);
- return NULL;
- }
- buf_node_z = &cla_z_buf->buf_list[y_index];
- buf_node_y = cla_y_buf->buf_list;
-
- /* The z buf node does not exist, applying for a page first. */
- if (!buf_node_z->va) {
- if (hinic5_cqm_cla_alloc(hinic5_cqm_handle, cla_table, buf_node_y, buf_node_z,
- y_index) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_alloc));
- hinic5_cqm_err(handle->dev_hdl,
- "Cla get: cla_table->type=%u\n",
- cla_table->type);
- return NULL;
- }
- }
-
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Cla get: 1L: z_refcount=0x%x, count=0x%x\n",
- buf_node_z->refcount, count);
- buf_node_z->refcount += count;
- offset = z_index * cla_table->obj_size;
- ret_addr = (u8 *)(buf_node_z->va) + offset;
- *pa = buf_node_z->pa + offset;
-
- return ret_addr;
-}
-
-static inline u8 *hinic5_cqm_cla_do_get_lvl2(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf_list *buf_node_x = NULL;
- struct tag_hinic5_cqm_buf_list *buf_node_y = NULL;
- struct tag_hinic5_cqm_buf_list *buf_node_z = NULL;
- u32 z_index = index & ((1U << (cla_table->z + 1)) - 1);
- u32 y_index = (index >> (cla_table->z + 1)) & ((1U << (cla_table->y - cla_table->z)) - 1);
- u32 x_index = index >> (cla_table->y + 1);
- u64 tmp = x_index * ((u32)(PAGE_SIZE << cla_table->trunk_order) / sizeof(dma_addr_t)) + y_index;
- u8 *ret_addr = NULL;
- u32 offset = 0;
-
- if (x_index >= cla_y_buf->buf_number || tmp >= cla_z_buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla get: index exceeds buf_number, x_index %u, y_index %u, y_buf_number %u, z_buf_number %u\n",
- x_index, y_index, cla_y_buf->buf_number, cla_z_buf->buf_number);
- return NULL;
- }
-
- buf_node_x = cla_x_buf->buf_list;
- buf_node_y = &cla_y_buf->buf_list[x_index];
- buf_node_z = &cla_z_buf->buf_list[tmp];
-
- /* The y buf node does not exist, applying for pages for y node. */
- if (!buf_node_y->va) {
- if (hinic5_cqm_cla_alloc(hinic5_cqm_handle, cla_table, buf_node_x, buf_node_y, x_index) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_alloc));
- return NULL;
- }
- }
-
- /* The z buf node does not exist, applying for pages for z node. */
- if (!buf_node_z->va) {
- if (hinic5_cqm_cla_alloc(hinic5_cqm_handle, cla_table, buf_node_y, buf_node_z, y_index) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_alloc));
- if (buf_node_y->refcount == 0)
- /* To release node Y, cache_invalid is
- * required.
- */
- hinic5_cqm_cla_free_with_cache_invalid(hinic5_cqm_handle, cla_table, buf_node_x, buf_node_y, x_index);
- return NULL;
- }
-
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Cla get: 2L: y_refcount=0x%x\n", buf_node_y->refcount);
- /* reference counting of the y buffer node needs to increase
- * by 1.
- */
- buf_node_y->refcount++;
- }
-
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Cla get: 2L: z_refcount=0x%x, count=0x%x\n", buf_node_z->refcount, count);
- buf_node_z->refcount += count;
- offset = z_index * cla_table->obj_size;
- ret_addr = (u8 *)(buf_node_z->va) + offset;
- *pa = buf_node_z->pa + offset;
-
- return ret_addr;
-}
-
-static inline u8 *hinic5_cqm_cla_do_get(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_0)
- return hinic5_cqm_cla_do_get_lvl0(hinic5_cqm_handle, cla_table, index, count, pa);
- if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_1)
- return hinic5_cqm_cla_do_get_lvl1(hinic5_cqm_handle, cla_table, index, count, pa);
- if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_2)
- return hinic5_cqm_cla_do_get_lvl2(hinic5_cqm_handle, cla_table, index, count, pa);
- WARN_ON(true);
- return NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_get
- * Description : Apply for block buffer in number of count from the index
- * position in the cla table. If the buffer is dynamic, this
- * function may block.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- * struct tag_hinic5_cqm_cla_table *cla_table,
- * u32 index,
- * u32 count,
- * dma_addr_t *pa
- * Output : None
- * Return Value : u8 *
- * 1.Date : 2025/3/15
- * Modification : Created function
- */
-u8 *hinic5_cqm_cla_get(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa)
-{
- const bool dynamic_alloc = !cla_table->alloc_static;
- u8 *ret_addr = NULL;
-
- /* The CLA memory of the Fake VF are holded by the parent
- * function, so the Fake VF can't get the memory. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle))
- return NULL;
-
- if (index >= cla_table->obj_num)
- return NULL;
-
- if (dynamic_alloc)
- mutex_lock(&cla_table->lock);
-
- ret_addr = hinic5_cqm_cla_do_get(hinic5_cqm_handle, cla_table, index, count, pa);
-
- if (dynamic_alloc)
- mutex_unlock(&cla_table->lock);
-
- return ret_addr;
-}
-
-/**
- * Prototype : hinic5_cqm_cla_put
- * Description : Decrease the value of reference counting on the trunk page.
- * If the value is 0, the trunk page is released.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- * struct tag_hinic5_cqm_cla_table *cla_table,
- * u32 index,
- * u32 count
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_cla_put(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table, u32 index, u32 count)
-{
- struct tag_hinic5_cqm_buf *cla_z_buf = &cla_table->cla_z_buf;
- struct tag_hinic5_cqm_buf *cla_y_buf = &cla_table->cla_y_buf;
- struct tag_hinic5_cqm_buf *cla_x_buf = &cla_table->cla_x_buf;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf_list *buf_node_z = NULL;
- struct tag_hinic5_cqm_buf_list *buf_node_y = NULL;
- struct tag_hinic5_cqm_buf_list *buf_node_x = NULL;
- u32 x_index = 0;
- u32 y_index = 0;
- u64 tmp;
-
- /* No buffer is applied for the Fake VF. */
- if (HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle))
- return;
-
- /* The buffer is applied statically, and the reference counting
- * does not need to be controlled.
- */
- if (cla_table->alloc_static)
- return;
-
- mutex_lock(&cla_table->lock);
-
- if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_1) {
- y_index = index >> (cla_table->z + 1);
-
- if (y_index >= cla_z_buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl, "Cla put: idx exceeds buf_number, y_idx %u, z_buf_num %u type %u\n",
- y_index, cla_z_buf->buf_number, cla_table->type);
- goto out;
- }
-
- buf_node_z = &cla_z_buf->buf_list[y_index];
- buf_node_y = cla_y_buf->buf_list;
-
- /* When the value of reference counting on the z node page is 0,
- * the z node page is released.
- */
- buf_node_z->refcount -= count;
- if (buf_node_z->refcount == 0)
- /* The cache invalid is not required for the Z node. */
- hinic5_cqm_cla_free_without_cache_invalid(hinic5_cqm_handle, cla_table, buf_node_y, buf_node_z, y_index);
- } else if (cla_table->cla_lvl == HINIC5_CQM_CLA_LVL_2) {
- y_index = (index >> (cla_table->z + 1)) & ((1U << (cla_table->y - cla_table->z)) - 1);
- x_index = index >> (cla_table->y + 1);
- tmp = x_index * ((u32)(PAGE_SIZE << cla_table->trunk_order) / sizeof(dma_addr_t)) + y_index;
-
- if (x_index >= cla_y_buf->buf_number || tmp >= cla_z_buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl,
- "Cla put: index exceeds buf_number, x_index %u, y_index %u, y_buf_number %u, z_buf_number %u\n",
- x_index, y_index, cla_y_buf->buf_number, cla_z_buf->buf_number);
- goto out;
- }
-
- buf_node_x = cla_x_buf->buf_list;
- buf_node_y = &cla_y_buf->buf_list[x_index];
- buf_node_z = &cla_z_buf->buf_list[tmp];
-
- /* When the value of reference counting on the z node page is 0,
- * the z node page is released.
- */
- buf_node_z->refcount -= count;
- if (buf_node_z->refcount == 0) {
- hinic5_cqm_cla_free_without_cache_invalid(hinic5_cqm_handle, cla_table, buf_node_y, buf_node_z, y_index);
-
- /* When the value of reference counting on the y node
- * page is 0, the y node page is released.
- */
- buf_node_y->refcount--;
- if (buf_node_y->refcount == 0)
- /* Node y requires cache to be invalid. */
- hinic5_cqm_cla_free_with_cache_invalid(hinic5_cqm_handle, cla_table, buf_node_x, buf_node_y, x_index);
- }
- }
-
-out:
- mutex_unlock(&cla_table->lock);
-}
-
-/**
- * Prototype : hinic5_cqm_cla_table_get
- * Description : Searches for the CLA table data structure corresponding to a
- * BAT entry.
- * Input : struct tag_hinic5_cqm_bat_table *bat_table,
- * u32 entry_type
- * Output : None
- * Return Value : struct tag_hinic5_cqm_cla_table *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_cla_table *hinic5_cqm_cla_table_get(struct tag_hinic5_cqm_bat_table *bat_table,
- u32 entry_type)
-{
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- u32 i = 0;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if ((cla_table != NULL) && (entry_type == cla_table->type))
- return cla_table;
- }
-
- return NULL;
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.h
deleted file mode 100644
index 951c717ee..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bat_cla.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bat_cla.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_BAT_CLA_H
-#define HINIC5_CQM_BAT_CLA_H
-
-#include <linux/types.h>
-#include <linux/mutex.h>
-
-#include "hinic5_hw_cfg.h"
-#include "hinic5_hinic5_cqm.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_object.h"
-
-/* When the connection check is enabled, the maximum number of connections
- * supported by the chip is 1M - 63, which cannot reach 1M
- */
-#define HINIC5_CQM_BAT_MAX_CONN_NUM (0x100000 - 63)
-#define HINIC5_CQM_BAT_MAX_CACHE_CONN_NUM (0x100000 - 63)
-
-#ifndef MAX_ORDER
-#ifdef MAX_PAGE_ORDER
-#define MAX_ORDER MAX_PAGE_ORDER
-#endif
-#endif
-
-#define CLA_TABLE_PAGE_ORDER 0
-#define HINIC5_CQM_4K_PAGE_ORDER 0
-#define HINIC5_CQM_4K_PAGE_SIZE 4096
-
-#define HINIC5_CQM_8K_PAGE_ORDER 1
-
-#define HINIC5_CQM_BAT_ENTRY_MAX 16
-#define HINIC5_CQM_BAT_ENTRY_SIZE 16
-#define HINIC5_CQM_BAT_STORE_API_SIZE 16
-#define HINIC5_CQM_BAT_MAX (HINIC5_CQM_BAT_ENTRY_MAX * HINIC5_CQM_BAT_ENTRY_SIZE)
-
-#define HINIC5_CQM_BAT_SIZE_FT_RDMA_PF 240
-#define HINIC5_CQM_BAT_SIZE_FT_RDMA_VF 160
-#define HINIC5_CQM_BAT_SIZE_FT_PF 192
-#define HINIC5_CQM_BAT_SIZE_FT_VF 112
-#define HINIC5_CQM_BAT_SIZE_RDMA_PF 160
-#define HINIC5_CQM_BAT_SIZE_RDMA_VF 80
-
-#define HINIC5_CQM_BAT_INDEX0 0
-#define HINIC5_CQM_BAT_INDEX1 1
-#define HINIC5_CQM_BAT_INDEX2 2
-#define HINIC5_CQM_BAT_INDEX3 3
-#define HINIC5_CQM_BAT_INDEX4 4
-#define HINIC5_CQM_BAT_INDEX5 5
-#define HINIC5_CQM_BAT_INDEX6 6
-#define HINIC5_CQM_BAT_INDEX7 7
-#define HINIC5_CQM_BAT_INDEX8 8
-#define HINIC5_CQM_BAT_INDEX9 9
-#define HINIC5_CQM_BAT_INDEX10 10
-#define HINIC5_CQM_BAT_INDEX11 11
-#define HINIC5_CQM_BAT_INDEX12 12
-#define HINIC5_CQM_BAT_INDEX13 13
-#define HINIC5_CQM_BAT_INDEX14 14
-#define HINIC5_CQM_BAT_INDEX15 15
-
-enum hinic5_cqm_bat_entry_type {
- HINIC5_CQM_BAT_ENTRY_T_CFG = 0,
- HINIC5_CQM_BAT_ENTRY_T_HASH = 1,
- HINIC5_CQM_BAT_ENTRY_T_QPC = 2,
- HINIC5_CQM_BAT_ENTRY_T_SCQC = 3,
- HINIC5_CQM_BAT_ENTRY_T_SRQC = 4,
- HINIC5_CQM_BAT_ENTRY_T_MPT = 5,
- HINIC5_CQM_BAT_ENTRY_T_GID = 6,
- HINIC5_CQM_BAT_ENTRY_T_LUN = 7,
- HINIC5_CQM_BAT_ENTRY_T_TASKMAP = 8,
- HINIC5_CQM_BAT_ENTRY_T_L3I = 9,
- HINIC5_CQM_BAT_ENTRY_T_CHILDC = 10,
- HINIC5_CQM_BAT_ENTRY_T_TIMER = 11,
- HINIC5_CQM_BAT_ENTRY_T_XID2CID = 12,
- HINIC5_CQM_BAT_ENTRY_T_REORDER = 13,
- HINIC5_CQM_BAT_ENTRY_T_INVALID = 14,
- HINIC5_CQM_BAT_ENTRY_T_MAX = 15,
-};
-
-/* CLA update mode */
-#define HINIC5_CQM_CLA_RECORD_NEW_GPA 0
-#define HINIC5_CQM_CLA_DEL_GPA_WITHOUT_CACHE_INVALID 1
-#define HINIC5_CQM_CLA_DEL_GPA_WITH_CACHE_INVALID 2
-
-#define HINIC5_CQM_CLA_LVL_0 0
-#define HINIC5_CQM_CLA_LVL_1 1
-#define HINIC5_CQM_CLA_LVL_2 2
-#define HINIC5_CQM_CLA_LVL_UNSUPPORT 3
-
-#define HINIC5_CQM_MAX_INDEX_BIT_DEFAULT 19
-
-#define HINIC5_CQM_CHIP_CACHELINE 256
-#define HINIC5_CQM_CHIP_TIMER_CACHELINE 512
-#define HINIC5_CQM_OBJECT_256 256
-#define HINIC5_CQM_OBJECT_512 512
-#define HINIC5_CQM_OBJECT_1024 1024
-#define HINIC5_CQM_CHIP_GPA_MASK 0x1ffffffffffffff
-#define HINIC5_CQM_CHIP_GPA_HIMASK 0x1ffffff
-#define HINIC5_CQM_CHIP_GPA_LOMASK 0xffffffff
-#define HINIC5_CQM_CHIP_GPA_HSHIFT 32
-
-/* Aligns with 64 buckets and shifts rightward by 6 bits */
-#define HINIC5_CQM_HASH_NUMBER_UNIT 6
-
-/* mem_size should be none-zero and be 2^n */
-#define HINIC5_CQM_IS_SECURE_MEMSIZE_VALID(mem_size) \
- (((mem_size) != 0) && (((mem_size) & ((mem_size) - 1)) == 0))
-
-struct hinic5_cqm_mem_addr {
- void *va;
- dma_addr_t pa;
-};
-
-struct hinic5_cqm_secure_mem_info {
- struct hinic5_cqm_mem_addr addr;
- u32 len;
-};
-
-struct tag_hinic5_cqm_cla_table {
- u32 type;
- u32 obj_size;
- u32 obj_num;
- u32 max_buffer_size;
-
- u32 cla_lvl;
- u32 trunk_order; /* Preferred page order for CLA buffer.
- * Set this before calling hinic5_cqm_cla_xyz(). This value
- * will be overriden by hinic5_cqm_cla_xyz() when
- * hugepage_hint is enabled.
- */
- bool hugepage_hint; /* Hint for hugepage alloc to improve TLB locality */
-
- /* Dynamic allocation */
- bool alloc_static; /* Whether the buffer is statically allocated */
- struct mutex lock; /* Lock for cla buffer allocation and free */
-
- u32 max_index_bit;
- u32 cacheline_x; /* x value calculated based on cacheline, used by the chip */
- u32 cacheline_y; /* y value calculated based on cacheline, used by the chip */
- u32 cacheline_z; /* z value calculated based on cacheline, used by the chip */
- u32 x; /* x value calculated based on obj_size, used by software */
- u32 y; /* y value calculated based on obj_size, used by software */
- u32 z; /* z value calculated based on obj_size, used by software */
- struct tag_hinic5_cqm_buf cla_x_buf;
- struct tag_hinic5_cqm_buf cla_y_buf;
- struct tag_hinic5_cqm_buf cla_z_buf;
-
- struct tag_hinic5_cqm_bitmap bitmap;
-
- struct tag_hinic5_cqm_object_table obj_table; /* Mapping table between
- * indexes and objects
- */
- struct hinic5_cqm_mem_addr secure_mem; /* Secure memory with consecutive physical addresses */
-
- char name[HINIC5_VRAM_NAME_APPLY_LEN];
-};
-
-struct tag_hinic5_cqm_bat_entry_cfg {
- u32 cur_conn_num_h_4 : 4;
- u32 rsv1 : 4;
- u32 max_conn_num : 20;
- u32 rsv2 : 4;
-
- u32 max_conn_cache : 10;
- u32 rsv3 : 6;
- u32 cur_conn_num_l_16 : 16;
-
- u32 bloom_filter_addr : 16;
- u32 cur_conn_cache : 10;
- u32 rsv4 : 6;
-
- u32 bucket_num : 16;
- u32 bloom_filter_len : 16;
-};
-
-#define HINIC5_CQM_BAT_NO_BYPASS_CACHE 0
-#define HINIC5_CQM_BAT_BYPASS_CACHE 1
-
-#define HINIC5_CQM_BAT_ENTRY_SIZE_256 0
-#define HINIC5_CQM_BAT_ENTRY_SIZE_512 1
-#define HINIC5_CQM_BAT_ENTRY_SIZE_1024 2
-
-struct tag_hinic5_cqm_bat_entry_standerd {
- u32 entry_size : 2; /* 0: 256B, 1: 512B, 2: 1024B, others reserved */
- u32 rsv1 : 6;
- u32 max_number : 22; /* Maximum indexable number. Some types of CLA can only use 20 bits. */
- u32 rsv2 : 2;
-
- u32 cla_gpa_h : 32;
-
- u32 cla_gpa_l : 32;
-
- u32 rsv3 : 8;
- u32 z : 5; /* SM uses memory index [Z: 0] to access physical memory. */
- u32 y : 5; /* SM uses memory index [Y: Z+1] to access 2nd CLA. */
- u32 x : 5; /* SM uses memory index [X: Y+1] to access 1st CLA. */
- u32 rsv24 : 1;
- u32 bypass : 1; /* 0: not bypass, 1: bypass */
- u32 cla_level : 2; /* 0: 0 level CLA, 1: 1 level CLA, 2: 2 levels CLA, others reserved */
- u32 rsv5 : 5;
-};
-
-struct tag_hinic5_cqm_bat_entry_vf2pf {
- u32 cla_gpa_h : 25;
- u32 pf_id : 5;
- u32 fake_vf_en : 1;
- u32 acs_spu_en : 1;
-};
-
-#define HINIC5_CQM_BAT_ENTRY_TASKMAP_NUM 4
-struct tag_hinic5_cqm_bat_entry_taskmap_addr {
- u32 gpa_h;
- u32 gpa_l;
-};
-
-struct tag_hinic5_cqm_bat_entry_taskmap {
- struct tag_hinic5_cqm_bat_entry_taskmap_addr addr[HINIC5_CQM_BAT_ENTRY_TASKMAP_NUM];
-};
-
-struct tag_hinic5_cqm_bat_table {
- u32 bat_entry_type[HINIC5_CQM_BAT_ENTRY_MAX];
- u8 bat[HINIC5_CQM_BAT_ENTRY_MAX * HINIC5_CQM_BAT_ENTRY_SIZE];
- struct tag_hinic5_cqm_cla_table entry[HINIC5_CQM_BAT_ENTRY_MAX];
- /* Secure memory with consecutive physical addresses */
- struct hinic5_cqm_secure_mem_info func_secure_mem;
- /* In LB mode 1/2, the following entries need to be configured in all
- * enabled SMFs, and the GPAs must be different and independent.
- */
- struct tag_hinic5_cqm_cla_table timer_entry[CHIP_SMF_NUM_MAX];
- struct tag_hinic5_cqm_cla_table hash_entry[CHIP_SMF_NUM_MAX];
- struct tag_hinic5_cqm_cla_table xid2cid_entry[CHIP_SMF_NUM_MAX];
- u32 bat_size;
-};
-
-struct tag_hinic5_cqm_bat_update_param {
- u32 smf_id;
- u32 func_id;
- u32 bat_offset;
- u32 update_size;
-};
-
-s32 hinic5_cqm_bat_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-void hinic5_cqm_bat_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-
-s32 hinic5_cqm_cla_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-void hinic5_cqm_cla_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 entry_numb);
-
-u8 *hinic5_cqm_cla_get(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count, dma_addr_t *pa);
-void hinic5_cqm_cla_put(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_cla_table *cla_table,
- u32 index, u32 count);
-
-struct tag_hinic5_cqm_cla_table *hinic5_cqm_cla_table_get(struct tag_hinic5_cqm_bat_table *bat_table,
- u32 entry_type);
-u32 hinic5_cqm_funcid2smfid(const struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-
-#endif /* HINIC5_CQM_BAT_CLA_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.c
deleted file mode 100644
index 618d9a25b..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.c
+++ /dev/null
@@ -1,1748 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bitmap_table.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/gfp.h>
-#ifndef __UEFI__
-#include <linux/numa.h>
-#endif
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_hinic5_vram_api.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_cmd.h"
-#include "hinic5_cqm_object_intern.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_vram_common.h"
-#include "hinic5_cqm_cmdq.h"
-
-#include "comm_defs.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-
-#define common_section
-
-#ifndef __WIN__
-struct malloc_memory {
- bool (*check_alloc_mode)(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf);
- s32 (*malloc_func)(struct hinic5_hwdev *handle, struct tag_hinic5_cqm_buf *buf);
-};
-
-struct free_memory {
- bool (*check_alloc_mode)(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf);
- void (*free_func)(struct tag_hinic5_cqm_buf *buf);
-};
-#endif
-/**
- * Prototype : hinic5_cqm_swab64(Encapsulation of __swab64)
- * Description : Perform big-endian conversion for a memory block (8 bytes).
- * Input : u8 *addr: Start address of the memory block
- * u32 cnt: Number of 8 bytes in the memory block
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_swab64(u8 *addr, u32 cnt)
-{
- u64 *temp = (u64 *)addr;
- u64 value = 0;
- u32 i;
-
- for (i = 0; i < cnt; i++) {
- value = __swab64(*temp);
- *temp = value;
- temp++;
- }
-}
-
-/**
- * Prototype : hinic5_cqm_swab32(Encapsulation of __swab32)
- * Description : Perform big-endian conversion for a memory block (4 bytes).
- * Input : u8 *addr: Start address of the memory block
- * u32 cnt: Number of 4 bytes in the memory block
- * Output : None
- * Return Value : void
- * 1.Date : 2015/7/23
- * Modification : Created function
- */
-void hinic5_cqm_swab32(u8 *addr, u32 cnt)
-{
- u32 *temp = (u32 *)addr;
- u32 value = 0;
- u32 i;
-
- for (i = 0; i < cnt; i++) {
- value = __swab32(*temp);
- *temp = value;
- temp++;
- }
-}
-
-/**
- * Prototype : hinic5_cqm_shift
- * Description : Calculates n in a 2^n number.(Find the logarithm of 2^n)
- * Input : u32 data
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u32 hinic5_cqm_shift(u32 data)
-{
- u32 data_num = data;
- s32 shift = -1;
-
- do {
- data_num >>= 1;
- shift++;
- } while (data_num != 0);
-
- return (u32)shift;
-}
-
-/**
- * Prototype : hinic5_cqm_check_align
- * Description : Check whether the value is 2^n-aligned. If 0 or 1, false is
- * returned.
- * Input : u32 data
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/9/15
- * Modification : Created function
- */
-bool hinic5_cqm_check_align(u32 data)
-{
- u32 data_num = data;
-
- if (data == 0)
- return false;
-
- do {
- /* When the value can be exactly divided by 2,
- * the value of data is shifted right by one bit, that is,
- * divided by 2.
- */
- if ((data_num & 0x1) == 0)
- data_num >>= 1;
- /* If the value cannot be divisible by 2, the value is
- * not 2^n-aligned and false is returned.
- */
- else
- return false;
- } while (data_num != 1);
-
- return true;
-}
-
-/**
- * Prototype : hinic5_cqm_kmalloc_align
- * Description : Allocates 2^n-byte-aligned memory for the start address.
- * Input : size_t size
- * gfp_t flags
- * u16 align_order
- * Output : None
- * Return Value : void *
- * 1.Date : 2017/9/22
- * Modification : Created function
- */
-void *hinic5_cqm_kmalloc_align(size_t size, gfp_t flags, u16 align_order)
-{
- void *orig_addr = NULL;
- void *align_addr = NULL;
- void *index_addr = NULL;
-
- orig_addr = kmalloc(size + ((u64)1 << align_order) + sizeof(void *),
- flags);
- if (!orig_addr)
- return NULL;
-
- index_addr = (void *)((char *)orig_addr + sizeof(void *));
- align_addr =
- (void *)(uintptr_t)((((u64)(uintptr_t)index_addr + ((u64)1 << align_order) - 1) >>
- align_order) << align_order);
-
- /* Record the original memory address for memory release. */
- index_addr = (void *)((char *)align_addr - sizeof(void *));
- *(void **)index_addr = orig_addr;
-
- return align_addr;
-}
-
-/**
- * Prototype : hinic5_cqm_kfree_align
- * Description : Release the memory allocated for starting address alignment.
- * Input : void *addr
- * Output : None
- * Return Value : void
- * 1.Date : 2017/9/22
- * Modification : Created function
- */
-void hinic5_cqm_kfree_align(void *addr)
-{
- void *index_addr = NULL;
-
- /* Release the original memory address. */
- index_addr = (void *)((char *)addr - sizeof(void *));
-
- hinic5_cqm_dbg_pr_on(hinic5_cqm_verbose,
- "free aligned address: %p, original address: %p\n",
- addr, *(void **)index_addr);
-
- kfree(*(void **)index_addr);
-}
-
-static void hinic5_cqm_write_lock(rwlock_t *lock, bool bh)
-{
- if (bh)
- write_lock_bh(lock);
- else
- write_lock(lock);
-}
-
-static void hinic5_cqm_write_unlock(rwlock_t *lock, bool bh)
-{
- if (bh)
- write_unlock_bh(lock);
- else
- write_unlock(lock);
-}
-
-static void hinic5_cqm_read_lock(rwlock_t *lock, bool bh)
-{
- if (bh)
- read_lock_bh(lock);
- else
- read_lock(lock);
-}
-
-static void hinic5_cqm_read_unlock(rwlock_t *lock, bool bh)
-{
- if (bh)
- read_unlock_bh(lock);
- else
- read_unlock(lock);
-}
-
-s32 hinic5_cqm_buf_alloc_direct(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf, bool direct)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct page **pages = NULL;
- u32 i, j, order;
-
- order = (u32)get_order(buf->buf_size);
-
- if (!direct) {
- buf->direct.va = NULL;
- return HINIC5_CQM_SUCCESS;
- }
-
- pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(pages));
- return HINIC5_CQM_FAIL;
- }
-
- for (i = 0; i < buf->buf_number; i++) {
- for (j = 0; j < ((u32)1 << order); j++)
- pages[(ulong)(unsigned int)((i << order) + j)] =
- (void *)virt_to_page((void *)((uintptr_t)buf->buf_list[i].va +
- PAGE_SIZE * j));
- }
-
- buf->direct.va = vmap(pages, buf->page_number, VM_MAP, PAGE_KERNEL);
- vfree(pages);
- if (!buf->direct.va) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(buf->direct.va));
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-#ifndef __WIN__
-
-static bool check_use_hinic5_vram(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf)
-{
- return buf->buf_info.use_hinic5_vram != 0 ? true : false;
-}
-
-static bool check_use_non_hinic5_vram(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf)
-{
- return buf->buf_info.use_hinic5_vram != 0 ? false : true;
-}
-
-static bool check_for_use_node_alloc(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf)
-{
- if (buf->buf_info.use_hinic5_vram == 0 && handle->board_info.service_mode == 0)
- return true;
-
- return false;
-}
-
-static bool check_for_nouse_node_alloc(const struct hinic5_hwdev *handle, const struct tag_hinic5_cqm_buf *buf)
-{
- if (buf->buf_info.use_hinic5_vram == 0 && handle->board_info.service_mode != 0)
- return true;
-
- return false;
-}
-
-#ifndef __UEFI__
-static u8 hinic5_cqm_hinic5_vram_node(struct hinic5_hwdev *handle)
-{
- if (nr_node_ids > 0) {
- u16 func_id = hinic5_global_func_id(handle);
- // nr_node_ids indicates the maximum number of available NUMA nodes, will not be greater than u8 max value
- return (u8)(func_id % nr_node_ids);
- }
- return HINIC5_VRAM_NUMA_NODE0;
-}
-#endif
-
-static s32 hinic5_cqm_buf_hinic5_vram_kalloc(struct hinic5_hwdev *handle, struct tag_hinic5_cqm_buf *buf)
-{
- void *vaddr = NULL;
- u32 i;
-
- vaddr = hinic5_hinic5_vram_kalloc_node(buf->buf_info.buf_hinic5_vram_name,
- (u64)buf->buf_size * buf->buf_number,
- hinic5_cqm_hinic5_vram_node(handle));
- if (!vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(buf_page));
- return HINIC5_CQM_FAIL;
- }
-
- for (i = 0; i < buf->buf_number; i++)
- buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_buf_hinic5_vram_free(struct tag_hinic5_cqm_buf *buf)
-{
- s32 i;
-
- if (buf->buf_list == NULL)
- return;
-
- if (buf->buf_list[0].va)
- hinic5_hinic5_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_hinic5_vram_name,
- (u64)buf->buf_size * buf->buf_number);
-
- for (i = 0; i < (s32)buf->buf_number; i++)
- buf->buf_list[i].va = NULL;
-}
-
-static void hinic5_cqm_buf_free_page_common(struct tag_hinic5_cqm_buf *buf)
-{
- u32 order;
- u32 i;
-
- if (buf->buf_list == NULL)
- return;
-
- order = (u32)get_order(buf->buf_size);
-
- for (i = 0; i < buf->buf_number; i++) {
- if (buf->buf_list[i].va) {
- free_pages((ulong)(uintptr_t)(buf->buf_list[i].va), order);
- buf->buf_list[i].va = NULL;
- }
- }
-}
-
-static s32 hinic5_cqm_buf_use_node_alloc_page(struct hinic5_hwdev *handle, struct tag_hinic5_cqm_buf *buf)
-{
- struct page *newpage = NULL;
- gfp_t flags = GFP_KERNEL | __GFP_ZERO;
- u32 order, i;
- void *va = NULL;
- s32 node = dev_to_node(handle->dev_hdl);
-
- order = (u32)get_order(buf->buf_size);
- if (order > 0)
- flags |= __GFP_COMP;
-
- for (i = 0; i < buf->buf_number; i++) {
- newpage = alloc_pages_node(node, flags, order);
- if (!newpage) {
- hinic5_cqm_warn(handle->dev_hdl,
- "alloc buf pages fail (%u/%u)\n",
- i, buf->buf_number);
- break;
- }
- va = (void *)page_address(newpage);
- /* Initialize the page after the page is applied for.
- * If hash entries are involved, the initialization
- * value must be 0.
- */
- memset(va, 0, buf->buf_size);
- buf->buf_list[i].va = va;
- }
-
- if (i != buf->buf_number) {
- hinic5_cqm_buf_free_page_common(buf);
- return HINIC5_CQM_BUF_ALLOC_BUDDY_PAGES_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_buf_unused_node_alloc_page(struct hinic5_hwdev *handle, struct tag_hinic5_cqm_buf *buf)
-{
- gfp_t flags = GFP_KERNEL | __GFP_ZERO;
- u32 order, i;
- void *va = NULL;
-
- order = (u32)get_order(buf->buf_size);
- if (order > 0)
- flags |= __GFP_COMP;
-
- for (i = 0; i < buf->buf_number; i++) {
- va = (void *)(uintptr_t)ossl_get_free_pages(flags, order);
- if (!va) {
- hinic5_cqm_warn(handle->dev_hdl,
- "alloc buf pages fail (%u/%u)\n",
- i, buf->buf_number);
- break;
- }
- /* Initialize the page after the page is applied for.
- * If hash entries are involved, the initialization
- * value must be 0.
- */
- memset(va, 0, buf->buf_size);
- buf->buf_list[i].va = va;
- }
-
- if (i != buf->buf_number) {
- hinic5_cqm_buf_free_page_common(buf);
- return HINIC5_CQM_BUF_ALLOC_BUDDY_PAGES_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static const struct malloc_memory g_malloc_funcs[] = {
- {check_use_hinic5_vram, hinic5_cqm_buf_hinic5_vram_kalloc},
- {check_for_use_node_alloc, hinic5_cqm_buf_use_node_alloc_page},
- {check_for_nouse_node_alloc, hinic5_cqm_buf_unused_node_alloc_page}
-};
-
-static const struct free_memory g_free_funcs[] = {
- {check_use_hinic5_vram, hinic5_cqm_buf_hinic5_vram_free},
- {check_use_non_hinic5_vram, hinic5_cqm_buf_free_page_common}
-};
-
-static s32 hinic5_cqm_buf_alloc_page(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
- u32 i;
-
- for (i = 0; i < malloc_funcs_num; i++) {
- if (g_malloc_funcs[i].check_alloc_mode &&
- g_malloc_funcs[i].malloc_func &&
- g_malloc_funcs[i].check_alloc_mode(handle, buf))
- return g_malloc_funcs[i].malloc_func(handle, buf);
- }
-
- hinic5_cqm_err(handle->dev_hdl, "Unknown alloc mode\n");
-
- return HINIC5_CQM_FAIL;
-}
-
-static void hinic5_cqm_buf_free_page(struct tag_hinic5_cqm_buf *buf)
-{
- u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
- u32 i;
-
- for (i = 0; i < free_funcs_num; i++) {
- if (g_free_funcs[i].check_alloc_mode &&
- g_free_funcs[i].free_func &&
- g_free_funcs[i].check_alloc_mode(NULL, buf))
- return g_free_funcs[i].free_func(buf);
- }
-}
-
-static s32 hinic5_cqm_buf_alloc_map(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct device *dev = hinic5_cqm_handle->dev;
- void *va = NULL;
- s32 i;
-
- for (i = 0; i < (s32)buf->buf_number; i++) {
- va = buf->buf_list[i].va;
- buf->buf_list[i].pa = dma_map_single(dev, va, buf->buf_size,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(dev, buf->buf_list[i].pa) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(buf_list));
- break;
- }
- }
-
- if (i != (s32)buf->buf_number) {
- i--;
- for (; i >= 0; i--)
- dma_unmap_single(dev, buf->buf_list[i].pa,
- buf->buf_size, DMA_BIDIRECTIONAL);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/* Applying for the buffer list descriptor space */
-s32 hinic5_cqm_buf_list_alloc(struct tag_hinic5_cqm_buf *buf)
-{
- size_t size = buf->buf_number * sizeof(struct tag_hinic5_cqm_buf_list);
-
- if (WARN_ON_ONCE(buf->buf_list))
- return HINIC5_CQM_SUCCESS;
-
- buf->buf_list = vmalloc(size);
- if (unlikely(!buf->buf_list)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(linux_buf_list));
- return HINIC5_CQM_FAIL;
- }
-
- memset(buf->buf_list, 0, size);
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_buf_alloc
- * Description : Apply for buffer space and DMA mapping for the struct tag_hinic5_cqm_buf
- * structure.
- * Input : struct tag_hinic5_cqm_buf *buf
- * struct device *dev
- * bool direct: Whether direct remapping is required
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_buf_alloc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf, bool direct)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i;
- s32 ret = HINIC5_CQM_FAIL;
-
- ret = hinic5_cqm_buf_list_alloc(buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS))
- return ret;
-
- /* Page for applying for each buffer */
- ret = hinic5_cqm_buf_alloc_page(hinic5_cqm_handle, buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(linux_hinic5_cqm_buf_alloc_page));
- goto err1;
- }
-
- /* PCI mapping of the buffer */
- ret = hinic5_cqm_buf_alloc_map(hinic5_cqm_handle, buf);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(linux_hinic5_cqm_buf_alloc_map));
- goto err2;
- }
-
- /* direct remapping */
- ret = hinic5_cqm_buf_alloc_direct(hinic5_cqm_handle, buf, direct);
- if (unlikely(ret != HINIC5_CQM_SUCCESS)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc_direct));
- goto err3;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err3:
- for (i = 0; i < buf->buf_number; i++)
- dma_unmap_single(hinic5_cqm_handle->dev, buf->buf_list[i].pa, buf->buf_size,
- DMA_BIDIRECTIONAL);
-err2:
- hinic5_cqm_buf_free_page(buf);
-err1:
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- return ret;
-}
-
-/**
- * Prototype : hinic5_cqm_buf_free
- * Description : Release the buffer space and DMA mapping for the struct tag_hinic5_cqm_buf
- * structure.
- * Input : struct tag_hinic5_cqm_buf *buf
- * struct device *dev
- * bool direct: Whether direct remapping is required
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_buf_free(struct tag_hinic5_cqm_buf *buf, struct device *dev)
-{
- u32 i;
-
- if (buf->direct.va) {
- vunmap(buf->direct.va);
- buf->direct.va = NULL;
- }
-
- // A secure mem buf doesn't need to call dma ummap and free pages.
- // see hinic5_cqm_cla_secure_mem_buf_alloc()
- if (buf->secure_mem_flag == HINIC5_CQM_SECURE_BUFFER_EN)
- goto free_buf_list;
-
- if (buf->buf_list) {
- for (i = 0; i < buf->buf_number; i++) {
- if (buf->buf_list[i].va)
- dma_unmap_single(dev, buf->buf_list[i].pa,
- buf->buf_size,
- DMA_BIDIRECTIONAL);
- }
- hinic5_cqm_buf_free_page(buf);
- }
-
-free_buf_list:
- if (buf->buf_list) {
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- }
-}
-
-#else /* __WIN__ */
-
-static s32 hinic5_cqm_buf_alloc_page(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct huge_buf_addr *bufs_addr = NULL;
- u32 total_size;
- u32 i;
-
- total_size = buf->buf_size * buf->buf_number;
-
- buf->huge_buf_number = (total_size / HINIC5_CQM_HUGE_BUF_SIZE) +
- ((total_size % HINIC5_CQM_HUGE_BUF_SIZE) ? 1 : 0);
- if (!buf->huge_buf_number) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(buf->huge_buf_number));
- return HINIC5_CQM_FAIL;
- }
-
- buf->bufs_addr = vmalloc(buf->huge_buf_number *
- sizeof(struct huge_buf_addr));
- if (!buf->bufs_addr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(bufs_addr));
- return HINIC5_CQM_FAIL;
- }
- memset(buf->bufs_addr, 0,
- buf->huge_buf_number * sizeof(struct huge_buf_addr));
-
- bufs_addr = buf->bufs_addr;
- for (i = 0; i < buf->huge_buf_number; i++) {
- if ((i + 1) == buf->huge_buf_number)
- bufs_addr[i].huge_buf_size =
- PAGE_SIZE <<
- get_order(total_size - HINIC5_CQM_HUGE_BUF_SIZE * i);
- else
- bufs_addr[i].huge_buf_size = HINIC5_CQM_HUGE_BUF_SIZE;
-
- bufs_addr[i].huge_buf_vaddr =
- __get_free_pages(GFP_KERNEL | __GFP_ZERO,
- get_order(bufs_addr[i].huge_buf_size));
- if (!bufs_addr[i].huge_buf_vaddr) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_ALLOC_FAIL(huge_buf_vaddr));
- break;
- }
- }
-
- /* exception processing */
- if (i != buf->huge_buf_number) {
- i--;
- for (; i >= 0; i--) {
- free_pages((ulong)(buf->bufs_addr[i].huge_buf_vaddr),
- get_order(buf->bufs_addr[i].huge_buf_size));
- buf->bufs_addr[i].huge_buf_vaddr = NULL;
- }
-
- vfree(buf->bufs_addr);
- buf->bufs_addr = NULL;
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_buf_alloc_map(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct device *dev = hinic5_cqm_handle->dev;
- struct huge_buf_addr *bufs_addr = NULL;
- u32 i;
-
- bufs_addr = buf->bufs_addr;
- for (i = 0; i < buf->huge_buf_number; i++) {
- bufs_addr[i].huge_buf_paddr = dma_map_single(dev, bufs_addr[i].huge_buf_vaddr,
- bufs_addr[i].huge_buf_size,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(dev, bufs_addr[i].huge_buf_paddr)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(huge_buf_paddr));
- break;
- }
- }
-
- if (i != buf->huge_buf_number) {
- i--;
- for (; i >= 0; i--)
- dma_unmap_single(dev, bufs_addr[i].huge_buf_paddr,
- bufs_addr[i].huge_buf_size,
- DMA_BIDIRECTIONAL);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-s32 hinic5_cqm_buf_alloc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf, bool direct)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct huge_buf_addr *bufs_addr = NULL;
- u32 cnt;
- u32 i;
- s32 j = 0;
-
- if (buf->buf_size > HINIC5_CQM_HUGE_BUF_SIZE) {
- hinic5_cqm_err(handle->dev_hdl, "Buffer size(0x%x) is large than huge buffer size(0x%x)\n",
- buf->buf_size, HINIC5_CQM_HUGE_BUF_SIZE);
- return HINIC5_CQM_FAIL;
- }
-
- /* Applying for the buffer list descriptor space */
- buf->buf_list = vmalloc(buf->buf_number * sizeof(struct tag_hinic5_cqm_buf_list));
- if (unlikely(buf->buf_list == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(win_buf_list));
- return HINIC5_CQM_FAIL;
- }
- memset(buf->buf_list,
- 0, buf->buf_number * sizeof(struct tag_hinic5_cqm_buf_list));
-
- /* Page for applying for each buffer */
- if (hinic5_cqm_buf_alloc_page(hinic5_cqm_handle, buf) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(win_hinic5_cqm_buf_alloc_page));
- goto err1;
- }
-
- /* PCI mapping of the buffer */
- if (hinic5_cqm_buf_alloc_map(hinic5_cqm_handle, buf) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(win_hinic5_cqm_buf_alloc_map));
- goto err2;
- }
-
- /* Assign a value to the buffer list space. */
- for (i = 0; i < buf->buf_number; i++) {
- bufs_addr = &buf->bufs_addr[j];
- cnt = bufs_addr->huge_buf_size / buf->buf_size;
- buf->buf_list[i].va = (void *)((u64)bufs_addr->huge_buf_vaddr +
- buf->buf_size * (i % cnt));
- buf->buf_list[i].pa = bufs_addr->huge_buf_paddr +
- buf->buf_size * (i % cnt);
-
- if (0 == ((i + 1) % cnt))
- j++;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err2:
- for (i = 0; i < buf->huge_buf_number; i++) {
- free_pages((ulong)(buf->bufs_addr[i].huge_buf_vaddr),
- get_order(buf->bufs_addr[i].huge_buf_size));
- buf->bufs_addr[i].huge_buf_vaddr = NULL;
- }
-
- vfree(buf->bufs_addr);
- buf->bufs_addr = NULL;
-
-err1:
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- return HINIC5_CQM_FAIL;
-}
-
-void hinic5_cqm_buf_free(struct tag_hinic5_cqm_buf *buf, struct device *dev)
-{
- u32 i;
-
- if (buf->bufs_addr) {
- for (i = 0; i < buf->huge_buf_number; i++) {
- dma_unmap_single(dev, buf->bufs_addr[i].huge_buf_paddr,
- buf->bufs_addr[i].huge_buf_size,
- DMA_BIDIRECTIONAL);
- free_pages((ulong)(buf->bufs_addr[i].huge_buf_vaddr),
- get_order(buf->bufs_addr[i].huge_buf_size));
- buf->bufs_addr[i].huge_buf_paddr = 0;
- buf->bufs_addr[i].huge_buf_vaddr = NULL;
- }
- vfree(buf->bufs_addr);
- buf->bufs_addr = NULL;
- }
-
- if (buf->buf_list) {
- vfree(buf->buf_list);
- buf->buf_list = NULL;
- }
-}
-
-#endif /* __WIN__ */
-
-static s32 hinic5_cqm_cla_cache_invalid_cmd(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- hinic5_cqm_cla_cache_invalid_cmd_s *cmd_info)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- s32 ret;
- u8 cmd;
-
- hinic5_cqm_handle->cmdq_ops->prepare_cmd_cache_invalidate(cmd_info, buf_in, &cmd);
-
- /* Send the cmdq command. */
- ret = hinic5_cqm_send_cmd_box((void *)(hinic5_cqm_handle->ex_handle), HINIC5_CQM_MOD_HINIC5_CQM,
- cmd, buf_in, NULL, NULL,
- HINIC5_CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- hinic5_cqm_err(handle->dev_hdl,
- "Cla cache invalid: hinic5_cqm_send_cmd_box_ret=%d\n",
- ret);
- hinic5_cqm_err(handle->dev_hdl,
- "Cla cache invalid: cla_cache_invalid_cmd: 0x%x 0x%x 0x%x\n",
- cmd_info->gpa_h, cmd_info->gpa_l, cmd_info->cache_size);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_cla_cache_invalid_all_smf(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- hinic5_cqm_cla_cache_invalid_cmd_s *cmd)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- u32 i;
- s32 ret = HINIC5_CQM_FAIL;
-
- for (i = 0; i < func_cap->smf_max_num; i++) {
- if ((func_cap->smf_pg & (1U << i)) != 0) {
- cmd->smf_id = i;
- ret = hinic5_cqm_cla_cache_invalid_cmd(hinic5_cqm_handle, buf_in, cmd);
- if (ret != HINIC5_CQM_SUCCESS)
- return ret;
- }
- }
- return ret;
-}
-
-s32 hinic5_cqm_cla_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, dma_addr_t pa, u32 cache_size)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- struct hinic5_func_attr *func_attr = NULL;
- struct tag_hinic5_cqm_bat_entry_vf2pf gpa = {0};
- hinic5_cqm_cla_cache_invalid_cmd_s cmd;
- u32 cla_gpa_h = 0;
- s32 ret = HINIC5_CQM_FAIL;
-
- buf_in = hinic5_cqm_cmd_alloc((void *)(hinic5_cqm_handle->ex_handle));
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- gpa.cla_gpa_h = HINIC5_CQM_ADDR_HI(pa) & HINIC5_CQM_CHIP_GPA_HIMASK;
- gpa.acs_spu_en = hinic5_cqm_get_acs_spu_en(hinic5_cqm_handle);
-
- /* In non-fake mode, set func_id to 0xffff.
- * Indicate the current func fake mode.
- * The value of func_id is a fake func ID.
- */
- if (HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle)) {
- cmd.func_id = hinic5_cqm_handle->func_attribute.func_global_idx;
- func_attr = &hinic5_cqm_handle->parent_hinic5_cqm_handle->func_attribute;
- gpa.fake_vf_en = 1;
- gpa.pf_id = func_attr->func_global_idx;
- } else {
- cmd.func_id = 0xffff;
- }
- memcpy(&cla_gpa_h, &gpa, sizeof(u32));
-
- /* Fill command and convert it to big endian */
- cmd.cache_size = cache_size;
- cmd.gpa_l = HINIC5_CQM_ADDR_LW(pa);
- cmd.gpa_h = cla_gpa_h;
-
- /* The normal mode is the 1822 traditional mode and is all configured
- * on SMF0.
- */
- /* Mode 0 is hashed to 4 SMF engines (excluding PPF) by func ID. */
- if (HINIC5_CQM_IS_LB_MODE_NORMAL(hinic5_cqm_handle) ||
- (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle) && !HINIC5_CQM_IS_PPF(hinic5_cqm_handle))) {
- cmd.smf_id = hinic5_cqm_funcid2smfid(hinic5_cqm_handle);
- ret = hinic5_cqm_cla_cache_invalid_cmd(hinic5_cqm_handle, buf_in, &cmd);
- /* Mode 1/2 are allocated to 4 SMF engines by flow. Therefore,
- * one function needs to be allocated to 4 SMF engines.
- */
- /* The PPF in mode 0 needs to be configured on 4 engines,
- * and the timer resources need to be shared by the 4 engines.
- */
- } else if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) ||
- (HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle) && HINIC5_CQM_IS_PPF(hinic5_cqm_handle))) {
- ret = hinic5_cqm_cla_cache_invalid_all_smf(hinic5_cqm_handle, buf_in, &cmd);
- } else {
- hinic5_cqm_err(handle->dev_hdl, "Cla cache invalid: unsupport lb mode=%u\n", hinic5_cqm_handle->func_capability.lb_mode);
- ret = HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_cmd_free((void *)(hinic5_cqm_handle->ex_handle), buf_in);
- return ret;
-}
-
-static void free_cache_inv(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf,
- s32 *inv_flag)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 order;
- u32 i;
-
- order = (u32)get_order(buf->buf_size);
-
- if (!hinic5_is_chip_present(handle))
- return;
-
- if (!buf->buf_list)
- return;
-
- for (i = 0; i < buf->buf_number; i++) {
- if (!buf->buf_list[i].va)
- continue;
-
- if (*inv_flag != HINIC5_CQM_SUCCESS)
- continue;
-
- /* In the Pangea environment, if the cmdq times out,
- * no subsequent message is sent.
- */
- *inv_flag = hinic5_cqm_cla_cache_invalid(hinic5_cqm_handle, buf->buf_list[i].pa,
- (u32)(PAGE_SIZE << order));
- if (*inv_flag != HINIC5_CQM_SUCCESS)
- hinic5_cqm_err(handle->dev_hdl,
- "Buffer free: fail to invalid buf_list pa cache, inv_flag=%d\n",
- *inv_flag);
- }
-}
-
-void hinic5_cqm_buf_free_cache_inv(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf,
- s32 *inv_flag)
-{
- if (!COMM_SUPPORT_SMF_CACHE_INVALID(hinic5_cqm_handle->ex_handle)) {
- /* Send a command to the chip to kick out the cache. */
- free_cache_inv(hinic5_cqm_handle, buf, inv_flag);
- }
-
- /* Clear host resources */
- hinic5_cqm_buf_free(buf, hinic5_cqm_handle->dev);
-}
-
-#define bitmap_section
-
-/**
- * Prototype : hinic5_cqm_single_bitmap_init
- * Description : Initialize a bitmap.
- * Input : struct tag_hinic5_cqm_bitmap *bitmap
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/9/9
- * Modification : Created function
- */
-static s32 hinic5_cqm_single_bitmap_init(struct tag_hinic5_cqm_bitmap *bitmap)
-{
- u32 nbytes;
-
- spin_lock_init(&bitmap->lock);
-
- nbytes = BITS_TO_LONGS(bitmap->max_num) * sizeof(long);
- if (bitmap->bitmap_info.use_hinic5_vram != 0)
- bitmap->table = hinic5_hinic5_vram_kalloc(bitmap->bitmap_info.buf_hinic5_vram_name, nbytes);
- else
- bitmap->table = vmalloc(nbytes);
-
- if (unlikely(bitmap->table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(bitmap->table));
- return HINIC5_CQM_FAIL;
- }
-
- memset(bitmap->table, 0, nbytes);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_bitmap_toe_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
-
- /* SRQC of TOE services is not managed through the CLA table,
- * but the bitmap is required to manage SRQid.
- */
- if (hinic5_cqm_handle->service[HINIC5_CQM_SERVICE_T_TOE].valid) {
- bitmap = &hinic5_cqm_handle->toe_own_capability.srqc_bitmap;
- bitmap->max_num =
- hinic5_cqm_handle->toe_own_capability.toe_srqc_number;
- bitmap->reserved_top = 0;
- bitmap->reserved_back = 0;
- bitmap->last = 0;
- if (bitmap->max_num == 0) {
- hinic5_cqm_info(handle->dev_hdl,
- "Bitmap init: toe_srqc_number=0, don't init bitmap\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- if (hinic5_cqm_single_bitmap_init(bitmap) != HINIC5_CQM_SUCCESS)
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_bitmap_toe_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
-
- if (hinic5_cqm_handle->service[HINIC5_CQM_SERVICE_T_TOE].valid) {
- bitmap = &hinic5_cqm_handle->toe_own_capability.srqc_bitmap;
- if (bitmap->table) {
- spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
- bitmap->table = NULL;
- }
- }
-}
-
-static s32 hinic5_cqm_bitmap_init_by_type(u32 type, struct tag_hinic5_cqm_bitmap *bitmap, struct tag_hinic5_cqm_func_capability *capability)
-{
- switch (type) {
- case HINIC5_CQM_BAT_ENTRY_T_QPC:
- bitmap->max_num = capability->qpc_number;
- bitmap->reserved_top = capability->qpc_reserved;
- bitmap->reserved_back = capability->qpc_reserved_back;
- bitmap->last = capability->qpc_reserved;
- bitmap->bitmap_info.use_hinic5_vram = get_use_hinic5_vram_flag();
- break;
- case HINIC5_CQM_BAT_ENTRY_T_MPT:
- bitmap->max_num = capability->mpt_number;
- bitmap->reserved_top = capability->mpt_reserved;
- bitmap->reserved_back = capability->mpt_reserved_back;
- bitmap->last = capability->mpt_reserved;
- break;
- case HINIC5_CQM_BAT_ENTRY_T_SCQC:
- bitmap->max_num = capability->scqc_number;
- bitmap->reserved_top = capability->scq_reserved;
- bitmap->reserved_back = capability->scq_reserved_back;
- bitmap->last = capability->scq_reserved;
- break;
- case HINIC5_CQM_BAT_ENTRY_T_SRQC:
- bitmap->max_num = capability->srqc_number;
- bitmap->reserved_top = capability->srq_reserved;
- bitmap->reserved_back = capability->srq_reserved_back;
- bitmap->last = capability->srq_reserved;
- break;
- default:
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-
-/**
- * Prototype : hinic5_cqm_bitmap_init
- * Description : Initialize the bitmap.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_bitmap_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- s32 ret = HINIC5_CQM_SUCCESS;
- u32 i;
- int err;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if (cla_table->obj_num == 0) {
- hinic5_cqm_info(handle->dev_hdl, "Cla alloc: cla_type %u, obj_num=0, don't init bitmap\n", cla_table->type);
- continue;
- }
-
- bitmap = &cla_table->bitmap;
- err = snprintf(bitmap->bitmap_info.buf_hinic5_vram_name,
- HINIC5_VRAM_NAME_MAX_LEN, "%s%s%02u", cla_table->name,
- HINIC5_VRAM_HINIC5_CQM_BITMAP_BASE, cla_table->type);
- if (err < 0) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm bitmap hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_bitmap_init_by_type(cla_table->type, bitmap, capability) == HINIC5_CQM_SUCCESS) {
- hinic5_cqm_info(handle->dev_hdl, "Bitmap init: cla_table_type=%u, max_num=0x%x\n",
- cla_table->type, bitmap->max_num);
- ret = hinic5_cqm_single_bitmap_init(bitmap);
- }
-
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Bitmap init: failed to init cla_table_type=%u, obj_num=0x%x\n",
- cla_table->type, cla_table->obj_num);
- goto err;
- }
- }
-
- if (hinic5_cqm_bitmap_toe_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS)
- goto err;
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_bitmap_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-static void hinic5_cqm_bitmap_table_free(struct tag_hinic5_cqm_bitmap *bitmap)
-{
- if (bitmap->bitmap_info.use_hinic5_vram != 0)
- hinic5_hinic5_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_hinic5_vram_name,
- BITS_TO_LONGS(bitmap->max_num) * sizeof(long));
- else
- vfree(bitmap->table);
- bitmap->table = NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_uninit
- * Description : Deinitialize the bitmap.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_bitmap_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- bitmap = &cla_table->bitmap;
- if (cla_table->type != HINIC5_CQM_BAT_ENTRY_T_INVALID) {
- if (bitmap->table) {
- spin_lock_deinit(&bitmap->lock);
- hinic5_cqm_bitmap_table_free(bitmap);
- }
- }
- }
-
- hinic5_cqm_bitmap_toe_uninit(hinic5_cqm_handle);
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_check_range
- * Description : Starting from begin, check whether the bits in number of count
- * are idle in the table. Requirement:
- * 1. This group of bits cannot cross steps.
- * 2. This group of bits must be 0.
- * Input : const ulong *table,
- * u32 step,
- * u32 max_num,
- * u32 begin,
- * u32 count
- * Output : None
- * Return Value : u32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-static u32 hinic5_cqm_bitmap_check_range(const ulong *table, u32 step, u32 max_num, u32 begin,
- u32 count)
-{
- u32 end = (begin + (count - 1));
- u32 i;
-
- /* Single-bit check is not performed. */
- if (count == 1)
- return begin;
-
- /* The end value exceeds the threshold. */
- if (end >= max_num)
- return max_num;
-
- /* Bit check, the next bit is returned when a non-zero bit is found. */
- for (i = (begin + 1); i <= end; i++) {
- if (test_bit((int)i, table))
- return i + 1;
- }
-
- /* Check whether it's in different steps. */
- if ((begin & (~(step - 1))) != (end & (~(step - 1))))
- return (end & (~(step - 1)));
-
- /* If the check succeeds, begin is returned. */
- return begin;
-}
-
-static void hinic5_cqm_bitmap_find(struct tag_hinic5_cqm_bitmap *bitmap, u32 *index, u32 last,
- u32 step, u32 count)
-{
- u32 last_num = last;
- u32 max_num = bitmap->max_num - bitmap->reserved_back;
- ulong *table = bitmap->table;
-
- do {
- *index = (u32)find_next_zero_bit(table, max_num, last_num);
- if (*index < max_num)
- last_num = hinic5_cqm_bitmap_check_range(table, step, max_num,
- *index, count);
- else
- break;
- } while (last_num != *index);
-}
-
-static u32 hinic5_cqm_bitmap_find_with_lowbits_forward(struct tag_hinic5_cqm_bitmap *bitmap,
- u32 start, u32 end, u32 lowbits, u32 lowbits_mask)
-{
- ulong *table = bitmap->table;
- u32 offset = start;
- u32 index = HINIC5_CQM_INDEX_INVALID;
-
- while (offset < end) {
- index = (u32)find_next_zero_bit(table, end, offset);
- if (index >= end)
- return HINIC5_CQM_INDEX_INVALID;
-
- if ((index & lowbits_mask) == lowbits) /* match lowbits */
- break;
-
- offset = index + 1;
- if (offset == end)
- return HINIC5_CQM_INDEX_INVALID;
- }
-
- return index;
-}
-
-static inline u32 find_next_zero_bit_reverse(const unsigned long *addr, u32 end, u32 start)
-{
- u32 i;
-
- for (i = start; i > end; i--) {
- if (test_bit(i, addr) == 0)
- return i;
- }
-
- return i;
-}
-
-static u32 hinic5_cqm_bitmap_find_with_lowbits_reverse(struct tag_hinic5_cqm_bitmap *bitmap,
- u32 start, u32 end, u32 lowbits, u32 lowbits_mask)
-{
- ulong *table = bitmap->table;
- u32 offset = start;
- u32 index = HINIC5_CQM_INDEX_INVALID;
-
- while (offset > end) {
- index = (u32)find_next_zero_bit_reverse(table, end, offset);
- if (index <= end)
- return HINIC5_CQM_INDEX_INVALID;
-
- if ((index & lowbits_mask) == lowbits) /* match lowbits */
- break;
-
- offset = index - 1;
- if (offset == end)
- return HINIC5_CQM_INDEX_INVALID;
- }
-
- return index;
-}
-
-/* search range is [start, end) or (end, start] */
-static u32 hinic5_cqm_bitmap_find_with_lowbits_align(struct tag_hinic5_cqm_bitmap *bitmap,
- u32 start, u32 end, u32 xid)
-{
- u32 lowbits_mode = HINIC5_CQM_DYNAMIC_XID_LB_MODE(xid);
- u32 lowbits_mask = HINIC5_CQM_DYNAMIC_XID_LOW_BIT_MASK(lowbits_mode);
- u32 lowbits = (HINIC5_CQM_DYNAMIC_XID_LOW_BITS(xid) & lowbits_mask);
- u32 index;
-
- if (start <= end)
- index = hinic5_cqm_bitmap_find_with_lowbits_forward(bitmap, start, end,
- lowbits, lowbits_mask);
- else
- index = hinic5_cqm_bitmap_find_with_lowbits_reverse(bitmap, start, end,
- lowbits, lowbits_mask);
-
- return index;
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_alloc
- * Description : Apply for a bitmap index. 0 and 1 must be left blank.
- * Scan backwards from where you last applied.
- * A string of consecutive indexes must be applied for and
- * cannot be applied for across trunks.
- * Input : struct tag_hinic5_cqm_bitmap *bitmap,
- * u32 step,
- * u32 count
- * Output : None
- * Return Value : u32
- * The obtained index is returned.
- * If a failure occurs, the value of max is returned.
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u32 hinic5_cqm_bitmap_alloc(struct tag_hinic5_cqm_bitmap *bitmap, u32 step, u32 count, bool update_last)
-{
- u32 index = 0;
- u32 max_num = bitmap->max_num - bitmap->reserved_back;
- u32 last = bitmap->last;
- ulong *table = bitmap->table;
- u32 i;
-
- spin_lock(&bitmap->lock);
-
- /* Search for an idle bit from the last position. */
- hinic5_cqm_bitmap_find(bitmap, &index, last, step, count);
-
- /* The preceding search fails. Search for an idle bit
- * from the beginning.
- */
- if (index >= max_num) {
- last = bitmap->reserved_top;
- hinic5_cqm_bitmap_find(bitmap, &index, last, step, count);
- }
-
- /* Set the found bit to 1 and reset last. */
- if (index < max_num) {
- for (i = index; i < (index + count); i++)
- set_bit(i, table);
-
- if (update_last) {
- bitmap->last = (index + count);
- if (bitmap->last >= max_num)
- bitmap->last = bitmap->reserved_top;
- }
- }
-
- spin_unlock(&bitmap->lock);
- return index;
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_alloc_lowbits_align
- * Description : Apply for a bitmap index with lowbits align.
- * Scan backwards from where you last applied if search all range.
- * A string of consecutive indexes must be applied for and
- * cannot be applied for across trunks.
- * Input : struct tag_hinic5_cqm_bitmap *bitmap,
- * struct tag_hinic5_cqm_bitmap_range *bp_range,
- * struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- * u32 xid,
- * bool update_last
- * Output : None
- * Return Value : u32
- * The obtained index is returned.
- * If a failure occurs, the value of invalid_index is returned.
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u32 hinic5_cqm_bitmap_alloc_lowbits_align(struct tag_hinic5_cqm_bitmap *bitmap,
- struct tag_hinic5_cqm_bitmap_range *bp_range,
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 xid, bool update_last)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- ulong *table = bitmap->table;
- u32 search_mode = HINIC5_CQM_DYNAMIC_XID_SEARCH_MODE(xid);
- u32 max_num = bitmap->max_num - bitmap->reserved_back;
- u32 index, last;
-
- spin_lock(&bitmap->lock);
-
- /* unsupport reverse search when search all range of bitmap */
- if (search_mode == HINIC5_CQM_XID_SEARCH_ALL) {
- last = bitmap->last;
- /* Search for an idle bit from the last position. */
- index = hinic5_cqm_bitmap_find_with_lowbits_align(bitmap, last, max_num, xid);
- /* The preceding search fails. Search for an idle bit from the beginning. */
- if (index == HINIC5_CQM_INDEX_INVALID) {
- last = bitmap->reserved_top;
- index = hinic5_cqm_bitmap_find_with_lowbits_align(bitmap, last, max_num, xid);
- }
- } else {
- if (HINIC5_CQM_BP_RANGE_VALID(bp_range->start, bp_range->end,
- bitmap->reserved_top, max_num) == 0) {
- hinic5_cqm_err(handle->dev_hdl,
- "Bitmap alloc: range invalid, start=0x%x, end=0x%x, min=0x%x, max=0x%x\n",
- bp_range->start, bp_range->end, bitmap->reserved_top, max_num);
- spin_unlock(&bitmap->lock);
- return HINIC5_CQM_INDEX_INVALID;
- }
- index = hinic5_cqm_bitmap_find_with_lowbits_align(bitmap, bp_range->start, bp_range->end,
- xid);
- }
-
- /* Set the found bit to 1 and reset last. */
- if (index != HINIC5_CQM_INDEX_INVALID) {
- set_bit(index, table);
-
- if (update_last && search_mode == HINIC5_CQM_XID_SEARCH_ALL) {
- bitmap->last = index + 1;
- if (bitmap->last >= max_num)
- bitmap->last = bitmap->reserved_top;
- }
- }
-
- spin_unlock(&bitmap->lock);
- return index;
-}
-
-static inline void bitmap_set_table(struct tag_hinic5_cqm_bitmap *bitmap, ulong *table, u32 *ret_index, u32 index)
-{
- spin_lock(&bitmap->lock);
- if (test_bit((int)index, table)) {
- *ret_index = HINIC5_CQM_INDEX_INVALID;
- } else {
- set_bit(index, table);
- *ret_index = index;
- }
- spin_unlock(&bitmap->lock);
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_alloc_reserved
- * Description : Reserve bit applied for based on index.
- * Input : struct tag_hinic5_cqm_bitmap *bitmap,
- * u32 count,
- * u32 index
- * Output : None
- * Return Value : u32
- * The obtained index is returned.
- * If a failure occurs, the value of max is returned.
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u32 hinic5_cqm_bitmap_alloc_reserved(struct tag_hinic5_cqm_bitmap *bitmap, u32 count, u32 index)
-{
- u32 ret_index;
-
- if (index >= bitmap->max_num || count != 1)
- return HINIC5_CQM_INDEX_INVALID;
-
- if (index >= bitmap->reserved_top && (index < bitmap->max_num - bitmap->reserved_back))
- return HINIC5_CQM_INDEX_INVALID;
-
- bitmap_set_table(bitmap, bitmap->table, &ret_index, index);
- return ret_index;
-}
-
-u32 hinic5_cqm_bitmap_alloc_by_xid(struct tag_hinic5_cqm_bitmap *bitmap, u32 count, u32 index)
-{
- u32 ret_index;
-
- if (index >= bitmap->max_num || count != 1)
- return HINIC5_CQM_INDEX_INVALID;
- bitmap_set_table(bitmap, bitmap->table, &ret_index, index);
- return ret_index;
-}
-
-/**
- * Prototype : hinic5_cqm_bitmap_free
- * Description : Releases a bitmap index.
- * Input : struct tag_hinic5_cqm_bitmap *bitmap,
- * u32 index,
- * u32 count
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_bitmap_free(struct tag_hinic5_cqm_bitmap *bitmap, u32 index, u32 count)
-{
- u32 i;
-
- spin_lock(&bitmap->lock);
-
- for (i = index; i < (index + count); i++)
- clear_bit((s32)i, bitmap->table);
-
- spin_unlock(&bitmap->lock);
-}
-
-#define obj_table_section
-
-/**
- * Prototype : hinic5_cqm_single_object_table_init
- * Description : Initialize a object table.
- * Input : struct tag_hinic5_cqm_object_table *obj_table
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/9/9
- * Modification : Created function
- */
-static s32 hinic5_cqm_single_object_table_init(struct tag_hinic5_cqm_object_table *obj_table)
-{
- rwlock_init(&obj_table->lock);
-
- obj_table->table = vmalloc(obj_table->max_num * sizeof(void *));
- if (unlikely(obj_table->table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(table));
- return HINIC5_CQM_FAIL;
- }
- memset(obj_table->table, 0, obj_table->max_num * sizeof(void *));
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_object_table_init
- * Description : Initialize the association table between objects and indexes.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_object_table_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *obj_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- s32 ret = HINIC5_CQM_SUCCESS;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- if (cla_table->obj_num == 0) {
- hinic5_cqm_info(handle->dev_hdl,
- "Obj table init: cla_table_type %u, obj_num=0, don't init obj table\n",
- cla_table->type);
- continue;
- }
-
- obj_table = &cla_table->obj_table;
-
- switch (cla_table->type) {
- case HINIC5_CQM_BAT_ENTRY_T_QPC:
- obj_table->max_num = capability->qpc_number;
- ret = hinic5_cqm_single_object_table_init(obj_table);
- break;
- case HINIC5_CQM_BAT_ENTRY_T_MPT:
- obj_table->max_num = capability->mpt_number;
- ret = hinic5_cqm_single_object_table_init(obj_table);
- break;
- case HINIC5_CQM_BAT_ENTRY_T_SCQC:
- obj_table->max_num = capability->scqc_number;
- ret = hinic5_cqm_single_object_table_init(obj_table);
- break;
- case HINIC5_CQM_BAT_ENTRY_T_SRQC:
- obj_table->max_num = capability->srqc_number;
- ret = hinic5_cqm_single_object_table_init(obj_table);
- break;
- default:
- break;
- }
-
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table init: failed to init cla_table_type=%u, obj_num=0x%x\n",
- cla_table->type, cla_table->obj_num);
- goto err;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_object_table_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_object_table_uninit
- * Description : Deinitialize the association table between objects and
- * indexes.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_table_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_object_table *obj_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- cla_table = &bat_table->entry[i];
- obj_table = &cla_table->obj_table;
- if (cla_table->type != HINIC5_CQM_BAT_ENTRY_T_INVALID) {
- if (obj_table->table) {
- rwlock_deinit(&obj_table->lock);
- vfree(obj_table->table);
- obj_table->table = NULL;
- }
- }
- }
-}
-
-/**
- * Prototype : hinic5_cqm_object_table_insert
- * Description : Insert an object
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * struct tag_hinic5_cqm_object_table *object_table
- * u32 index
- * struct tag_hinic5_cqm_object *obj
- * bool bh
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_object_table_insert(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, struct tag_hinic5_cqm_object *obj, bool bh)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- if (index >= object_table->max_num) {
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table insert: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_write_lock(&object_table->lock, bh);
-
- if (!object_table->table[index]) {
- object_table->table[index] = obj;
- hinic5_cqm_write_unlock(&object_table->lock, bh);
- return HINIC5_CQM_SUCCESS;
- }
-
- hinic5_cqm_write_unlock(&object_table->lock, bh);
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table insert: object_table->table[0x%x] has been inserted\n",
- index);
-
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_object_table_remove
- * Description : Remove an object
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * struct tag_hinic5_cqm_object_table *object_table
- * u32 index
- * const struct tag_hinic5_cqm_object *obj
- * bool bh
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_table_remove(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, const struct tag_hinic5_cqm_object *obj, bool bh)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- if (index >= object_table->max_num) {
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table remove: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return;
- }
-
- hinic5_cqm_write_lock(&object_table->lock, bh);
-
- if (object_table->table[index] && object_table->table[index] == obj)
- object_table->table[index] = NULL;
- else
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table remove: object_table->table[0x%x] has been removed\n",
- index);
-
- hinic5_cqm_write_unlock(&object_table->lock, bh);
-}
-
-/**
- * Prototype : hinic5_cqm_object_table_get
- * Description : Remove an object
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle
- * struct tag_hinic5_cqm_object_table *object_table
- * u32 index
- * bool bh
- * Output : None
- * Return Value : struct tag_hinic5_cqm_object *obj
- * 1.Date : 2018/6/20
- * Modification : Created function
- */
-struct tag_hinic5_cqm_object *hinic5_cqm_object_table_get(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, bool bh)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object *obj = NULL;
-
- if (index >= object_table->max_num) {
- hinic5_cqm_err(handle->dev_hdl,
- "Obj table get: index 0x%x exceeds max_num 0x%x\n",
- index, object_table->max_num);
- return NULL;
- }
-
- hinic5_cqm_read_lock(&object_table->lock, bh);
-
- obj = object_table->table[index];
- if (obj)
- atomic_inc(&obj->refcount);
-
- hinic5_cqm_read_unlock(&object_table->lock, bh);
-
- return obj;
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.h
deleted file mode 100644
index 5f3e114da..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bitmap_table.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bitmap_table.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_BITMAP_TABLE_H
-#define HINIC5_CQM_BITMAP_TABLE_H
-
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-
-#include "hinic5_hinic5_vram_api.h"
-#include "hinic5_cqm_object.h"
-#include "hinic5_vram_common.h"
-
-/* hinic5_cqm_buf_alloc() failed due to buddy allocator page exhaustion. */
-#define HINIC5_CQM_BUF_ALLOC_BUDDY_PAGES_FAIL (HINIC5_CQM_CONTINUE + 1)
-
-struct tag_hinic5_cqm_bitmap_range {
- u32 start;
- u32 end;
-};
-
-struct tag_hinic5_cqm_bitmap {
- ulong *table;
- u32 max_num;
- u32 last;
- u32 reserved_top; /* reserved index */
- u32 reserved_back;
- spinlock_t lock; /* lock for hinic5_cqm */
- struct hinic5_vram_buf_info bitmap_info;
-};
-
-struct tag_hinic5_cqm_object_table {
- /* Now is big array. Later will be optimized as a red-black tree. */
- struct tag_hinic5_cqm_object **table;
- u32 max_num;
- rwlock_t lock;
-};
-
-struct tag_hinic5_cqm_handle;
-
-s32 hinic5_cqm_bitmap_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-void hinic5_cqm_bitmap_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-u32 hinic5_cqm_bitmap_alloc(struct tag_hinic5_cqm_bitmap *bitmap, u32 step, u32 count, bool update_last);
-u32 hinic5_cqm_bitmap_alloc_lowbits_align(struct tag_hinic5_cqm_bitmap *bitmap,
- struct tag_hinic5_cqm_bitmap_range *bp_range,
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- u32 xid, bool update_last);
-u32 hinic5_cqm_bitmap_alloc_reserved(struct tag_hinic5_cqm_bitmap *bitmap, u32 count, u32 index);
-void hinic5_cqm_bitmap_free(struct tag_hinic5_cqm_bitmap *bitmap, u32 index, u32 count);
-s32 hinic5_cqm_object_table_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-void hinic5_cqm_object_table_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-s32 hinic5_cqm_object_table_insert(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, struct tag_hinic5_cqm_object *obj, bool bh);
-void hinic5_cqm_object_table_remove(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, const struct tag_hinic5_cqm_object *obj, bool bh);
-struct tag_hinic5_cqm_object *hinic5_cqm_object_table_get(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_object_table *object_table,
- u32 index, bool bh);
-u32 hinic5_cqm_bitmap_alloc_by_xid(struct tag_hinic5_cqm_bitmap *bitmap, u32 count, u32 index);
-void hinic5_cqm_swab64(u8 *addr, u32 cnt);
-void hinic5_cqm_swab32(u8 *addr, u32 cnt);
-bool hinic5_cqm_check_align(u32 data);
-u32 hinic5_cqm_shift(u32 data);
-s32 hinic5_cqm_buf_list_alloc(struct tag_hinic5_cqm_buf *buf);
-s32 hinic5_cqm_buf_alloc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf, bool direct);
-s32 hinic5_cqm_buf_alloc_direct(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf, bool direct);
-void hinic5_cqm_buf_free(struct tag_hinic5_cqm_buf *buf, struct device *dev);
-void hinic5_cqm_buf_free_cache_inv(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct tag_hinic5_cqm_buf *buf,
- s32 *inv_flag);
-s32 hinic5_cqm_cla_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, dma_addr_t pa,
- u32 cache_size);
-void *hinic5_cqm_kmalloc_align(size_t size, gfp_t flags, u16 align_order);
-void hinic5_cqm_kfree_align(void *addr);
-
-#endif /* HINIC5_CQM_BITMAP_TABLE_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.c
deleted file mode 100644
index e70943310..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bloomfilter.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_typedef_inner.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_cmd.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_bloomfilter.h"
-
-#include "hinic5_cqm_npu_cmd.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-
-/**
- * Prototype : bloomfilter_init_cmd
- * Description : host send cmd to ucode to init bloomfilter mem
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/8/13
- * Modification : Created function
- */
-static s32 bloomfilter_init_cmd(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *capability = &hinic5_cqm_handle->func_capability;
- hinic5_cqm_bloomfilter_init_cmd_s *cmd = NULL;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- s32 ret;
-
- buf_in = hinic5_cqm_cmd_alloc((void *)(hinic5_cqm_handle->ex_handle));
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- /* Fill the command format and convert it to big-endian. */
- buf_in->size = sizeof(hinic5_cqm_bloomfilter_init_cmd_s);
- cmd = (hinic5_cqm_bloomfilter_init_cmd_s *)(buf_in->buf);
- cmd->bloom_filter_addr = capability->bloomfilter_addr;
- cmd->bloom_filter_len = capability->bloomfilter_length;
-
- hinic5_cqm_swab32((u8 *)cmd,
- (sizeof(hinic5_cqm_bloomfilter_init_cmd_s) >> HINIC5_CQM_DW_SHIFT));
-
- ret = hinic5_cqm_send_cmd_box((void *)(hinic5_cqm_handle->ex_handle),
- HINIC5_CQM_MOD_HINIC5_CQM, HINIC5_CQM_CMD_T_BLOOMFILTER_INIT, buf_in,
- NULL, NULL, HINIC5_CQM_CMD_TIMEOUT,
- HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl, "Bloomfilter: %s ret=%d\n", __func__,
- ret);
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl, "Bloomfilter: %s: 0x%x 0x%x\n",
- __func__, cmd->bloom_filter_addr,
- cmd->bloom_filter_len);
- hinic5_cqm_cmd_free((void *)(hinic5_cqm_handle->ex_handle), buf_in);
- return HINIC5_CQM_FAIL;
- }
- hinic5_cqm_cmd_free((void *)(hinic5_cqm_handle->ex_handle), buf_in);
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_func_bloomfilter_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bloomfilter_table *bloomfilter_table = &hinic5_cqm_handle->bloomfilter_table;
-
- if (bloomfilter_table->table) {
- mutex_deinit(&bloomfilter_table->lock);
- vfree(bloomfilter_table->table);
- bloomfilter_table->table = NULL;
- }
-}
-
-static s32 hinic5_cqm_func_bloomfilter_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_bloomfilter_table *bloomfilter_table = NULL;
- struct tag_hinic5_cqm_func_capability *capability = NULL;
- u32 array_size;
- s32 ret;
-
- bloomfilter_table = &hinic5_cqm_handle->bloomfilter_table;
- capability = &hinic5_cqm_handle->func_capability;
-
- if (capability->bloomfilter_length == 0) {
- hinic5_cqm_info(hinic5_cqm_handle->ex_handle->dev_hdl,
- "Bloomfilter: bf_length=0, don't need to init bloomfilter\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- /* The unit of bloomfilter_length is 64B(512bits). Each bit is a table
- * node. Therefore the value must be shift 9 bits to the left.
- */
- bloomfilter_table->table_size = capability->bloomfilter_length <<
- HINIC5_CQM_BF_LENGTH_UNIT;
- /* The unit of bloomfilter_length is 64B. The unit of array entryis 32B.
- */
- array_size = capability->bloomfilter_length << 1;
- if (array_size == 0 || array_size > HINIC5_CQM_BF_BITARRAY_MAX) {
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(array_size));
- return HINIC5_CQM_FAIL;
- }
-
- bloomfilter_table->array_mask = array_size - 1;
- /* This table is not a bitmap, it is the counter of corresponding bit.
- */
- bloomfilter_table->table = vmalloc(bloomfilter_table->table_size *
- (sizeof(u32)));
- if (unlikely(bloomfilter_table->table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(table));
- return HINIC5_CQM_FAIL;
- }
-
- memset(bloomfilter_table->table, 0,
- (bloomfilter_table->table_size * sizeof(u32)));
-
- /* The the bloomfilter must be initialized to 0 by ucode,
- * because the bloomfilter is mem mode
- */
- if (hinic5_cqm_handle->func_capability.bloomfilter_enable != 0) {
- ret = bloomfilter_init_cmd(hinic5_cqm_handle);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(hinic5_cqm_handle->ex_handle->dev_hdl,
- "Bloomfilter: bloomfilter_init_cmd ret=%d\n",
- ret);
- vfree(bloomfilter_table->table);
- bloomfilter_table->table = NULL;
- return HINIC5_CQM_FAIL;
- }
- }
-
- mutex_init(&bloomfilter_table->lock);
-
- hinic5_cqm_dbg(hinic5_cqm_handle->dev,
- "Bloomfilter: table_size=0x%x, array_size=0x%x\n",
- bloomfilter_table->table_size, array_size);
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_fake_bloomfilter_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 i, child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return;
-
- for (i = 0; i < child_func_number; i++) {
- hinic5_cqm_func_bloomfilter_uninit(hinic5_cqm_handle->fake_hinic5_cqm_handle[i]);
- }
-}
-
-static s32 hinic5_cqm_fake_bloomfilter_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 i, child_func_number;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return HINIC5_CQM_SUCCESS;
-
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++) {
- fake_hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[i];
- if (hinic5_cqm_func_bloomfilter_init(fake_hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_func_bloomfilter_init));
- goto bloomfilter_init_err;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-
-bloomfilter_init_err:
- hinic5_cqm_fake_bloomfilter_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_bloomfilter_init
- * Description : initialize the bloomfilter of hinic5_cqm
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/7/6
- * Modification : Created function
- */
-s32 hinic5_cqm_bloomfilter_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- if (hinic5_cqm_fake_bloomfilter_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_fake_bloomfilter_init));
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_func_bloomfilter_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_func_bloomfilter_init));
- goto bloomfilter_init_err;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-bloomfilter_init_err:
- hinic5_cqm_fake_bloomfilter_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_bloomfilter_uninit
- * Description : uninitialize the bloomfilter of hinic5_cqm
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2016/7/6
- * Modification : Created function
- */
-void hinic5_cqm_bloomfilter_uninit(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- hinic5_cqm_fake_bloomfilter_uninit(hinic5_cqm_handle);
- hinic5_cqm_func_bloomfilter_uninit(hinic5_cqm_handle);
-}
-
-/**
- * Prototype : hinic5_cqm_bloomfilter_cmd
- * Description : host send bloomfilter api cmd to ucode
- * Input : void *ex_handle
- * u32 op,
- * u32 k_flag
- * u64 id,
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/7/7
- * Modification : Created function
- */
-s32 hinic5_cqm_bloomfilter_cmd(void *ex_handle, u16 func_id, u32 op, u32 k_flag, u64 id)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_cmd_buf *buf_in = NULL;
- hinic5_cqm_bloomfilter_cmd_s *cmd = NULL;
- s32 ret;
-
- buf_in = hinic5_cqm_cmd_alloc(ex_handle);
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(buf_in));
- return HINIC5_CQM_FAIL;
- }
-
- /* Fill the command format and convert it to big-endian. */
- buf_in->size = sizeof(hinic5_cqm_bloomfilter_cmd_s);
- cmd = (hinic5_cqm_bloomfilter_cmd_s *)(buf_in->buf);
- memset((void *)cmd, 0, sizeof(hinic5_cqm_bloomfilter_cmd_s));
- cmd->func_id = func_id;
- cmd->k_en = k_flag;
- cmd->index_h = (u32)(id >> HINIC5_CQM_DW_OFFSET);
- cmd->index_l = (u32)(id & HINIC5_CQM_DW_MASK);
-
- hinic5_cqm_swab32((u8 *)cmd, (sizeof(hinic5_cqm_bloomfilter_cmd_s) >> HINIC5_CQM_DW_SHIFT));
-
- ret = hinic5_cqm_send_cmd_box(ex_handle, HINIC5_CQM_MOD_HINIC5_CQM, (u8)op, buf_in, NULL,
- NULL, HINIC5_CQM_CMD_TIMEOUT, HINIC5_CHANNEL_DEFAULT);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_send_cmd_box));
- hinic5_cqm_err(handle->dev_hdl, "Bloomfilter: bloomfilter_cmd ret=%d\n",
- ret);
- hinic5_cqm_err(handle->dev_hdl, "Bloomfilter: op=0x%x, cmd: 0x%x 0x%x 0x%x 0x%x\n",
- op, *((u32 *)(void *)cmd), *(((u32 *)(void *)cmd) + HINIC5_CQM_DW_INDEX1),
- *(((u32 *)(void *)cmd) + HINIC5_CQM_DW_INDEX2),
- *(((u32 *)(void *)cmd) + HINIC5_CQM_DW_INDEX3));
- hinic5_cqm_cmd_free(ex_handle, buf_in);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_cmd_free(ex_handle, buf_in);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-STATIC struct tag_hinic5_cqm_handle *hinic5_cqm_get_func_hinic5_cqm_handle(struct hinic5_hwdev *ex_handle, u16 func_id)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- u32 child_func_start, child_func_number;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(ex_handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return NULL;
- }
-
- /* function id is PF/VF */
- if (func_id == hinic5_global_func_id(ex_handle))
- return hinic5_cqm_handle;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle)) {
- hinic5_cqm_err(ex_handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle)));
- return NULL;
- }
-
- child_func_start = hinic5_cqm_get_child_func_start(hinic5_cqm_handle);
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
- /* function id is fake vf */
- if (func_id >= child_func_start && (func_id < (child_func_start + child_func_number)))
- return hinic5_cqm_handle->fake_hinic5_cqm_handle[func_id - (u16)child_func_start];
-
- return NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_bloomfilter_inc
- * Description : The reference counting field is added to the ID of the
- * bloomfilter.
- * Input : void *ex_handle
- * u64 id--hash value
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/7/7
- * Modification : Created function
- */
-s32 hinic5_cqm_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_bloomfilter_table *bloomfilter_table = NULL;
- u32 array_tmp[HINIC5_CQM_BF_SECTION_NUMBER] = {0};
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- u32 array_index, array_bit, i;
- u32 k_flag = 0;
-
- if (!ex_handle)
- return HINIC5_CQM_FAIL;
-
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Bloomfilter: func_id: %d, inc id=0x%llx\n", func_id, id);
-
- hinic5_cqm_handle = hinic5_cqm_get_func_hinic5_cqm_handle(ex_handle, func_id);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_handle->func_capability.bloomfilter_enable == 0) {
- hinic5_cqm_info(handle->dev_hdl, "Bloomfilter inc: bloomfilter is disable\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- /* |(array_index=0)32B(array_bit:256bits)|(array_index=1)32B(256bits)|
- * array_index = 0~bloomfilter_table->table_size/256bit
- * array_bit = 0~255
- */
- bloomfilter_table = &hinic5_cqm_handle->bloomfilter_table;
-
- /* The array index identifies a 32-byte entry. */
- array_index = (u32)HINIC5_CQM_BF_BITARRAY_INDEX(id, bloomfilter_table->array_mask);
- /* convert the unit of array_index to bit */
- array_index = array_index << HINIC5_CQM_BF_ENTRY_SIZE_UNIT;
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Bloomfilter: inc id=0x%llx, array_index=0x%x\n", id, array_index);
-
- mutex_lock(&bloomfilter_table->lock);
- for (i = 0; i < HINIC5_CQM_BF_SECTION_NUMBER; i++) {
- /* the position of the bit in 64-bit section */
- array_bit = (id >> (HINIC5_CQM_BF_SECTION_BASE + i * HINIC5_CQM_BF_SECTION_SIZE)) & HINIC5_CQM_BF_SECTION_MASK;
- /* array_bit + number of 32-byte array entries + number of
- * 64-bit sections before the section
- */
- array_bit = array_bit + array_index + (i * HINIC5_CQM_BF_SECTION_BIT_NUMBER);
-
- /* array_temp[i] records the index of the bloomfilter.
- * It is used to roll back the reference counting of the
- * bitarray.
- */
- array_tmp[i] = array_bit;
-
- /* Add one to the corresponding bit in bloomfilter table.
- * If the value changes from 0 to 1, change the corresponding
- * bit in k_flag.
- */
- (bloomfilter_table->table[array_bit])++;
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Bloomfilter: inc bloomfilter_table->table[%d]=0x%x\n",
- array_bit, bloomfilter_table->table[array_bit]);
- if (bloomfilter_table->table[array_bit] == 1)
- k_flag |= (1U << i);
- }
-
- /* send cmd to ucode and set corresponding bit. */
- if (k_flag != 0 && hinic5_cqm_bloomfilter_cmd(ex_handle, func_id, HINIC5_CQM_CMD_T_BLOOMFILTER_SET,
- k_flag, id) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bloomfilter_cmd_inc));
- for (i = 0; i < HINIC5_CQM_BF_SECTION_NUMBER; i++) {
- array_bit = array_tmp[i];
- (bloomfilter_table->table[array_bit])--;
- }
- mutex_unlock(&bloomfilter_table->lock);
- return HINIC5_CQM_FAIL;
- }
-
- mutex_unlock(&bloomfilter_table->lock);
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_bloomfilter_inc);
-
-/**
- * Prototype : hinic5_cqm_bloomfilter_dec
- * Description : The reference counting field is decreased to the ID of the
- * bloomfilter.
- * Input : void *ex_handle
- * u64 id--hash value
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/7/7
- * Modification : Created function
- */
-s32 hinic5_cqm_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_bloomfilter_table *bloomfilter_table = NULL;
- u32 array_tmp[HINIC5_CQM_BF_SECTION_NUMBER] = {0};
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- u32 array_index, array_bit, i;
- u32 k_flag = 0;
-
- if (!ex_handle)
- return HINIC5_CQM_FAIL;
-
- hinic5_cqm_handle = hinic5_cqm_get_func_hinic5_cqm_handle(ex_handle, func_id);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_handle->func_capability.bloomfilter_enable == 0) {
- hinic5_cqm_info(handle->dev_hdl, "Bloomfilter dec: bloomfilter is disable\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- bloomfilter_table = &hinic5_cqm_handle->bloomfilter_table;
-
- /* The array index identifies a 32-byte entry. */
- array_index = (u32)HINIC5_CQM_BF_BITARRAY_INDEX(id, bloomfilter_table->array_mask);
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Bloomfilter: dec id=0x%llx, array_index=0x%x\n", id, array_index);
-
- mutex_lock(&bloomfilter_table->lock);
- for (i = 0; i < HINIC5_CQM_BF_SECTION_NUMBER; i++) {
- /* the position of the bit in 64-bit section */
- array_bit = (id >> (HINIC5_CQM_BF_SECTION_BASE + i * HINIC5_CQM_BF_SECTION_SIZE)) &
- HINIC5_CQM_BF_SECTION_MASK;
- /* array_bit + number of 32-byte array entries + number of
- * 64-bit sections before the section
- */
- array_bit = array_bit + (array_index << 0x8) + (i * 0x40);
-
- /* array_temp[i] records the index of the bloomfilter.
- * It is used to roll back the reference counting of the
- * bitarray.
- */
- array_tmp[i] = array_bit;
-
- /* Deduct one to the corresponding bit in bloomfilter table.
- * If the value changes from 1 to 0, change the corresponding
- * bit in k_flag. Do not continue -1 when the reference counting
- * value of the bit is 0.
- */
- if (bloomfilter_table->table[array_bit] != 0) {
- bloomfilter_table->table[array_bit]--;
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Bloomfilter: dec bloomfilter_table->table[%d]=0x%x\n",
- array_bit, bloomfilter_table->table[array_bit]);
- if (bloomfilter_table->table[array_bit] == 0)
- k_flag |= (1U << i);
- }
- }
-
- /* send cmd to ucode and clear corresponding bit. */
- if (k_flag != 0 && hinic5_cqm_bloomfilter_cmd(ex_handle, func_id, HINIC5_CQM_CMD_T_BLOOMFILTER_CLEAR,
- k_flag, id) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bloomfilter_cmd_dec));
- for (i = 0; i < HINIC5_CQM_BF_SECTION_NUMBER; i++) {
- array_bit = array_tmp[i];
- (bloomfilter_table->table[array_bit])++;
- }
- mutex_unlock(&bloomfilter_table->lock);
- return HINIC5_CQM_FAIL;
- }
-
- mutex_unlock(&bloomfilter_table->lock);
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_bloomfilter_dec);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.h
deleted file mode 100644
index d1595ca79..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_bloomfilter.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_bloomfilter.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_BLOOMFILTER_H
-#define HINIC5_CQM_BLOOMFILTER_H
-
-#include <linux/types.h>
-#include <linux/mutex.h>
-
-/* Bloomfilter entry size is 32B(256bit), whitch index is the 48-32-bit of the
- * hash. |31~26|25~20|19~14|13~8| will be used to locate 4 bloom filter section
- * in one entry. k_en[3:0] used to specify the section of bloom filter.
- */
-#define HINIC5_CQM_BF_ENTRY_SIZE 32
-#define HINIC5_CQM_BF_ENTRY_SIZE_UNIT 8
-#define HINIC5_CQM_BF_BITARRAY_MAX BIT(17)
-
-#define HINIC5_CQM_BF_SECTION_NUMBER 4
-#define HINIC5_CQM_BF_SECTION_BASE 8
-#define HINIC5_CQM_BF_SECTION_SIZE 6
-#define HINIC5_CQM_BF_SECTION_MASK 0x3f
-#define HINIC5_CQM_BF_SECTION_BIT_NUMBER 64
-
-#define HINIC5_CQM_BF_ARRAY_INDEX_OFFSET 32
-#define HINIC5_CQM_BF_BITARRAY_INDEX(id, mask) \
- (((id) >> HINIC5_CQM_BF_ARRAY_INDEX_OFFSET) & (mask))
-
-/* The unit of bloomfilter_length is 64B(512bits). */
-#define HINIC5_CQM_BF_LENGTH_UNIT 9
-
-#define HINIC5_CQM_DW_MASK 0xffffffff
-#define HINIC5_CQM_DW_OFFSET 32
-#define HINIC5_CQM_DW_INDEX0 0
-#define HINIC5_CQM_DW_INDEX1 1
-#define HINIC5_CQM_DW_INDEX2 2
-#define HINIC5_CQM_DW_INDEX3 3
-
-struct tag_hinic5_cqm_bloomfilter_table {
- u32 *table;
- u32 table_size; /* The unit is bit */
- u32 array_mask; /* The unit of array entry is 32B, used to address entry
- */
- struct mutex lock;
-};
-
-/* only for test */
-s32 hinic5_cqm_bloomfilter_cmd(void *ex_handle, u16 func_id, u32 op, u32 k_flag, u64 id);
-s32 hinic5_cqm_bloomfilter_init(void *ex_handle);
-void hinic5_cqm_bloomfilter_uninit(void *ex_handle);
-s32 hinic5_cqm_bloomfilter_inc(void *ex_handle, u16 func_id, u64 id);
-s32 hinic5_cqm_bloomfilter_dec(void *ex_handle, u16 func_id, u64 id);
-
-#endif /* HINIC5_CQM_BLOOMFILTER_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.c
deleted file mode 100644
index 5d1e32f08..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_cmd.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-
-#include "ossl_knl.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_main.h"
-
-/**
- * Prototype : hinic5_cqm_cmd_alloc
- * Description : Apply for a cmd buffer. The buffer size is fixed to 2 KB.
- * The buffer content is not cleared and needs to be cleared by
- * services.
- * Input : void *ex_handle
- * Output : None
- * Return Value : struct tag_hinic5_cqm_cmd_buf *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_cmd_buf *hinic5_cqm_cmd_alloc(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_cmd_alloc_cnt);
-
- return (struct tag_hinic5_cqm_cmd_buf *)(void *)hinic5_alloc_cmd_buf(ex_handle);
-}
-EXPORT_SYMBOL(hinic5_cqm_cmd_alloc);
-
-/**
- * Prototype : hinic5_cqm_cmd_free
- * Description : Release for a cmd buffer.
- * Input : void *ex_handle
- * struct tag_hinic5_cqm_cmd_buf *cmd_buf
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_cmd_free(void *ex_handle, struct tag_hinic5_cqm_cmd_buf *cmd_buf)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
- if (unlikely(cmd_buf == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(cmd_buf));
- return;
- }
- if (unlikely(cmd_buf->buf == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_cmd_free_cnt);
-
- hinic5_free_cmd_buf(ex_handle, (struct hinic5_cmd_buf *)(void *)cmd_buf);
-}
-EXPORT_SYMBOL(hinic5_cqm_cmd_free);
-
-/**
- * Prototype : hinic5_cqm_send_cmd_box
- * Description : Send a cmd message in box mode.
- * This interface will mount a completion quantity,
- * causing sleep.
- * Input : void *ex_handle
- * u8 mod
- * u8 cmd,
- * struct tag_hinic5_cqm_cmd_buf *buf_in
- * struct tag_hinic5_cqm_cmd_buf *buf_out
- * u64 *out_param
- * u32 timeout
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_cmd_buf *buf_out, u64 *out_param, u32 timeout,
- u16 channel)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf_in));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(buf_in->buf == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf));
- return HINIC5_CQM_FAIL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_send_cmd_box_cnt);
-
- return hinic5_cmdq_detail_resp(ex_handle, mod, cmd,
- (struct hinic5_cmd_buf *)(void *)buf_in,
- (struct hinic5_cmd_buf *)(void *)buf_out,
- out_param, timeout, channel);
-}
-EXPORT_SYMBOL(hinic5_cqm_send_cmd_box);
-
-/**
- * Prototype : hinic5_cqm_lb_send_cmd_box
- * Description : Send a cmd message in box mode and open cos_id.
- * This interface will mount a completion quantity,
- * causing sleep.
- * Input : void *ex_handle
- * u8 mod
- * u8 cmd
- * u8 cos_id
- * struct tag_hinic5_cqm_cmd_buf *buf_in
- * struct tag_hinic5_cqm_cmd_buf *buf_out
- * u64 *out_param
- * u32 timeout
- * Output : None
- * Return Value : s32
- * 1.Date : 2020/4/9
- * Modification : Created function
- */
-s32 hinic5_cqm_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
- struct tag_hinic5_cqm_cmd_buf *buf_in, struct tag_hinic5_cqm_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf_in));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(buf_in->buf == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf_in->buf));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_send_cmd_box_cnt);
-
- return hinic5_cos_id_detail_resp(ex_handle, mod, cmd, cos_id,
- (struct hinic5_cmd_buf *)(void *)buf_in,
- (struct hinic5_cmd_buf *)(void *)buf_out,
- out_param, timeout, channel);
-}
-EXPORT_SYMBOL(hinic5_cqm_lb_send_cmd_box);
-
-/**
- * Prototype : hinic5_cqm_send_cmd_imm
- * Description : Send a cmd message in imm mode.
- * This interface will mount a completion quantity,
- * causing sleep.
- * Input : void *ex_handle
- * u8 mod
- * u8 cmd
- * struct tag_hinic5_cqm_cmd_buf *buf_in
- * u64 *out_param
- * u32 timeout
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd, struct tag_hinic5_cqm_cmd_buf *buf_in,
- u64 *out_param, u32 timeout, u16 channel)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(buf_in == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf_in));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(buf_in->buf == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(buf));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_send_cmd_imm_cnt);
-
- return hinic5_cmdq_direct_resp((void *)ex_handle, mod, cmd,
- (struct hinic5_cmd_buf *)(void *)buf_in,
- out_param, timeout, channel);
-}
-EXPORT_SYMBOL(hinic5_cqm_send_cmd_imm);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.h
deleted file mode 100644
index b9410cc06..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_CMD_H
-#define HINIC5_CQM_CMD_H
-
-#include <linux/types.h>
-
-#include "hinic5_cqm_object.h"
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif
-#endif /* __cplusplus */
-
-#ifndef HI1825V100
-#define HINIC5_CQM_CMD_TIMEOUT 10000 /* ms */
-#else
-#define HINIC5_CQM_CMD_TIMEOUT 1000000 /* ms */
-#endif
-
-struct tag_hinic5_cqm_cmd_buf *hinic5_cqm_cmd_alloc(void *ex_handle);
-void hinic5_cqm_cmd_free(void *ex_handle, struct tag_hinic5_cqm_cmd_buf *cmd_buf);
-s32 hinic5_cqm_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_cmd_buf *buf_out, u64 *out_param, u32 timeout,
- u16 channel);
-s32 hinic5_cqm_lb_send_cmd_box(void *ex_handle, u8 mod, u8 cmd, u8 cos_id,
- struct tag_hinic5_cqm_cmd_buf *buf_in, struct tag_hinic5_cqm_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel);
-s32 hinic5_cqm_send_cmd_imm(void *ex_handle, u8 mod, u8 cmd, struct tag_hinic5_cqm_cmd_buf *buf_in,
- u64 *out_param, u32 timeout, u16 channel);
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-
-#endif /* HINIC5_CQM_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq.h
deleted file mode 100644
index b09da939f..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_cmdq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_CMDQ_H
-#define HINIC5_CQM_CMDQ_H
-
-#include "ossl_knl.h"
-#include "hinic5_cqm_npu_cmd_defs.h"
-#include "hinic5_cqm_main.h"
-
-struct hinic5_cqm_cmdq_ops {
- s32 (*prepare_cmd_buf_bat_update)(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_cmd_buf *buf_in,
- struct tag_hinic5_cqm_bat_update_param *param,
- u8 *cmd);
- void (*prepare_cmd_buf_cla_update)(hinic5_cqm_cla_update_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in, u8 *cmd);
- void (*prepare_cmd_cache_invalidate)(hinic5_cqm_cla_cache_invalid_cmd_s *cmd_info,
- struct tag_hinic5_cqm_cmd_buf *buf_in, u8 *cmd);
-};
-
-struct hinic5_cqm_cmdq_ops *hinic5_cqm_cmdq_get_182x_ops(void);
-struct hinic5_cqm_cmdq_ops *hinic5_cqm_cmdq_get_187x_ops(void);
-
-void hinic5_cqm_cmdq_adapt_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq_adapt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq_adapt.c
deleted file mode 100644
index 85f18134e..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_cmdq_adapt.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_cmdq_adapt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include "hinic5_cqm_cmdq.h"
-#include "hinic5_hwdev.h"
-
-void hinic5_cqm_cmdq_adapt_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- if (!COMM_SUPPORT_HTN_CMD(hinic5_cqm_handle->ex_handle)) {
- hinic5_cqm_handle->cmdq_ops = hinic5_cqm_cmdq_get_182x_ops();
- } else {
- hinic5_cqm_handle->cmdq_ops = hinic5_cqm_cmdq_get_187x_ops();
- }
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.c
deleted file mode 100644
index 0591a9a2d..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_db.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_mt.h"
-#include "hinic5_hwdev.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_object_intern.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_db.h"
-
-/**
- * Prototype : hinic5_cqm_db_addr_alloc
- * Description : Apply for a page of hardware doorbell and dwqe.
- * The indexes are the same. The obtained addresses are physical
- * addresses. Each function has a maximum of 1K addresses(DB).
- * Input : void *ex_handle
- * void __iomem **db_addr,
- * void __iomem **dwqe_addr
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-s32 hinic5_cqm_db_addr_alloc(void *ex_handle, void __iomem **db_addr,
- void __iomem **dwqe_addr)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(db_addr == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(db_addr));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(dwqe_addr == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(dwqe_addr));
- return HINIC5_CQM_FAIL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_db_addr_alloc_cnt);
-
- return hinic5_alloc_db_addr(ex_handle, db_addr, dwqe_addr);
-}
-
-s32 hinic5_cqm_db_phy_addr_alloc(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr)
-{
- return hinic5_alloc_db_phy_addr(ex_handle, db_paddr, dwqe_addr);
-}
-
-/**
- * Prototype : hinic5_cqm_db_addr_free
- * Description : Release a page of hardware doorbell and dwqe.
- * Input : void *ex_handle
- * const void __iomem **db_addr,
- * void __iomem **dwqe_addr
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-void hinic5_cqm_db_addr_free(void *ex_handle, const void __iomem *db_addr,
- void __iomem *dwqe_addr)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_db_addr_free_cnt);
-
- hinic5_free_db_addr(ex_handle, db_addr, dwqe_addr);
-}
-
-static void hinic5_cqm_db_phy_addr_free(void *ex_handle, const u64 *db_paddr, const u64 *dwqe_addr)
-{
- hinic5_free_db_phy_addr(ex_handle, *db_paddr, *dwqe_addr);
-}
-
-static bool hinic5_cqm_need_db_init(s32 service)
-{
- switch (service) {
- case HINIC5_CQM_SERVICE_T_NIC:
- case HINIC5_CQM_SERVICE_T_OVS:
- case HINIC5_CQM_SERVICE_T_IPSEC:
- case HINIC5_CQM_SERVICE_T_VIRTIO:
- case HINIC5_CQM_SERVICE_T_PPA:
- return false;
- default:
- return true;
- }
-}
-
-/**
- * Prototype : hinic5_cqm_db_init
- * Description : Initialize the doorbell of the HINIC5_CQM.
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-s32 hinic5_cqm_db_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- s32 i;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- /* Allocate hardware doorbells to services. */
- for (i = 0; i < HINIC5_CQM_SERVICE_T_MAX; i++) {
- service = &hinic5_cqm_handle->service[i];
- if (!hinic5_cqm_need_db_init(i) || !service->valid)
- continue;
-
- if (hinic5_cqm_db_addr_alloc(ex_handle, &service->hardware_db_vaddr,
- &service->dwqe_vaddr) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_db_addr_alloc));
- break;
- }
-
- if (hinic5_cqm_db_phy_addr_alloc(handle, &service->hardware_db_paddr,
- &service->dwqe_paddr) !=
- HINIC5_CQM_SUCCESS) {
- hinic5_cqm_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_db_phy_addr_alloc));
- break;
- }
- }
-
- if (i != HINIC5_CQM_SERVICE_T_MAX) {
- i--;
- for (; i >= 0; i--) {
- service = &hinic5_cqm_handle->service[i];
- if (!hinic5_cqm_need_db_init(i) || !service->valid)
- continue;
-
- hinic5_cqm_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- hinic5_cqm_db_phy_addr_free(ex_handle,
- &service->hardware_db_paddr,
- &service->dwqe_paddr);
- }
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_db_uninit
- * Description : Deinitialize the doorbell of the HINIC5_CQM.
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-void hinic5_cqm_db_uninit(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- s32 i;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- /* Release hardware doorbell. */
- for (i = 0; i < HINIC5_CQM_SERVICE_T_MAX; i++) {
- service = &hinic5_cqm_handle->service[i];
- if (service->valid && hinic5_cqm_need_db_init(i)) {
- hinic5_cqm_db_addr_free(ex_handle, service->hardware_db_vaddr,
- service->dwqe_vaddr);
- hinic5_cqm_db_phy_addr_free(ex_handle, &service->hardware_db_paddr,
- &service->dwqe_paddr);
- }
- }
-}
-
-/**
- * Prototype : hinic5_cqm_get_db_addr
- * Description : Return hardware DB vaddr.
- * Input : void *ex_handle
- * u32 service_type
- * Output : None
- * Return Value : void *
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-void *hinic5_cqm_get_db_addr(void *ex_handle, u32 service_type)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- if (service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- pr_err("service_type is out of bounds\n");
- return NULL;
- }
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return NULL;
- }
-
- service = &hinic5_cqm_handle->service[service_type];
-
- return (void *)service->hardware_db_vaddr;
-}
-EXPORT_SYMBOL(hinic5_cqm_get_db_addr);
-
-/**
- * Prototype : hinic5_cqm_get_db_addr
- * Description : Return hardware DB Phyaddr.
- * Input : void *ex_handle
- * u32 service_type
- * Output : None
- * Return Value : void *
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-s32 hinic5_cqm_get_hardware_db_addr(void *ex_handle, u64 *addr,
- enum hinic5_service_type service_type)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(addr == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(addr));
- return HINIC5_CQM_FAIL;
- }
-
- if (service_type < SERVICE_T_NIC || service_type >= SERVICE_T_MAX) {
- pr_err("%s service_type = %d state is error\n", __func__,
- service_type);
- return HINIC5_CQM_FAIL;
- }
-
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- service = &hinic5_cqm_handle->service[service_type];
-
- *addr = service->hardware_db_paddr;
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_get_hardware_db_addr);
-
-/**
- * Prototype : hinic5_cqm_ring_hardware_db
- * Description : Ring hardware DB to chip.
- * Input : void *ex_handle
- * u32 service_type: Each kernel-mode service is allocated a
- * hardware db page.
- * u8 db_count: The bit[7:0] of PI can't be store in 64-bit db.
- * u64 db: It contains the content of db, whitch is organized by
- * service, including big-endian conversion
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-s32 hinic5_cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
-#if defined(__UEFI__) && defined(__HIFC__)
- EFI_STATUS Status;
- u64 *offset = NULL;
-#endif
-
- if (service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- pr_err("service_type is out of bounds\n");
- return HINIC5_CQM_FAIL;
- }
- if (!ex_handle)
- return HINIC5_CQM_FAIL;
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (!hinic5_cqm_handle)
- return HINIC5_CQM_FAIL;
-
- service = &hinic5_cqm_handle->service[service_type];
-
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
-#if defined(__UEFI__) && defined(__HIFC__)
- offset = ((u64 *)service->hardware_db_vaddr + db_count);
- MemoryFence();
- Status = ((BUS_IO_PROTOCOL *)handle->pcidev_hdl)->Mem.Write(handle->pcidev_hdl,
- EfiBusIoWidthUint64, 0x2,
- (u64)offset, 1,
- (void *)&db);
- MemoryFence();
-
- if (EFI_ERROR(Status))
- DEBUGPRINT(CRITICAL, "Hifc: write doorbell fails: %r\n",
- Status);
-#else
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- *((u64 *)service->hardware_db_vaddr + db_count) = db;
-#endif
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_ring_hardware_db);
-
-/**
- * Prototype : hinic5_cqm_ring_hardware_db_fc
- * Description : Ring fake vf hardware DB to chip.
- * Input : void *ex_handle
- * u32 service_type: Each kernel-mode service is allocated a
- * hardware db page.
- * u8 db_count: The bit[7:0] of PI can't be store in 64-bit db.
- * u8 pagenum: Indicates the doorbell address offset of the fake
- * VFID.
- * u64 db: It contains the content of db, whitch is organized by
- * service, including big-endian conversion.
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-s32 hinic5_cqm_ring_hardware_db_fc(void *ex_handle, u32 service_type, u8 db_count,
- u8 pagenum, u64 db)
-{
-#define HIFC_DB_FAKE_VF_OFFSET 32
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
- void *dbaddr = NULL;
-
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- service = &hinic5_cqm_handle->service[service_type];
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- dbaddr = (u8 *)service->hardware_db_vaddr +
- ((pagenum + HIFC_DB_FAKE_VF_OFFSET) * HINIC5_DB_PAGE_SIZE);
- *((u64 *)dbaddr + db_count) = db;
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_ring_direct_wqe_db
- * Description : Ring direct wqe hardware DB to chip.
- * Input : void *ex_handle
- * u32 service_type: Each kernel-mode service is allocated a
- * hardware db page.
- * u8 db_count: The bit[7:0] of PI can't be store in 64-bit db.
- * void *direct_wqe: The content of direct_wqe.
- * u16 length: The length of direct_wqe.
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-s32 hinic5_cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
- void *direct_wqe)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
- u64 *tmp = (u64 *)direct_wqe;
- int i;
-
- if (!ex_handle)
- return HINIC5_CQM_FAIL;
-
- if (service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- pr_err("service_type is out of bounds\n");
- return HINIC5_CQM_FAIL;
- }
-
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (!hinic5_cqm_handle)
- return HINIC5_CQM_FAIL;
-
- service = &hinic5_cqm_handle->service[service_type];
-
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- for (i = 0; i < 0x80 / 0x8; i++)
- *((u64 *)service->dwqe_vaddr + 0x40 + i) = *tmp++;
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_ring_direct_wqe_db);
-
-s32 hinic5_cqm_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type,
- void *direct_wqe)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
- u64 *tmp = (u64 *)direct_wqe;
- int i;
-
- handle = (struct hinic5_hwdev *)ex_handle;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- service = &hinic5_cqm_handle->service[service_type];
-
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- *((u64 *)service->dwqe_vaddr + 0x0) = tmp[0x2];
- *((u64 *)service->dwqe_vaddr + 0x1) = tmp[0x3];
- *((u64 *)service->dwqe_vaddr + 0x2) = tmp[0x0];
- *((u64 *)service->dwqe_vaddr + 0x3) = tmp[0x1];
- tmp += 0x4;
-
- /* The FC use 256B WQE. The directwqe is written at block0,
- * and the length is 256B
- */
- for (i = 0x4; i < 0x20; i++)
- *((u64 *)service->dwqe_vaddr + i) = *tmp++;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_ring_hardware_db_update_pri
- * Description : Provides the doorbell interface for the HINIC5_CQM to convert the PRI
- * to the CoS. The doorbell transmitted by the service must be
- * the host sequence. This interface converts the network
- * sequence.
- * Input : void *ex_handle
- * u32 service_type: Each kernel-mode service is allocated a
- * hardware db page.
- * u8 db_count: The bit[7:0] of PI can't be store in 64-bit db.
- * u64 db: It contains the content of db, whitch is organized by
- * service, including big-endian conversion.
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/11/24
- * Modification : Created function
- */
-s32 hinic5_cqm_ring_hardware_db_update_pri(void *ex_handle, u32 service_type,
- u8 db_count, u64 db)
-{
- struct tag_hinic5_cqm_db_common *db_common = (struct tag_hinic5_cqm_db_common *)(void *)(&db);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- handle = (struct hinic5_hwdev *)ex_handle;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- service = &hinic5_cqm_handle->service[service_type];
-
- /* the HINIC5_CQM converts the PRI to the CoS */
- db_common->cos = 0x7 - db_common->cos;
-
- hinic5_cqm_swab32((u8 *)db_common, sizeof(u64) >> HINIC5_CQM_DW_SHIFT);
-
- /* Considering the performance of ringing hardware db,
- * the parameter is not checked.
- */
- wmb();
- *((u64 *)service->hardware_db_vaddr + db_count) = db;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_ring_software_db
- * Description : Ring software db.
- * Input : struct tag_hinic5_cqm_object *object
- * u64 db_record: It contains the content of db, whitch is
- * organized by service, including big-endian
- * conversion. For RQ/SQ: This field is filled
- * with the doorbell_record area of queue_header.
- * For CQ: This field is filled with the value of
- * ci_record in queue_header.
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-s32 hinic5_cqm_ring_software_db(struct tag_hinic5_cqm_object *object, u64 db_record)
-{
- struct tag_hinic5_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
- struct tag_hinic5_cqm_rdma_qinfo *rdma_qinfo = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
- handle = hinic5_cqm_handle->ex_handle;
-
- if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_RQ ||
- object->object_type == HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_SQ ||
- object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- nonrdma_qinfo = (struct tag_hinic5_cqm_nonrdma_qinfo *)(void *)object;
- nonrdma_qinfo->common.q_header_vaddr->doorbell_record =
- db_record;
- } else if ((object->object_type == HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_CQ) ||
- (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ)) {
- nonrdma_qinfo = (struct tag_hinic5_cqm_nonrdma_qinfo *)(void *)object;
- nonrdma_qinfo->common.q_header_vaddr->ci_record = db_record;
- } else if ((object->object_type == HINIC5_CQM_OBJECT_RDMA_QP) ||
- (object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ)) {
- rdma_qinfo = (struct tag_hinic5_cqm_rdma_qinfo *)(void *)object;
- rdma_qinfo->common.q_header_vaddr->doorbell_record = db_record;
- } else if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- rdma_qinfo = (struct tag_hinic5_cqm_rdma_qinfo *)(void *)object;
- rdma_qinfo->common.q_header_vaddr->ci_record = db_record;
- } else {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object->object_type));
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_ring_software_db);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.h
deleted file mode 100644
index 8131d9020..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_db.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_db.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_DB_H
-#define HINIC5_CQM_DB_H
-
-#include <linux/types.h>
-
-struct tag_hinic5_cqm_db_common {
-#if (BYTE_ORDER == LITTLE_ENDIAN)
- u32 rsvd1 : 23;
- u32 c : 1;
- u32 cos : 3;
- u32 service_type : 5;
-#else
- u32 service_type : 5;
- u32 cos : 3;
- u32 c : 1;
- u32 rsvd1 : 23;
-#endif
-
- u32 rsvd2;
-};
-
-/* Only for test */
-s32 hinic5_cqm_db_addr_alloc(void *ex_handle, void __iomem **db_addr,
- void __iomem **dwqe_addr);
-s32 hinic5_cqm_db_phy_addr_alloc(void *ex_handle, u64 *db_paddr, u64 *dwqe_addr);
-
-s32 hinic5_cqm_db_init(void *ex_handle);
-void hinic5_cqm_db_uninit(void *ex_handle);
-
-s32 hinic5_cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count,
- u64 db);
-
-#endif /* HINIC5_CQM_DB_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.c
deleted file mode 100644
index 1f6e1ab03..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_fast_msg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/semaphore.h>
-#include <linux/workqueue.h>
-
-#include "comm_defs.h"
-#include "ossl_knl.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_dev_mgmt.h"
-#include "hinic5_hwif_inner.h"
-#include "hinic5_cqm_fast_msg.h"
-
-s32 hinic5_cqm_fast_msg_create_q(void *ex_handle, u32 queue_num, u32 sq_depth, u32 rq_depth)
-{
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_fast_msg_create_q);
-
-s32 hinic5_cqm_fast_msg_connect(void *ex_handle, struct dest_info *des_info, resp_func *rsp, recv_func *recv)
-{
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_fast_msg_connect);
-
-s32 hinic5_cqm_fast_msg_close(void *ex_handle, u64 msg_id)
-{
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_fast_msg_close);
-
-s32 hinic5_cqm_fast_msg_listen(void *ex_handle, u32 credit, resp_func *rsp, recv_func *recv)
-{
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_fast_msg_listen);
-
-s32 hinic5_cqm_fast_msg_send(void *ex_handle, u64 msg_id, struct dest_info *des_info, u8 *buf_res)
-{
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_fast_msg_send);
-
-static int hinic5_cqm_fast_msg_pf_handler(void *pri_handle, u16 vf_id, u16 cmd, void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
-{
-#define SPU_HOST_ID 4
-
- struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)pri_handle;
- void *ppf_hw_dev = NULL;
- int ret;
-
- if (!hwdev)
- return -EINVAL;
-
- ppf_hw_dev = hinic5_get_ppf_hw_dev_unsafe(pri_handle);
- if (!ppf_hw_dev) {
- pr_err("hinic5_cqm_fast_msg_pf_handler ppf is null.\n");
- return -EINVAL;
- }
-
- sdk_info(hwdev->dev_hdl, "hinic5_cqm_fast_msg_pf_handler recv vf 0x%x mbox, cmd: 0x%x\n",
- vf_id, cmd);
-
- ret = hinic5_mbox_ppf_to_host(ppf_hw_dev, HINIC5_MOD_FAKE_FMSG, 0,
- SPU_HOST_ID, buf_in, in_size, buf_out,
- out_size, 0, HINIC5_CHANNEL_UB);
- if (ret != 0) {
- pr_err("hinic5_cqm_fast_msg_pf_handler failed send msg to host %u ret:%d\n",
- SPU_HOST_ID, ret);
- return ret;
- }
- return 0;
-}
-
-static struct hinic5_hwdev *get_pf_dev_by_ppf(struct hinic5_hwdev *ppf_hwdev, bool hold, u16 pf_id)
-{
- struct hinic5_adev *adev = NULL;
- struct card_node *chip_node = NULL;
- struct hinic5_adev *dev = NULL;
-
- if (!ppf_hwdev)
- return NULL;
-
- adev = ppf_hwdev->adapter_hdl;
- if (!adev)
- return NULL;
-
- hinic5_lld_hold();
- chip_node = adev->chip_node;
- list_for_each_entry(dev, &chip_node->func_list, node) {
- if (dev->hwdev && hinic5_global_func_id(dev->hwdev) == pf_id) {
- if (hold)
- hinic5_lld_dev_hold(&dev->lld_dev);
- hinic5_lld_put();
- return dev->hwdev;
- }
- }
- hinic5_lld_put();
-
- return NULL;
-}
-
-static int hinic5_cqm_fast_msg_ppf_handler(void *pri_handle, u16 pf_idx, u16 vf_id, u16 cmd, void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
-{
-#define SDI_PPF_ID 16
-#define HOST_PF_ID 2
-#define SPU_HOST_VFID 64U
-
- struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)pri_handle;
- struct hinic5_hwdev *pf_hwdev = NULL;
- fast_msg_t *msg = (fast_msg_t *)buf_in;
- u16 ppf_id;
- int ret = 0;
-
- if (!hwdev)
- return -EINVAL;
-
- ppf_id = hinic5_global_func_id(hwdev);
- if (ppf_id == SDI_PPF_ID) {
- pr_err("hinic5_cqm_fast_msg_ppf_handler channel error, src: 0x%x cmd: 0x%x.\n",
- pf_idx, cmd);
- } else {
- pf_hwdev = get_pf_dev_by_ppf(hwdev, false, HOST_PF_ID);
- if (!pf_hwdev) {
- pr_err("hinic5_cqm_fast_msg_ppf_handler pf hwdev is null\n");
- return -EFAULT;
- }
- ret = hinic5_mbox_to_vf(pf_hwdev, msg->dst_fe_idx - SPU_HOST_VFID + 1u,
- HINIC5_MOD_FAKE_FMSG, 0, buf_in,
- in_size, buf_out, out_size, 0, HINIC5_CHANNEL_UB);
- }
- return ret;
-}
-
-s32 hinic5_cqm_init_fast_msg(void *hwdev)
-{
- struct hinic5_hwdev *hw_dev = (struct hinic5_hwdev *)hwdev;
-
- if (HINIC5_IS_PPF(hw_dev))
- hinic5_register_ppf_mbox_cb(hwdev, HINIC5_MOD_FAKE_FMSG, hwdev,
- hinic5_cqm_fast_msg_ppf_handler);
- if (HINIC5_IS_PF(hw_dev))
- hinic5_register_pf_mbox_cb(hwdev, HINIC5_MOD_FAKE_FMSG, hwdev,
- hinic5_cqm_fast_msg_pf_handler);
- return 0;
-}
-
-void hinic5_cqm_deinit_fast_msg(void *hwdev)
-{
- struct hinic5_hwdev *hw_dev = (struct hinic5_hwdev *)hwdev;
-
- if (HINIC5_IS_PPF(hw_dev))
- hinic5_unregister_ppf_mbox_cb(hwdev, HINIC5_MOD_FAKE_FMSG);
-
- if (HINIC5_IS_PF(hw_dev))
- hinic5_unregister_pf_mbox_cb(hwdev, HINIC5_MOD_FAKE_FMSG);
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.h
deleted file mode 100644
index cb609c5b1..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_fast_msg.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_fast_msg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_FAST_MSG_H
-#define HINIC5_CQM_FAST_MSG_H
-
-#include <linux/types.h>
-#include <linux/module.h>
-
-#include "ossl_knl.h"
-
-struct dest_info {
- u32 func_id;
- u32 queue_id;
-};
-
-struct src_info {
- u32 func_id;
- u32 queue_id;
- u64 msg_id;
-};
-
-typedef struct fast_msg {
- u16 dst_fe_idx;
-} fast_msg_t;
-
-typedef s32 (resp_func)(u64 msg_id, u8 *buf_res, s32 result);
-typedef s32 (recv_func)(struct src_info *src, u8 *buf_res);
-s32 hinic5_cqm_fast_msg_create_q(void *ex_handle, u32 queue_num, u32 sq_depth, u32 rq_depth);
-s32 hinic5_cqm_fast_msg_connect(void *ex_handle, struct dest_info *des_info, resp_func *rsp, recv_func *recv);
-s32 hinic5_cqm_fast_msg_close(void *ex_handle, u64 msg_id);
-s32 hinic5_cqm_fast_msg_listen(void *ex_handle, u32 credit, resp_func *rsp, recv_func *recv);
-s32 hinic5_cqm_fast_msg_send(void *ex_handle, u64 msg_id, struct dest_info *des_info, u8 *buf_res);
-s32 hinic5_cqm_init_fast_msg(void *hwdev);
-void hinic5_cqm_deinit_fast_msg(void *hwdev);
-
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.c
deleted file mode 100644
index 5aa4ae4db..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.c
+++ /dev/null
@@ -1,2078 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_main.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-
-#include "ossl_knl.h"
-#include "hinic5_hw.h"
-#include "hinic5_mt.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
-#include "hinic5_hw_cfg.h"
-#include "hinic5_hinic5_vram_api.h"
-#include "hinic5_typedef_inner.h"
-
-#include "hinic5_vram_common.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_bloomfilter.h"
-#include "hinic5_cqm_db.h"
-#include "hinic5_cqm_cmdq.h"
-#include "hinic5_cqm_main.h"
-
-static s32 hinic5_cqm_set_fake_vf_child_timer(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle, bool en)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)hinic5_cqm_handle->ex_handle;
- u16 func_global_idx;
- s32 ret;
-
- if (fake_hinic5_cqm_handle->func_capability.timer_enable == 0) {
- return HINIC5_CQM_SUCCESS;
- }
-
- func_global_idx = fake_hinic5_cqm_handle->func_attribute.func_global_idx;
- ret = hinic5_func_tmr_bitmap_set(hinic5_cqm_handle->ex_handle, func_global_idx, en);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "func_id %u Timer %s timer bitmap failed\n",
- func_global_idx, en ? "enable" : "disable");
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_unset_fake_vf_timer(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 i, child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++)
- (void)hinic5_cqm_set_fake_vf_child_timer(hinic5_cqm_handle, hinic5_cqm_handle->fake_hinic5_cqm_handle[i], false);
-}
-
-static s32 hinic5_cqm_set_fake_vf_timer(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 i, child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++) {
- s32 ret = hinic5_cqm_set_fake_vf_child_timer(hinic5_cqm_handle, hinic5_cqm_handle->fake_hinic5_cqm_handle[i], true);
- if (ret != HINIC5_CQM_SUCCESS)
- goto err;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_unset_fake_vf_timer(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-static s32 hinic5_cqm_set_timer_enable(void *ex_handle)
-{
- struct hinic5_hwdev *handle = ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- u16 func_id = hinic5_global_func_id(ex_handle);
- int is_in_kexec;
-
- is_in_kexec = hinic5_vram_get_kexec_flag();
- if (is_in_kexec != 0) {
- hinic5_cqm_info(handle->dev_hdl, "Skip starting hinic5_cqm timer during kexec\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- /* Enable children */
- if (HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle) &&
- hinic5_cqm_set_fake_vf_timer(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS)
- return HINIC5_CQM_FAIL;
-
- /* Enable self */
- if (hinic5_func_tmr_bitmap_set(ex_handle, func_id, true) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Timer start: enable timer bitmap failed\n");
- goto err;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- if (HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- hinic5_cqm_unset_fake_vf_timer(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-static void hinic5_cqm_set_timer_disable(void *ex_handle)
-{
- struct hinic5_hwdev *handle = ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
-
- /* Disable self */
- if (hinic5_func_tmr_bitmap_set(ex_handle, hinic5_global_func_id(ex_handle),
- false) != HINIC5_CQM_SUCCESS)
- hinic5_cqm_err(handle->dev_hdl, "func_id %u Timer stop: disable timer bitmap failed\n",
- hinic5_global_func_id(ex_handle));
-
- /* Disable children */
- if (HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- hinic5_cqm_unset_fake_vf_timer(hinic5_cqm_handle);
-}
-
-static u32 hinic5_cqm_set_vio_enable(void *ex_handle, bool enable)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- int err;
-
- if (!ex_handle)
- return HINIC5_CQM_FAIL;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (!hinic5_cqm_handle->service[HINIC5_CQM_SERVICE_T_VIRTIO].valid)
- return HINIC5_CQM_SUCCESS;
-
- err = hinic5_func_vio_en(ex_handle, enable);
- if (err != 0) {
- hinic5_cqm_err(handle->dev_hdl, "VIO %s failed, err %d\n",
- (enable ? "enable" : "disable"), err);
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_info(handle->dev_hdl, "VIO %s success\n",
- (enable ? "enable" : "disable"));
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_initialize_recource(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- /* Initialize memory entries such as BAT, CLA, and bitmap. */
- if (hinic5_cqm_mem_init(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_mem_init));
- return HINIC5_CQM_FAIL;
- }
-
- /* Event callback initialization */
- if (hinic5_cqm_event_init(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_event_init));
- goto err1;
- }
-
- /* Doorbell initiation */
- if (hinic5_cqm_db_init(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_db_init));
- goto err2;
- }
-
- /* Initialize the bloom filter. */
- if (hinic5_cqm_bloomfilter_init(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bloomfilter_init));
- goto err3;
- }
-
- if (hinic5_cqm_set_timer_enable(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_set_timer_enable));
- goto err4;
- }
-
- if (hinic5_cqm_set_vio_enable(ex_handle, true) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_set_vio_enable));
- goto err5;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err5:
- hinic5_cqm_set_timer_disable(ex_handle);
-err4:
- hinic5_cqm_bloomfilter_uninit(ex_handle);
-err3:
- hinic5_cqm_db_uninit(ex_handle);
-err2:
- hinic5_cqm_event_uninit(ex_handle);
-err1:
- hinic5_cqm_mem_uninit(ex_handle);
- return HINIC5_CQM_FAIL;
-}
-
-static struct tag_hinic5_cqm_handle *hinic5_cqm_handle_create(void)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
-
- hinic5_cqm_handle = kzalloc(sizeof(*hinic5_cqm_handle), GFP_KERNEL);
- if (unlikely(!hinic5_cqm_handle)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(hinic5_cqm_handle));
- return NULL;
- }
-
- /* Clear the memory to prevent other systems from
- * not clearing the memory.
- */
- memset(hinic5_cqm_handle, 0, sizeof(struct tag_hinic5_cqm_handle));
-
- atomic_set(&hinic5_cqm_handle->handle_state, HINIC5_CQM_HANDLE_STATE_INIT);
-
- return hinic5_cqm_handle;
-}
-
-static struct tag_hinic5_cqm_handle *hinic5_cqm_handle_fork(struct tag_hinic5_cqm_handle *parent_handle)
-{
- struct tag_hinic5_cqm_handle *child_handle = NULL;
-
- child_handle = kzalloc(sizeof(*child_handle), GFP_KERNEL);
- if (unlikely(!child_handle)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(child_handle));
- return NULL;
- }
-
- /* Copy the attributes of the parent HINIC5_CQM handle to the child HINIC5_CQM
- * handle and modify the values of function.
- */
- memcpy(child_handle,
- parent_handle, sizeof(struct tag_hinic5_cqm_handle));
-
- /* Clear state & unlink some references */
- atomic_set(&child_handle->handle_state, HINIC5_CQM_HANDLE_STATE_INIT);
- memset(child_handle->fake_hinic5_cqm_handle,
- 0, sizeof(child_handle->fake_hinic5_cqm_handle));
-
- return child_handle;
-}
-
-/**
- * Prototype : hinic5_cqm_init
- * Description : Complete HINIC5_CQM initialization.
- * If the function is a parent fake function, copy the fake.
- * If it is a child fake function (in the fake copy function,
- * not in this function), set fake_en in the BAT/CLA table.
- * hinic5_cqm_init->hinic5_cqm_mem_init->hinic5_cqm_fake_init(copy)
- * If the child fake conflict occurs, resources are not
- * initialized, but the timer must be enabled.
- * If the function is of the normal type,
- * follow the normal process.
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = hinic5_cqm_handle_create();
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_handle_create));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle->ex_handle = handle;
- hinic5_cqm_handle->dev = handle->dev_hdl;
- handle->hinic5_cqm_hdl = (void *)hinic5_cqm_handle;
-
- /* 187x ops or 182x ops */
- hinic5_cqm_cmdq_adapt_init(hinic5_cqm_handle);
- /* Clearing Statistics */
- memset(&handle->hw_stats.hinic5_cqm_stats, 0, sizeof(struct hinic5_cqm_stats));
-
- /* Reads VF/PF information. */
- hinic5_cqm_handle->func_attribute = handle->hwif->attr;
- hinic5_cqm_info(handle->dev_hdl, "Func init: function[%u] type %d(0:PF,1:VF,2:PPF)\n",
- hinic5_cqm_handle->func_attribute.func_global_idx, hinic5_cqm_handle->func_attribute.func_type);
-
- /* Read capability from configuration management module */
- ret = hinic5_cqm_capability_init(ex_handle);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_capability_init));
- goto err1;
- }
-
- /* memory doorbell event bloomfilter timer init */
- if (hinic5_cqm_initialize_recource(ex_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_initialize_recource));
- goto err1;
- }
-
- atomic_set(&hinic5_cqm_handle->handle_state, HINIC5_CQM_HANDLE_STATE_READY);
- return HINIC5_CQM_SUCCESS;
-
-err1:
- kfree(handle->hinic5_cqm_hdl);
- handle->hinic5_cqm_hdl = NULL;
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_uninit
- * Description : Deinitializes the HINIC5_CQM module. This function is called once
- * each time a function is removed.
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_uninit(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
-
- atomic_set(&hinic5_cqm_handle->handle_state, HINIC5_CQM_HANDLE_STATE_REMOVE);
-
- hinic5_cqm_set_vio_enable(ex_handle, false);
-
- hinic5_cqm_set_timer_disable(ex_handle);
-
- /* After the TMR timer stops, the system releases resources
- * after a delay of one or two milliseconds.
- */
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle)) {
- if (hinic5_cqm_handle->func_capability.timer_enable ==
- HINIC5_CQM_TIMER_ENABLE) {
- hinic5_cqm_info(handle->dev_hdl, "PPF timer stop\n");
- ret = hinic5_ppf_tmr_stop(handle);
- if (ret != HINIC5_CQM_SUCCESS)
- /* The timer fails to be stopped,
- * and the resource release is not affected.
- */
- hinic5_cqm_info(handle->dev_hdl, "PPF timer stop, ret=%d\n", ret);
- }
-
- usleep_range(0x384, 0x3E8); /* Somebody requires a delay of 1 ms,
- * which is inaccurate.
- */
- }
-
- /* Release Bloom Filter Table */
- hinic5_cqm_bloomfilter_uninit(ex_handle);
-
- /* Release hardware doorbell */
- hinic5_cqm_db_uninit(ex_handle);
-
- /* Cancel the callback of the event */
- hinic5_cqm_event_uninit(ex_handle);
-
- /* Release various memory tables and require the service
- * to release all objects.
- */
- hinic5_cqm_mem_uninit(ex_handle);
-
- /* Release hinic5_cqm_handle */
- handle->hinic5_cqm_hdl = NULL;
- kfree(hinic5_cqm_handle);
-}
-
-static void hinic5_cqm_test_mode_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct service_cap *service_capability)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- if (service_capability->test_mode == 0)
- return;
-
- hinic5_cqm_info(handle->dev_hdl, "Enter HINIC5_CQM test mode\n");
-
- func_cap->qpc_number = service_capability->test_qpc_num;
- func_cap->qpc_reserved =
- GET_MAX(func_cap->qpc_reserved,
- service_capability->test_qpc_resvd_num);
- func_cap->xid_alloc_mode = service_capability->test_xid_alloc_mode;
- func_cap->gpa_check_enable = service_capability->test_gpa_check_enable;
- func_cap->pagesize_reorder = service_capability->test_page_size_reorder;
- func_cap->qpc_alloc_static =
- (bool)(service_capability->test_qpc_alloc_mode);
- func_cap->scqc_alloc_static =
- (bool)(service_capability->test_scqc_alloc_mode);
- func_cap->flow_table_based_conn_number =
- service_capability->test_max_conn_num;
- func_cap->flow_table_based_conn_cache_number =
- service_capability->test_max_cache_conn_num;
- func_cap->scqc_number = service_capability->test_scqc_num;
- func_cap->mpt_number = service_capability->test_mpt_num;
- func_cap->mpt_reserved = service_capability->test_mpt_recvd_num;
- func_cap->reorder_number = service_capability->test_reorder_num;
- /* 256K buckets, 256K*64B = 16MB */
- func_cap->hash_number = service_capability->test_hash_num;
-}
-
-static void hinic5_cqm_service_capability_update(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
-
- func_cap->qpc_number = GET_MIN(HINIC5_CQM_MAX_QPC_NUM, func_cap->qpc_number);
- func_cap->scqc_number = GET_MIN(HINIC5_CQM_MAX_SCQC_NUM,
- func_cap->scqc_number);
- func_cap->srqc_number = GET_MIN(HINIC5_CQM_MAX_SRQC_NUM,
- func_cap->srqc_number);
- func_cap->childc_number = GET_MIN(HINIC5_CQM_MAX_CHILDC_NUM,
- func_cap->childc_number);
-}
-
-static void hinic5_cqm_service_valid_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- const struct service_cap *service_capability)
-{
- u32 type = service_capability->chip_svc_type;
- struct tag_hinic5_cqm_service *svc = hinic5_cqm_handle->service;
-
- svc[HINIC5_CQM_SERVICE_T_NIC].valid = (type & CFG_SERVICE_MASK_NIC) != 0;
- svc[HINIC5_CQM_SERVICE_T_OVS].valid = (type & CFG_SERVICE_MASK_OVS) != 0;
- svc[HINIC5_CQM_SERVICE_T_ROCE].valid = (type & CFG_SERVICE_MASK_ROCE) != 0;
- svc[HINIC5_CQM_SERVICE_T_TOE].valid = (type & CFG_SERVICE_MASK_TOE) != 0;
- svc[HINIC5_CQM_SERVICE_T_FC].valid = (type & CFG_SERVICE_MASK_FC) != 0;
- svc[HINIC5_CQM_SERVICE_T_IPSEC].valid = (type & CFG_SERVICE_MASK_IPSEC) != 0;
- svc[HINIC5_CQM_SERVICE_T_VBS].valid = (type & CFG_SERVICE_MASK_VBS) != 0;
- svc[HINIC5_CQM_SERVICE_T_VIRTIO].valid = (type & CFG_SERVICE_MASK_VIRTIO) != 0;
- svc[HINIC5_CQM_SERVICE_T_IOE].valid = false;
- svc[HINIC5_CQM_SERVICE_T_PPA].valid = (type & CFG_SERVICE_MASK_PPA) != 0;
- svc[HINIC5_CQM_SERVICE_T_UB].valid = (type & CFG_SERVICE_MASK_UB) != 0;
- svc[HINIC5_CQM_SERVICE_T_JBOF].valid = (type & CFG_SERVICE_MASK_JBOF) != 0;
- svc[HINIC5_CQM_SERVICE_T_VROCE].valid = (type & CFG_SERVICE_MASK_VROCE) != 0;
- svc[HINIC5_CQM_SERVICE_T_DMMU].valid = (type & CFG_SERVICE_MASK_DMMU) != 0;
- svc[HINIC5_CQM_SERVICE_T_CFM].valid = (type & CFG_SERVICE_MASK_CFM) != 0;
-}
-
-static void hinic5_cqm_service_capability_init_nic(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: nic is valid, but nic need not be init by hinic5_cqm\n");
-}
-
-static void hinic5_cqm_service_capability_init_ovs(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct ovs_service_cap *ovs_cap = &service_capability->ovs_cap;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ovs is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ovs qpc 0x%x\n",
- ovs_cap->dev_ovs_cap.max_pctxs);
- func_cap->hash_number += ovs_cap->dev_ovs_cap.max_pctxs;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- func_cap->qpc_number += ovs_cap->dev_ovs_cap.max_pctxs;
- func_cap->qpc_basic_size = GET_MAX(ovs_cap->pctx_sz,
- func_cap->qpc_basic_size);
- func_cap->qpc_reserved += ovs_cap->dev_ovs_cap.max_pctxs;
- func_cap->qpc_alloc_static = true;
- func_cap->pagesize_reorder = HINIC5_CQM_OVS_PAGESIZE_ORDER;
-}
-
-static void hinic5_cqm_service_capability_roce_cap_print(struct hinic5_hwdev *handle,
- const struct hinic5_board_info *board_info, const struct dev_roce_svc_own_cap *roce_own_cap)
-{
- hinic5_cqm_info(handle->dev_hdl, "Cap init: roce is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
- roce_own_cap->max_qps, roce_own_cap->max_cqs,
- roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, srv_bmp:0x%x\n",
- board_info->board_type, board_info->scenes_id, board_info->service_en_bitmap);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: reserved_qps:0x%x, reserved_qps_back:0x%x, "
- "reserved_cqs:0x%x, reserved_cqs_back:0x%x\n",
- roce_own_cap->reserved_qps, roce_own_cap->reserved_qps_back,
- roce_own_cap->reserved_cqs, roce_own_cap->reserved_cqs_back);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: reserved_srqs:0x%x, reserved_srqs_back:0x%x, "
- "max_pd:0x%x, max_xrcd:0x%x, max_gid:0x%x\n",
- roce_own_cap->reserved_srqs, roce_own_cap->reserved_srqs_back,
- roce_own_cap->max_pd, roce_own_cap->max_xrcd, roce_own_cap->max_gid);
-}
-
-static void hinic5_cqm_service_capability_init_roce(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct rdma_service_cap *rdma_cap = &service_capability->rdma_cap;
- struct dev_roce_svc_own_cap *roce_own_cap = &rdma_cap->dev_rdma_cap.roce_own_cap;
-
- hinic5_cqm_service_capability_roce_cap_print(handle, &handle->board_info, roce_own_cap);
-
- func_cap->use_fake_parent_cla = true;
-
- if (COMM_SUPPORT_EXTEND_CAPBILITY(handle)) {
- func_cap->qpc_reserved += roce_own_cap->reserved_qps;
- func_cap->qpc_reserved_back += roce_own_cap->reserved_qps_back;
- func_cap->scq_reserved += roce_own_cap->reserved_cqs;
- func_cap->srq_reserved += roce_own_cap->reserved_srqs;
- } else {
- func_cap->qpc_reserved += HINIC5_CQM_QPC_ROCE_RSVD;
- func_cap->scq_reserved += HINIC5_CQM_CQ_ROCE_RSVD;
- func_cap->srq_reserved += HINIC5_CQM_SRQ_ROCE_RSVD;
- }
-
- func_cap->xid_alloc_mode = false; /* xid fast reuse */
- func_cap->qpc_number += roce_own_cap->max_qps;
- func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz, func_cap->qpc_basic_size);
- func_cap->qpc_alloc_static = true;
- func_cap->scqc_alloc_static = true;
- func_cap->srqc_alloc_static = true;
- func_cap->scqc_number += roce_own_cap->max_cqs;
- func_cap->scqc_basic_size = GET_MAX(rdma_cap->cqc_entry_sz, func_cap->scqc_basic_size);
- func_cap->srqc_number += roce_own_cap->max_srqs;
- func_cap->srqc_basic_size = GET_MAX(roce_own_cap->srqc_entry_sz, func_cap->srqc_basic_size);
- func_cap->mpt_number += roce_own_cap->max_mpts;
- func_cap->mpt_reserved += rdma_cap->reserved_mrws;
- func_cap->mpt_basic_size = GET_MAX(rdma_cap->mpt_entry_sz, func_cap->mpt_basic_size);
- if (COMM_SUPPORT_EXTEND_CAPBILITY(handle))
- func_cap->gid_number = roce_own_cap->max_gid;
- else
- func_cap->gid_number = HINIC5_CQM_GID_RDMA_NUM;
-
- func_cap->gid_basic_size = HINIC5_CQM_GID_SIZE_32;
- func_cap->childc_number += roce_own_cap->max_child_ctx_num;
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
-}
-
-static void hinic5_cqm_service_capability_init_vroce(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct rdma_service_cap *rdma_cap = &service_capability->rdma_cap;
- struct dev_roce_svc_own_cap *roce_own_cap = &rdma_cap->dev_rdma_cap.roce_own_cap;
-
- if (IS_MASTER_HOST(handle)) {
- func_cap->hash_number = roce_own_cap->max_qps;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: vroce is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: hash_number 0x%x hash_basic_size 0x%x\n", func_cap->hash_number,
- func_cap->hash_basic_size);
- }
-}
-
-static void hinic5_cqm_service_capability_init_toe(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_toe_private_capability *toe_own_cap = &hinic5_cqm_handle->toe_own_capability;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct rdma_service_cap *rdma_cap = &service_capability->rdma_cap;
- struct toe_service_cap *toe_cap = &service_capability->toe_cap;
- struct dev_toe_svc_cap *dev_toe_cap = &toe_cap->dev_toe_cap;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: toe is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: toe qpc 0x%x, scqc 0x%x, srqc 0x%x\n",
- dev_toe_cap->max_pctxs, dev_toe_cap->max_cqs,
- dev_toe_cap->max_srqs);
- func_cap->hash_number += dev_toe_cap->max_pctxs;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- func_cap->qpc_number += dev_toe_cap->max_pctxs;
- func_cap->qpc_basic_size = GET_MAX(toe_cap->pctx_sz,
- func_cap->qpc_basic_size);
- func_cap->qpc_alloc_static = true;
- func_cap->scqc_number += dev_toe_cap->max_cqs;
- func_cap->scqc_basic_size = GET_MAX(toe_cap->scqc_sz,
- func_cap->scqc_basic_size);
- func_cap->scqc_alloc_static = true;
-
- toe_own_cap->toe_srqc_number = dev_toe_cap->max_srqs;
- toe_own_cap->toe_srqc_start_id = dev_toe_cap->srq_id_start;
- toe_own_cap->toe_srqc_basic_size = HINIC5_CQM_SRQC_SIZE_64;
- func_cap->childc_number += dev_toe_cap->max_cctxt;
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256,
- func_cap->childc_basic_size);
- func_cap->mpt_number += dev_toe_cap->max_mpts;
- func_cap->mpt_reserved = 0;
- func_cap->mpt_basic_size = GET_MAX(rdma_cap->mpt_entry_sz,
- func_cap->mpt_basic_size);
-}
-
-static void hinic5_cqm_service_capability_init_ioe(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ioe is valid\n");
-}
-
-static void hinic5_cqm_service_capability_init_fc(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct fc_service_cap *fc_cap = &service_capability->fc_cap;
- struct dev_fc_svc_cap *dev_fc_cap = &fc_cap->dev_fc_cap;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: fc is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: fc qpc 0x%x, scqc 0x%x, srqc 0x%x\n",
- dev_fc_cap->max_parent_qpc_num, dev_fc_cap->scq_num,
- dev_fc_cap->srq_num);
- func_cap->hash_number += dev_fc_cap->max_parent_qpc_num;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- func_cap->qpc_number += dev_fc_cap->max_parent_qpc_num;
- func_cap->qpc_basic_size = GET_MAX(fc_cap->parent_qpc_size,
- func_cap->qpc_basic_size);
- func_cap->qpc_alloc_static = true;
- func_cap->scqc_number += dev_fc_cap->scq_num;
- func_cap->scqc_basic_size = GET_MAX(fc_cap->scqc_size,
- func_cap->scqc_basic_size);
- func_cap->srqc_number += dev_fc_cap->srq_num;
- func_cap->srqc_basic_size = GET_MAX(fc_cap->srqc_size,
- func_cap->srqc_basic_size);
- func_cap->lun_number = HINIC5_CQM_LUN_FC_NUM;
- func_cap->lun_basic_size = HINIC5_CQM_LUN_SIZE_8;
- func_cap->taskmap_number = HINIC5_CQM_TASKMAP_FC_NUM;
- func_cap->taskmap_basic_size = PAGE_SIZE;
- func_cap->childc_number += dev_fc_cap->max_child_qpc_num;
- func_cap->childc_basic_size = GET_MAX(fc_cap->child_qpc_size,
- func_cap->childc_basic_size);
- func_cap->pagesize_reorder = HINIC5_CQM_FC_PAGESIZE_ORDER;
-}
-
-static void hinic5_cqm_service_capability_init_vbs(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: vbs is valid\n");
-
- /* If the entry size is greater than the cache line (256 bytes),
- * align the entries by cache line.
- */
- func_cap->qpc_basic_size = GET_MAX(HINIC5_CQM_VBS_QPC_SIZE,
- func_cap->qpc_basic_size);
- func_cap->qpc_alloc_static = true;
- func_cap->scqc_basic_size = HINIC5_CQM_VBS_SCQC_SIZE;
- func_cap->scqc_alloc_static = false;
- func_cap->scq_reserved += service_capability->vbs_cap.vbs_max_volq;
- func_cap->childc_number += service_capability->vbs_cap.vbs_child_ctx_num;
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
- func_cap->xid_alloc_mode = false;
- func_cap->hash_number += service_capability->vbs_cap.vbs_hash_bucket_num;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
-
- func_cap->qpc_number += service_capability->vbs_cap.vbs_max_volq;
- func_cap->scqc_number += service_capability->vbs_cap.vbs_max_volq;
-}
-
-static void hinic5_cqm_service_capability_init_jbof(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct jbof_service_cap *jbof_cap = &service_capability->jbof_cap;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: jbof is valid\n");
- func_cap->qpc_alloc_static = true;
- func_cap->qpc_number += jbof_cap->max_parent_qpc_num;
- func_cap->qpc_basic_size = GET_MAX(jbof_cap->parent_qpc_size,
- func_cap->qpc_basic_size);
- func_cap->childc_number += jbof_cap->max_child_qpc_num;
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256,
- func_cap->childc_basic_size);
- func_cap->hash_number += jbof_cap->hash_bucket_num;
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
-}
-
-static void hinic5_cqm_service_capability_init_ipsec(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct ipsec_service_cap *ipsec_cap = &service_capability->ipsec_cap;
- struct dev_ipsec_svc_cap *ipsec_srvcap = &ipsec_cap->dev_ipsec_cap;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- func_cap->childc_number += (ipsec_srvcap->max_sactxs + ipsec_srvcap->max_spctxs);
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256,
- func_cap->childc_basic_size);
- func_cap->scqc_number += ipsec_srvcap->max_cqs;
- func_cap->scqc_basic_size = GET_MAX(HINIC5_CQM_SCQC_SIZE_64,
- func_cap->scqc_basic_size);
- func_cap->scqc_alloc_static = true;
- func_cap->hash_number += HINIC5_CQM_CRYPT_HASH_BUCKET_NUM(ipsec_srvcap->sa_hash_bucket_num + ipsec_srvcap->sp_hash_bucket_num);
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- hinic5_cqm_info(handle->dev_hdl, "Cap init: max_sactxs: 0x%x, max_spctxs: 0x%x, childc_bsize %u\n",
- ipsec_srvcap->max_sactxs, ipsec_srvcap->max_spctxs, func_cap->childc_basic_size);
- hinic5_cqm_info(handle->dev_hdl, "scqc_num 0x%x, scqc_bsize %u\n", ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
- hinic5_cqm_info(handle->dev_hdl,
- "Cap init: ipsec sa_hash_bucket_num: 0x%x, sp_hash_bucket_num: 0x%x, hash_basic_size %u\n",
- ipsec_srvcap->sa_hash_bucket_num, ipsec_srvcap->sp_hash_bucket_num, func_cap->hash_basic_size);
-}
-
-static void hinic5_cqm_service_capability_init_virtio(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *svc_cap = (struct service_cap *)pra;
- u32 vq_num, vq_size, xid2cid_size;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: virtio is valid\n");
-
- vq_num = svc_cap->virtio_vq_num != 0 ? svc_cap->virtio_vq_num : HINIC5_CQM_VIRTIO_VQ_NUM_DEFAULT;
- vq_num += svc_cap->nvme_qp_num;
- vq_size = vq_num * svc_cap->virtio_vq_size;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: vq_num 0x%x, vq_size 0x%x\n", vq_num, vq_size);
-
- if (COMM_SUPPORT_VIRTIO_FC_CACHE(handle)) {
- /* In VirtIO function context cache mode,
- * the VQs are divided and stored in all enabled SMFs. */
- xid2cid_size = vq_size / func_cap->smf_enabled_num;
- xid2cid_size += svc_cap->vio_func_num * HINIC5_CQM_VIRTIO_FC_SIZE;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: vio_func_num 0x%x\n", svc_cap->vio_func_num);
- } else {
- xid2cid_size = vq_size;
- }
-
- func_cap->xid2cid_number += xid2cid_size / HINIC5_CQM_CHIP_CACHELINE;
- func_cap->xid2cid_basic_size = HINIC5_CQM_CHIP_CACHELINE;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: xid2cid_size 0x%x, xid2cid_number 0x%x\n",
- xid2cid_size, func_cap->xid2cid_number);
-}
-
-static void hinic5_cqm_service_capability_init_ppa(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct ppa_service_cap *ppa_cap = &service_capability->ppa_cap;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ppa is valid\n");
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
- func_cap->qpc_alloc_static = true;
- func_cap->pagesize_reorder = HINIC5_CQM_PPA_PAGESIZE_ORDER;
- func_cap->qpc_basic_size = GET_MAX(ppa_cap->pctx_sz,
- func_cap->qpc_basic_size);
-}
-
-static void hinic5_cqm_service_capability_init_ub(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, void *pra)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct service_cap *service_capability = (struct service_cap *)pra;
- struct ub_dev_cap_sdk_res *ub_sdk_res = &service_capability->ub_cap.sdk_res;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ub is valid\n");
-
- func_cap->use_fake_parent_cla = true;
-
- func_cap->scqc_alloc_static = true;
- func_cap->scqc_basic_size = GET_MAX(func_cap->scqc_basic_size, ub_sdk_res->cqc_entry_sz);
- func_cap->scqc_number += ub_sdk_res->max_tp;
- func_cap->scqc_number += ub_sdk_res->max_jfc;
- func_cap->scqc_number += ub_sdk_res->max_jetty_grp;
- func_cap->scqc_number += ub_sdk_res->max_vtp;
- func_cap->scqc_number += ub_sdk_res->max_utp;
- func_cap->scqc_number += ub_sdk_res->max_tpg;
-
- func_cap->scq_reserved += ub_sdk_res->max_tp;
- func_cap->scq_reserved += ub_sdk_res->max_jfrc;
-
- func_cap->srqc_number += ub_sdk_res->max_jfr;
- func_cap->srqc_basic_size = ub_sdk_res->srqc_entry_sz;
- func_cap->srqc_alloc_static = true;
-
- func_cap->mpt_basic_size = GET_MAX(ub_sdk_res->mpt_entry_sz, func_cap->mpt_basic_size);
- func_cap->mpt_number += ub_sdk_res->max_mpts;
-
- func_cap->qpc_alloc_static = true;
- func_cap->qpc_number += ub_sdk_res->max_jetty;
- func_cap->qpc_number += ub_sdk_res->max_tp;
- func_cap->qpc_basic_size = GET_MAX(func_cap->qpc_basic_size, ub_sdk_res->qpc_entry_sz);
- func_cap->gid_number += ub_sdk_res->max_gid;
- func_cap->gid_basic_size = HINIC5_CQM_GID_SIZE_32;
- func_cap->childc_number += ub_sdk_res->max_tpg + (ub_sdk_res->max_tp >> 1);
- func_cap->childc_basic_size = GET_MAX(HINIC5_CQM_CHILDC_SIZE_256, func_cap->childc_basic_size);
-}
-
-struct hinic5_cqm_srv_cap_init hinic5_serv_cap_init_list[] = {
- {HINIC5_CQM_SERVICE_T_NIC, hinic5_cqm_service_capability_init_nic},
- {HINIC5_CQM_SERVICE_T_OVS, hinic5_cqm_service_capability_init_ovs},
- {HINIC5_CQM_SERVICE_T_ROCE, hinic5_cqm_service_capability_init_roce},
- {HINIC5_CQM_SERVICE_T_TOE, hinic5_cqm_service_capability_init_toe},
- {HINIC5_CQM_SERVICE_T_IOE, hinic5_cqm_service_capability_init_ioe},
- {HINIC5_CQM_SERVICE_T_FC, hinic5_cqm_service_capability_init_fc},
- {HINIC5_CQM_SERVICE_T_VBS, hinic5_cqm_service_capability_init_vbs},
- {HINIC5_CQM_SERVICE_T_IPSEC, hinic5_cqm_service_capability_init_ipsec},
- {HINIC5_CQM_SERVICE_T_VIRTIO, hinic5_cqm_service_capability_init_virtio},
- {HINIC5_CQM_SERVICE_T_PPA, hinic5_cqm_service_capability_init_ppa},
- {HINIC5_CQM_SERVICE_T_UB, hinic5_cqm_service_capability_init_ub},
- {HINIC5_CQM_SERVICE_T_JBOF, hinic5_cqm_service_capability_init_jbof},
- {HINIC5_CQM_SERVICE_T_VROCE, hinic5_cqm_service_capability_init_vroce},
-};
-
-static void hinic5_cqm_service_capability_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct service_cap *service_capability)
-{
- u32 list_size = ARRAY_SIZE(hinic5_serv_cap_init_list);
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 i;
-
- for (i = 0; i < HINIC5_CQM_SERVICE_T_MAX; i++) {
- hinic5_cqm_handle->service[i].valid = false;
- hinic5_cqm_handle->service[i].has_register = false;
- hinic5_cqm_handle->service[i].buf_order = 0;
- }
-
- hinic5_cqm_service_valid_init(hinic5_cqm_handle, service_capability);
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: service type %d\n",
- service_capability->chip_svc_type);
-
- for (i = 0; i < list_size; i++) {
- if (hinic5_cqm_handle->service[hinic5_serv_cap_init_list[i].service_type].valid &&
- hinic5_serv_cap_init_list[i].serv_cap_proc) {
- hinic5_serv_cap_init_list[i].serv_cap_proc(hinic5_cqm_handle, (void *)service_capability);
- }
- }
-}
-
-static u32 get_fake_func_type(struct tag_hinic5_cqm_fake_cfg *fake_cfg, u16 func_id)
-{
- if (func_id == fake_cfg->parent_func)
- return HINIC5_CQM_FAKE_FUNC_PARENT;
-
- if (func_id >= fake_cfg->child_func_start &&
- func_id < (fake_cfg->child_func_start + fake_cfg->child_func_number))
- return HINIC5_CQM_FAKE_FUNC_CHILD;
-
- return HINIC5_CQM_FAKE_FUNC_UNUSED;
-}
-
-/* Set func_type in fake_hinic5_cqm_handle to ppf, pf, or vf. */
-static void hinic5_cqm_set_func_type(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 idx = hinic5_cqm_handle->func_attribute.func_global_idx;
-
- if (idx == 0)
- hinic5_cqm_handle->func_attribute.func_type = HINIC5_CQM_PPF;
- else if (idx < HINIC5_CQM_MAX_PF_NUM)
- hinic5_cqm_handle->func_attribute.func_type = HINIC5_CQM_PF;
- else
- hinic5_cqm_handle->func_attribute.func_type = HINIC5_CQM_VF;
-}
-
-static void hinic5_cqm_capability_init_smf(struct hinic5_hwdev *handle, struct service_cap *svc_cap)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
-
- func_cap->lb_mode = svc_cap->lb_mode;
-
- /* Initializing the LB Mode */
- if (func_cap->lb_mode == HINIC5_CQM_LB_MODE_NORMAL)
- func_cap->smf_pg = 0;
- else
- func_cap->smf_pg = svc_cap->smf_pg;
- func_cap->smf_max_num = svc_cap->smf_max_num;
- func_cap->smf_enabled_num = svc_cap->smf_enabled_num;
- func_cap->bat_cid_index_bit_width = svc_cap->bat_cid_index_bit_width;
-
- hinic5_cqm_info(handle->dev_hdl,
- "Cap init: lb_mode %u, smf_pg %u, smf_max_num %u\n",
- func_cap->lb_mode, func_cap->smf_pg, func_cap->smf_max_num);
-}
-
-static void hinic5_cqm_capability_init_fake_vf(struct hinic5_hwdev *handle, struct service_cap *svc_cap)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_fake_cfg *cfg = &func_cap->fake_cfg;
-
- func_cap->fake_func_type = HINIC5_CQM_FAKE_FUNC_UNUSED;
- memset(cfg, 0, sizeof(*cfg));
-
- if (svc_cap->fake_vf_num != 0) {
- u32 parent_func_id = svc_cap->fake_vf_parent_func_id;
- if (parent_func_id == 0)
- parent_func_id = hinic5_cqm_handle->func_attribute.port_to_port_idx;
-
- cfg->parent_func = parent_func_id;
- cfg->child_func_start = svc_cap->fake_vf_start_id;
- cfg->child_func_number = svc_cap->fake_vf_num_cfg;
-
- cfg->fake_vf_lazy_init = svc_cap->fake_vf_lazy_init;
-
- cfg->fake_vf_max_pctx = svc_cap->fake_vf_max_pctx;
- cfg->fake_vf_max_scqc_ctx = svc_cap->fake_vf_max_scqc_ctx;
- cfg->fake_vf_max_srqc_ctx = svc_cap->fake_vf_max_srqc_ctx;
- cfg->fake_vf_max_gid_ctx = svc_cap->fake_vf_max_gid_ctx;
- cfg->fake_vf_max_mpt_ctx = svc_cap->fake_vf_max_mpt_ctx;
- cfg->fake_vf_max_childc_ctx = svc_cap->fake_vf_max_childc_ctx;
-
- if (svc_cap->fake_vf_qpc_ctx_size_en)
- cfg->fake_vf_qpc_basic_size = 0x1 << svc_cap->fake_vf_qpc_ctx_size_order;
-
- cfg->fake_vf_bfilter_start_addr = svc_cap->fake_vf_bfilter_start_addr;
- cfg->fake_vf_bfilter_len = svc_cap->fake_vf_bfilter_len;
-
- func_cap->fake_func_type = get_fake_func_type(cfg, hinic5_global_func_id(handle));
- }
-
- hinic5_cqm_info(handle->dev_hdl,
- "Cap init: fake_func_type %u, parent %u, child start %u num %u, lazy init %d\n",
- func_cap->fake_func_type, cfg->parent_func,
- cfg->child_func_start, cfg->child_func_number,
- cfg->fake_vf_lazy_init);
-}
-
-static int hinic5_cqm_capability_init_bloomfilter(struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
-
- func_cap->bloomfilter_enable = service_capability->bloomfilter_en;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: bloomfilter_enable %u (1: enable; 0: disable)\n",
- func_cap->bloomfilter_enable);
-
- if (func_cap->bloomfilter_enable != 0) {
- func_cap->bloomfilter_length = service_capability->bfilter_len;
- func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
- if (func_cap->bloomfilter_length != 0 &&
- !hinic5_cqm_check_align(func_cap->bloomfilter_length)) {
- hinic5_cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
- func_cap->bloomfilter_length);
-
- return HINIC5_CQM_FAIL;
- }
- }
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: bloomfilter_length 0x%x, bloomfilter_addr 0x%x\n",
- func_cap->bloomfilter_length, func_cap->bloomfilter_addr);
-
- return 0;
-}
-
-static void hinic5_cqm_capability_init_part_cap(struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
-
- func_cap->flow_table_based_conn_number = service_capability->max_connect_num;
- func_cap->flow_table_based_conn_cache_number = service_capability->max_stick2cache_num;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: cfg max_conn_num 0x%x, max_cache_conn_num 0x%x\n",
- func_cap->flow_table_based_conn_number,
- func_cap->flow_table_based_conn_cache_number);
-
- func_cap->hash_basic_size = HINIC5_CQM_HASH_BUCKET_SIZE_64;
-
- func_cap->qpc_reserved = 0;
- func_cap->qpc_reserved_back = 0;
- func_cap->mpt_reserved = 0;
- func_cap->mpt_reserved_back = 0;
- func_cap->scq_reserved = 0;
- func_cap->scq_reserved_back = 0;
- func_cap->srq_reserved = 0;
- func_cap->srq_reserved_back = 0;
- func_cap->qpc_alloc_static = false;
- func_cap->scqc_alloc_static = false;
- func_cap->srqc_alloc_static = false;
-
- func_cap->l3i_number = 0;
- func_cap->l3i_basic_size = HINIC5_CQM_L3I_SIZE_8;
-
- func_cap->xid_alloc_mode = true; /* xid alloc do not reuse */
- func_cap->gpa_check_enable = true;
-}
-
-STATIC int hinic5_cqm_get_ppf_timer_cfg(struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct timer_vf_info_seg *vf_segs = func_cap->timer_vf_segs;
- struct service_cap *svc_cap = &handle->cfg_mgmt->svc_cap;
- u16 vf_actual = 0;
- int i, err;
-
- err = hinic5_get_ppf_timer_cfg(handle);
- if (err != 0)
- return err;
-
- func_cap->timer_pf_id_start = svc_cap->timer_pf_id_start;
- func_cap->timer_pf_num = svc_cap->timer_pf_num;
- func_cap->timer_vf_id_start = svc_cap->timer_vf_id_start;
- func_cap->timer_vf_num = svc_cap->timer_vf_num;
-
- memcpy(func_cap->timer_vf_segs,
- svc_cap->timer_vf_segs, sizeof(svc_cap->timer_vf_segs));
-
- for (i = 0; i < TIMER_VF_SEGS_NUM; i++) {
- if (vf_segs[i].start == 0)
- break;
- vf_actual += vf_segs[i].num;
- }
-
- func_cap->timer_vf_num_actual = vf_actual;
- if (vf_actual == 0)
- func_cap->timer_vf_num_actual = func_cap->timer_vf_num;
-
- hinic5_cqm_info(handle->dev_hdl,
- "host timer cfg: pf start %u, num %u. vf start %u, num %u, actual %u, seg deploy %d\n",
- func_cap->timer_pf_id_start, func_cap->timer_pf_num,
- func_cap->timer_vf_id_start, func_cap->timer_vf_num,
- func_cap->timer_vf_num_actual,
- func_cap->timer_vf_deploy_with_segs);
-
- hinic5_cqm_info(handle->dev_hdl,
- "vf timer segs: %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u %u-%u\n",
- vf_segs[0x0].start, vf_segs[0x0].start + vf_segs[0x0].num,
- vf_segs[0x1].start, vf_segs[0x1].start + vf_segs[0x1].num,
- vf_segs[0x2].start, vf_segs[0x2].start + vf_segs[0x2].num,
- vf_segs[0x3].start, vf_segs[0x3].start + vf_segs[0x3].num,
- vf_segs[0x4].start, vf_segs[0x4].start + vf_segs[0x4].num,
- vf_segs[0x5].start, vf_segs[0x5].start + vf_segs[0x5].num,
- vf_segs[0x6].start, vf_segs[0x6].start + vf_segs[0x6].num);
- return 0;
-}
-
-static int hinic5_cqm_capability_init_timer(struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- u32 total_timer_num = 0;
- int err;
-
- /* Initializes the PPF capabilities: include timer, pf, vf. */
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle) && (service_capability->timer_en != 0)) {
- func_cap->pf_num = service_capability->pf_num;
- func_cap->pf_id_start = service_capability->pf_id_start;
- func_cap->vf_num = service_capability->vf_num;
- func_cap->vf_id_start = service_capability->vf_id_start;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: total function num 0x%x\n",
- service_capability->host_total_function);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: pf_num 0x%x, pf_id_start 0x%x, vf_num 0x%x, vf_id_start 0x%x\n",
- func_cap->pf_num, func_cap->pf_id_start,
- func_cap->vf_num, func_cap->vf_id_start);
-
- err = hinic5_cqm_get_ppf_timer_cfg(handle);
- if (err != 0)
- return err;
-
- total_timer_num = func_cap->timer_pf_num + func_cap->timer_vf_num;
- }
-
- func_cap->timer_enable = service_capability->timer_en;
- hinic5_cqm_info(handle->dev_hdl, "Cap init: timer_enable %u (1: enable; 0: disable)\n",
- func_cap->timer_enable);
-
- func_cap->timer_number = HINIC5_CQM_TIMER_ALIGN_SCALE_NUM * total_timer_num;
- func_cap->timer_basic_size = HINIC5_CQM_TIMER_SIZE_32;
-
- return 0;
-}
-
-static void print_bat_cap(struct hinic5_hwdev *hwdev, const char *prefix_in,
- struct tag_hinic5_cqm_func_capability *cap)
-{
- const char *prefix = prefix_in ? prefix_in : "";
-
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: hash number 0x%x\n",
- prefix, cap->hash_number);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: qpc number 0x%x, reserved 0x%x, basic size 0x%x, alloc static %d\n",
- prefix, cap->qpc_number, cap->qpc_reserved, cap->qpc_basic_size,
- cap->qpc_alloc_static);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: scqc number 0x%x, reserved 0x%x, basic size 0x%x, alloc static %d\n",
- prefix, cap->scqc_number, cap->scq_reserved, cap->scqc_basic_size,
- cap->scqc_alloc_static);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: srqc number 0x%x, reserved 0x%x, basic size 0x%x, alloc static %d\n",
- prefix, cap->srqc_number, cap->srq_reserved, cap->srqc_basic_size,
- cap->srqc_alloc_static);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: mpt number 0x%x, reserved 0x%x\n",
- prefix, cap->mpt_number, cap->mpt_reserved);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: gid number 0x%x, lun number 0x%x\n",
- prefix, cap->gid_number, cap->lun_number);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: taskmap number 0x%x, l3i number 0x%x\n",
- prefix, cap->taskmap_number, cap->l3i_number);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: childc number 0x%x, basic size 0x%x\n",
- prefix, cap->childc_number, cap->childc_basic_size);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: timer number 0x%x\n",
- prefix, cap->timer_number);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: xid2cid number 0x%x, alloc static %d\n",
- prefix, cap->xid2cid_number, cap->xid_alloc_mode);
- hinic5_cqm_info(hwdev->dev_hdl, "%sCap init: reorder number 0x%x\n",
- prefix, cap->reorder_number);
-}
-
-static void hinic5_cqm_capability_init_cap_print(struct hinic5_hwdev *handle)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
-
- func_cap->ft_enable = service_capability->sf_svc_attr.ft_en;
- func_cap->rdma_enable = service_capability->sf_svc_attr.rdma_en;
- func_cap->gpa_spu_en = service_capability->func_gpa_spu_en;
-
- hinic5_cqm_info(handle->dev_hdl, "Cap init: pagesize_reorder %u\n", func_cap->pagesize_reorder);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: acs_spu_en %u, gpa_check_enable %d\n",
- func_cap->gpa_spu_en, func_cap->gpa_check_enable);
- hinic5_cqm_info(handle->dev_hdl, "Cap init: ft_enable %d, rdma_enable %d\n",
- func_cap->ft_enable, func_cap->rdma_enable);
-
- print_bat_cap(handle, NULL, func_cap);
-}
-
-/**
- * Prototype : hinic5_cqm_capability_init
- * Description : Initializes the function and service capabilities of the HINIC5_CQM.
- * Information needs to be read from the configuration management
- * module.
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/12/9
- * Modification : Created function
- */
-s32 hinic5_cqm_capability_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- struct service_cap *service_capability = &handle->cfg_mgmt->svc_cap;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- int err = 0;
-
- err = hinic5_cqm_capability_init_timer(handle);
- if (err != 0)
- goto out;
-
- err = hinic5_cqm_capability_init_bloomfilter(handle);
- if (err != 0)
- goto out;
-
- hinic5_cqm_capability_init_part_cap(handle);
-
- hinic5_cqm_capability_init_smf(handle, service_capability);
-
- hinic5_cqm_capability_init_fake_vf(handle, service_capability);
-
- hinic5_cqm_service_capability_init(hinic5_cqm_handle, service_capability);
-
- hinic5_cqm_test_mode_init(hinic5_cqm_handle, service_capability);
-
- hinic5_cqm_service_capability_update(hinic5_cqm_handle);
-
- hinic5_cqm_capability_init_cap_print(handle);
-
- return HINIC5_CQM_SUCCESS;
-
-out:
- if (HINIC5_CQM_IS_PPF(hinic5_cqm_handle))
- func_cap->timer_enable = 0;
-
- return err;
-}
-
-static void hinic5_cqm_fake_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- u32 i;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return;
-
- for (i = 0; i < HINIC5_CQM_FAKE_FUNC_MAX; i++) {
- kfree(hinic5_cqm_handle->fake_hinic5_cqm_handle[i]);
- hinic5_cqm_handle->fake_hinic5_cqm_handle[i] = NULL;
- }
-}
-
-static void set_fake_hinic5_cqm_attr(struct hinic5_hwdev *handle, struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle,
- u32 child_func_start, u32 i)
-{
- struct hinic5_func_attr *func_attr = &fake_hinic5_cqm_handle->func_attribute;
- struct tag_hinic5_cqm_func_capability *func_cap = &fake_hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_fake_cfg *cfg = &func_cap->fake_cfg;
-
- func_attr->func_global_idx = (u16)(child_func_start + i);
- hinic5_cqm_set_func_type(fake_hinic5_cqm_handle);
-
- func_cap->fake_func_type = HINIC5_CQM_FAKE_FUNC_CHILD_AGENT;
-
- func_cap->qpc_number = cfg->fake_vf_max_pctx;
- func_cap->scqc_number = cfg->fake_vf_max_scqc_ctx;
- func_cap->srqc_number = cfg->fake_vf_max_srqc_ctx;
- func_cap->gid_number = cfg->fake_vf_max_gid_ctx;
- func_cap->mpt_number = cfg->fake_vf_max_mpt_ctx;
- func_cap->childc_number = cfg->fake_vf_max_childc_ctx;
- func_cap->hash_number = cfg->fake_vf_max_pctx;
- func_cap->qpc_reserved = cfg->fake_vf_max_pctx;
-
- if (cfg->fake_vf_qpc_basic_size != 0)
- func_cap->qpc_basic_size = cfg->fake_vf_qpc_basic_size;
-
- if (cfg->fake_vf_bfilter_len != 0) {
- func_cap->bloomfilter_enable = true;
- func_cap->bloomfilter_addr = cfg->fake_vf_bfilter_start_addr +
- cfg->fake_vf_bfilter_len * i;
- func_cap->bloomfilter_length = cfg->fake_vf_bfilter_len;
- }
-
- hinic5_cqm_service_capability_update(fake_hinic5_cqm_handle);
-}
-
-static void print_fake_hinic5_cqm_attr(struct hinic5_hwdev *hwdev, struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle)
-{
- hinic5_cqm_func_capability_s *fake_func_cap = &fake_hinic5_cqm_handle->func_capability;
- struct hinic5_func_attr *fake_func_attr = &fake_hinic5_cqm_handle->func_attribute;
- const u16 fake_func_id = fake_func_attr->func_global_idx;
- char prefix[0x20] = { 0 };
- hinic5_cqm_info(hwdev->dev_hdl, "[Fake %u] global_func_idx %u, func_type %d, parent_func_idx %u\n",
- fake_func_id, fake_func_id, fake_func_attr->func_type, hinic5_global_func_id(hwdev));
-
- sprintf(prefix, "[Fake %u] ", fake_func_id);
- print_bat_cap(hwdev, prefix, fake_func_cap);
-}
-
-/**
- * Prototype : hinic5_cqm_fake_init
- * Description : When the fake VF mode is supported, the HINIC5_CQM handles of
- * the fake VFs need to be copied.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle: Parent HINIC5_CQM handle of the current PF
- * Output : None
- * Return Value : s32
- * 1.Date : 2020/4/15
- * Modification : Created function
- */
-static s32 hinic5_cqm_fake_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 child_func_start, child_func_number, i;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return HINIC5_CQM_SUCCESS;
-
- child_func_start = hinic5_cqm_get_child_func_start(hinic5_cqm_handle);
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
- if (child_func_number == 0) {
- hinic5_cqm_warn(handle->dev_hdl, "no child func, skip fake init\n");
- return HINIC5_CQM_SUCCESS;
- }
-
- for (i = 0; i < child_func_number; i++) {
- fake_hinic5_cqm_handle = hinic5_cqm_handle_fork(hinic5_cqm_handle);
- if (!fake_hinic5_cqm_handle) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_handle_fork));
- goto err;
- }
-
- set_fake_hinic5_cqm_attr(handle, fake_hinic5_cqm_handle, (u32)child_func_start, i);
- print_fake_hinic5_cqm_attr(handle, fake_hinic5_cqm_handle);
-
- fake_hinic5_cqm_handle->parent_hinic5_cqm_handle = hinic5_cqm_handle;
- hinic5_cqm_handle->fake_hinic5_cqm_handle[i] = fake_hinic5_cqm_handle;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_fake_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-static void hinic5_cqm_fake_mem_uninit(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 child_func_number, i;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return;
-
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++) {
- fake_hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[i];
- atomic_set(&fake_hinic5_cqm_handle->handle_state, HINIC5_CQM_HANDLE_STATE_REMOVE);
-
- hinic5_cqm_object_table_uninit(fake_hinic5_cqm_handle);
- hinic5_cqm_bitmap_uninit(fake_hinic5_cqm_handle);
- hinic5_cqm_cla_uninit(fake_hinic5_cqm_handle, HINIC5_CQM_BAT_ENTRY_MAX);
- hinic5_cqm_bat_uninit(fake_hinic5_cqm_handle);
- }
-}
-
-static s32 fake_hinic5_cqm_handle_mem_init(struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = fake_hinic5_cqm_handle->ex_handle;
-
- if (!HINIC5_CQM_IS_FAKE_CHILD_AGENT(fake_hinic5_cqm_handle))
- return HINIC5_CQM_FAIL;
-
- if (atomic_cmpxchg(&fake_hinic5_cqm_handle->handle_state,
- HINIC5_CQM_HANDLE_STATE_INIT, HINIC5_CQM_HANDLE_STATE_READY
- ) != HINIC5_CQM_HANDLE_STATE_INIT) {
- hinic5_cqm_warn(handle->dev_hdl, "[Fake %u] mem already inited\n",
- fake_hinic5_cqm_handle->func_attribute.func_global_idx);
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_bat_init(fake_hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bat_init));
- goto err1;
- }
-
- if (hinic5_cqm_cla_init(fake_hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_init));
- goto err2;
- }
-
- if (hinic5_cqm_bitmap_init(fake_hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bitmap_init));
- goto err3;
- }
-
- if (hinic5_cqm_object_table_init(fake_hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_table_init));
- goto err4;
- }
-
- hinic5_cqm_info(handle->dev_hdl, "[Fake %u] mem inited\n",
- fake_hinic5_cqm_handle->func_attribute.func_global_idx);
-
- return HINIC5_CQM_SUCCESS;
-
-err4:
- hinic5_cqm_bitmap_uninit(fake_hinic5_cqm_handle);
-err3:
- hinic5_cqm_cla_uninit(fake_hinic5_cqm_handle, HINIC5_CQM_BAT_ENTRY_MAX);
-err2:
- hinic5_cqm_bat_uninit(fake_hinic5_cqm_handle);
-err1:
- hinic5_cqm_fake_mem_uninit(fake_hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_fake_mem_init
- * Description : Initialize resources of the extended fake function.
- * Input : struct tag_hinic5_cqm_handle *hinic5_cqm_handle: Parent HINIC5_CQM handle of the current PF
- * Output : None
- * Return Value : s32
- * 1.Date : 2020/4/15
- * Modification : Created function
- */
-static s32 hinic5_cqm_fake_mem_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 child_func_number, i;
- int ret;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return HINIC5_CQM_SUCCESS;
-
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++) {
- fake_hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[i];
- ret = snprintf(fake_hinic5_cqm_handle->name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%s%02u", hinic5_cqm_handle->name, HINIC5_VRAM_HINIC5_CQM_FAKE_MEM_BASE, i);
- if (ret < 0) {
- hinic5_cqm_err(handle->dev_hdl, "fake hinic5_cqm handle hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
-
- /* Fake VF lazy init support */
- if (hinic5_cqm_is_fake_vf_lazy_init(hinic5_cqm_handle)) {
- hinic5_cqm_info(handle->dev_hdl, "[Fake %u] init delayed\n",
- fake_hinic5_cqm_handle->func_attribute.func_global_idx);
- continue;
- }
-
- ret = fake_hinic5_cqm_handle_mem_init(fake_hinic5_cqm_handle);
- if (ret != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(fake_hinic5_cqm_handle_mem_init));
- goto err;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err:
- hinic5_cqm_fake_mem_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_mem_init
- * Description : Initialize HINIC5_CQM memory, including tables at different levels.
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-s32 hinic5_cqm_mem_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- int ret;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- ret = snprintf(hinic5_cqm_handle->name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%02u", HINIC5_VRAM_HINIC5_CQM_GLB_FUNC_BASE, hinic5_global_func_id(handle));
- if (ret < 0) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm handle hinic5_vram name snprintf_s failed");
- return HINIC5_CQM_FAIL;
- }
- if (hinic5_cqm_fake_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_fake_init));
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_cqm_fake_mem_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_fake_mem_init));
- goto err1;
- }
-
- if (hinic5_cqm_bat_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bat_init));
- goto err2;
- }
-
- if (hinic5_cqm_cla_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_init));
- goto err3;
- }
-
- if (hinic5_cqm_bitmap_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_bitmap_init));
- goto err4;
- }
-
- if (hinic5_cqm_object_table_init(hinic5_cqm_handle) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_table_init));
- goto err5;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err5:
- hinic5_cqm_bitmap_uninit(hinic5_cqm_handle);
-err4:
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, HINIC5_CQM_BAT_ENTRY_MAX);
-err3:
- hinic5_cqm_bat_uninit(hinic5_cqm_handle);
-err2:
- hinic5_cqm_fake_mem_uninit(hinic5_cqm_handle);
-err1:
- hinic5_cqm_fake_uninit(hinic5_cqm_handle);
- return HINIC5_CQM_FAIL;
-}
-
-int hinic5_cqm_init_fake_vf(void *ex_handle, u32 vf_id)
-{
- struct hinic5_hwdev *handle = ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 child_func_start, child_func_number;
- int err;
-
- if (unlikely(!ex_handle)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return -EINVAL;
- }
-
- hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- if (unlikely(!hinic5_cqm_handle)) {
- hinic5_cqm_err(handle->dev_hdl, "Stateful not init\n");
- return -EINVAL;
- }
-
- if (unlikely(atomic_read(&hinic5_cqm_handle->handle_state) != HINIC5_CQM_HANDLE_STATE_READY)) {
- hinic5_cqm_err(handle->dev_hdl, "Stateful not ready\n");
- return -EAGAIN;
- }
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle)) {
- hinic5_cqm_err(handle->dev_hdl, "Not a Fake VF group parent\n");
- return -EPERM;
- }
-
- child_func_start = hinic5_cqm_get_child_func_start(hinic5_cqm_handle);
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
- if (vf_id < child_func_start || vf_id >= child_func_start + child_func_number) {
- hinic5_cqm_err(handle->dev_hdl,
- "VF %u is not in the Fake VF group\n", vf_id);
- return -EINVAL;
- }
-
- fake_hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[vf_id - child_func_start];
- err = fake_hinic5_cqm_handle_mem_init(fake_hinic5_cqm_handle);
- if (err != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(fake_hinic5_cqm_handle_mem_init));
- return -EFAULT;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(hinic5_cqm_init_fake_vf);
-
-void hinic5_cqm_cla_fake_vf_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 reset_flag)
-{
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle = NULL;
- u32 child_func_number, i;
- u16 func_global_idx;
- int err;
-
- if (!HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle))
- return;
-
- child_func_number = hinic5_cqm_get_child_func_number(hinic5_cqm_handle);
-
- for (i = 0; i < child_func_number; i++) {
- fake_hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[i];
- func_global_idx = fake_hinic5_cqm_handle->func_attribute.func_global_idx;
-
- err = hinic5_func_reset(handle, func_global_idx,
- BIT(reset_flag), HINIC5_CHANNEL_COMM);
- if (err != 0)
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm fake vf cla cache invalid err, func_id 0x%x\n", func_global_idx);
- }
-}
-
-void hinic5_cqm_cla_func_cache_invalid(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 reset_flag)
-{
- int err;
- u16 func_id;
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)hinic5_cqm_handle->ex_handle;
-
- func_id = hinic5_global_func_id(handle);
- err = hinic5_func_reset(handle, func_id, BIT(reset_flag), HINIC5_CHANNEL_COMM);
- if (err != 0)
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm cla cache invalid err, func_index = 0x%x\n", func_id);
-}
-
-/**
- * Prototype : hinic5_cqm_mem_uninit
- * Description : Deinitialize HINIC5_CQM memory, including tables at different levels.
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-void hinic5_cqm_mem_uninit(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
-
- hinic5_cqm_object_table_uninit(hinic5_cqm_handle);
- hinic5_cqm_bitmap_uninit(hinic5_cqm_handle);
-
- if (COMM_SUPPORT_SMF_CACHE_INVALID(handle)) {
- hinic5_cqm_cla_fake_vf_cache_invalid(hinic5_cqm_handle, RES_TYPE_SMF);
- hinic5_cqm_cla_func_cache_invalid(hinic5_cqm_handle, RES_TYPE_SMF);
- }
-
- hinic5_cqm_cla_uninit(hinic5_cqm_handle, HINIC5_CQM_BAT_ENTRY_MAX);
- hinic5_cqm_bat_uninit(hinic5_cqm_handle);
- hinic5_cqm_fake_mem_uninit(hinic5_cqm_handle);
-
- if (COMM_SUPPORT_SMF_CACHE_INVALID(handle)) {
- hinic5_cqm_cla_fake_vf_cache_invalid(hinic5_cqm_handle, RES_TYPE_SMF_CACHE_INVALID);
- hinic5_cqm_cla_func_cache_invalid(hinic5_cqm_handle, RES_TYPE_SMF_CACHE_INVALID);
- }
-
- hinic5_cqm_fake_uninit(hinic5_cqm_handle);
-}
-
-/**
- * Prototype : hinic5_cqm_event_init
- * Description : Initialize HINIC5_CQM event callback.
- * Input : void *ex_handle
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-s32 hinic5_cqm_event_init(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
-
- /* Registers the CEQ and AEQ callback functions. */
- if (hinic5_ceq_register_cb(ex_handle, ex_handle, HINIC5_NON_L2NIC_SCQ,
- hinic5_cqm_scq_callback) != CHIPIF_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Event: fail to register scq callback\n");
- return HINIC5_CQM_FAIL;
- }
-
- if (hinic5_ceq_register_cb(ex_handle, ex_handle, HINIC5_NON_L2NIC_ECQ,
- hinic5_cqm_ecq_callback) != CHIPIF_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Event: fail to register ecq callback\n");
- goto err1;
- }
-
- if (hinic5_ceq_register_cb(ex_handle, ex_handle, HINIC5_NON_L2NIC_NO_CQ_EQ,
- hinic5_cqm_nocq_callback) != CHIPIF_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Event: fail to register nocq callback\n");
- goto err2;
- }
-
- if (hinic5_aeq_register_swe_cb(ex_handle, ex_handle, HINIC5_STATEFUL_EVENT,
- hinic5_cqm_aeq_callback) != CHIPIF_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, "Event: fail to register aeq callback\n");
- goto err3;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err3:
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_NO_CQ_EQ);
-err2:
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_ECQ);
-err1:
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_SCQ);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_event_uninit
- * Description : Deinitialize HINIC5_CQM event callback.
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2015/7/6
- * Modification : Created function
- */
-void hinic5_cqm_event_uninit(void *ex_handle)
-{
- hinic5_aeq_unregister_swe_cb(ex_handle, HINIC5_STATEFUL_EVENT);
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_NO_CQ_EQ);
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_ECQ);
- hinic5_ceq_unregister_cb(ex_handle, HINIC5_NON_L2NIC_SCQ);
-}
-
-/**
- * Prototype : hinic5_cqm_scq_callback
- * Description : HINIC5_CQM module callback processing for the ceq,
- * which processes NON_L2NIC_SCQ.
- * Input : void *ex_handle
- * u32 ceqe_data
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-void hinic5_cqm_scq_callback(void *ex_handle, u32 ceqe_data)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_service_register_template *service_template = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct tag_hinic5_cqm_queue *hinic5_cqm_queue = NULL;
- struct tag_hinic5_cqm_object *obj = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(scq_callback_ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_scq_callback_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(scq_callback_hinic5_cqm_handle));
- return;
- }
-
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Event: %s, ceqe_data=0x%x\n", __func__, ceqe_data);
- obj = hinic5_cqm_object_get(ex_handle, HINIC5_CQM_OBJECT_NONRDMA_SCQ,
- HINIC5_CQM_CQN_FROM_CEQE(ceqe_data), true);
- if (unlikely(obj == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(scq_callback_obj));
- return;
- }
-
- if (unlikely(obj->service_type >= HINIC5_CQM_SERVICE_T_MAX)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(obj->service_type));
- hinic5_cqm_object_put(obj);
- return;
- }
-
- service = &hinic5_cqm_handle->service[obj->service_type];
- service_template = &service->service_template;
- if (service_template->shared_cq_ceq_callback) {
- hinic5_cqm_queue = (struct tag_hinic5_cqm_queue *)(void *)obj;
- service_template->shared_cq_ceq_callback(service_template->service_handle,
- HINIC5_CQM_CQN_FROM_CEQE(ceqe_data),
- hinic5_cqm_queue->priv);
- } else {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_PTR_NULL(shared_cq_ceq_callback));
- }
-
- hinic5_cqm_object_put(obj);
-}
-
-/**
- * Prototype : hinic5_cqm_ecq_callback
- * Description : HINIC5_CQM module callback processing for the ceq,
- * which processes NON_L2NIC_ECQ.
- * Input : void *ex_handle
- * u32 ceqe_data
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-void hinic5_cqm_ecq_callback(void *ex_handle, u32 ceqe_data)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_service_register_template *service_template = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct tag_hinic5_cqm_qpc_mpt *qpc = NULL;
- struct tag_hinic5_cqm_object *obj = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ecq_callback_ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_ecq_callback_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ecq_callback_hinic5_cqm_handle));
- return;
- }
-
- obj = hinic5_cqm_object_get(ex_handle, HINIC5_CQM_OBJECT_SERVICE_CTX,
- HINIC5_CQM_XID_FROM_CEQE(ceqe_data), true);
- if (unlikely(obj == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ecq_callback_obj));
- return;
- }
-
- if (unlikely(obj->service_type >= HINIC5_CQM_SERVICE_T_MAX)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(obj->service_type));
- hinic5_cqm_object_put(obj);
- return;
- }
-
- service = &hinic5_cqm_handle->service[obj->service_type];
- service_template = &service->service_template;
- if (service_template->embedded_cq_ceq_callback) {
- qpc = (struct tag_hinic5_cqm_qpc_mpt *)(void *)obj;
- service_template->embedded_cq_ceq_callback(service_template->service_handle,
- HINIC5_CQM_XID_FROM_CEQE(ceqe_data), qpc->priv);
- } else {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_PTR_NULL(embedded_cq_ceq_callback));
- }
-
- hinic5_cqm_object_put(obj);
-}
-
-/**
- * Prototype : hinic5_cqm_nocq_callback
- * Description : HINIC5_CQM module callback processing for the ceq,
- * which processes NON_L2NIC_NO_CQ_EQ.
- * Input : void *ex_handle
- * u32 ceqe_data
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-void hinic5_cqm_nocq_callback(void *ex_handle, u32 ceqe_data)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_service_register_template *service_template = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct tag_hinic5_cqm_qpc_mpt *qpc = NULL;
- struct tag_hinic5_cqm_object *obj = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(nocq_callback_ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_nocq_callback_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(nocq_callback_hinic5_cqm_handle));
- return;
- }
-
- obj = hinic5_cqm_object_get(ex_handle, HINIC5_CQM_OBJECT_SERVICE_CTX,
- HINIC5_CQM_XID_FROM_CEQE(ceqe_data), true);
- if (unlikely(obj == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(nocq_callback_obj));
- return;
- }
-
- if (unlikely(obj->service_type >= HINIC5_CQM_SERVICE_T_MAX)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(obj->service_type));
- hinic5_cqm_object_put(obj);
- return;
- }
-
- service = &hinic5_cqm_handle->service[obj->service_type];
- service_template = &service->service_template;
- if (service_template->no_cq_ceq_callback) {
- qpc = (struct tag_hinic5_cqm_qpc_mpt *)(void *)obj;
- service_template->no_cq_ceq_callback(service_template->service_handle,
- HINIC5_CQM_XID_FROM_CEQE(ceqe_data),
- HINIC5_CQM_QID_FROM_CEQE(ceqe_data),
- qpc->priv);
- } else {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_PTR_NULL(no_cq_ceq_callback));
- }
-
- hinic5_cqm_object_put(obj);
-}
-
-/* Distributes events to different service modules
- * based on the event type.
- */
-static u32 hinic5_cqm_aeq_event2type(u8 event)
-{
- if (event < HINIC5_CQM_AEQ_BASE_T_DMMU)
- return HINIC5_CQM_SERVICE_T_NIC;
- if (event < HINIC5_CQM_AEQ_BASE_T_ROCE)
- return HINIC5_CQM_SERVICE_T_DMMU;
- if (event < HINIC5_CQM_AEQ_BASE_T_FC)
- return HINIC5_CQM_SERVICE_T_ROCE;
- if (event < HINIC5_CQM_AEQ_BASE_T_IOE)
- return HINIC5_CQM_SERVICE_T_FC;
- if (event < HINIC5_CQM_AEQ_BASE_T_TOE)
- return HINIC5_CQM_SERVICE_T_IOE;
- if (event < HINIC5_CQM_AEQ_BASE_T_UB)
- return HINIC5_CQM_SERVICE_T_TOE;
- if (event < HINIC5_CQM_AEQ_BASE_T_VBS)
- return HINIC5_CQM_SERVICE_T_UB;
- if (event < HINIC5_CQM_AEQ_BASE_T_IPSEC)
- return HINIC5_CQM_SERVICE_T_VBS;
- if (event < HINIC5_CQM_AEQ_BASE_T_MAX)
- return HINIC5_CQM_SERVICE_T_IPSEC;
- return HINIC5_CQM_SERVICE_T_MAX;
-}
-
-/**
- * Prototype : hinic5_cqm_aeq_callback
- * Description : HINIC5_CQM module callback processing for the aeq.
- * Input : void *ex_handle
- * u8 event
- * u64 data
- * Output : None
- * Return Value : void
- * 1.Date : 2015/5/5
- * Modification : Created function
- */
-u8 hinic5_cqm_aeq_callback(void *ex_handle, u8 event, u8 *data)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_service_register_template *service_template = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- u8 event_level = FAULT_LEVEL_MAX;
- u32 service_type;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(aeq_callback_ex_handle));
- return event_level;
- }
-
- if (event >= HINIC5_CQM_AEQ_CALLBACK_CNT_MAX) {
- hinic5_cqm_err(handle->dev_hdl, "hinic5_cqm aeq event invalid %u\n", event);
- return event_level;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_aeq_callback_cnt[event]);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(aeq_callback_hinic5_cqm_handle));
- return event_level;
- }
-
- /* Distributes events to different service modules
- * based on the event type.
- */
- service_type = hinic5_cqm_aeq_event2type(event);
- if (service_type == HINIC5_CQM_SERVICE_T_MAX) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(event));
- return event_level;
- }
-
- service = &hinic5_cqm_handle->service[service_type];
- service_template = &service->service_template;
-
- if (!service_template->aeq_level_callback)
- hinic5_cqm_err(handle->dev_hdl, "Event: service_type %u aeq_level_callback unregistered, event %u\n",
- service_type, event);
- else
- event_level = service_template->aeq_level_callback(service_template->service_handle,
- event, data);
-
- if (!service_template->aeq_callback)
- hinic5_cqm_err(handle->dev_hdl, "Event: service_type %u aeq_callback unregistered\n",
- service_type);
- else
- service_template->aeq_callback(service_template->service_handle,
- event, data);
-
- return event_level;
-}
-
-/**
- * Prototype : hinic5_cqm_service_register
- * Description : Callback template for the service driver
- * to register with the HINIC5_CQM.
- * Input : void *ex_handle
- * struct tag_service_register_template *service_template
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/5
- * Modification : Created function
- */
-s32 hinic5_cqm_service_register(void *ex_handle, struct tag_service_register_template *service_template)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(service_template == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(service_template));
- return HINIC5_CQM_FAIL;
- }
-
- if (service_template->service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_WRONG_VALUE(service_template->service_type));
- return HINIC5_CQM_FAIL;
- }
- service = &hinic5_cqm_handle->service[service_template->service_type];
- if (!service->valid) {
- hinic5_cqm_err(handle->dev_hdl, "Service register: service_type %u is invalid\n",
- service_template->service_type);
- return HINIC5_CQM_FAIL;
- }
-
- if (service->has_register) {
- hinic5_cqm_err(handle->dev_hdl, "Service register: service_type %u has registered\n",
- service_template->service_type);
- return HINIC5_CQM_FAIL;
- }
-
- service->has_register = true;
- memcpy((void *)(&service->service_template),
- (void *)service_template,
- sizeof(struct tag_service_register_template));
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_service_register);
-
-/**
- * Prototype : hinic5_cqm_service_unregister
- * Description : The service driver deregisters the callback function
- * from the HINIC5_CQM.
- * Input : void *ex_handle
- * u32 service_type
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/5
- * Modification : Created function
- */
-void hinic5_cqm_service_unregister(void *ex_handle, u32 service_type)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
-
- if (service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return;
- }
-
- service = &hinic5_cqm_handle->service[service_type];
- if (!service->valid)
- hinic5_cqm_err(handle->dev_hdl, "Service unregister: service_type %u is disable\n",
- service_type);
-
- service->has_register = false;
- memset(&service->service_template, 0,
- sizeof(struct tag_service_register_template));
-}
-EXPORT_SYMBOL(hinic5_cqm_service_unregister);
-
-s32 hinic5_cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct service_cap *svc_cap = NULL;
-
- if (!ex_handle || !handle->cfg_mgmt)
- return HINIC5_CQM_FAIL;
-
- svc_cap = &handle->cfg_mgmt->svc_cap;
-
- if (fake_vf_num_cfg > svc_cap->fake_vf_num) {
- hinic5_cqm_err(handle->dev_hdl, "fake_vf_num_cfg is invlaid, fw fake_vf_num is %u\n",
- svc_cap->fake_vf_num);
- return HINIC5_CQM_FAIL;
- }
-
- /* fake_vf_num_cfg is valid when func type is HINIC5_CQM_FAKE_FUNC_PARENT */
- svc_cap->fake_vf_num_cfg = fake_vf_num_cfg;
- hinic5_cqm_info(handle->dev_hdl, "fake_vf_num_cfg set to %u\n", fake_vf_num_cfg);
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_fake_vf_num_set);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.h
deleted file mode 100644
index 02759f350..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_main.h
+++ /dev/null
@@ -1,512 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_main.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_MAIN_H
-#define HINIC5_CQM_MAIN_H
-
-#include "hinic5_crm.h"
-#include "hinic5_cqm_bloomfilter.h"
-#include "hinic5_hwif_inner.h"
-#include "hinic5_cqm_bat_cla.h"
-
-#define GET_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define GET_MIN(a, b) ((a) < (b) ? (a) : (b))
-#define HINIC5_CQM_DW_SHIFT 2
-#define HINIC5_CQM_QW_SHIFT 3
-
-#define CHIPIF_SUCCESS 0
-#define CHIPIF_FAIL (-1)
-
-#define HINIC5_CQM_TIMER_ENABLE 1
-#define HINIC5_CQM_TIMER_DISABLE 0
-
-#define HINIC5_CQM_HANDLE_STATE_INIT 0
-#define HINIC5_CQM_HANDLE_STATE_READY 1
-#define HINIC5_CQM_HANDLE_STATE_REMOVE 2
-
-/* The value must be the same as that of hinic5_service_type in hinic5_crm.h. */
-#define HINIC5_CQM_SERVICE_T_NIC SERVICE_T_NIC
-#define HINIC5_CQM_SERVICE_T_OVS SERVICE_T_OVS
-#define HINIC5_CQM_SERVICE_T_ROCE SERVICE_T_ROCE
-#define HINIC5_CQM_SERVICE_T_TOE SERVICE_T_TOE
-#define HINIC5_CQM_SERVICE_T_IOE SERVICE_T_IOE
-#define HINIC5_CQM_SERVICE_T_FC SERVICE_T_FC
-#define HINIC5_CQM_SERVICE_T_VBS SERVICE_T_VBS
-#define HINIC5_CQM_SERVICE_T_IPSEC SERVICE_T_IPSEC
-#define HINIC5_CQM_SERVICE_T_VIRTIO SERVICE_T_VIRTIO
-#define HINIC5_CQM_SERVICE_T_PPA SERVICE_T_PPA
-#define HINIC5_CQM_SERVICE_T_UB SERVICE_T_UB
-#define HINIC5_CQM_SERVICE_T_JBOF SERVICE_T_JBOF
-#define HINIC5_CQM_SERVICE_T_VROCE SERVICE_T_VROCE
-#define HINIC5_CQM_SERVICE_T_DMMU SERVICE_T_DMMU
-#define HINIC5_CQM_SERVICE_T_CFM SERVICE_T_CFM
-#define HINIC5_CQM_SERVICE_T_MAX SERVICE_T_MAX
-
-struct tag_hinic5_cqm_service {
- bool valid; /* Whether to enable this service on the function. */
- bool has_register; /* Registered or Not */
- u64 hardware_db_paddr;
- void __iomem *hardware_db_vaddr;
- u64 dwqe_paddr;
- void __iomem *dwqe_vaddr;
- u32 buf_order; /* The size of each buf node is 2^buf_order pages. */
- struct tag_service_register_template service_template;
-};
-
-struct tag_hinic5_cqm_fake_cfg {
- u32 parent_func; /* The parent func_id of the fake vfs. */
- u32 child_func_start; /* The start func_id of the child fake vfs. */
- u32 child_func_number; /* The number of the child fake vfs. */
-
- bool fake_vf_lazy_init;
-
- u32 fake_vf_max_pctx;
- u32 fake_vf_max_scqc_ctx;
- u32 fake_vf_max_srqc_ctx;
- u32 fake_vf_max_gid_ctx;
- u32 fake_vf_max_mpt_ctx;
- u32 fake_vf_max_childc_ctx;
-
- u8 fake_vf_qpc_basic_size;
-
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
-};
-
-typedef struct tag_hinic5_cqm_func_capability {
- /* BAT_PTR table(SMLC) */
- bool ft_enable; /* BAT for flow table enable: support toe/ioe/fc service
- */
- bool rdma_enable; /* BAT for rdma enable: support RoCE */
- /* VAT table(SMIR) */
- bool ft_pf_enable; /* Same as ft_enable. BAT entry for toe/ioe/fc on pf
- */
- bool rdma_pf_enable; /* Same as rdma_enable. BAT entry for rdma on pf */
-
- u8 gpa_spu_en;
-
- /* Dynamic or static memory allocation during the application of
- * specified QPC/SCQC for each service.
- */
- bool qpc_alloc_static;
- bool scqc_alloc_static;
- bool srqc_alloc_static;
-
- u8 timer_enable; /* Whether the timer function is enabled */
- u8 bloomfilter_enable; /* Whether the bloomgfilter function is enabled
- */
- u32 flow_table_based_conn_number; /* Maximum number of connections for
- * toe/ioe/fc, whitch cannot excedd
- * qpc_number
- */
- u32 flow_table_based_conn_cache_number; /* Maximum number of sticky
- * caches
- */
- u32 bloomfilter_length; /* Size of the bloomfilter table, 64-byte
- * aligned
- */
- u32 bloomfilter_addr; /* Start position of the bloomfilter table in the
- * SMF main cache.
- */
- u32 qpc_reserved; /* Reserved bit in bitmap */
- u32 qpc_reserved_back; /* Reserved back bit in bitmap */
- u32 mpt_reserved; /* The ROCE/IWARP MPT also has a reserved bit. */
- u32 mpt_reserved_back; /* Reserved back bit in bitmap */
-
- /* All basic_size must be 2^n-aligned. */
- u32 hash_number; /* The number of hash bucket. The size of BAT table is
- * aliaed with 64 bucket. At least 64 buckets is
- * required.
- */
- u32 hash_basic_size; /* THe basic size of hash bucket is 64B, including
- * 5 valid entry and one next entry.
- */
- u32 qpc_number;
- u32 qpc_basic_size;
-
- /* Number of PFs/VFs on the current host only for timer resource used */
- u32 pf_num;
- u32 pf_id_start;
- u32 vf_num;
- u32 vf_id_start;
-
- u8 timer_pf_id_start;
- u8 timer_pf_num;
- u16 timer_vf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_num_actual;
- bool timer_vf_deploy_with_segs;
- struct timer_vf_info_seg timer_vf_segs[TIMER_VF_SEGS_NUM];
-
- bool use_fake_parent_cla;
-
- /* SMF capabilities */
- u32 lb_mode;
- /* A bitmap indicating which SMFs are enabled.
- * For example, 0101B indicates that SMF0 and SMF2 are enabled.
- * The valid length of this bitmap is smf_max_num.
- */
- u32 smf_pg;
- u32 smf_max_num;
- u32 smf_enabled_num;
-
- /* SMF BAT capabilities */
- u8 bat_cid_index_bit_width;
-
- /* Fake VF capabilities */
- u32 fake_func_type; /* Whether the current function belongs to the fake
- * group (parent or child)
- */
- struct tag_hinic5_cqm_fake_cfg fake_cfg;
-
- /* Note: for hinic5_cqm specail test */
- u32 pagesize_reorder;
- bool xid_alloc_mode;
- bool gpa_check_enable;
- u32 scq_reserved;
- u32 scq_reserved_back;
- u32 srq_reserved;
- u32 srq_reserved_back;
-
- u32 mpt_number;
- u32 mpt_basic_size;
- u32 scqc_number;
- u32 scqc_basic_size;
- u32 srqc_number;
- u32 srqc_basic_size;
-
- u32 gid_number;
- u32 gid_basic_size;
- u32 lun_number;
- u32 lun_basic_size;
- u32 taskmap_number;
- u32 taskmap_basic_size;
- u32 l3i_number;
- u32 l3i_basic_size;
- u32 childc_number;
- u32 childc_basic_size;
- u32 child_qpc_id_start; /* FC service Child CTX is global addressing. */
- u32 childc_number_all_function; /* The chip supports a maximum of 8096
- * child CTXs.
- */
- u32 timer_number;
- u32 timer_basic_size;
- u32 xid2cid_number;
- u32 xid2cid_basic_size;
- u32 reorder_number;
- u32 reorder_basic_size;
-} hinic5_cqm_func_capability_s;
-
-#define HINIC5_CQM_PF TYPE_PF
-#define HINIC5_CQM_VF TYPE_VF
-#define HINIC5_CQM_PPF TYPE_PPF
-#define HINIC5_CQM_UNKNOWN TYPE_UNKNOWN
-#define HINIC5_CQM_MAX_PF_NUM 32
-
-#define HINIC5_CQM_LB_MODE_NORMAL 0xff
-#define HINIC5_CQM_LB_MODE_0 0
-#define HINIC5_CQM_LB_MODE_1 1
-#define HINIC5_CQM_LB_MODE_2 2
-
-#define HINIC5_CQM_FPGA_MODE 0
-#define HINIC5_CQM_EMU_MODE 1
-
-#define HINIC5_CQM_FAKE_FUNC_UNUSED 0U /* The HINIC5_CQM handle does not use Fake VF. */
-#define HINIC5_CQM_FAKE_FUNC_PARENT 1U /* The HINIC5_CQM handle is responsible for
- initializing some VF's resouces. */
-#define HINIC5_CQM_FAKE_FUNC_CHILD_AGENT 2U /* An agent handle created by a Fake VF
- Parent that acts as a Fake VF Child
- in Fake VF Parent's process. */
-#define HINIC5_CQM_FAKE_FUNC_CHILD 3U /* Some resources of this HINIC5_CQM handle
- are managed by a Fake VF Parent. */
-
-#define HINIC5_CQM_FAKE_FUNC_MAX 32
-
-#define HINIC5_CQM_QPC_ROCE_PER_DRCT 12
-#define HINIC5_CQM_QPC_ROCE_NORMAL 0
-#define HINIC5_CQM_QPC_ROCE_VBS_MODE 2
-
-struct tag_hinic5_cqm_toe_private_capability {
- /* TOE srq is different from other services
- * and does not need to be managed by the CLA table.
- */
- u32 toe_srqc_number;
- u32 toe_srqc_basic_size;
- u32 toe_srqc_start_id;
-
- struct tag_hinic5_cqm_bitmap srqc_bitmap;
-};
-
-struct hinic5_cqm_cmdq_ops;
-struct tag_hinic5_cqm_handle {
- struct hinic5_hwdev *ex_handle;
- struct device *dev;
- struct hinic5_func_attr func_attribute; /* vf/pf attributes */
- struct tag_hinic5_cqm_func_capability func_capability; /* function capability set */
- struct tag_hinic5_cqm_service service[HINIC5_CQM_SERVICE_T_MAX]; /* Service-related structure */
- struct tag_hinic5_cqm_bat_table bat_table;
- struct tag_hinic5_cqm_bloomfilter_table bloomfilter_table;
-
- atomic_t handle_state; /* see HINIC5_CQM_HANDLE_STATE_XXX */
-
- /* fake-vf-related structure */
- struct tag_hinic5_cqm_handle *fake_hinic5_cqm_handle[HINIC5_CQM_FAKE_FUNC_MAX];
- struct tag_hinic5_cqm_handle *parent_hinic5_cqm_handle;
-
- struct tag_hinic5_cqm_toe_private_capability toe_own_capability; /* TOE service-related
- * capability set
- */
-
- char name[HINIC5_VRAM_NAME_MAX_LEN];
- struct hinic5_cqm_cmdq_ops *cmdq_ops;
-};
-
-#define HINIC5_CQM_FUNC_TYPE(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_attribute.func_type)
-#define HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_capability.fake_func_type)
-
-#define HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle) \
- (HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_FAKE_FUNC_PARENT)
-#define HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle) \
- (HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_FAKE_FUNC_CHILD)
-#define HINIC5_CQM_IS_FAKE_CHILD_AGENT(hinic5_cqm_handle) \
- (HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_FAKE_FUNC_CHILD_AGENT)
-
-#define HINIC5_CQM_IS_PPF(hinic5_cqm_handle) (HINIC5_CQM_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_PPF)
-#define HINIC5_CQM_IS_VF(hinic5_cqm_handle) (HINIC5_CQM_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_VF && \
- HINIC5_CQM_FAKE_FUNC_TYPE(hinic5_cqm_handle) == HINIC5_CQM_FAKE_FUNC_UNUSED)
-
-#define HINIC5_CQM_CLA_IS_SECURE_MEM(type) ((type) == HINIC5_CQM_BAT_ENTRY_T_QPC || (type) == HINIC5_CQM_BAT_ENTRY_T_MPT || \
- (type) == HINIC5_CQM_BAT_ENTRY_T_SCQC || (type) == HINIC5_CQM_BAT_ENTRY_T_SRQC)
-
-#define HINIC5_CQM_IS_LB_MODE_NORMAL(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_capability.lb_mode == HINIC5_CQM_LB_MODE_NORMAL)
-#define HINIC5_CQM_IS_LB_MODE_0(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_capability.lb_mode == HINIC5_CQM_LB_MODE_0)
-#define HINIC5_CQM_IS_LB_MODE_1(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_capability.lb_mode == HINIC5_CQM_LB_MODE_1)
-#define HINIC5_CQM_IS_LB_MODE_2(hinic5_cqm_handle) ((hinic5_cqm_handle)->func_capability.lb_mode == HINIC5_CQM_LB_MODE_2)
-#define HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle) (HINIC5_CQM_IS_LB_MODE_1(hinic5_cqm_handle) || HINIC5_CQM_IS_LB_MODE_2(hinic5_cqm_handle))
-
-#define HINIC5_CQM_CQN_FROM_CEQE(data) ((data) & 0xfffff)
-#define HINIC5_CQM_XID_FROM_CEQE(data) ((data) & 0xfffff)
-#define HINIC5_CQM_QID_FROM_CEQE(data) (((data) >> 20) & 0x7)
-#define HINIC5_CQM_TYPE_FROM_CEQE(data) (((data) >> 23) & 0x7)
-
-#define HINIC5_CQM_HASH_BUCKET_SIZE_64 64
-
-#define HINIC5_CQM_MAX_QPC_NUM 0x100000
-#define HINIC5_CQM_MAX_SCQC_NUM 0x100000
-#define HINIC5_CQM_MAX_SRQC_NUM 0x100000
-#define HINIC5_CQM_MAX_CHILDC_NUM 0x100000
-
-#define HINIC5_CQM_QPC_SIZE_256 256
-#define HINIC5_CQM_QPC_SIZE_512 512
-#define HINIC5_CQM_QPC_SIZE_1024 1024
-
-#define HINIC5_CQM_SCQC_SIZE_32 32
-#define HINIC5_CQM_SCQC_SIZE_64 64
-#define HINIC5_CQM_SCQC_SIZE_128 128
-
-#define HINIC5_CQM_SRQC_SIZE_32 32
-#define HINIC5_CQM_SRQC_SIZE_64 64
-#define HINIC5_CQM_SRQC_SIZE_128 128
-
-#define HINIC5_CQM_MPT_SIZE_64 64
-
-#define HINIC5_CQM_GID_SIZE_32 32
-
-#define HINIC5_CQM_LUN_SIZE_8 8
-
-#define HINIC5_CQM_L3I_SIZE_8 8
-
-#define HINIC5_CQM_TIMER_SIZE_32 32
-
-#define HINIC5_CQM_XID2CID_SIZE_8 8
-
-#define HINIC5_CQM_REORDER_SIZE_256 256
-
-#define HINIC5_CQM_CHILDC_SIZE_256 256
-
-#define HINIC5_CQM_XID2CID_VBS_NUM (2 * 1024) /* 2K nvme Q */
-
-#define HINIC5_CQM_VBS_QPC_SIZE 512
-
-#define HINIC5_CQM_VBS_SCQC_SIZE 128
-
-/* Default number of VirtIO VQs.
- * Future models should get this value from the MGMT.
- */
-#define HINIC5_CQM_VIRTIO_VQ_NUM_DEFAULT (16 * 1024)
-#define HINIC5_CQM_VIRTIO_FC_SIZE 256 /* VirtIO Function Context size */
-
-#define HINIC5_CQM_GID_RDMA_NUM 128
-
-#define HINIC5_CQM_LUN_FC_NUM 64
-
-#define HINIC5_CQM_TASKMAP_FC_NUM 4
-
-#define HINIC5_CQM_L3I_COMM_NUM 64
-
-#define HINIC5_CQM_CHILDC_OVS_VBS_NUM (8 * 1024)
-#define HINIC5_CQM_CHILDC_VBS_NUM (2 * 1024)
-
-#define HINIC5_CQM_TIMER_SCALE_NUM (2 * 1024)
-#define HINIC5_CQM_TIMER_ALIGN_WHEEL_NUM 8
-#define HINIC5_CQM_TIMER_ALIGN_SCALE_NUM \
- (HINIC5_CQM_TIMER_SCALE_NUM * HINIC5_CQM_TIMER_ALIGN_WHEEL_NUM)
-
-#define HINIC5_CQM_QPC_OVS_RSVD (1024 * 1024)
-#define HINIC5_CQM_QPC_ROCE_RSVD 2
-#define HINIC5_CQM_QPC_ROCEAA_SWITCH_QP_NUM 4
-#define HINIC5_CQM_QPC_ROCEAA_RSVD \
- (4 * 1024 + HINIC5_CQM_QPC_ROCEAA_SWITCH_QP_NUM) /* 4096 Normal QP +
- * 4 Switch QP
- */
-#define HINIC5_CQM_CQ_ROCE_RSVD 16
-#define HINIC5_CQM_CQ_UB_RSVD 131072 // 128K
-#define HINIC5_CQM_SRQ_ROCE_RSVD 16
-
-#define HINIC5_CQM_CQ_ROCEAA_RSVD 64
-#define HINIC5_CQM_SRQ_ROCEAA_RSVD 64
-#define HINIC5_CQM_QPC_ROCE_VBS_RSVD_BACK 204800 /* 200K */
-#define HINIC5_CQM_CQ_VBS_VOLQ_RSVD (2 + 2048)
-#define HINIC5_CQM_CQ_ROCE_VBS_RSVD GET_MAX(HINIC5_CQM_QPC_ROCE_VBS_RSVD_BACK, HINIC5_CQM_CQ_VBS_VOLQ_RSVD)
-
-#define HINIC5_CQM_OVS_MAX_TIMER_FUNC 48
-
-#define HINIC5_CQM_HASH_BUCKET_NUM_UNIT_4_TO_64 4
-#define HINIC5_CQM_CRYPT_HASH_BUCKET_NUM(tbl_num) ((tbl_num) >> HINIC5_CQM_HASH_BUCKET_NUM_UNIT_4_TO_64)
-
-#define HINIC5_CQM_PPA_PAGESIZE_ORDER 8
-
-#if defined(__WIN__) && defined(__HIFC__)
-#define HINIC5_CQM_FC_PAGESIZE_ORDER 8
-#else
-#define HINIC5_CQM_FC_PAGESIZE_ORDER 0
-#endif
-
-#define HINIC5_CQM_QHEAD_ALIGN_ORDER 6
-
-typedef void (*serv_cap_init_cb)(struct tag_hinic5_cqm_handle *, void *);
-
-struct hinic5_cqm_srv_cap_init {
- u32 service_type;
- serv_cap_init_cb serv_cap_proc;
-};
-
-/* Only for llt test */
-s32 hinic5_cqm_capability_init(void *ex_handle);
-/* Can be defined as static */
-s32 hinic5_cqm_mem_init(void *ex_handle);
-void hinic5_cqm_mem_uninit(void *ex_handle);
-s32 hinic5_cqm_event_init(void *ex_handle);
-void hinic5_cqm_event_uninit(void *ex_handle);
-void hinic5_cqm_scq_callback(void *ex_handle, u32 ceqe_data);
-void hinic5_cqm_ecq_callback(void *ex_handle, u32 ceqe_data);
-void hinic5_cqm_nocq_callback(void *ex_handle, u32 ceqe_data);
-u8 hinic5_cqm_aeq_callback(void *ex_handle, u8 event, u8 *data);
-
-s32 hinic5_cqm_init(void *ex_handle);
-void hinic5_cqm_uninit(void *ex_handle);
-s32 hinic5_cqm_service_register(void *ex_handle, struct tag_service_register_template *service_template);
-void hinic5_cqm_service_unregister(void *ex_handle, u32 service_type);
-
-s32 hinic5_cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
-
-#define HINIC5_CQM_LOG_ID 0
-
-#define HINIC5_CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
-#define HINIC5_CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
-#define HINIC5_CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
-#define HINIC5_CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
-#define HINIC5_CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
-
-#define hinic5_cqm_err(dev, format, ...) dev_err(dev, "[HINIC5_CQM]" format, ##__VA_ARGS__)
-#define hinic5_cqm_warn(dev, format, ...) dev_warn(dev, "[HINIC5_CQM]" format, ##__VA_ARGS__)
-#define hinic5_cqm_notice(dev, format, ...) \
- dev_notice(dev, "[HINIC5_CQM]" format, ##__VA_ARGS__)
-#define hinic5_cqm_info(dev, format, ...) dev_info(dev, "[HINIC5_CQM]" format, ##__VA_ARGS__)
-
-#ifdef __HINIC5_CQM_DEBUG__
-extern bool hinic5_cqm_verbose;
-
-#define hinic5_cqm_dbg(dev, format, ...) dev_info(dev, "[HINIC5_CQM]" format, ##__VA_ARGS__)
-#define hinic5_cqm_dbg_on(condition, dev, format, ...) \
- ({ \
- if (condition) \
- hinic5_cqm_dbg(dev, format, ##__VA_ARGS__); \
- })
-
-#define hinic5_cqm_dbg_pr(format, ...) pr_info("[HINIC5_CQM]" format, ##__VA_ARGS__)
-#define hinic5_cqm_dbg_pr_on(condition, format, ...) \
- ({ \
- if (condition) \
- hinic5_cqm_dbg_pr(format, ##__VA_ARGS__); \
- })
-
-static inline void hinic5_cqm_dbg_byte_print(struct device *dev, u32 *ptr, u32 len)
-{
- u32 i;
- for (i = 0; i < (len >> 0x2); i += 0x4)
- hinic5_cqm_dbg(dev, "%.8x %.8x %.8x %.8x\n",
- ptr[i], ptr[i + 0x1], ptr[i + 0x2], ptr[i + 0x3]);
-}
-#else
-#define hinic5_cqm_dbg(format, ...)
-#define hinic5_cqm_dbg_on(condition, format, ...)
-#define hinic5_cqm_dbg_pr(format, ...)
-#define hinic5_cqm_dbg_pr_on(condition, format, ...)
-#define hinic5_cqm_dbg_byte_print(dev, ptr, len)
-#endif
-
-#define HINIC5_CQM_PTR_CHECK_ERR(desc) pr_err("[HINIC5_CQM]" desc)
-
-static inline u32 hinic5_cqm_get_child_func_start(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- return func_cap->fake_cfg.child_func_start;
-}
-
-/*
- * Get the number of child functions.
- * The number of child functions can be zero.
- */
-static inline u32 hinic5_cqm_get_child_func_number(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- return func_cap->fake_cfg.child_func_number;
-}
-
-static inline bool hinic5_cqm_is_fake_vf_lazy_init(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- return func_cap->fake_cfg.fake_vf_lazy_init;
-}
-
-/**
- * SMF support to use acs_spu_en to determine whether to send data over the HVA
- * interface or API ring.
- * @ref 'SPU ACCESS' in SM FS
- * @return 1: over HVA, 0 over API ring
- */
-static inline u8 hinic5_cqm_get_acs_spu_en(struct tag_hinic5_cqm_handle *hinic5_cqm_handle)
-{
- struct hinic5_hwdev *hwdev = hinic5_cqm_handle->ex_handle;
-
- if (hinic5_cqm_handle->func_capability.gpa_spu_en == FUNC_GPA_SPU_DIS)
- return 0;
- if (hinic5_cqm_handle->func_capability.gpa_spu_en == FUNC_GPA_SPU_EN)
- return 0x1;
-
- if (!hinic5_in_spu(hwdev))
- return 0;
-
- /* Load balancing from the SMF to the CPI, depending on the func ID. */
- return hinic5_global_func_id(hwdev) & 0x1;
-}
-
-#endif /* HINIC5_CQM_MAIN_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.c
deleted file mode 100644
index 35f832dd9..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.c
+++ /dev/null
@@ -1,1707 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_object.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_typedef_inner.h"
-
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_object_intern.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_object.h"
-
-static inline void hinic5_cqm_object_init(struct tag_hinic5_cqm_object *object, u32 service_type,
- enum hinic5_cqm_object_type object_type, u32 object_size,
- void *hinic5_cqm_handle)
-{
- object->service_type = service_type;
- object->object_type = object_type;
- object->object_size = object_size;
- atomic_set(&object->refcount, 1);
- init_completion(&object->free);
- object->hinic5_cqm_handle = hinic5_cqm_handle;
-}
-
-static s32 hinic5_cqm_object_create_check(struct tag_hinic5_cqm_handle *hinic5_cqm_handle, u32 service_type)
-{
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- if (unlikely(service_type >= HINIC5_CQM_SERVICE_T_MAX)) {
- hinic5_cqm_err(hinic5_cqm_handle->dev, "invalid service %u\n", service_type);
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(!hinic5_cqm_handle->service[service_type].has_register)) {
- hinic5_cqm_err(hinic5_cqm_handle->dev, "service %u has not registered\n", service_type);
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_object_qpc_mpt_create
- * Description : create QPC/MPT
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type: must be mpt or ctx.
- * u32 object_size: unit is Byte
- * void *object_priv: private structure of the service layer,
- * it can be NULL.
- * u32 index: apply for the reserved qpn 0~(1M-1) based on this value;
- * if automatic allocation is required,
- * index[20:0] : fixed to 0x1fffff
- * index[23:21] : specified xid_lowbits[2:0]
- * index[26:24] : xid[2:0] match mode, see HINIC5_CQM_DYNAMIC_XID_MOD
- * index[27] : search mode,
- * 0---specify the XID range,
- * 1---search for the entire dynamic area
- * index[31:28] : rsvd
- * notes: when index is HINIC5_CQM_INDEX_INVALID, means match all available xid
- * u32 bitmap_start: start index of dynamic xid search range,
- * valid when index[25]=0 && index[20:0]=0x1fffff
- * u32 bitmap_end: end index of dynamic xid search range,
- * valid when index[25]=0 && index[20:0]=0x1fffff
- * when search forward(bitmap_start<bitmap_end),
- * search range is [bitmap_start, bitmap_end)
- * when search reverse(bitmap_start>bitmap_end),
- * search range is (bitmap_end, bitmap_start].
- * bitmap_start=bitmap_end is illegal in range search mode
- * Output : None
- * Return Value : struct tag_hinic5_cqm_qpc_mpt *
- * 1.Date : 2016/2/16
- * Modification : Created function
- */
-struct tag_hinic5_cqm_qpc_mpt *hinic5_cqm_object_qpc_mpt_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 object_size, void *object_priv, u32 index,
- u32 bitmap_start, u32 bitmap_end)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_qpc_mpt_info *qpc_mpt_info = NULL;
- struct tag_hinic5_cqm_bitmap_range bp_range;
- s32 ret = HINIC5_CQM_FAIL;
- u32 relative_index;
- u32 fake_func_id;
- u32 index_num = index;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_qpc_mpt_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (object_type != HINIC5_CQM_OBJECT_SERVICE_CTX && object_type != HINIC5_CQM_OBJECT_MPT) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- /* fake vf adaption, switch to corresponding VF. */
- if (HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle) &&
- !hinic5_cqm_handle->func_capability.use_fake_parent_cla) {
- struct tag_hinic5_cqm_fake_cfg *fake_cfg = &hinic5_cqm_handle->func_capability.fake_cfg;
- if (fake_cfg->fake_vf_max_pctx == 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(fake_cfg->fake_vf_max_pctx));
- return NULL;
- }
-
- fake_func_id = index_num / fake_cfg->fake_vf_max_pctx;
- relative_index = index_num % fake_cfg->fake_vf_max_pctx;
-
- if (fake_func_id >= hinic5_cqm_get_child_func_number(hinic5_cqm_handle)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(fake_func_id));
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(index));
- return NULL;
- }
-
- index_num = relative_index;
- hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[fake_func_id];
- }
-
- qpc_mpt_info = kzalloc(sizeof(*qpc_mpt_info), GFP_ATOMIC);
- if (unlikely(qpc_mpt_info == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(qpc_mpt_info));
- return NULL;
- }
-
- hinic5_cqm_object_init(&qpc_mpt_info->common.object, service_type, object_type,
- object_size, hinic5_cqm_handle);
- qpc_mpt_info->common.xid = index_num;
- bp_range.start = bitmap_start;
- bp_range.end = bitmap_end;
-
- qpc_mpt_info->common.priv = object_priv;
-
- ret = hinic5_cqm_qpc_mpt_create(&qpc_mpt_info->common.object, &bp_range);
- if (ret == HINIC5_CQM_SUCCESS)
- return &qpc_mpt_info->common;
-
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_qpc_mpt_create));
- kfree(qpc_mpt_info);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_qpc_mpt_create);
-
-static struct tag_hinic5_cqm_queue *hinic5_cqm_create_rqs(struct tag_hinic5_cqm_nonrdma_qinfo *rq_qinfo, struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct hinic5_hwdev *handle, u32 init_rq_num)
-{
- u32 i;
- /* 3. create queue header */
- rq_qinfo->common.q_header_vaddr = hinic5_cqm_kmalloc_align(sizeof(struct tag_hinic5_cqm_queue_header),
- GFP_KERNEL | __GFP_ZERO, HINIC5_CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(q_header_vaddr));
- return NULL;
- }
-
- rq_qinfo->common.q_header_paddr = dma_map_single(hinic5_cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
- sizeof(struct tag_hinic5_cqm_queue_header), DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev, rq_qinfo->common.q_header_paddr) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(q_header_vaddr));
- goto err1;
- }
-
- /* 4. create rq */
- for (i = 0; i < init_rq_num; i++) {
- if (hinic5_cqm_container_create(&rq_qinfo->common.object, NULL, true) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_container_create));
- goto err2;
- }
- if (!rq_qinfo->common.head_container)
- rq_qinfo->common.head_container = rq_qinfo->common.tail_container;
- }
-
- return &rq_qinfo->common;
-
-err2:
- hinic5_cqm_container_free(rq_qinfo->common.head_container, NULL,
- &rq_qinfo->common);
-err1:
- hinic5_cqm_kfree_align(rq_qinfo->common.q_header_vaddr);
- rq_qinfo->common.q_header_vaddr = NULL;
- return NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_object_recv_queue_create
- * Description : when srq is used, create rq.
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type
- * u32 init_rq_num
- * u32 container_size
- * u32 wqe_size
- * void *object_priv
- * Output : None
- * Return Value : struct tag_hinic5_cqm_queue *
- * 1.Date : 2016/2/16
- * Modification : Created function
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_recv_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 init_rq_num, u32 container_size,
- u32 wqe_size, void *object_priv)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_nonrdma_qinfo *rq_qinfo = NULL;
- struct tag_hinic5_cqm_queue *ret = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_rq_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (object_type != HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_RQ) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- if (service_type != HINIC5_CQM_SERVICE_T_TOE) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return NULL;
- }
-
- /* 1. create rq qinfo */
- rq_qinfo = kzalloc(sizeof(*rq_qinfo), GFP_KERNEL);
- if (unlikely(rq_qinfo == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(rq_qinfo));
- return NULL;
- }
-
- /* 2. init rq qinfo */
- rq_qinfo->container_size = container_size;
- rq_qinfo->wqe_size = wqe_size;
- rq_qinfo->wqe_per_buf = container_size / wqe_size - 1;
-
- rq_qinfo->common.queue_link_mode = HINIC5_CQM_QUEUE_TOE_SRQ_LINK_MODE;
- rq_qinfo->common.priv = object_priv;
- hinic5_cqm_object_init(&rq_qinfo->common.object, service_type, object_type,
- init_rq_num, hinic5_cqm_handle);
-
- /* 3. create rq */
- ret = hinic5_cqm_create_rqs(rq_qinfo, hinic5_cqm_handle, handle, init_rq_num);
- if (ret == NULL)
- kfree(rq_qinfo);
-
- return ret;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_recv_queue_create);
-
-/**
- * Prototype : hinic5_cqm_object_share_recv_queue_add_container
- * Description : allocate new container for srq
- * Input : struct tag_hinic5_cqm_queue *common
- * Output : None
- * Return Value : tail_container address
- * 1.Date : 2016/2/14
- * Modification : Created function
- */
-s32 hinic5_cqm_object_share_recv_queue_add_container(struct tag_hinic5_cqm_queue *common)
-{
- if (unlikely(common == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(common));
- return HINIC5_CQM_FAIL;
- }
-
- return hinic5_cqm_container_create(&common->object, NULL, true);
-}
-EXPORT_SYMBOL(hinic5_cqm_object_share_recv_queue_add_container);
-
-s32 hinic5_cqm_object_srq_add_container_free(struct tag_hinic5_cqm_queue *common, u8 **container_addr)
-{
- if (unlikely(common == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(common));
- return HINIC5_CQM_FAIL;
- }
-
- return hinic5_cqm_container_create(&common->object, container_addr, false);
-}
-EXPORT_SYMBOL(hinic5_cqm_object_srq_add_container_free);
-
-static bool hinic5_cqm_object_share_recv_queue_param_check(struct hinic5_hwdev *handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 container_size, u32 wqe_size)
-{
- /* service_type must be HINIC5_CQM_SERVICE_T_TOE */
- if (service_type != HINIC5_CQM_SERVICE_T_TOE) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return false;
- }
-
- /* container size2^N aligning */
- if (!hinic5_cqm_check_align(container_size)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(container_size));
- return false;
- }
-
- /* external parameter check: object_type must be
- * HINIC5_CQM_OBJECT_NONRDMA_SRQ
- */
- if (object_type != HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return false;
- }
-
- /* wqe_size, the divisor, cannot be 0 */
- if (wqe_size == 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(wqe_size));
- return false;
- }
-
- return true;
-}
-
-/**
- * Prototype : hinic5_cqm_object_share_recv_queue_create
- * Description : create srq
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type
- * u32 container_number
- * u32 container_size
- * u32 wqe_size
- * Output : None
- * Return Value : struct tag_hinic5_cqm_queue *
- * 1.Date : 2016/2/1
- * Modification : Created function
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_share_recv_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 container_number, u32 container_size,
- u32 wqe_size)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_nonrdma_qinfo *srq_qinfo = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_srq_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (!hinic5_cqm_object_share_recv_queue_param_check(handle, service_type, object_type,
- container_size, wqe_size))
- return NULL;
-
- /* 2. create and initialize srq info */
- srq_qinfo = kzalloc(sizeof(*srq_qinfo), GFP_KERNEL);
- if (unlikely(srq_qinfo == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(srq_qinfo));
- return NULL;
- }
-
- hinic5_cqm_object_init(&srq_qinfo->common.object, service_type, object_type,
- container_number, hinic5_cqm_handle);
-
- srq_qinfo->common.queue_link_mode = HINIC5_CQM_QUEUE_TOE_SRQ_LINK_MODE;
- srq_qinfo->common.priv = NULL;
- srq_qinfo->wqe_per_buf = container_size / wqe_size - 1;
- srq_qinfo->wqe_size = wqe_size;
- srq_qinfo->container_size = container_size;
- service = &hinic5_cqm_handle->service[service_type];
- srq_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
-
- /* 3. create srq and srq ctx */
- ret = hinic5_cqm_share_recv_queue_create(&srq_qinfo->common.object);
- if (ret == HINIC5_CQM_SUCCESS)
- return &srq_qinfo->common;
-
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_share_recv_queue_create));
- kfree(srq_qinfo);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_share_recv_queue_create);
-
-/* FC RQ is SRQ. (Different from the SRQ concept of TOE, FC indicates
- * that packets received by all flows are placed on the same RQ.
- * The SRQ of TOE is similar to the RQ resource pool.)
- */
-static bool hinic5_cqm_object_fc_srq_param_check(struct hinic5_hwdev *handle, u32 service_type,
- enum hinic5_cqm_object_type object_type, u32 wqe_size)
-{
- /* service_type must be HINIC5_CQM_SERVICE_T_FC */
- if (service_type != HINIC5_CQM_SERVICE_T_FC) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return false;
- }
-
- /* object_type must be HINIC5_CQM_OBJECT_NONRDMA_SRQ */
- if (object_type != HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return false;
- }
-
- if (wqe_size >= PAGE_SIZE || !hinic5_cqm_check_align(wqe_size)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(wqe_size));
- return false;
- }
-
- return true;
-}
-
-/**
- * Prototype : hinic5_cqm_object_fc_rq_create
- * Description : RQ creation temporarily provided for the FC service.
- * Special requirement: The number of valid WQEs in the queue
- * must meet the number of transferred WQEs. Linkwqe can only be
- * filled at the end of the page. The actual valid number exceeds
- * the requirement. In this case, the service needs to be
- * informed of the additional number to be created.
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type
- * u32 wqe_number: Number of valid WQEs
- * u32 wqe_size
- * void *object_priv
- * Output : None
- * 1.Date : 2016/3/1
- * Modification : Created function
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_fc_srq_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- u32 valid_wqe_per_buffer, buf_size, buf_num;
- u32 wqe_sum; /* include linkwqe, normal wqe */
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_fc_srq_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (!hinic5_cqm_object_fc_srq_param_check(handle, service_type, object_type, wqe_size))
- return NULL;
-
- service = &hinic5_cqm_handle->service[service_type];
- buf_size = (u32)(PAGE_SIZE << (service->buf_order));
- /* subtract 1 link wqe */
- valid_wqe_per_buffer = buf_size / wqe_size - 1;
- buf_num = wqe_number / valid_wqe_per_buffer;
- if (wqe_number % valid_wqe_per_buffer != 0)
- buf_num++;
-
- /* calculate the total number of WQEs */
- wqe_sum = buf_num * (valid_wqe_per_buffer + 1);
- nonrdma_qinfo = kzalloc(sizeof(*nonrdma_qinfo), GFP_KERNEL);
- if (unlikely(nonrdma_qinfo == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(nonrdma_qinfo));
- return NULL;
- }
-
- hinic5_cqm_object_init(&nonrdma_qinfo->common.object, service_type, object_type,
- wqe_sum, hinic5_cqm_handle);
-
- /* Initialize the doorbell used by the current queue.
- * The default doorbell is the hardware doorbell.
- */
- nonrdma_qinfo->common.current_q_doorbell = HINIC5_CQM_HARDWARE_DOORBELL;
- /* Currently, the connection mode is fixed. In the future,
- * the service needs to transfer the connection mode.
- */
- nonrdma_qinfo->common.queue_link_mode = HINIC5_CQM_QUEUE_RING_MODE;
-
- /* initialize public members */
- nonrdma_qinfo->common.priv = object_priv;
- nonrdma_qinfo->common.valid_wqe_num = wqe_sum - buf_num;
-
- /* initialize internal private members */
- nonrdma_qinfo->wqe_size = wqe_size;
- /* RQ (also called SRQ of FC) created by FC services,
- * CTX needs to be created.
- */
- nonrdma_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
-
- ret = hinic5_cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
- if (ret == HINIC5_CQM_SUCCESS)
- return &nonrdma_qinfo->common;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_fc_queue_create));
- kfree(nonrdma_qinfo);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_fc_srq_create);
-
-static bool hinic5_cqm_object_nonrdma_queue_param_check(struct hinic5_hwdev *handle,
- enum hinic5_cqm_object_type object_type, u32 wqe_size)
-{
- /* wqe_size can't be more than PAGE_SIZE, can't be zero, must be power
- * of 2 the function of hinic5_cqm_check_align is to check above
- */
- if (wqe_size >= PAGE_SIZE || (!hinic5_cqm_check_align(wqe_size))) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(wqe_size));
- return false;
- }
-
- /* nonrdma supports: RQ, SQ, SRQ, CQ, SCQ */
- if (object_type < HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_RQ ||
- object_type > HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return false;
- }
-
- return true;
-}
-
-/**
- * Prototype : hinic5_cqm_object_nonrdma_queue_create
- * Description : create nonrdma queue
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type: can be embedded RQ/SQ/CQ and
- * SRQ/SCQ.
- * u32 wqe_number: include link wqe
- * u32 wqe_size: fixed length, must be power of 2
- * void *object_priv: private structure of the service layer,
- * it can be NULL.
- * Output : None
- * Return Value : struct tag_hinic5_cqm_queue *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_nonrdma_qinfo *nonrdma_qinfo = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_nonrdma_queue_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (!hinic5_cqm_object_nonrdma_queue_param_check(handle, object_type, wqe_size))
- return NULL;
-
- nonrdma_qinfo = kzalloc(sizeof(*nonrdma_qinfo), GFP_KERNEL);
- if (unlikely(nonrdma_qinfo == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(nonrdma_qinfo));
- return NULL;
- }
-
- hinic5_cqm_object_init(&nonrdma_qinfo->common.object, service_type, object_type,
- wqe_number, hinic5_cqm_handle);
-
- /* Initialize the doorbell used by the current queue.
- * The default value is hardware doorbell
- */
- nonrdma_qinfo->common.current_q_doorbell = HINIC5_CQM_HARDWARE_DOORBELL;
- /* Currently, the link mode is hardcoded and needs to be transferred by
- * the service side.
- */
- nonrdma_qinfo->common.queue_link_mode = HINIC5_CQM_QUEUE_RING_MODE;
-
- nonrdma_qinfo->common.priv = object_priv;
-
- /* Initialize internal private members */
- nonrdma_qinfo->wqe_size = wqe_size;
- service = &hinic5_cqm_handle->service[service_type];
- if (object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- nonrdma_qinfo->q_ctx_size = service->service_template.scq_ctx_size;
- } else if (object_type == HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- /* Currently, the SRQ of the service is created through a
- * dedicated interface.
- */
- nonrdma_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
- }
-
- ret = hinic5_cqm_nonrdma_queue_create(&nonrdma_qinfo->common.object);
- if (ret == HINIC5_CQM_SUCCESS)
- return &nonrdma_qinfo->common;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_nonrdma_queue_create));
- kfree(nonrdma_qinfo);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_nonrdma_queue_create);
-
-static bool hinic5_cqm_object_rdma_queue_param_check(struct hinic5_hwdev *handle, u32 service_type,
- enum hinic5_cqm_object_type object_type)
-{
- /* service_type must be HINIC5_CQM_SERVICE_T_ROCE or HINIC5_CQM_SERVICE_T_UB */
- if (service_type != HINIC5_CQM_SERVICE_T_ROCE && service_type != HINIC5_CQM_SERVICE_T_UB && service_type != HINIC5_CQM_SERVICE_T_VBS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return false;
- }
-
- /* rdma supports: QP, SRQ, SCQ */
- if (object_type > HINIC5_CQM_OBJECT_RDMA_SCQ || object_type < HINIC5_CQM_OBJECT_RDMA_QP) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return false;
- }
-
- return true;
-}
-
-/**
- * Prototype : hinic5_cqm_object_rdma_queue_create
- * Description : create rdma queue
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type: can be QP and SRQ/SCQ.
- * u32 object_size
- * void *object_priv: private structure of the service layer,
- * it can be NULL.
- * bool room_header_alloc: Whether to apply for queue room and
- * header space
- * u32 xid: apply for the reserved qpn 0~(1M-1) based on this value;
- * if automatic allocation is required,
- * xid[20:0] : fixed to 0x1fffff
- * xid[23:21] : specified xid_lowbits[2:0]
- * xid[26:24] : xid[2:0] match mode, see HINIC5_CQM_DYNAMIC_XID_MOD
- * xid[27] : search mode,
- * 0---specify the XID range,
- * 1---search for the entire dynamic area
- * xid[31:28] : rsvd
- * notes: when index is HINIC5_CQM_INDEX_INVALID, means match all available xid
- * u32 bitmap_start: start index of dynamic xid search range,
- * valid when index[25]=0 && index[20:0]=0x1fffff
- * u32 bitmap_end: end index of dynamic xid search range,
- * valid when index[25]=0 && index[20:0]=0x1fffff
- * when search forward(bitmap_start<bitmap_end),
- * search range is [bitmap_start, bitmap_end)
- * when search reverse(bitmap_start>bitmap_end),
- * search range is (bitmap_end, bitmap_start].
- * bitmap_start=bitmap_end is illegal in range search mode
- * Output : None
- * Return Value : struct tag_hinic5_cqm_queue *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_rdma_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 object_size, void *object_priv,
- bool room_header_alloc, u32 xid,
- u32 bitmap_start, u32 bitmap_end)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_rdma_qinfo *rdma_qinfo = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct tag_hinic5_cqm_bitmap_range bp_range;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_rdma_queue_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- if (!hinic5_cqm_object_rdma_queue_param_check(handle, service_type, object_type))
- return NULL;
-
- rdma_qinfo = kzalloc(sizeof(*rdma_qinfo), GFP_KERNEL);
- if (unlikely(rdma_qinfo == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(rdma_qinfo));
- return NULL;
- }
-
- hinic5_cqm_object_init(&rdma_qinfo->common.object, service_type, object_type,
- object_size, hinic5_cqm_handle);
- rdma_qinfo->common.queue_link_mode = HINIC5_CQM_QUEUE_RDMA_QUEUE_MODE;
- rdma_qinfo->common.priv = object_priv;
- rdma_qinfo->common.current_q_room = HINIC5_CQM_RDMA_Q_ROOM_1;
- rdma_qinfo->room_header_alloc = room_header_alloc;
- rdma_qinfo->common.index = xid;
- bp_range.start = bitmap_start;
- bp_range.end = bitmap_end;
-
- /* Initializes the doorbell used by the current queue.
- * The default value is hardware doorbell
- */
- rdma_qinfo->common.current_q_doorbell = HINIC5_CQM_HARDWARE_DOORBELL;
-
- service = &hinic5_cqm_handle->service[service_type];
- if (object_type == HINIC5_CQM_OBJECT_RDMA_SCQ)
- rdma_qinfo->q_ctx_size = service->service_template.scq_ctx_size;
- else if (object_type == HINIC5_CQM_OBJECT_RDMA_SRQ)
- rdma_qinfo->q_ctx_size = service->service_template.srq_ctx_size;
-
- ret = hinic5_cqm_rdma_queue_create(&rdma_qinfo->common.object, &bp_range);
- if (ret == HINIC5_CQM_SUCCESS)
- return &rdma_qinfo->common;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_rdma_queue_create));
- kfree(rdma_qinfo);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_rdma_queue_create);
-
-/**
- * Prototype : hinic5_cqm_object_rdma_table_get
- * Description : create mtt and rdmarc of the rdma service
- * Input : void *ex_handle
- * u32 service_type
- * enum hinic5_cqm_object_type object_type
- * u32 index_base: start of index
- * u32 index_number
- * Output : None
- * Return Value : struct tag_hinic5_cqm_mtt_rdmarc *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_mtt_rdmarc *hinic5_cqm_object_rdma_table_get(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 index_base, u32 index_number)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_rdma_table *rdma_table = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- s32 ret;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_rdma_table_create_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (hinic5_cqm_object_create_check(hinic5_cqm_handle, service_type) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_create_check));
- return NULL;
- }
-
- /* service_type must be HINIC5_CQM_SERVICE_T_ROCE or HINIC5_CQM_SERVICE_T_UB */
- if (service_type != HINIC5_CQM_SERVICE_T_ROCE && service_type != HINIC5_CQM_SERVICE_T_UB) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(service_type));
- return NULL;
- }
-
- if (object_type != HINIC5_CQM_OBJECT_MTT &&
- object_type != HINIC5_CQM_OBJECT_RDMARC) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object_type));
- return NULL;
- }
-
- rdma_table = kzalloc(sizeof(*rdma_table), GFP_KERNEL);
- if (unlikely(rdma_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(rdma_table));
- return NULL;
- }
-
- hinic5_cqm_object_init(&rdma_table->common.object, service_type, object_type,
- (u32)(index_number * sizeof(dma_addr_t)), hinic5_cqm_handle);
- rdma_table->common.index_base = index_base;
- rdma_table->common.index_number = index_number;
-
- ret = hinic5_cqm_rdma_table_create(&rdma_table->common.object);
- if (ret == HINIC5_CQM_SUCCESS)
- return &rdma_table->common;
-
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_rdma_table_create));
- kfree(rdma_table);
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_rdma_table_get);
-
-static inline void hinic5_cqm_object_do_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = object->hinic5_cqm_handle;
- const u32 object_type = object->object_type;
-
- switch (object_type) {
- case HINIC5_CQM_OBJECT_SERVICE_CTX:
- case HINIC5_CQM_OBJECT_MPT:
- hinic5_cqm_qpc_mpt_delete(object);
- return;
- case HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_RQ:
- case HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_SQ:
- case HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_CQ:
- case HINIC5_CQM_OBJECT_NONRDMA_SCQ:
- hinic5_cqm_nonrdma_queue_delete(object);
- return;
- case HINIC5_CQM_OBJECT_NONRDMA_SRQ:
- if (object->service_type == HINIC5_CQM_SERVICE_T_TOE)
- hinic5_cqm_share_recv_queue_delete(object);
- else
- hinic5_cqm_nonrdma_queue_delete(object);
- return;
- case HINIC5_CQM_OBJECT_RDMA_QP:
- case HINIC5_CQM_OBJECT_RDMA_SRQ:
- case HINIC5_CQM_OBJECT_RDMA_SCQ:
- hinic5_cqm_rdma_queue_delete(object);
- return;
- case HINIC5_CQM_OBJECT_MTT:
- case HINIC5_CQM_OBJECT_RDMARC:
- hinic5_cqm_rdma_table_delete(object);
- return;
- default:
- hinic5_cqm_err(hinic5_cqm_handle->dev, HINIC5_CQM_WRONG_VALUE(object_type));
- return;
- }
-}
-
-/**
- * Prototype : hinic5_cqm_object_delete
- * Description : Deletes a created object. This function may be sleep and wait
- * for all operations on this object to be performed.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return;
- }
- if (!object->hinic5_cqm_handle) {
- pr_err("[HINIC5_CQM]object del: hinic5_cqm_handle is null, service type %u, refcount %d\n",
- object->service_type, (int)object->refcount.counter);
- kfree(object);
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
-
- if (!hinic5_cqm_handle->ex_handle) {
- pr_err("[HINIC5_CQM]object del: ex_handle is null, service type %u, refcount %d\n",
- object->service_type, (int)object->refcount.counter);
- kfree(object);
- return;
- }
-
- handle = hinic5_cqm_handle->ex_handle;
-
- if (object->service_type >= HINIC5_CQM_SERVICE_T_MAX) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object->service_type));
- kfree(object);
- return;
- }
-
- hinic5_cqm_object_do_delete(object);
- kfree(object);
-}
-EXPORT_SYMBOL(hinic5_cqm_object_delete);
-
-/**
- * Prototype : hinic5_cqm_object_offset_addr
- * Description : Only the rdma table can be searched to obtain the PA and VA
- * at the specified offset of the object buffer.
- * Input : struct tag_hinic5_cqm_object *object
- * u32 offset: For a rdma table, the offset is the absolute index
- * number.
- * dma_addr_t *paddr: PA(physical address)
- * Output : None
- * Return Value : u8 *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u8 *hinic5_cqm_object_offset_addr(struct tag_hinic5_cqm_object *object, u32 offset, dma_addr_t *paddr)
-{
- u32 object_type;
-
- if (!object)
- return NULL;
-
- object_type = object->object_type;
-
- /* The data flow path takes performance into consideration and
- * does not check input parameters.
- */
- switch (object_type) {
- case HINIC5_CQM_OBJECT_MTT:
- case HINIC5_CQM_OBJECT_RDMARC:
- return hinic5_cqm_rdma_table_offset_addr(object, offset, paddr);
- default:
- break;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_offset_addr);
-
-/**
- * Prototype : hinic5_cqm_object_get
- * Description : Obtain an object based on the index.
- * Input : void *ex_handle
- * enum hinic5_cqm_object_type object_type
- * u32 index: support qpn,mptn,scqn,srqn (n->number)
- * bool bh
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-struct tag_hinic5_cqm_object *hinic5_cqm_object_get(void *ex_handle, enum hinic5_cqm_object_type object_type,
- u32 index, bool bh)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_bat_table *bat_table = NULL;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_object *object = NULL;
-
- if (!ex_handle)
- return NULL;
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (!hinic5_cqm_handle)
- return NULL;
-
- bat_table = &hinic5_cqm_handle->bat_table;
-
- /* The data flow path takes performance into consideration and
- * does not check input parameters.
- */
- switch (object_type) {
- case HINIC5_CQM_OBJECT_SERVICE_CTX:
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_QPC);
- break;
- case HINIC5_CQM_OBJECT_MPT:
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_MPT);
- break;
- case HINIC5_CQM_OBJECT_RDMA_SRQ:
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SRQC);
- break;
- case HINIC5_CQM_OBJECT_RDMA_SCQ:
- case HINIC5_CQM_OBJECT_NONRDMA_SCQ:
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SCQC);
- break;
- default:
- return NULL;
- }
-
- if (!cla_table) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_table_get));
- return NULL;
- }
-
- object_table = &cla_table->obj_table;
- object = hinic5_cqm_object_table_get(hinic5_cqm_handle, object_table, index, bh);
- return object;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_get);
-
-/**
- * Prototype : hinic5_cqm_object_put
- * Description : This function must be called after the hinic5_cqm_object_get
- * function. Otherwise, the object cannot be released.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_put(struct tag_hinic5_cqm_object *object)
-{
- /* The data flow path takes performance into consideration and
- * does not check input parameters.
- */
- if (!object)
- return;
-
- if (atomic_dec_and_test(&object->refcount) != 0)
- complete(&object->free);
-}
-EXPORT_SYMBOL(hinic5_cqm_object_put);
-
-/**
- * Prototype : hinic5_cqm_object_funcid
- * Description : Obtain the ID of the function to which the object belongs.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : If successful, the ID of the function will be returned.
- * If fail HINIC5_CQM_FAIL(-1) will be returned.
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_object_funcid(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(object->hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
-
- return hinic5_cqm_handle->func_attribute.func_global_idx;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_funcid);
-
-/**
- * Prototype : hinic5_cqm_object_resize_alloc_new
- * Description : Currently this function is only used for RoCE.
- * The CQ buffer is ajusted, but the cqn and cqc remain
- * unchanged. This function allocates new buffer, but do not
- * release old buffer. The valid buffer is still old buffer.
- * Input : struct tag_hinic5_cqm_object *object
- * u32 object_size
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_object_resize_alloc_new(struct tag_hinic5_cqm_object *object, u32 object_size)
-{
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = (struct tag_hinic5_cqm_rdma_qinfo *)(void *)object;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_service *service = NULL;
- struct tag_hinic5_cqm_buf *q_room_buf = NULL;
- struct hinic5_hwdev *handle = NULL;
- u32 order, buf_size;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object->hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
- handle = hinic5_cqm_handle->ex_handle;
-
- /* This interface is used only for the CQ of RoCE service. */
- if (object->service_type == HINIC5_CQM_SERVICE_T_ROCE &&
- object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- service = hinic5_cqm_handle->service + object->service_type;
- order = service->buf_order;
- buf_size = (u32)(PAGE_SIZE << order);
-
- if (qinfo->common.current_q_room == HINIC5_CQM_RDMA_Q_ROOM_1)
- q_room_buf = &qinfo->common.q_room_buf_2;
- else
- q_room_buf = &qinfo->common.q_room_buf_1;
-
- if (qinfo->room_header_alloc) {
- q_room_buf->buf_number = ALIGN(object_size, buf_size) /
- buf_size;
- q_room_buf->page_number = q_room_buf->buf_number <<
- order;
- q_room_buf->buf_size = buf_size;
- if (hinic5_cqm_buf_alloc(hinic5_cqm_handle, q_room_buf, true) ==
- HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- qinfo->new_object_size = object_size;
- return HINIC5_CQM_SUCCESS;
- }
-
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_WRONG_VALUE(qinfo->room_header_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_err(handle->dev_hdl, "Cq resize alloc: service_type %u object_type %u do not support resize\n",
- object->service_type, object->object_type);
- return HINIC5_CQM_FAIL;
-}
-EXPORT_SYMBOL(hinic5_cqm_object_resize_alloc_new);
-
-/**
- * Prototype : hinic5_cqm_object_resize_free_new
- * Description : Currently this function is only used for RoCE.
- * The CQ buffer is ajusted, but the cqn and cqc remain
- * unchanged. This function frees new buffer, and is used to deal
- * with exceptions.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_resize_free_new(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = (struct tag_hinic5_cqm_rdma_qinfo *)(void *)object;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_buf *q_room_buf = NULL;
- struct hinic5_hwdev *handle = NULL;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
- handle = hinic5_cqm_handle->ex_handle;
-
- /* This interface is used only for the CQ of RoCE service. */
- if (object->service_type == HINIC5_CQM_SERVICE_T_ROCE &&
- object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- if (qinfo->common.current_q_room == HINIC5_CQM_RDMA_Q_ROOM_1)
- q_room_buf = &qinfo->common.q_room_buf_2;
- else
- q_room_buf = &qinfo->common.q_room_buf_1;
-
- qinfo->new_object_size = 0;
-
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
- } else {
- hinic5_cqm_err(handle->dev_hdl, "Cq resize free: service_type %u object_type %u do not support resize\n",
- object->service_type, object->object_type);
- }
-}
-EXPORT_SYMBOL(hinic5_cqm_object_resize_free_new);
-
-/**
- * Prototype : hinic5_cqm_object_resize_free_old
- * Description : Currently this function is only used for RoCE.
- * The CQ buffer is ajusted, but the cqn and cqc remain
- * unchanged. This function frees old buffer and switches the
- * valid buffer to new buffer.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_object_resize_free_old(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = (struct tag_hinic5_cqm_rdma_qinfo *)(void *)object;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_buf *q_room_buf = NULL;
-
- if (unlikely(object == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(object));
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
-
- /* This interface is used only for the CQ of RoCE service. */
- if (object->service_type == HINIC5_CQM_SERVICE_T_ROCE &&
- object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- if (qinfo->common.current_q_room == HINIC5_CQM_RDMA_Q_ROOM_1) {
- q_room_buf = &qinfo->common.q_room_buf_1;
- qinfo->common.current_q_room = HINIC5_CQM_RDMA_Q_ROOM_2;
- } else {
- q_room_buf = &qinfo->common.q_room_buf_2;
- qinfo->common.current_q_room = HINIC5_CQM_RDMA_Q_ROOM_1;
- }
-
- object->object_size = qinfo->new_object_size;
-
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
- }
-}
-EXPORT_SYMBOL(hinic5_cqm_object_resize_free_old);
-
-/**
- * Prototype : hinic5_cqm_gid_base
- * Description : Obtain the base virtual address of the gid table for FT
- * debug.
- * Input : void *ex_handle
- * Output : None
- * 1.Date : 2015/9/8
- * Modification : Created function
- */
-void *hinic5_cqm_gid_base(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bat_table *bat_table = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_buf *cla_z_buf = NULL;
- u32 entry_type, i;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return NULL;
- }
-
- bat_table = &hinic5_cqm_handle->bat_table;
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- entry_type = bat_table->bat_entry_type[i];
- if (entry_type == HINIC5_CQM_BAT_ENTRY_T_GID) {
- cla_table = &bat_table->entry[i];
- cla_z_buf = &cla_table->cla_z_buf;
- if (cla_z_buf->buf_list)
- return cla_z_buf->buf_list->va;
- }
- }
-
- return NULL;
-}
-
-/**
- * Prototype : hinic5_cqm_timer_base
- * Description : Obtain the base virtual address of the timer for live
- * migration.
- * Input : void *ex_handle
- * Output : None
- * Return Value : void
- * 1.Date : 2020/5/21
- * Modification : Created function
- */
-void *hinic5_cqm_timer_base(void *ex_handle)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bat_table *bat_table = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_buf *cla_z_buf = NULL;
- u32 entry_type, i;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return NULL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return NULL;
- }
-
- /* Timer resource is configured on PPF. */
- if (!HINIC5_CQM_IS_PPF(hinic5_cqm_handle)) {
- hinic5_cqm_err(handle->dev_hdl, "%s: wrong function type:%d\n",
- __func__, handle->hwif->attr.func_type);
- return NULL;
- }
-
- bat_table = &hinic5_cqm_handle->bat_table;
-
- for (i = 0; i < HINIC5_CQM_BAT_ENTRY_MAX; i++) {
- entry_type = bat_table->bat_entry_type[i];
- if (entry_type != HINIC5_CQM_BAT_ENTRY_T_TIMER)
- continue;
-
- cla_table = &bat_table->entry[i];
- cla_z_buf = &cla_table->cla_z_buf;
-
- if (!cla_z_buf->direct.va) {
- if (hinic5_cqm_buf_alloc_direct(hinic5_cqm_handle, cla_z_buf, true) ==
- HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc_direct));
- return NULL;
- }
- }
-
- return cla_z_buf->direct.va;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_cqm_timer_base);
-
-static inline bool val_in_range(u32 val, u32 start, u32 num)
-{
- return val >= start && val - start < num;
-}
-
-/* Convert func id to func offset used in timer buffers. */
-STATIC s32 hinic5_cqm_timer_get_func_offset(struct hinic5_hwdev *ex_handle,
- u32 func_id, u32 *func_offset)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = ex_handle->hinic5_cqm_hdl;
- struct tag_hinic5_cqm_func_capability *cap = &hinic5_cqm_handle->func_capability;
- u32 vf_offset;
- int i;
-
- /* PF */
- if (val_in_range(func_id, cap->timer_pf_id_start, cap->timer_pf_num)) {
- *func_offset = func_id - cap->timer_pf_id_start;
- return HINIC5_CQM_SUCCESS;
- }
-
- if (!val_in_range(func_id, cap->timer_vf_id_start, cap->timer_vf_num))
- goto fail;
-
- if (!cap->timer_vf_deploy_with_segs) {
- vf_offset = func_id - cap->timer_vf_id_start;
- *func_offset = cap->timer_pf_num + vf_offset;
- return HINIC5_CQM_SUCCESS;
- }
-
- /* Timer buffer segmentation deployment */
- vf_offset = 0;
- for (i = 0; i < ARRAY_SIZE(cap->timer_vf_segs); i++) {
- struct timer_vf_info_seg *seg = &cap->timer_vf_segs[i];
- if (seg->start == 0)
- break;
- if (val_in_range(func_id, seg->start, seg->num)) {
- vf_offset += func_id - seg->start;
- *func_offset = cap->timer_pf_num + vf_offset;
- return HINIC5_CQM_SUCCESS;
- }
- vf_offset += seg->num;
- }
-
-fail:
- hinic5_cqm_err(ex_handle->dev_hdl,
- "Timer clear: wrong func id %u\n", func_id);
- return HINIC5_CQM_FAIL;
-}
-
-STATIC void hinic5_cqm_clear_timer(struct hinic5_hwdev *handle, u32 func_id,
- struct tag_hinic5_cqm_cla_table *cla_table)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = handle->hinic5_cqm_hdl;
- struct tag_hinic5_cqm_func_capability *cap = &hinic5_cqm_handle->func_capability;
- struct tag_hinic5_cqm_buf *cla_buf = &cla_table->cla_z_buf;
- u32 func_timer_size = HINIC5_CQM_TIMER_ALIGN_SCALE_NUM * cap->timer_basic_size;
- u32 func_buf_num = 0, func_offset = 0;
- u32 i, func_buf_start, func_buf_end;
- s32 ret;
-
- ret = hinic5_cqm_timer_get_func_offset(handle, func_id, &func_offset);
- if (ret == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_timer_get_func_offset));
- return;
- }
-
- if (cla_buf->buf_size == 0)
- goto fail;
- func_buf_num = func_timer_size / cla_buf->buf_size;
- if (func_buf_num == 0) {
- /* Func timer size smaller than CLA buffer? Not yet implemented */
- goto fail;
- }
-
- func_buf_start = func_offset * func_buf_num;
- func_buf_end = func_buf_start + func_buf_num;
- if (func_buf_end > cla_buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl,
- "Timer clear: func buffer end %u overflow, limit %u.\n",
- func_buf_end, cla_buf->buf_number);
- goto fail;
- }
-
- hinic5_cqm_dbg(handle->dev_hdl,
- "Timer clear: func id %u, offset %u. cla lvl %u.\n",
- func_id, func_offset, cla_table->cla_lvl);
-
- for (i = func_buf_start; i < func_buf_end; i++) {
- hinic5_cqm_dbg_on(hinic5_cqm_verbose, handle->dev_hdl,
- "Timer clear: buf %4u, pa 0x%lx, va 0x%lx\n",
- i, (uintptr_t)cla_buf->buf_list[i].pa,
- (uintptr_t)cla_buf->buf_list[i].va);
- memset(cla_buf->buf_list[i].va, 0, cla_buf->buf_size);
- }
- return;
-
-fail:
- hinic5_cqm_err(handle->dev_hdl,
- "Timer clear: failed. timer cla lvl %u, buf size %u, buf num 0x%x\n",
- cla_table->cla_lvl, cla_buf->buf_size, cla_buf->buf_number);
- hinic5_cqm_err(handle->dev_hdl,
- "Timer clear: func id %u, offset %u. func timer size 0x%x, func buf num %u\n",
- func_id, func_offset, func_timer_size, func_buf_num);
-}
-
-/**
- * Prototype : hinic5_cqm_function_timer_clear
- * Description : Clear the timer buffer based on the function ID.
- * The function ID starts from 0 and the timer buffer is arranged
- * in sequence by function ID.
- * Input : void *ex_handle
- * u32 functionid
- * Output : None
- * Return Value : void
- * 1.Date : 2016/12/19
- * Modification : Created function
- */
-void hinic5_cqm_function_timer_clear(void *ex_handle, u32 function_id)
-{
- /* The timer buffer of one function is 32B*8wheel*2048spoke=128*4k */
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- u32 loop, i;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_func_timer_clear_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
-
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- cla_table = &hinic5_cqm_handle->bat_table.timer_entry[0];
- loop = hinic5_cqm_handle->func_capability.smf_max_num;
- } else {
- cla_table = hinic5_cqm_cla_table_get(&hinic5_cqm_handle->bat_table, HINIC5_CQM_BAT_ENTRY_T_TIMER);
- loop = 1;
- }
-
- if (unlikely(cla_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(cla_table));
- return;
- }
- for (i = 0; i < loop; i++) {
- hinic5_cqm_clear_timer(handle, function_id, cla_table);
- cla_table++;
- }
-}
-EXPORT_SYMBOL(hinic5_cqm_function_timer_clear);
-
-/**
- * Prototype : hinic5_cqm_function_hash_buf_clear
- * Description : clear hash buffer based on global function_id
- * Input : void *ex_handle
- * s32 global_funcid
- * Output : None
- * Return Value : None
- * 1.Date : 2017/11/27
- * Modification : Created function
- * 2.Date : 2021/02/23
- * Modification : Add para func_id; clear hash buf by func_id
- */
-void hinic5_cqm_function_hash_buf_clear(void *ex_handle, s32 global_funcid)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_func_capability *func_cap = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_buf *cla_z_buf = NULL;
- s32 fake_funcid;
- u32 loop;
- u32 i;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_func_hash_buf_clear_cnt);
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
- func_cap = &hinic5_cqm_handle->func_capability;
-
- /* fake vf adaption, switch to corresponding VF. */
- if (HINIC5_CQM_IS_FAKE_PARENT(hinic5_cqm_handle)) {
- fake_funcid = global_funcid -
- (s32)(func_cap->fake_cfg.child_func_start);
- hinic5_cqm_info(handle->dev_hdl, "fake_funcid =%d\n", fake_funcid);
- if (fake_funcid < 0 || fake_funcid >= HINIC5_CQM_FAKE_FUNC_MAX) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(fake_funcid));
- return;
- }
-
- hinic5_cqm_handle = hinic5_cqm_handle->fake_hinic5_cqm_handle[fake_funcid];
- }
-
- if (HINIC5_CQM_IS_LB_MODE_1_OR_2(hinic5_cqm_handle)) {
- cla_table = &hinic5_cqm_handle->bat_table.hash_entry[0];
- loop = hinic5_cqm_handle->func_capability.smf_max_num;
- } else {
- cla_table = hinic5_cqm_cla_table_get(&hinic5_cqm_handle->bat_table, HINIC5_CQM_BAT_ENTRY_T_HASH);
- loop = 1;
- }
-
- if (unlikely(cla_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(cla_table));
- return;
- }
-
- while (loop > 0) {
- cla_z_buf = &cla_table->cla_z_buf;
-
- for (i = 0; i < cla_z_buf->buf_number; i++)
- memset(cla_z_buf->buf_list[i].va, 0, cla_z_buf->buf_size);
-
- cla_table++;
- loop--;
- }
-}
-EXPORT_SYMBOL(hinic5_cqm_function_hash_buf_clear);
-
-void hinic5_cqm_srq_used_rq_container_delete(struct tag_hinic5_cqm_object *object, u8 *container)
-{
- struct tag_hinic5_cqm_queue *common = NULL;
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_srq_linkwqe *srq_link_wqe = NULL;
- struct hinic5_hwdev *handle = NULL;
- dma_addr_t addr;
- u32 link_wqe_offset;
-
- if (!object || !container) {
- pr_err("object or container is null\n");
- return;
- }
-
- common = container_of(object, struct tag_hinic5_cqm_queue, object);
- qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo, common);
- link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(common->object.hinic5_cqm_handle);
- handle = hinic5_cqm_handle->ex_handle;
-
- /* 1. Obtain the current container pa through link wqe table,
- * unmap pa
- */
- srq_link_wqe = (struct tag_hinic5_cqm_srq_linkwqe *)((uintptr_t)container + link_wqe_offset);
- /* shift right by 2 bits to get the length of dw(4B) */
- hinic5_cqm_swab32((u8 *)(srq_link_wqe), sizeof(struct tag_hinic5_cqm_linkwqe) >> 2);
-
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
- srq_link_wqe->current_buffer_gpa_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Rq container del: buffer physical addr is null\n");
- return;
- }
- dma_unmap_single(hinic5_cqm_handle->dev, addr, qinfo->container_size,
- DMA_BIDIRECTIONAL);
-
- /* 2. Obtain the current container va through link wqe table, free va */
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
- srq_link_wqe->current_buffer_addr_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Rq container del: buffer virtual addr is null\n");
- return;
- }
- kfree((void *)(uintptr_t)addr);
-}
-EXPORT_SYMBOL(hinic5_cqm_srq_used_rq_container_delete);
-
-s32 hinic5_cqm_dtoe_share_recv_queue_create(void *ex_handle, u32 contex_size,
- u32 *index_count, u32 *index)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_toe_private_capability *tow_own_cap = NULL;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- u32 step;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(index_count == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(index_count));
- return HINIC5_CQM_FAIL;
- }
- if (unlikely(index == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(index));
- return HINIC5_CQM_FAIL;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return HINIC5_CQM_FAIL;
- }
-
- tow_own_cap = &hinic5_cqm_handle->toe_own_capability;
-
- bitmap = &tow_own_cap->srqc_bitmap;
- *index_count = (ALIGN(contex_size, tow_own_cap->toe_srqc_basic_size)) /
- tow_own_cap->toe_srqc_basic_size;
- /* toe srqc number must align of 2 */
- step = ALIGN(tow_own_cap->toe_srqc_number, 2);
- *index = hinic5_cqm_bitmap_alloc(bitmap, step, *index_count,
- hinic5_cqm_handle->func_capability.xid_alloc_mode);
- if (*index >= bitmap->max_num) {
- hinic5_cqm_err(handle->dev_hdl, "Srq create: queue index %u exceeds max_num %u\n",
- *index, bitmap->max_num);
- return HINIC5_CQM_FAIL;
- }
- *index += tow_own_cap->toe_srqc_start_id;
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_srq_create_cnt);
-
- return HINIC5_CQM_SUCCESS;
-}
-EXPORT_SYMBOL(hinic5_cqm_dtoe_share_recv_queue_create);
-
-void hinic5_cqm_dtoe_free_srq_bitmap_index(void *ex_handle, u32 index_count, u32 index)
-{
- struct hinic5_hwdev *handle = (struct hinic5_hwdev *)ex_handle;
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
-
- if (unlikely(ex_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(ex_handle));
- return;
- }
-
- hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(handle->hinic5_cqm_hdl);
- if (unlikely(hinic5_cqm_handle == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(hinic5_cqm_handle));
- return;
- }
-
- bitmap = &hinic5_cqm_handle->toe_own_capability.srqc_bitmap;
- if ((index + index_count) > bitmap->max_num || (index + index_count) <= index) { // Avoid wrap-around
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_WRONG_VALUE(index + index_count));
- return;
- }
-
- hinic5_cqm_bitmap_free(bitmap, index, index_count);
-}
-EXPORT_SYMBOL(hinic5_cqm_dtoe_free_srq_bitmap_index);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.h
deleted file mode 100644
index 5ceb17e73..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_object.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_OBJECT_H
-#define HINIC5_CQM_OBJECT_H
-
-#include "comm_defs.h"
-#include "hinic5_hinic5_cqm.h"
-
-#define HINIC5_CQM_LINKWQE_128B 128
-#define HINIC5_CQM_MOD_TOE HINIC5_MOD_TOE
-#define HINIC5_CQM_MOD_HINIC5_CQM HINIC5_MOD_HINIC5_CQM
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif
-#endif /* __cplusplus */
-
-/**
- * @brief: create FC SRQ.
- * @details: The number of valid WQEs in the queue must meet the number of
- * transferred WQEs. Linkwqe can only be filled at the end of the
- * page. The actual number of valid links exceeds the requirement.
- * The service needs to be informed of the number of extra links to
- * be created.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param wqe_number: number of WQEs
- * @param wqe_size: wqe size
- * @param object_priv: pointer to object private information
- * @retval struct tag_hinic5_cqm_queue*: queue structure pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_fc_srq_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-
-/**
- * @brief: create RQ.
- * @details: When SRQ is used, the RQ queue is created.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param init_rq_num: number of containers
- * @param container_size: container size
- * @param wqe_size: wqe size
- * @param object_priv: pointer to object private information
- * @retval struct tag_hinic5_cqm_queue*: queue structure pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_recv_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 init_rq_num, u32 container_size,
- u32 wqe_size, void *object_priv);
-
-/**
- * @brief: SRQ applies for a new container and is linked after the container
- * is created.
- * @details: SRQ applies for a new container and is linked after the container
- * is created.
- * @param common: queue structure pointer
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-s32 hinic5_cqm_object_share_recv_queue_add_container(struct tag_hinic5_cqm_queue *common);
-
-/**
- * @brief: SRQ applies for a new container. After the container is created,
- * no link is attached to the container. The service is attached to
- * the container.
- * @details: SRQ applies for a new container. After the container is created,
- * no link is attached to the container. The service is attached to
- * the container.
- * @param common: queue structure pointer
- * @param container_addr: returned container address
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-s32 hinic5_cqm_object_srq_add_container_free(struct tag_hinic5_cqm_queue *common, u8 **container_addr);
-
-/**
- * @brief: create SRQ for TOE services.
- * @details: create SRQ for TOE services.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param container_number: number of containers
- * @param container_size: container size
- * @param wqe_size: wqe size
- * @retval struct tag_hinic5_cqm_queue*: queue structure pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_share_recv_queue_create(void *ex_handle,
- u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 container_number,
- u32 container_size,
- u32 wqe_size);
-
-/**
- * @brief: create QPC and MPT.
- * @details: When QPC and MPT are created, the interface sleeps.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param object_size: object size, in bytes.
- * @param object_priv: private structure of the service layer.
- * The value can be NULL.
- * @param index: apply for reserved qpn based on the value. If automatic
- * allocation is required, fill HINIC5_CQM_INDEX_INVALID.
- * @param bitmap_start: start index of bitmap when range search.
- * @param bitmap_end: end index of bitmap when range search.
- * @retval struct tag_hinic5_cqm_qpc_mpt *: pointer to the QPC/MPT structure
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_qpc_mpt *hinic5_cqm_object_qpc_mpt_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 object_size, void *object_priv,
- u32 index, u32 bitmap_start, u32 bitmap_end);
-
-/**
- * @brief: create a queue for non-RDMA services.
- * @details: create a queue for non-RDMA services. The interface sleeps.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param wqe_number: number of Link WQEs
- * @param wqe_size: fixed length, size 2^n
- * @param object_priv: private structure of the service layer.
- * The value can be NULL.
- * @retval struct tag_hinic5_cqm_queue *: queue structure pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_nonrdma_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 wqe_number, u32 wqe_size,
- void *object_priv);
-
-/**
- * @brief: create a RDMA service queue.
- * @details: create a queue for the RDMA service. The interface sleeps.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param object_size: object size
- * @param object_priv: private structure of the service layer.
- * The value can be NULL.
- * @param room_header_alloc: whether to apply for the queue room and header
- * space
- * @param xid: apply for reserved qpn based on the value. If automatic
- * allocation is required, fill HINIC5_CQM_INDEX_INVALID.
- * @param bitmap_start: start index of bitmap when range search.
- * @param bitmap_end: end index of bitmap when range search.
- * @retval struct tag_hinic5_cqm_queue *: queue structure pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_queue *hinic5_cqm_object_rdma_queue_create(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 object_size, void *object_priv,
- bool room_header_alloc, u32 xid,
- u32 bitmap_start, u32 bitmap_end);
-
-/**
- * @brief: create the MTT and RDMARC of the RDMA service.
- * @details: create the MTT and RDMARC of the RDMA service.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param object_type: object type
- * @param index_base: start index number
- * @param index_number: index number
- * @retval struct tag_hinic5_cqm_mtt_rdmarc *: pointer to the MTT/RDMARC structure
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_mtt_rdmarc *hinic5_cqm_object_rdma_table_get(void *ex_handle, u32 service_type,
- enum hinic5_cqm_object_type object_type,
- u32 index_base, u32 index_number);
-
-/**
- * @brief: delete created objects.
- * @details: delete the created object. This function does not return until all
- * operations on the object are complete.
- * @param object: object pointer
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_object_delete(struct tag_hinic5_cqm_object *object);
-
-/**
- * @brief: obtains the physical address and virtual address at the specified
- * offset of the object buffer.
- * @details: Only RDMA table query is supported to obtain the physical address
- * and virtual address at the specified offset of the object buffer.
- * @param object: object pointer
- * @param offset: for a rdma table, offset is the absolute index number.
- * @param paddr: The physical address is returned only for the rdma table.
- * @retval u8 *: buffer specify the virtual address at the offset
- * @date: 2019-5-4
- */
-u8 *hinic5_cqm_object_offset_addr(struct tag_hinic5_cqm_object *object, u32 offset, dma_addr_t *paddr);
-
-/**
- * @brief: obtain object according index.
- * @details: obtain object according index.
- * @param ex_handle: device pointer that represents the PF
- * @param object_type: object type
- * @param index: support qpn,mptn,scqn,srqn
- * @param bh: whether to disable the bottom half of the interrupt
- * @retval struct tag_hinic5_cqm_object *: object pointer
- * @date: 2019-5-4
- */
-struct tag_hinic5_cqm_object *hinic5_cqm_object_get(void *ex_handle, enum hinic5_cqm_object_type object_type,
- u32 index, bool bh);
-
-/**
- * @brief: object reference counting release
- * @details: After the function hinic5_cqm_object_get is invoked, this API must be put.
- * Otherwise, the object cannot be released.
- * @param object: object pointer
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_object_put(struct tag_hinic5_cqm_object *object);
-
-/**
- * @brief: obtain the ID of the function where the object resides.
- * @details: obtain the ID of the function where the object resides.
- * @param object: object pointer
- * @retval >=0: ID of function
- * @retval -1: fail
- * @date: 2020-4-15
- */
-s32 hinic5_cqm_object_funcid(struct tag_hinic5_cqm_object *object);
-
-/**
- * @brief: apply for a new space for an object.
- * @details: Currently, this parameter is valid only for the ROCE service.
- * The CQ buffer size is adjusted, but the CQN and CQC remain
- * unchanged. New buffer space is applied for, and the old buffer
- * space is not released. The current valid buffer is still the old
- * buffer.
- * @param object: object pointer
- * @param object_size: new buffer size
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-s32 hinic5_cqm_object_resize_alloc_new(struct tag_hinic5_cqm_object *object, u32 object_size);
-
-/**
- * @brief: release the newly applied buffer space for the object.
- * @details: This function is used to release the newly applied buffer space for
- * service exception handling.
- * @param object: object pointer
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_object_resize_free_new(struct tag_hinic5_cqm_object *object);
-
-/**
- * @brief: release old buffer space for objects.
- * @details: This function releases the old buffer and sets the current valid
- * buffer to the new buffer.
- * @param object: object pointer
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_object_resize_free_old(struct tag_hinic5_cqm_object *object);
-
-/**
- * @brief: release container.
- * @details: release container.
- * @param object: object pointer
- * @param container: container pointer to be released
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_srq_used_rq_container_delete(struct tag_hinic5_cqm_object *object, u8 *container);
-
-void *hinic5_cqm_get_db_addr(void *ex_handle, u32 service_type);
-
-s32 hinic5_cqm_ring_hardware_db_fc(void *ex_handle, u32 service_type, u8 db_count,
- u8 pagenum, u64 db);
-
-/**
- * @brief: provide the interface of knocking on doorbell.
- * The HINIC5_CQM converts the pri to cos.
- * @details: provide interface of knocking on doorbell for the HINIC5_CQM to convert
- * the pri to cos. The doorbell transferred by the service must be the
- * host sequence. This interface converts the network sequence.
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: Each kernel-mode service is allocated a hardware
- * doorbell page.
- * @param db_count: PI[7:0] beyond 64b in the doorbell
- * @param db: The doorbell content is organized by the service. If there is
- * endian conversion, the service needs to complete the conversion.
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-s32 hinic5_cqm_ring_hardware_db_update_pri(void *ex_handle, u32 service_type,
- u8 db_count, u64 db);
-
-/**
- * @brief: knock on software doorbell.
- * @details: knock on software doorbell.
- * @param object: object pointer
- * @param db_record: software doorbell content. If there is big-endian
- * conversion, the service needs to complete the conversion.
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-s32 hinic5_cqm_ring_software_db(struct tag_hinic5_cqm_object *object, u64 db_record);
-
-/**
- * @brief: reference counting is added to the bloom filter ID.
- * @details: reference counting is added to the bloom filter ID. When the ID
- * changes from 0 to 1, the sending API is set to 1.
- * This interface sleeps.
- * @param ex_handle: device pointer that represents the PF
- * @param id: id
- * @retval 0: success
- * @retval -1: fail
- * @date: 2019-5-4
- */
-void *hinic5_cqm_gid_base(void *ex_handle);
-
-/**
- * @brief: obtain the base virtual address of the timer.
- * @details: obtain the base virtual address of the timer.
- * @param ex_handle: device pointer that represents the PF
- * @retval void *: base virtual address of the timer
- * @date: 2020-5-21
- */
-void *hinic5_cqm_timer_base(void *ex_handle);
-
-/**
- * @brief: clear timer buffer.
- * @details: clear the timer buffer based on the function ID. Function IDs start
- * from 0, and timer buffers are arranged by function ID.
- * @param ex_handle: device pointer that represents the PF
- * @param function_id: function id
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_function_timer_clear(void *ex_handle, u32 function_id);
-
-/**
- * @brief: clear hash buffer.
- * @details: clear the hash buffer based on the function ID.
- * @param ex_handle: device pointer that represents the PF
- * @param global_funcid
- * @retval: void
- * @date: 2019-5-4
- */
-void hinic5_cqm_function_hash_buf_clear(void *ex_handle, s32 global_funcid);
-
-s32 hinic5_cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
- void *direct_wqe);
-
-/**
- * @brief: Knock direct wqe db for fc
- * @details: Knock direct wqe db for fc
- * @param ex_handle: device pointer that represents the PF
- * @param service_type: service type
- * @param direct_wqe: direct wqe to write
- * @retval: s32, 0 success, others failure
- */
-s32 hinic5_cqm_ring_direct_wqe_db_fc(void *ex_handle, u32 service_type,
- void *direct_wqe);
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif
-#endif /* __cplusplus */
-
-#endif /* HINIC5_CQM_OBJECT_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.c
deleted file mode 100644
index 779284491..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.c
+++ /dev/null
@@ -1,1481 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_object_intern.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-
-#include "ossl_knl.h"
-#include "hinic5_crm.h"
-#include "hinic5_hw.h"
-#include "hinic5_hwdev.h"
-
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-#include "hinic5_cqm_bat_cla.h"
-#include "hinic5_cqm_main.h"
-#include "hinic5_cqm_object_intern.h"
-
-#define srq_obj_intern_if_section
-
-/**
- * Prototype : hinic5_cqm_container_free
- * Description : Only the container buffer is released. The buffer in the WQE
- * and fast link tables are not involved.
- * Containers can be released from head to tail, including head
- * and tail. This function does not modify the start and
- * end pointers of qinfo records.
- * Input : u8 *srq_head_container
- * u8 *srq_tail_container: If it is NULL, it means to release
- * container from head to tail.
- * struct tag_hinic5_cqm_queue *common
- * Output : None
- * Return Value : void
- * 1.Date : 2016/2/1
- * Modification : Created function
- */
-void hinic5_cqm_container_free(u8 *srq_head_container, u8 *srq_tail_container,
- struct tag_hinic5_cqm_queue *common)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(common->object.hinic5_cqm_handle);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_srq_linkwqe *srq_link_wqe = NULL;
- u32 container_size = qinfo->container_size;
- struct device *dev = hinic5_cqm_handle->dev;
- u64 addr;
- u8 *srqhead_container = srq_head_container;
- u8 *srqtail_container = srq_tail_container;
-
- if (unlikely(srqhead_container == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_PTR_NULL(srqhead_container));
- return;
- }
-
- /* 1. The range is released cyclically from the head to the tail, i.e.
- * [head:tail]. If the tail is null, the range is [head:null]. Oterwise,
- * [head:tail->next).
- */
- if (srqtail_container) {
- /* [head:tail->next): Update srqtail_container to the next
- * container va.
- */
- srq_link_wqe = (struct tag_hinic5_cqm_srq_linkwqe *)(srqtail_container +
- link_wqe_offset);
- /* Only the link wqe part needs to be converted. */
- hinic5_cqm_swab32((u8 *)(srq_link_wqe), sizeof(struct tag_hinic5_cqm_linkwqe) >> HINIC5_CQM_DW_SHIFT);
- srqtail_container = (u8 *)(uintptr_t)HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->fixed_next_buffer_addr_h,
- srq_link_wqe->fixed_next_buffer_addr_l);
- }
-
- do {
- /* 2. Obtain the link wqe of the current container */
- srq_link_wqe = (struct tag_hinic5_cqm_srq_linkwqe *)(srqhead_container +
- link_wqe_offset);
- /* Only the link wqe part needs to be converted. */
- hinic5_cqm_swab32((u8 *)(srq_link_wqe), sizeof(struct tag_hinic5_cqm_linkwqe) >> HINIC5_CQM_DW_SHIFT);
- /* Obtain the va of the next container using the link wqe. */
- srqhead_container = (u8 *)(uintptr_t)HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->fixed_next_buffer_addr_h,
- srq_link_wqe->fixed_next_buffer_addr_l);
-
- /* 3. Obtain the current container pa from the link wqe,
- * and cancel the mapping
- */
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
- srq_link_wqe->current_buffer_gpa_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Container free: buffer physical addr is null\n");
- return;
- }
- dma_unmap_single(dev, (dma_addr_t)addr, container_size,
- DMA_BIDIRECTIONAL);
-
- /* 4. Obtain the container va through linkwqe and release the
- * container va.
- */
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
- srq_link_wqe->current_buffer_addr_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Container free: buffer virtual addr is null\n");
- return;
- }
- kfree((void *)(uintptr_t)addr);
- } while (srqhead_container != srqtail_container);
-}
-
-static void hinic5_cqm_update_srq_link_wqe(u32 link_wqe_offset, u8 *new_container,
- dma_addr_t new_container_pa)
-{
- struct tag_hinic5_cqm_srq_linkwqe *srq_link_wqe =
- (struct tag_hinic5_cqm_srq_linkwqe *)((uintptr_t)new_container + link_wqe_offset);
- struct tag_hinic5_cqm_linkwqe *link_wqe = &srq_link_wqe->linkwqe;
-
- link_wqe->o = HINIC5_CQM_LINK_WQE_OWNER_INVALID;
- link_wqe->ctrlsl = HINIC5_CQM_LINK_WQE_CTRLSL_VALUE;
- link_wqe->lp = HINIC5_CQM_LINK_WQE_LP_INVALID;
- link_wqe->wf = HINIC5_CQM_WQE_WF_LINK;
- srq_link_wqe->current_buffer_gpa_h = HINIC5_CQM_ADDR_HI(new_container_pa);
- srq_link_wqe->current_buffer_gpa_l = HINIC5_CQM_ADDR_LW(new_container_pa);
- srq_link_wqe->current_buffer_addr_h = HINIC5_CQM_ADDR_HI((uintptr_t)new_container);
- srq_link_wqe->current_buffer_addr_l = HINIC5_CQM_ADDR_LW((uintptr_t)new_container);
-
- /* Convert only the area accessed by the chip to the network sequence */
- hinic5_cqm_swab32((u8 *)link_wqe, sizeof(struct tag_hinic5_cqm_linkwqe) >> HINIC5_CQM_DW_SHIFT);
-}
-
-/**
- * Prototype : hinic5_cqm_container_create
- * Description : Create a container for the RQ or SRQ, link it to the tail of
- * the queue, and update the tail container pointer of the queue.
- * Input : struct tag_hinic5_cqm_object *object
- * u8 **container_addr
- * bool link
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/2/16
- * Modification : Created function
- */
-s32 hinic5_cqm_container_create(struct tag_hinic5_cqm_object *object, u8 **container_addr, bool link)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(object->hinic5_cqm_handle);
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo, common);
- u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_srq_linkwqe *srq_link_wqe = NULL;
- struct tag_hinic5_cqm_linkwqe *link_wqe = NULL;
- dma_addr_t new_container_pa;
- u8 *new_container = NULL;
-
- /* 1. Applying for Container Space and Initializing Invalid/Normal WQE
- * of the Container.
- */
- new_container = kzalloc(qinfo->container_size, GFP_ATOMIC);
- if (!new_container) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(new_container));
- return HINIC5_CQM_FAIL;
- }
-
- /* Container PCI mapping */
- new_container_pa = dma_map_single(hinic5_cqm_handle->dev, new_container, qinfo->container_size, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev, new_container_pa) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(new_container_pa));
- kfree(new_container);
- return HINIC5_CQM_FAIL;
- }
-
- /* 2. The container is linked to the SRQ, and the link wqe of
- * tail_container and new_container is updated.
- */
- /* If the SRQ is not empty, update the linkwqe of the tail container. */
- if (link) {
- if (common->tail_container) {
- srq_link_wqe = (struct tag_hinic5_cqm_srq_linkwqe *)(common->tail_container + link_wqe_offset);
- link_wqe = &srq_link_wqe->linkwqe;
- link_wqe->next_page_gpa_h = __swab32((u32)HINIC5_CQM_ADDR_HI(new_container_pa));
- link_wqe->next_page_gpa_l = __swab32((u32)HINIC5_CQM_ADDR_LW(new_container_pa));
- link_wqe->next_buffer_addr_h = __swab32((u32)HINIC5_CQM_ADDR_HI((uintptr_t)new_container));
- link_wqe->next_buffer_addr_l = __swab32((u32)HINIC5_CQM_ADDR_LW((uintptr_t)new_container));
- /* make sure next page gpa and next buffer addr of
- * link wqe update first
- */
- wmb();
- /* The SRQ tail container may be accessed by the chip.
- * Therefore, obit must be set to 1 at last.
- */
- (*(u32 *)(void *)link_wqe) |= 0x80;
- /* make sure obit set ahead of fixed next buffer addr
- * updating of srq link wqe
- */
- wmb();
- srq_link_wqe->fixed_next_buffer_addr_h = (u32)HINIC5_CQM_ADDR_HI((uintptr_t)new_container);
- srq_link_wqe->fixed_next_buffer_addr_l = (u32)HINIC5_CQM_ADDR_LW((uintptr_t)new_container);
- }
- }
-
- /* Update the Invalid WQE of a New Container */
- clear_bit(0x1F, (ulong *)new_container);
- /* Update the link wqe of the new container. */
- hinic5_cqm_update_srq_link_wqe(link_wqe_offset, new_container, new_container_pa);
- if (link)
- /* Update the tail pointer of a queue. */
- common->tail_container = new_container;
- else
- *container_addr = new_container;
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_srq_container_init
- * Description : Initialize the SRQ to create all containers and link them.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/2/3
- * Modification : Created function
- */
-static s32 hinic5_cqm_srq_container_init(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 container_num = object->object_size;
- s32 ret;
- u32 i;
-
- if (common->head_container || common->tail_container) {
- hinic5_cqm_err(handle->dev_hdl, "Srq container init: srq tail/head container not null\n");
- return HINIC5_CQM_FAIL;
- }
-
- /* Applying for a Container
- * During initialization, the head/tail pointer is null.
- * After the first application is successful, head=tail.
- */
- ret = hinic5_cqm_container_create(&qinfo->common.object, NULL, true);
- if (ret == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, "Srq container init: hinic5_cqm_srq_container_add fail\n");
- return HINIC5_CQM_FAIL;
- }
- common->head_container = common->tail_container;
-
- /* The container is dynamically created and the tail pointer is updated.
- * If the container fails to be created, release the containers from
- * head to null.
- */
- for (i = 1; i < container_num; i++) {
- ret = hinic5_cqm_container_create(&qinfo->common.object, NULL, true);
- if (ret == HINIC5_CQM_FAIL) {
- hinic5_cqm_container_free(common->head_container, NULL,
- &qinfo->common);
- return HINIC5_CQM_FAIL;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_share_recv_queue_create
- * Description : Create SRQ(share receive queue)
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : s32
- * 1.Date : 2016/1/27
- * Modification : Created function
- */
-s32 hinic5_cqm_share_recv_queue_create(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_toe_private_capability *toe_own_cap = &hinic5_cqm_handle->toe_own_capability;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- u32 step;
- s32 ret;
-
- /* 1. Create srq container, including initializing the link wqe. */
- ret = hinic5_cqm_srq_container_init(object);
- if (ret == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_srq_container_init));
- return HINIC5_CQM_FAIL;
- }
-
- /* 2. Create srq ctx: SRQ CTX is directly delivered by the driver to the
- * chip memory area through the cmdq channel, and no CLA table
- * management is required. Therefore, the HINIC5_CQM applies for only one empty
- * buffer for the driver.
- */
- /* bitmap applies for index */
- bitmap = &toe_own_cap->srqc_bitmap;
- qinfo->index_count = (ALIGN(qinfo->q_ctx_size,
- toe_own_cap->toe_srqc_basic_size)) /
- toe_own_cap->toe_srqc_basic_size;
- /* align with 2 as the upper bound */
- step = ALIGN(toe_own_cap->toe_srqc_number, 2);
- qinfo->common.index = hinic5_cqm_bitmap_alloc(bitmap, step, qinfo->index_count,
- func_cap->xid_alloc_mode);
- if (qinfo->common.index >= bitmap->max_num) {
- hinic5_cqm_err(handle->dev_hdl, "Srq create: queue index %u exceeds max_num %u\n",
- qinfo->common.index, bitmap->max_num);
- goto err1;
- }
- qinfo->common.index += toe_own_cap->toe_srqc_start_id;
-
- /* apply for buffer for SRQC */
- common->q_ctx_vaddr = kzalloc(qinfo->q_ctx_size, GFP_KERNEL);
- if (!common->q_ctx_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(q_ctx_vaddr));
- goto err2;
- }
- return HINIC5_CQM_SUCCESS;
-
-err2:
- hinic5_cqm_bitmap_free(bitmap,
- qinfo->common.index - toe_own_cap->toe_srqc_start_id,
- qinfo->index_count);
-err1:
- hinic5_cqm_container_free(common->head_container, common->tail_container,
- &qinfo->common);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_srq_used_rq_delete
- * Description : Delete RQ in TOE SRQ mode.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2016/5/19
- * Modification : Created function
- */
-static void hinic5_cqm_srq_used_rq_delete(const struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)(common->object.hinic5_cqm_handle);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- u32 link_wqe_offset = qinfo->wqe_per_buf * qinfo->wqe_size;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_srq_linkwqe *srq_link_wqe = NULL;
- dma_addr_t addr;
-
- /* Currently, the SRQ solution does not support RQ initialization
- * without mounting container.
- * As a result, RQ resources are released incorrectly.
- * Temporary workaround: Only one container is mounted during RQ
- * initialization and only one container is released
- * during resource release.
- */
- if (unlikely(common->head_container == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR("Rq del: rq has no contianer to release\n");
- return;
- }
-
- /* 1. Obtain current container pa from the link wqe table and
- * cancel the mapping.
- */
- srq_link_wqe = (struct tag_hinic5_cqm_srq_linkwqe *)(common->head_container + link_wqe_offset);
- /* Only the link wqe part needs to be converted. */
- hinic5_cqm_swab32((u8 *)(srq_link_wqe), sizeof(struct tag_hinic5_cqm_linkwqe) >> HINIC5_CQM_DW_SHIFT);
-
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_gpa_h,
- srq_link_wqe->current_buffer_gpa_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Rq del: buffer physical addr is null\n");
- return;
- }
- dma_unmap_single(hinic5_cqm_handle->dev, addr, qinfo->container_size,
- DMA_BIDIRECTIONAL);
-
- /* 2. Obtain the container va through the linkwqe and release. */
- addr = HINIC5_CQM_ADDR_COMBINE(srq_link_wqe->current_buffer_addr_h,
- srq_link_wqe->current_buffer_addr_l);
- if (addr == 0) {
- hinic5_cqm_err(handle->dev_hdl, "Rq del: buffer virtual addr is null\n");
- return;
- }
- kfree((void *)(uintptr_t)addr);
-}
-
-/**
- * Prototype : hinic5_cqm_share_recv_queue_delete
- * Description : The SRQ object is deleted. Delete only containers that are not
- * used by SRQ, that is, containers from the head to the tail.
- * The RQ releases containers that have been used by the RQ.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2016/2/2
- * Modification : Created function
- */
-void hinic5_cqm_share_recv_queue_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bitmap *bitmap = &hinic5_cqm_handle->toe_own_capability.srqc_bitmap;
- u32 index = common->index - hinic5_cqm_handle->toe_own_capability.toe_srqc_start_id;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
-
- /* 1. Wait for completion and ensure that all references to the QPC
- * are complete.
- */
- if (atomic_dec_and_test(&object->refcount) != 0)
- complete(&object->free);
- else
- hinic5_cqm_err(handle->dev_hdl, "Srq del: object is referred by others, has to wait for completion\n");
-
- wait_for_completion(&object->free);
- destroy_completion(&object->free);
- /* 2. The corresponding index in the bitmap is cleared. */
- hinic5_cqm_bitmap_free(bitmap, index, qinfo->index_count);
-
- /* 3. SRQC resource release */
- if (unlikely(common->q_ctx_vaddr == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR("Srq del: srqc kfree, context virtual addr is null\n");
- return;
- }
- kfree(common->q_ctx_vaddr);
-
- /* 4. The SRQ queue is released. */
- hinic5_cqm_container_free(common->head_container, NULL, &qinfo->common);
-}
-
-#define obj_intern_if_section
-
-/* include dynamic and static applications. */
-static u32 hinic5_cqm_general_bitmap_alloc(struct tag_hinic5_cqm_object *object,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_bitmap_range *bp_range,
- u32 xid, u32 count)
-{
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_func_capability *func_cap = &hinic5_cqm_handle->func_capability;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_bitmap *bitmap = &cla_table->bitmap;
- u32 index;
-
- if (HINIC5_CQM_DYNAMIC_XID_ALLOC_MODE(xid)) {
- if (HINIC5_CQM_DYNAMIC_XID_LB_MODE(xid) != HINIC5_CQM_XID_LOW_BIT_NONE ||
- HINIC5_CQM_DYNAMIC_XID_SEARCH_MODE(xid) != HINIC5_CQM_XID_SEARCH_ALL) {
- if (count > 1) {
- hinic5_cqm_warn(handle->dev_hdl, "Not support alloc multiple bits.\n");
- return HINIC5_CQM_INDEX_INVALID;
- }
- index = hinic5_cqm_bitmap_alloc_lowbits_align(bitmap, bp_range, hinic5_cqm_handle,
- xid, func_cap->xid_alloc_mode);
- } else {
- /* apply for an index normally */
- index = hinic5_cqm_bitmap_alloc(bitmap, 1U << (cla_table->z + 1),
- count, func_cap->xid_alloc_mode);
- }
-
- if (index >= bitmap->max_num - bitmap->reserved_back) {
- hinic5_cqm_warn(handle->dev_hdl,
- "cqm bitmap alloc, index is err. index:0x%x, max_num:0x%x, reserved_back:0x%x\n",
- index, bitmap->max_num, bitmap->reserved_back);
- return HINIC5_CQM_INDEX_INVALID;
- }
- } else {
- if ((IS_MASTER_HOST(handle)) && (hinic5_func_type((void *)handle) != TYPE_PPF) &&
- (hinic5_support_vroce((void *)handle, NULL))) {
- /* If PF is vroce control function, apply for index by xid */
- index = hinic5_cqm_bitmap_alloc_by_xid(bitmap, count, xid);
- } else {
- /* apply for index to be reserved */
- index = hinic5_cqm_bitmap_alloc_reserved(bitmap, count, xid);
- }
- if (index != xid) {
- hinic5_cqm_warn(handle->dev_hdl,
- "cqm bitmap alloc, index(0x%x) != xid(0x%x).\n",
- index, xid);
- return HINIC5_CQM_INDEX_INVALID;
- }
- }
-
- return index;
-}
-
-/**
- * Prototype : hinic5_cqm_qpc_mpt_bitmap_alloc
- * Description : Apply for index from the bitmap when creating QPC or MPT.
- * Input : struct tag_hinic5_cqm_object *object
- * struct tag_hinic5_cqm_cla_table *cla_table
- * struct tag_hinic5_cqm_bitmap_range *bp_range
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-static s32 hinic5_cqm_qpc_mpt_bitmap_alloc(struct tag_hinic5_cqm_object *object,
- struct tag_hinic5_cqm_cla_table *cla_table,
- struct tag_hinic5_cqm_bitmap_range *bp_range)
-{
- struct tag_hinic5_cqm_qpc_mpt *common = container_of(object, struct tag_hinic5_cqm_qpc_mpt, object);
- struct tag_hinic5_cqm_qpc_mpt_info *qpc_mpt_info = container_of(common,
- struct tag_hinic5_cqm_qpc_mpt_info,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 xid = qpc_mpt_info->common.xid;
-
- qpc_mpt_info->index_count =
- (ALIGN(object->object_size, cla_table->obj_size)) / cla_table->obj_size;
- qpc_mpt_info->common.xid = hinic5_cqm_general_bitmap_alloc(object, cla_table, bp_range,
- xid, qpc_mpt_info->index_count);
- if (qpc_mpt_info->common.xid == HINIC5_CQM_INDEX_INVALID) {
- hinic5_cqm_warn(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_general_bitmap_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_qpc_mpt_create
- * Description : Create QPC or MPT
- * Input : struct tag_hinic5_cqm_object *object
- * struct tag_hinic5_cqm_bitmap_range *bp_range
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_qpc_mpt_create(struct tag_hinic5_cqm_object *object, struct tag_hinic5_cqm_bitmap_range *bp_range)
-{
- struct tag_hinic5_cqm_qpc_mpt *common = container_of(object, struct tag_hinic5_cqm_qpc_mpt, object);
- struct tag_hinic5_cqm_qpc_mpt_info *qpc_mpt_info = container_of(common, struct tag_hinic5_cqm_qpc_mpt_info, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- bool is_lock_bh;
- u32 index, count;
-
- /* find the corresponding cla table */
- if (object->object_type == HINIC5_CQM_OBJECT_SERVICE_CTX) {
- cla_table = hinic5_cqm_cla_table_get(&hinic5_cqm_handle->bat_table, HINIC5_CQM_BAT_ENTRY_T_QPC);
- } else if (object->object_type == HINIC5_CQM_OBJECT_MPT) {
- cla_table = hinic5_cqm_cla_table_get(&hinic5_cqm_handle->bat_table, HINIC5_CQM_BAT_ENTRY_T_MPT);
- } else {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object->object_type));
- return HINIC5_CQM_FAIL;
- }
-
- if (unlikely(cla_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_table_get));
- return HINIC5_CQM_FAIL;
- }
-
- /* Bitmap applies for index. */
- if (hinic5_cqm_qpc_mpt_bitmap_alloc(object, cla_table, bp_range) == HINIC5_CQM_FAIL) {
- hinic5_cqm_warn(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_qpc_mpt_bitmap_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- bitmap = &cla_table->bitmap;
- index = qpc_mpt_info->common.xid;
- count = qpc_mpt_info->index_count;
-
- /* Find the trunk page from the BAT/CLA and allocate the buffer.
- * Ensure that the released buffer has been cleared.
- */
- if (!HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- /* The CLA memory of the Fake VF are holded by the parent
- * function, so the Fake VF can't get the memory. */
- qpc_mpt_info->common.vaddr = hinic5_cqm_cla_get(hinic5_cqm_handle, cla_table,
- index, count, &common->paddr);
-
- if (!qpc_mpt_info->common.vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_get));
- hinic5_cqm_err(handle->dev_hdl,
- "Qpc mpt init: qpc mpt vaddr is null, alloc_static=%d\n",
- cla_table->alloc_static);
- goto err1;
- }
- }
-
- /* Indexes are associated with objects, and FC is executed
- * in the interrupt context.
- */
- object_table = &cla_table->obj_table;
- is_lock_bh = (object->service_type != HINIC5_CQM_SERVICE_T_FC);
- if (hinic5_cqm_object_table_insert(hinic5_cqm_handle, object_table, index, object, is_lock_bh) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_object_table_insert));
- goto err2;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err2:
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, index, count);
-err1:
- hinic5_cqm_bitmap_free(bitmap, index, count);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_qpc_mpt_delete
- * Description : Delete QPC or MPT.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_qpc_mpt_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_qpc_mpt *common = container_of(object, struct tag_hinic5_cqm_qpc_mpt, object);
- struct tag_hinic5_cqm_qpc_mpt_info *qpc_mpt_info = container_of(common,
- struct tag_hinic5_cqm_qpc_mpt_info,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- u32 count = qpc_mpt_info->index_count;
- u32 index = qpc_mpt_info->common.xid;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_qpc_mpt_delete_cnt);
-
- /* find the corresponding cla table */
- if (object->object_type == HINIC5_CQM_OBJECT_SERVICE_CTX) {
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_QPC);
- } else if (object->object_type == HINIC5_CQM_OBJECT_MPT) {
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_MPT);
- } else {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(object->object_type));
- return;
- }
-
- if (unlikely(cla_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_table_get_qpc));
- return;
- }
-
- /* disassociate index and object */
- object_table = &cla_table->obj_table;
- if (object->service_type == HINIC5_CQM_SERVICE_T_FC)
- hinic5_cqm_object_table_remove(hinic5_cqm_handle, object_table, index, object,
- false);
- else
- hinic5_cqm_object_table_remove(hinic5_cqm_handle, object_table, index, object,
- true);
-
- /* wait for completion to ensure that all references to
- * the QPC are complete
- */
- if (atomic_dec_and_test(&object->refcount) != 0)
- complete(&object->free);
- else
- hinic5_cqm_err(handle->dev_hdl, "Qpc mpt del: object is referred by others, has to wait for completion\n");
-
- /* Static QPC allocation must be non-blocking.
- * Services ensure that the QPC is referenced
- * when the QPC is deleted. Roce and UB service
- * should depend on completion to avoid race condition.
- */
- if (!cla_table->alloc_static || object->service_type == HINIC5_CQM_SERVICE_T_ROCE ||
- object->service_type == HINIC5_CQM_SERVICE_T_UB)
- wait_for_completion(&object->free);
-
- /* VMware FC need explicitly deinit spin_lock in completion */
- destroy_completion(&object->free);
-
- /* release qpc buffer */
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, index, count);
-
- /* release the index to the bitmap */
- bitmap = &cla_table->bitmap;
- hinic5_cqm_bitmap_free(bitmap, index, count);
-}
-
-/**
- * Prototype : hinic5_cqm_linkwqe_fill
- * Description : Used to organize the queue buffer of non-RDMA services and
- * fill the link wqe.
- * Input : wqe_per_buf: Linkwqe is not included.
- * wqe_number: Linkwqe is not included.
- * tail: true - The linkwqe must be at the end of the page;
- * false - The linkwqe can be not at the end of the page.
- * Output : None
- * Return Value : void
- * 1.Date : 2015/6/15
- * Modification : Created function
- */
-static void hinic5_cqm_linkwqe_fill(struct tag_hinic5_cqm_buf *buf, u32 wqe_per_buf, u32 wqe_size,
- u32 wqe_number, bool tail, u8 link_mode)
-{
- struct tag_hinic5_cqm_linkwqe_128B *linkwqe = NULL;
- struct tag_hinic5_cqm_linkwqe *wqe = NULL;
- dma_addr_t addr;
- u8 *tmp = NULL;
- u8 *va = NULL;
- u32 i;
-
- /* The linkwqe of other buffer except the last buffer
- * is directly filled to the tail.
- */
- for (i = 0; i < buf->buf_number; i++) {
- va = (u8 *)(buf->buf_list[i].va);
-
- if (i != (buf->buf_number - 1)) {
- wqe = (struct tag_hinic5_cqm_linkwqe *)(va + (u32)(wqe_size * wqe_per_buf));
- wqe->wf = HINIC5_CQM_WQE_WF_LINK;
- wqe->ctrlsl = HINIC5_CQM_LINK_WQE_CTRLSL_VALUE;
- wqe->lp = HINIC5_CQM_LINK_WQE_LP_INVALID;
- /* The valid value of link wqe needs to be set to 1.
- * Each service ensures that o-bit=1 indicates that
- * link wqe is valid and o-bit=0 indicates that
- * link wqe is invalid.
- */
- wqe->o = HINIC5_CQM_LINK_WQE_OWNER_VALID;
- addr = buf->buf_list[(u32)(i + 1)].pa;
- wqe->next_page_gpa_h = HINIC5_CQM_ADDR_HI(addr);
- wqe->next_page_gpa_l = HINIC5_CQM_ADDR_LW(addr);
- } else { /* linkwqe special padding of the last buffer */
- if (tail) {
- /* must be filled at the end of the page */
- tmp = va + (u32)(wqe_size * wqe_per_buf);
- wqe = (struct tag_hinic5_cqm_linkwqe *)tmp;
- } else {
- /* The last linkwqe is filled
- * following the last wqe.
- */
- tmp = va + (u32)(wqe_size * (wqe_number - wqe_per_buf *
- (buf->buf_number - 1)));
- wqe = (struct tag_hinic5_cqm_linkwqe *)tmp;
- }
- wqe->wf = HINIC5_CQM_WQE_WF_LINK;
- wqe->ctrlsl = HINIC5_CQM_LINK_WQE_CTRLSL_VALUE;
-
- /* In link mode, the last link WQE is invalid;
- * In ring mode, the last link wqe is valid, pointing to
- * the home page, and the lp is set.
- */
- if (link_mode == HINIC5_CQM_QUEUE_LINK_MODE) {
- wqe->o = HINIC5_CQM_LINK_WQE_OWNER_INVALID;
- } else {
- /* The lp field of the last link_wqe is set to
- * 1, indicating that the meaning of the o-bit
- * is reversed.
- */
- wqe->lp = HINIC5_CQM_LINK_WQE_LP_VALID;
- wqe->o = HINIC5_CQM_LINK_WQE_OWNER_VALID;
- addr = buf->buf_list[0].pa;
- wqe->next_page_gpa_h = HINIC5_CQM_ADDR_HI(addr);
- wqe->next_page_gpa_l = HINIC5_CQM_ADDR_LW(addr);
- }
- }
-
- if (wqe_size == HINIC5_CQM_LINKWQE_128B) {
- /* After the B800 version, the WQE obit scheme is
- * changed. The 64B bits before and after the 128B WQE
- * need to be assigned a value:
- * ifoe the 63rd bit from the end of the last 64B is
- * obit;
- * toe the 157th bit from the end of the last 64B is
- * obit.
- */
- linkwqe = (struct tag_hinic5_cqm_linkwqe_128B *)(void *)wqe;
- linkwqe->second64B.third_16B.bs.toe_o = HINIC5_CQM_LINK_WQE_OWNER_VALID;
- linkwqe->second64B.forth_16B.bs.ifoe_o = HINIC5_CQM_LINK_WQE_OWNER_VALID;
-
- /* shift 2 bits by right to get length of dw(4B) */
- hinic5_cqm_swab32((u8 *)wqe, sizeof(struct tag_hinic5_cqm_linkwqe_128B) >> 2);
- } else {
- /* shift 2 bits by right to get length of dw(4B) */
- hinic5_cqm_swab32((u8 *)wqe, sizeof(struct tag_hinic5_cqm_linkwqe) >> 2);
- }
- }
-}
-
-static int hinic5_cqm_nonrdma_queue_ctx_create_scq(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- bool bh = false;
-
- /* find the corresponding cla table */
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SCQC);
- if (!cla_table) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(nonrdma_hinic5_cqm_cla_table_get));
- return HINIC5_CQM_FAIL;
- }
-
- /* bitmap applies for index */
- bitmap = &cla_table->bitmap;
- qinfo->index_count = (ALIGN(qinfo->q_ctx_size, cla_table->obj_size)) / cla_table->obj_size;
- qinfo->common.index = hinic5_cqm_bitmap_alloc(bitmap, 1U << (cla_table->z + 1),
- qinfo->index_count,
- hinic5_cqm_handle->func_capability.xid_alloc_mode);
- if (qinfo->common.index >= bitmap->max_num) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(nonrdma_hinic5_cqm_bitmap_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- /* find the trunk page from BAT/CLA and allocate the buffer */
- common->q_ctx_vaddr = hinic5_cqm_cla_get(hinic5_cqm_handle, cla_table, qinfo->common.index,
- qinfo->index_count, &common->q_ctx_paddr);
- if (!common->q_ctx_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(nonrdma_hinic5_cqm_cla_get_lock));
- hinic5_cqm_bitmap_free(bitmap, qinfo->common.index, qinfo->index_count);
- return HINIC5_CQM_FAIL;
- }
-
- /* index and object association */
- object_table = &cla_table->obj_table;
- bh = (object->service_type == HINIC5_CQM_SERVICE_T_FC) ? false : true;
- if (hinic5_cqm_object_table_insert(hinic5_cqm_handle, object_table, qinfo->common.index, object,
- bh) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(nonrdma_hinic5_cqm_object_table_insert));
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, qinfo->common.index, qinfo->index_count);
- hinic5_cqm_bitmap_free(bitmap, qinfo->common.index, qinfo->index_count);
-
- return HINIC5_CQM_FAIL;
- }
-
- return 0;
-}
-
-static s32 hinic5_cqm_nonrdma_queue_ctx_create(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 shift;
- int ret;
-
- if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- shift = hinic5_cqm_shift(qinfo->q_ctx_size);
- common->q_ctx_vaddr = hinic5_cqm_kmalloc_align(qinfo->q_ctx_size,
- GFP_KERNEL | __GFP_ZERO,
- (u16)shift);
- if (!common->q_ctx_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(q_ctx_vaddr));
- return HINIC5_CQM_FAIL;
- }
-
- common->q_ctx_paddr = dma_map_single(hinic5_cqm_handle->dev, common->q_ctx_vaddr,
- qinfo->q_ctx_size, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev, common->q_ctx_paddr) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(q_ctx_vaddr));
- hinic5_cqm_kfree_align(common->q_ctx_vaddr);
- common->q_ctx_vaddr = NULL;
- return HINIC5_CQM_FAIL;
- }
- } else if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- ret = hinic5_cqm_nonrdma_queue_ctx_create_scq(object);
- if (ret != 0)
- return ret;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static void hinic5_cqm_free_queue_header(struct tag_hinic5_cqm_queue *common, struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct hinic5_hwdev *handle)
-{
- dma_unmap_single(hinic5_cqm_handle->dev, common->q_header_paddr, sizeof(struct tag_hinic5_cqm_queue_header),
- DMA_BIDIRECTIONAL);
-
- hinic5_cqm_kfree_align(common->q_header_vaddr);
- common->q_header_vaddr = NULL;
-}
-
-static s32 hinic5_cqm_alloc_queue_header(struct tag_hinic5_cqm_queue *common, struct tag_hinic5_cqm_handle *hinic5_cqm_handle,
- struct hinic5_hwdev *handle)
-{
- common->q_header_vaddr = hinic5_cqm_kmalloc_align(sizeof(struct tag_hinic5_cqm_queue_header),
- GFP_KERNEL | __GFP_ZERO, HINIC5_CQM_QHEAD_ALIGN_ORDER);
- if (!common->q_header_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_ALLOC_FAIL(q_header_vaddr));
- return HINIC5_CQM_FAIL;
- }
-
- common->q_header_paddr = dma_map_single(hinic5_cqm_handle->dev, common->q_header_vaddr,
- sizeof(struct tag_hinic5_cqm_queue_header), DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev, common->q_header_paddr) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(q_header_vaddr));
- hinic5_cqm_kfree_align(common->q_header_vaddr);
- common->q_header_vaddr = NULL;
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-/**
- * Prototype : hinic5_cqm_nonrdma_queue_create
- * Description : Create a queue for non-RDMA services.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_nonrdma_queue_create(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_buf *q_room_buf = &common->q_room_buf_1;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- u32 wqe_number = qinfo->common.object.object_size;
- u32 wqe_size = qinfo->wqe_size;
- u32 order = hinic5_cqm_handle->service[object->service_type].buf_order;
- u32 buf_number, buf_size;
- bool tail = false; /* determine whether the linkwqe is at the end of the page */
-
- /* When creating a CQ/SCQ queue, the page size is 4 KB,
- * the linkwqe must be at the end of the page.
- */
- if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_EMBEDDED_CQ || object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- /* depth: 2^n-aligned; depth range: 256-32 K */
- if (wqe_number < HINIC5_CQM_CQ_DEPTH_MIN || wqe_number > HINIC5_CQM_CQ_DEPTH_MAX) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(wqe_number));
- return HINIC5_CQM_FAIL;
- }
- if (!hinic5_cqm_check_align(wqe_number)) {
- hinic5_cqm_err(handle->dev_hdl, "Nonrdma queue alloc: wqe_number is not align on 2^n\n");
- return HINIC5_CQM_FAIL;
- }
-
- order = HINIC5_CQM_4K_PAGE_ORDER; /* wqe page 4k */
- tail = true; /* The linkwqe must be at the end of the page. */
- buf_size = HINIC5_CQM_4K_PAGE_SIZE;
- } else {
- buf_size = (u32)(PAGE_SIZE << order);
- }
-
- /* Calculate the total number of buffers required,
- * -1 indicates that the link wqe in a buffer is deducted.
- */
- qinfo->wqe_per_buf = (buf_size / wqe_size) - 1;
- /* number of linkwqes that are included in the depth transferred
- * by the service
- */
- buf_number = ALIGN((wqe_size * wqe_number), buf_size) / buf_size;
-
- /* apply for buffer */
- q_room_buf->buf_number = buf_number;
- q_room_buf->buf_size = buf_size;
- q_room_buf->page_number = buf_number << order;
- if (hinic5_cqm_buf_alloc(hinic5_cqm_handle, q_room_buf, false) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc));
- return HINIC5_CQM_FAIL;
- }
- /* fill link wqe, wqe_number - buf_number is the number of wqe without
- * link wqe
- */
- hinic5_cqm_linkwqe_fill(q_room_buf, qinfo->wqe_per_buf, wqe_size, wqe_number - buf_number, tail, common->queue_link_mode);
-
- /* create queue header */
- if (hinic5_cqm_alloc_queue_header(common, hinic5_cqm_handle, handle) != HINIC5_CQM_SUCCESS) {
- goto err1;
- }
-
- /* create queue ctx */
- if (hinic5_cqm_nonrdma_queue_ctx_create(object) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_nonrdma_queue_ctx_create));
- goto err2;
- }
-
- return HINIC5_CQM_SUCCESS;
-
-err2:
- hinic5_cqm_free_queue_header(common, hinic5_cqm_handle, handle);
-err1:
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
- return HINIC5_CQM_FAIL;
-}
-
-/**
- * Prototype : hinic5_cqm_nonrdma_queue_delete
- * Description : Delete the queues of non-RDMA services.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_nonrdma_queue_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_nonrdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_nonrdma_qinfo, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct tag_hinic5_cqm_buf *q_room_buf = &common->q_room_buf_1;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- u32 index = qinfo->common.index;
- u32 count = qinfo->index_count;
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_nonrdma_queue_delete_cnt);
-
- /* The SCQ has an independent SCQN association. */
- if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SCQC);
- if (unlikely(cla_table == NULL)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_cla_table_get_queue));
- return;
- }
-
- /* disassociate index and object */
- object_table = &cla_table->obj_table;
- hinic5_cqm_object_table_remove(hinic5_cqm_handle, object_table, index, object, object->service_type != HINIC5_CQM_SERVICE_T_FC);
- }
-
- /* wait for completion to ensure that all references to
- * the QPC are complete
- */
- if (atomic_dec_and_test(&object->refcount) != 0)
- complete(&object->free);
- else
- hinic5_cqm_err(handle->dev_hdl, "Nonrdma queue del: object is referred by others, has to wait for completion\n");
-
- wait_for_completion(&object->free);
- destroy_completion(&object->free);
-
- /* If the q header exists, release. */
- if (qinfo->common.q_header_vaddr) {
- dma_unmap_single(hinic5_cqm_handle->dev, common->q_header_paddr, sizeof(struct tag_hinic5_cqm_queue_header),
- DMA_BIDIRECTIONAL);
-
- hinic5_cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
- }
-
- /* RQ deletion in TOE SRQ mode */
- if (common->queue_link_mode == HINIC5_CQM_QUEUE_TOE_SRQ_LINK_MODE)
- hinic5_cqm_srq_used_rq_delete(&common->object);
- else
- /* If q room exists, release. */
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
- /* SRQ and SCQ have independent CTXs and release. */
- if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SRQ) {
- /* The CTX of the SRQ of the nordma is
- * applied for independently.
- */
- if (common->q_ctx_vaddr) {
- dma_unmap_single(hinic5_cqm_handle->dev, common->q_ctx_paddr, qinfo->q_ctx_size, DMA_BIDIRECTIONAL);
-
- hinic5_cqm_kfree_align(common->q_ctx_vaddr);
- common->q_ctx_vaddr = NULL;
- }
- } else if (object->object_type == HINIC5_CQM_OBJECT_NONRDMA_SCQ) {
- /* The CTX of the SCQ of the nordma is managed by BAT/CLA. */
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, index, count);
-
- /* release the index to the bitmap */
- bitmap = &cla_table->bitmap;
- hinic5_cqm_bitmap_free(bitmap, index, count);
- }
-}
-
-static s32 hinic5_cqm_rdma_queue_ctx_create(struct tag_hinic5_cqm_object *object, struct tag_hinic5_cqm_bitmap_range *bp_range)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_rdma_qinfo, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
-
- if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ || object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ)
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SRQC);
- else
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SCQC);
-
- if (!cla_table) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(rdma_hinic5_cqm_cla_table_get));
- return HINIC5_CQM_FAIL;
- }
-
- qinfo->index_count = (ALIGN(qinfo->q_ctx_size, cla_table->obj_size)) / cla_table->obj_size;
- qinfo->common.index = hinic5_cqm_general_bitmap_alloc(object, cla_table, bp_range, qinfo->common.index,
- qinfo->index_count);
- if (qinfo->common.index == HINIC5_CQM_INDEX_INVALID) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_general_bitmap_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- /* bitmap applies for index */
- bitmap = &cla_table->bitmap;
-
- /* find the trunk page from BAT/CLA and allocate the buffer */
- if (!HINIC5_CQM_IS_FAKE_CHILD(hinic5_cqm_handle)) {
- /* The CLA memory of the Fake VF are holded by the parent
- * function, so the Fake VF can't get the memory. */
- qinfo->common.q_ctx_vaddr =
- hinic5_cqm_cla_get(hinic5_cqm_handle, cla_table, qinfo->common.index,
- qinfo->index_count, &qinfo->common.q_ctx_paddr);
- if (!qinfo->common.q_ctx_vaddr) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(rdma_hinic5_cqm_cla_get_lock));
- hinic5_cqm_bitmap_free(bitmap, qinfo->common.index, qinfo->index_count);
- return HINIC5_CQM_FAIL;
- }
- }
-
- /* associate index and object */
- object_table = &cla_table->obj_table;
- if (hinic5_cqm_object_table_insert(hinic5_cqm_handle, object_table, qinfo->common.index, object, true) != HINIC5_CQM_SUCCESS) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_FUNCTION_FAIL(rdma_hinic5_cqm_object_table_insert));
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, qinfo->common.index, qinfo->index_count);
- hinic5_cqm_bitmap_free(bitmap, qinfo->common.index, qinfo->index_count);
- return HINIC5_CQM_FAIL;
- }
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-static s32 hinic5_cqm_qinfo_judgment(struct tag_hinic5_cqm_rdma_qinfo *qinfo, struct tag_hinic5_cqm_buf *q_room_buf,
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle, struct hinic5_hwdev *handle)
-{
- if (hinic5_cqm_buf_alloc(hinic5_cqm_handle, q_room_buf, true) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc));
- return HINIC5_CQM_FAIL;
- }
-
- /* queue header */
- qinfo->common.q_header_vaddr =
- hinic5_cqm_kmalloc_align(sizeof(struct tag_hinic5_cqm_queue_header),
- GFP_KERNEL | __GFP_ZERO,
- HINIC5_CQM_QHEAD_ALIGN_ORDER);
- if (!qinfo->common.q_header_vaddr) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_ALLOC_FAIL(q_header_vaddr));
-
- if (qinfo->room_header_alloc)
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
-
- return HINIC5_CQM_FAIL;
- }
-
- qinfo->common.q_header_paddr =
- dma_map_single(hinic5_cqm_handle->dev,
- qinfo->common.q_header_vaddr,
- sizeof(struct tag_hinic5_cqm_queue_header),
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(hinic5_cqm_handle->dev,
- qinfo->common.q_header_paddr) != 0) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_MAP_FAIL(q_header_vaddr));
-
- if (qinfo->room_header_alloc) {
- hinic5_cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
- }
-
- if (qinfo->room_header_alloc)
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
-
- return HINIC5_CQM_FAIL;
- }
-
- return 0;
-}
-
-/**
- * Prototype : hinic5_cqm_rdma_queue_create
- * Description : Create rdma queue.
- * Input : struct tag_hinic5_cqm_object *object
- * : struct tag_hinic5_cqm_bitmap_range *bp_range
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_rdma_queue_create(struct tag_hinic5_cqm_object *object, struct tag_hinic5_cqm_bitmap_range *bp_range)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_rdma_qinfo,
- common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_service *service = hinic5_cqm_handle->service + object->service_type;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *q_room_buf = NULL;
- u32 order = service->buf_order;
- u32 buf_size = (u32)(PAGE_SIZE << order);
-
- if (qinfo->room_header_alloc) {
- /* apply for queue room buffer */
- if (qinfo->common.current_q_room == HINIC5_CQM_RDMA_Q_ROOM_1)
- q_room_buf = &qinfo->common.q_room_buf_1;
- else
- q_room_buf = &qinfo->common.q_room_buf_2;
-
- q_room_buf->buf_number = ALIGN(object->object_size, buf_size) /
- buf_size;
- q_room_buf->page_number = (q_room_buf->buf_number << order);
- q_room_buf->buf_size = buf_size;
-
- if (hinic5_cqm_qinfo_judgment(qinfo, q_room_buf, hinic5_cqm_handle, handle) == HINIC5_CQM_FAIL) {
- return HINIC5_CQM_FAIL;
- }
- }
-
- /* queue ctx */
- if (hinic5_cqm_rdma_queue_ctx_create(object, bp_range) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_rdma_queue_ctx_create));
-
- if (qinfo->room_header_alloc) {
- dma_unmap_single(hinic5_cqm_handle->dev, qinfo->common.q_header_paddr,
- sizeof(struct tag_hinic5_cqm_queue_header),
- DMA_BIDIRECTIONAL);
- }
-
- if (qinfo->room_header_alloc) {
- hinic5_cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
- }
-
- if (qinfo->room_header_alloc) {
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
- }
-
- return HINIC5_CQM_FAIL;
- }
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_rdma_queue_delete
- * Description : Create rdma queue.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_rdma_queue_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_queue *common = container_of(object, struct tag_hinic5_cqm_queue, object);
- struct tag_hinic5_cqm_rdma_qinfo *qinfo = container_of(common, struct tag_hinic5_cqm_rdma_qinfo, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle = (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct tag_hinic5_cqm_bat_table *bat_table = &hinic5_cqm_handle->bat_table;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_object_table *object_table = NULL;
- struct tag_hinic5_cqm_cla_table *cla_table = NULL;
- struct tag_hinic5_cqm_buf *q_room_buf = NULL;
- struct tag_hinic5_cqm_bitmap *bitmap = NULL;
- u32 index = qinfo->common.index;
- u32 count = qinfo->index_count;
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_rdma_queue_delete_cnt);
-
- q_room_buf = (qinfo->common.current_q_room == HINIC5_CQM_RDMA_Q_ROOM_1) ?
- &qinfo->common.q_room_buf_1 : &qinfo->common.q_room_buf_2;
-
- /* SCQ and SRQ are associated with independent SCQN and SRQN. */
- if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ || object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ) {
- if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SCQC);
- } else if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ) {
- cla_table = hinic5_cqm_cla_table_get(bat_table, HINIC5_CQM_BAT_ENTRY_T_SRQC);
- }
- if (unlikely(!cla_table)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_FUNCTION_FAIL
- (hinic5_cqm_cla_table_get));
- return;
- }
- /* disassociate index and object */
- object_table = &cla_table->obj_table;
- hinic5_cqm_object_table_remove(hinic5_cqm_handle, object_table,
- index, object, true);
- }
-
- /* wait for completion to make sure all references are complete */
- if (atomic_dec_and_test(&object->refcount) != 0)
- complete(&object->free);
- else
- hinic5_cqm_err(handle->dev_hdl, "Rdma queue del: object is referred by others, has to wait for completion\n");
-
- wait_for_completion(&object->free);
- destroy_completion(&object->free);
-
- /* If the q header exists, release. */
- if (qinfo->room_header_alloc && qinfo->common.q_header_vaddr) {
- dma_unmap_single(hinic5_cqm_handle->dev, qinfo->common.q_header_paddr,
- sizeof(struct tag_hinic5_cqm_queue_header), DMA_BIDIRECTIONAL);
-
- hinic5_cqm_kfree_align(qinfo->common.q_header_vaddr);
- qinfo->common.q_header_vaddr = NULL;
- }
-
- /* If q room exists, release. */
- hinic5_cqm_buf_free(q_room_buf, hinic5_cqm_handle->dev);
-
- /* SRQ and SCQ have independent CTX, released. */
- if (object->object_type == HINIC5_CQM_OBJECT_RDMA_SRQ ||
- object->object_type == HINIC5_CQM_OBJECT_RDMA_SCQ) {
- hinic5_cqm_cla_put(hinic5_cqm_handle, cla_table, index, count);
-
- /* release the index to the bitmap */
- bitmap = &cla_table->bitmap;
- hinic5_cqm_bitmap_free(bitmap, index, count);
- }
-}
-
-/**
- * Prototype : hinic5_cqm_rdma_table_create
- * Description : Create RDMA-related entries.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : s32
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-s32 hinic5_cqm_rdma_table_create(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_mtt_rdmarc *common =
- container_of(object, struct tag_hinic5_cqm_mtt_rdmarc, object);
- struct tag_hinic5_cqm_rdma_table *rdma_table =
- container_of(common, struct tag_hinic5_cqm_rdma_table, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle =
- (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *buf = &rdma_table->buf;
-
- /* Less than one page is allocated by actual size.
- * RDMARC also requires physical continuity.
- */
- if (object->object_size <= PAGE_SIZE ||
- object->object_type == HINIC5_CQM_OBJECT_RDMARC) {
- buf->buf_number = 1;
- buf->page_number = buf->buf_number;
- buf->buf_size = object->object_size;
- buf->direct.va = dma_alloc_coherent(hinic5_cqm_handle->dev, buf->buf_size,
- &buf->direct.pa, GFP_ATOMIC);
- if (unlikely(!buf->direct.va)) {
- HINIC5_CQM_PTR_CHECK_ERR(HINIC5_CQM_ALLOC_FAIL(direct));
- return HINIC5_CQM_FAIL;
- }
- } else { /* page-by-page alignment greater than one page */
- buf->buf_number = ALIGN(object->object_size, PAGE_SIZE) /
- PAGE_SIZE;
- buf->page_number = buf->buf_number;
- buf->buf_size = PAGE_SIZE;
- if (hinic5_cqm_buf_alloc(hinic5_cqm_handle, buf, true) == HINIC5_CQM_FAIL) {
- hinic5_cqm_err(handle->dev_hdl,
- HINIC5_CQM_FUNCTION_FAIL(hinic5_cqm_buf_alloc));
- return HINIC5_CQM_FAIL;
- }
- }
-
- rdma_table->common.vaddr = (u8 *)(buf->direct.va);
-
- return HINIC5_CQM_SUCCESS;
-}
-
-/**
- * Prototype : hinic5_cqm_rdma_table_delete
- * Description : Delete RDMA-related Entries.
- * Input : struct tag_hinic5_cqm_object *object
- * Output : None
- * Return Value : void
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-void hinic5_cqm_rdma_table_delete(struct tag_hinic5_cqm_object *object)
-{
- struct tag_hinic5_cqm_mtt_rdmarc *common =
- container_of(object, struct tag_hinic5_cqm_mtt_rdmarc, object);
- struct tag_hinic5_cqm_rdma_table *rdma_table =
- container_of(common, struct tag_hinic5_cqm_rdma_table, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle =
- (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *buf = &rdma_table->buf;
-
- atomic_inc(&handle->hw_stats.hinic5_cqm_stats.hinic5_cqm_rdma_table_delete_cnt);
-
- if (buf->buf_number == 1) {
- if (buf->direct.va) {
- dma_free_coherent(hinic5_cqm_handle->dev, buf->buf_size,
- buf->direct.va, buf->direct.pa);
- buf->direct.va = NULL;
- }
- } else {
- hinic5_cqm_buf_free(buf, hinic5_cqm_handle->dev);
- }
-}
-
-/**
- * Prototype : hinic5_cqm_rdma_table_offset_addr
- * Description : Obtain the address of the RDMA entry based on the offset.
- * The offset is the index.
- * Input : struct tag_hinic5_cqm_object *object
- * u32 offset
- * dma_addr_t *paddr
- * Output : None
- * Return Value : u8 *
- * 1.Date : 2015/4/15
- * Modification : Created function
- */
-u8 *hinic5_cqm_rdma_table_offset_addr(struct tag_hinic5_cqm_object *object, u32 offset, dma_addr_t *paddr)
-{
- struct tag_hinic5_cqm_mtt_rdmarc *common =
- container_of(object, struct tag_hinic5_cqm_mtt_rdmarc, object);
- struct tag_hinic5_cqm_rdma_table *rdma_table =
- container_of(common, struct tag_hinic5_cqm_rdma_table, common);
- struct tag_hinic5_cqm_handle *hinic5_cqm_handle =
- (struct tag_hinic5_cqm_handle *)object->hinic5_cqm_handle;
- struct hinic5_hwdev *handle = hinic5_cqm_handle->ex_handle;
- struct tag_hinic5_cqm_buf *buf = &rdma_table->buf;
- struct tag_hinic5_cqm_buf_list *buf_node = NULL;
- u32 buf_id, buf_offset;
-
- if (offset < rdma_table->common.index_base ||
- ((offset - rdma_table->common.index_base) >=
- rdma_table->common.index_number)) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(offset));
- return NULL;
- }
-
- if (buf->buf_number == 1) {
- buf_offset = (u32)((offset - rdma_table->common.index_base) *
- (sizeof(dma_addr_t)));
-
- *paddr = buf->direct.pa + buf_offset;
- return ((u8 *)(buf->direct.va)) + buf_offset;
- }
-
- buf_id = (offset - rdma_table->common.index_base) /
- (PAGE_SIZE / sizeof(dma_addr_t));
- buf_offset = (u32)((offset - rdma_table->common.index_base) -
- (buf_id * (PAGE_SIZE / sizeof(dma_addr_t))));
- buf_offset = (u32)(buf_offset * sizeof(dma_addr_t));
-
- if (buf_id >= buf->buf_number) {
- hinic5_cqm_err(handle->dev_hdl, HINIC5_CQM_WRONG_VALUE(buf_id));
- return NULL;
- }
- buf_node = buf->buf_list + buf_id;
- *paddr = buf_node->pa + buf_offset;
-
- return ((u8 *)(buf->direct.va)) +
- (offset - rdma_table->common.index_base) * (sizeof(dma_addr_t));
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.h
deleted file mode 100644
index a5650e18d..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_cqm/hinic5_cqm_object_intern.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cqm_object_intern.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_CQM_OBJECT_INTERN_H
-#define HINIC5_CQM_OBJECT_INTERN_H
-
-#include "ossl_knl.h"
-#include "hinic5_cqm_object.h"
-#include "hinic5_cqm_bitmap_table.h"
-
-#define HINIC5_CQM_CQ_DEPTH_MAX 32768
-#define HINIC5_CQM_CQ_DEPTH_MIN 256
-
-/* linkwqe */
-#define HINIC5_CQM_LINK_WQE_CTRLSL_VALUE 2
-#define HINIC5_CQM_LINK_WQE_LP_VALID 1
-#define HINIC5_CQM_LINK_WQE_LP_INVALID 0
-#define HINIC5_CQM_LINK_WQE_OWNER_VALID 1
-#define HINIC5_CQM_LINK_WQE_OWNER_INVALID 0
-
-#define HINIC5_CQM_ADDR_COMBINE(high_addr, low_addr) \
- ((((dma_addr_t)(high_addr)) << 32) + ((dma_addr_t)(low_addr)))
-#define HINIC5_CQM_ADDR_HI(addr) ((u32)((u64)(addr) >> 32))
-#define HINIC5_CQM_ADDR_LW(addr) ((u32)((u64)(addr) & 0xffffffff))
-
-#define HINIC5_CQM_QPC_LAYOUT_TABLE_SIZE 16
-
-/* cla bitmap */
-#define HINIC5_CQM_DYNAMIC_XID_LOW_BIT_MASK(lb_mode) \
- ((~(lb_mode)) & HINIC5_CQM_XID_LOW_BITS_MASK)
-
-#define HINIC5_CQM_DYNAMIC_XID_ALLOC_MODE(xid) \
- (((xid) & HINIC5_CQM_DYNAMIC_XID_MASK) == HINIC5_CQM_DYNAMIC_XID_MASK)
-#define HINIC5_CQM_DYNAMIC_XID_LB_MODE(xid) \
- (((xid) >> HINIC5_CQM_XID_LB_MODE_SHIFT) & HINIC5_CQM_XID_LB_MODE_MASK)
-#define HINIC5_CQM_DYNAMIC_XID_LOW_BITS(xid) \
- (((xid) >> HINIC5_CQM_XID_LOW_BITS_SHIFT) & HINIC5_CQM_XID_LOW_BITS_MASK)
-#define HINIC5_CQM_DYNAMIC_XID_SEARCH_MODE(xid) \
- (((xid) >> HINIC5_CQM_XID_SEARCH_MODE_SHIFT) & HINIC5_CQM_XID_SEARCH_MODE_MASK)
-
-#define HINIC5_CQM_BP_RANGE_VALID(start, end, min_index, max_index) \
- (((start) >= (min_index)) && ((start) <= (max_index)) && \
- ((end) >= (min_index)) && ((end) <= (max_index)) && ((start) != (end)))
-
-struct tag_hinic5_cqm_qpc_layout_table_node {
- u32 type;
- u32 size;
- u32 offset;
- struct tag_hinic5_cqm_object *object;
-};
-
-struct tag_hinic5_cqm_qpc_mpt_info {
- struct tag_hinic5_cqm_qpc_mpt common;
- /* Different service has different QPC.
- * The large QPC/mpt will occupy some continuous indexes in bitmap.
- */
- u32 index_count;
- struct tag_hinic5_cqm_qpc_layout_table_node
- qpc_layout_table[HINIC5_CQM_QPC_LAYOUT_TABLE_SIZE];
-};
-
-struct tag_hinic5_cqm_nonrdma_qinfo {
- struct tag_hinic5_cqm_queue common;
- u32 wqe_size;
- /* Number of WQEs in each buffer (excluding link WQEs)
- * For SRQ, the value is the number of WQEs contained in a container.
- */
- u32 wqe_per_buf;
- u32 q_ctx_size;
- /* When different services use CTXs of different sizes,
- * a large CTX occupies multiple consecutive indexes in the bitmap.
- */
- u32 index_count;
-
- /* add for srq */
- u32 container_size;
-};
-
-struct tag_hinic5_cqm_rdma_qinfo {
- struct tag_hinic5_cqm_queue common;
- bool room_header_alloc;
- /* This field is used to temporarily record the new object_size during
- * CQ resize.
- */
- u32 new_object_size;
- u32 q_ctx_size;
- /* When different services use CTXs of different sizes,
- * a large CTX occupies multiple consecutive indexes in the bitmap.
- */
- u32 index_count;
-};
-
-struct tag_hinic5_cqm_rdma_table {
- struct tag_hinic5_cqm_mtt_rdmarc common;
- struct tag_hinic5_cqm_buf buf;
-};
-
-void hinic5_cqm_container_free(u8 *srq_head_container, u8 *srq_tail_container,
- struct tag_hinic5_cqm_queue *common);
-s32 hinic5_cqm_container_create(struct tag_hinic5_cqm_object *object,
- u8 **container_addr, bool link);
-s32 hinic5_cqm_share_recv_queue_create(struct tag_hinic5_cqm_object *object);
-void hinic5_cqm_share_recv_queue_delete(struct tag_hinic5_cqm_object *object);
-s32 hinic5_cqm_qpc_mpt_create(struct tag_hinic5_cqm_object *object,
- struct tag_hinic5_cqm_bitmap_range *bp_range);
-void hinic5_cqm_qpc_mpt_delete(struct tag_hinic5_cqm_object *object);
-s32 hinic5_cqm_nonrdma_queue_create(struct tag_hinic5_cqm_object *object);
-void hinic5_cqm_nonrdma_queue_delete(struct tag_hinic5_cqm_object *object);
-s32 hinic5_cqm_rdma_queue_create(struct tag_hinic5_cqm_object *object,
- struct tag_hinic5_cqm_bitmap_range *bp_range);
-void hinic5_cqm_rdma_queue_delete(struct tag_hinic5_cqm_object *object);
-s32 hinic5_cqm_rdma_table_create(struct tag_hinic5_cqm_object *object);
-void hinic5_cqm_rdma_table_delete(struct tag_hinic5_cqm_object *object);
-u8 *hinic5_cqm_rdma_table_offset_addr(struct tag_hinic5_cqm_object *object,
- u32 offset, dma_addr_t *paddr);
-
-#endif /* HINIC5_CQM_OBJECT_INTERN_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_hinic5_vram.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_hinic5_vram.c
deleted file mode 100644
index 055547a3e..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_hinic5_vram.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hinic5_vram.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : hinic5_hinic5_vram.c
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/async.h>
-
-#include "ossl_knl.h"
-#include "hinic5_typedef_inner.h"
-#include "hinic5_mt.h"
-#include "hinic5_hwdev.h"
-#include "hinic5_common.h"
-#include "hinic5_crm.h"
-#include "hinic5_sriov.h"
-#include "hinic5_dev_mgmt.h"
-#include "hinic5_nictool.h"
-#include "hinic5_hw.h"
-
-#include "hinic5_vram_common.h"
-#include "hinic5_hinic5_vram.h"
-
-static ASYNC_DOMAIN_EXCLUSIVE(g_hiudk_async_domain);
-static hiudk_async_ctrl g_hiudk_async_ctrl;
-
-int hiudk5_register_flush_fn(void *lld_dev, hiudk_flush_fn fn)
-{
- int i;
- int cur_idx = -1;
-
- if (!lld_dev) {
- pr_err("Sdk: register flush function para is null.\n");
- return -ENODEV;
- }
-
- spin_lock(&g_hiudk_async_ctrl.lock);
-
- for (i = CMD_MAX_MAX_PF_NUM - 1; i >= 0; i--) {
- if (!g_hiudk_async_ctrl.flush_infos[i].lld_dev) {
- cur_idx = i;
- break;
- }
- }
-
- if (cur_idx == -1) {
- spin_unlock(&g_hiudk_async_ctrl.lock);
- pr_err("Sdk: register flush function failed, no available async crtl info.\n");
- return -ENOMEM;
- }
-
- g_hiudk_async_ctrl.flush_infos[cur_idx].lld_dev = lld_dev;
- g_hiudk_async_ctrl.flush_infos[cur_idx].flush_ops = fn;
- g_hiudk_async_ctrl.flush_infos[cur_idx].ret = 0;
-
- spin_unlock(&g_hiudk_async_ctrl.lock);
-
- return 0;
-}
-EXPORT_SYMBOL(hiudk5_register_flush_fn);
-
-int hiudk5_unregister_flush_fn(void *lld_dev)
-{
- int i;
-
- if (!lld_dev) {
- pr_err("Sdk: unregister flush function para is null.\n");
- return -ENODEV;
- }
-
- spin_lock(&g_hiudk_async_ctrl.lock);
-
- for (i = CMD_MAX_MAX_PF_NUM - 1; i >= 0; i--) {
- if (lld_dev == g_hiudk_async_ctrl.flush_infos[i].lld_dev) {
- g_hiudk_async_ctrl.flush_infos[i].lld_dev = NULL;
- g_hiudk_async_ctrl.flush_infos[i].flush_ops = NULL;
- g_hiudk_async_ctrl.flush_infos[i].ret = 0;
-
- spin_unlock(&g_hiudk_async_ctrl.lock);
- return 0;
- }
- }
-
- spin_unlock(&g_hiudk_async_ctrl.lock);
-
- return -ENODEV;
-}
-EXPORT_SYMBOL(hiudk5_unregister_flush_fn);
-
-void hinic5_flush_dev(void *priv_data, async_cookie_t cookie)
-{
- hiudk_dev_flush_infos *cur_dev = priv_data;
-
- if (!cur_dev->lld_dev || !cur_dev->flush_ops)
- return;
-
- cur_dev->ret = cur_dev->flush_ops(cur_dev->lld_dev);
-}
-
-STATIC int hisdk5_notify_flush_dev(struct notifier_block *nb,
- unsigned long action,
- void *data)
-{
- int i;
-
- rtnl_lock();
-
- for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
- if (g_hiudk_async_ctrl.flush_infos[i].lld_dev)
- async_schedule_domain(hinic5_flush_dev,
- &g_hiudk_async_ctrl.flush_infos[i],
- &g_hiudk_async_domain);
-
- rtnl_unlock();
-
- return 0;
-}
-
-STATIC int hiudk_os_hotreplace_msg_to_mpu(u8 replace_flag)
-{
- int ret;
- void *dev = NULL;
-
- dev = hinic5_get_ppf_dev();
- if (!dev) {
- pr_err("Get ppf dev failed before os hotreplace.\n");
- return -ENXIO;
- }
-
- ret = hinic5_set_ppf_tbl_hotreplace_flag(dev, replace_flag);
- if (ret != 0) {
- pr_err("Send mbox to mpu failed in hiudk, ret:%d, flag:%u.\n", ret, replace_flag);
- return ret;
- }
-
- return 0;
-}
-
-STATIC int hiudk_notify_pre_update(struct notifier_block *nb,
- unsigned long action,
- void *data)
-{
- int ret;
-
- pr_info("Set driver flag and mpu flag before os hotreplace.\n");
- // set kexec status set to 1, indicate doing kexec
- ret = hinic5_set_kexec_status(1);
- if (ret != 0) {
- pr_err("Set kexec flag failed before os hotreplace.\n");
- return ret;
- }
-
- ret = hiudk_os_hotreplace_msg_to_mpu(MPU_OS_HOTREPLACE_FLAG);
- if (ret != 0) {
- pr_err("Send mbox to mpu failed before os hotreplace.\n");
- return ret;
- }
-
- return 0;
-}
-
-STATIC int hiudk_notify_post_update(struct notifier_block *nb,
- unsigned long action,
- void *data)
-{
- int ret;
-
- pr_info("Clear driver flag and mpu flag after os hotreplace.\n");
- // set kexec status set to 0, indicate kexec done
- ret = hinic5_set_kexec_status(0);
- if (ret != 0) {
- pr_err("Set kexec flag failed after os hotreplace.\n");
- return ret;
- }
-
- ret = hiudk_os_hotreplace_msg_to_mpu(0);
- if (ret != 0) {
- pr_err("Send mbox to mpu failed after os hotreplace.\n");
- return ret;
- }
-
- return 0;
-}
-
-int hinic5_wait_for_devices_flush(struct notifier_block *nb,
- unsigned long action,
- void *data)
-{
- int i;
- int ret = 0;
-
- async_synchronize_full_domain(&g_hiudk_async_domain);
-
- for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
- if (g_hiudk_async_ctrl.flush_infos[i].ret != 0) {
- ret = g_hiudk_async_ctrl.flush_infos[i].ret;
- pr_err("Sdk: wait netdev[%d] flush done error, ret:%d.\n", i, ret);
- return ret;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL(hinic5_wait_for_devices_flush);
-
-static struct notifier_block hiudk_notifier_pre_update = {
- .notifier_call = hiudk_notify_pre_update,
- .next = NULL,
- .priority = 0
-};
-
-static struct notifier_block hisdk5_notifier_flush_dev = {
- .notifier_call = hisdk5_notify_flush_dev,
- .next = NULL,
- .priority = 0
-};
-
-static struct notifier_block hisdk5_notifier_wait_flush_done = {
- .notifier_call = hinic5_wait_for_devices_flush,
- .next = NULL,
- .priority = 0
-};
-
-static struct notifier_block hiudk_notifier_post_update = {
- .notifier_call = hiudk_notify_post_update,
- .next = NULL,
- .priority = 0
-};
-
-int hisdk5_hinic5_vram_init(void)
-{
- int err;
-
- spin_lock_init(&g_hiudk_async_ctrl.lock);
- lookup_hinic5_vram_related_symbols();
-
- err = hinic5_get_kexec_status();
- if (err != 0) {
- pr_err("Get in kexec status failed, err: %d\n", err);
- goto get_kexec_status_err;
- }
-
- err = hi_register_nvwa_notifier(PRE_UPDATE_KERNEL, &hiudk_notifier_pre_update);
- if (err != 0) {
- pr_err("Register nvwa pre update failed, err: %d\n", err);
- goto register_pre_update_nvwa_err;
- }
-
- err = hi_register_nvwa_notifier(POST_UPDATE_KERNEL, &hiudk_notifier_post_update);
- if (err != 0) {
- pr_err("Register nvwa post update failed, err: %d\n", err);
- goto register_post_update_nvwa_err;
- }
-
- err = hi_register_nvwa_notifier(FLUSH_DURING_KUP, &hisdk5_notifier_flush_dev);
- if (err != 0) {
- pr_err("Register nvwa flush device failed, err: %d\n", err);
- goto register_flush_dev_err;
- }
-
- err = hi_register_euleros_reboot_notifier(&hisdk5_notifier_wait_flush_done);
- if (err != 0) {
- pr_err("Register wait flush device notify failed, err: %d\n", err);
- goto register_reboot_err;
- }
-
- return 0;
-
-register_reboot_err:
- (void)hi_unregister_nvwa_notifier(FLUSH_DURING_KUP, &hisdk5_notifier_flush_dev);
-register_flush_dev_err:
- (void)hi_unregister_nvwa_notifier(POST_UPDATE_KERNEL, &hiudk_notifier_post_update);
-register_post_update_nvwa_err:
- (void)hi_unregister_nvwa_notifier(PRE_UPDATE_KERNEL, &hiudk_notifier_pre_update);
-register_pre_update_nvwa_err:
-get_kexec_status_err:
- spin_lock_deinit(&g_hiudk_async_ctrl.lock);
- return err;
-}
-
-void hisdk5_hinic5_vram_deinit(void)
-{
- (void)hi_unregister_euleros_reboot_notifier(&hisdk5_notifier_wait_flush_done);
- (void)hi_unregister_nvwa_notifier(FLUSH_DURING_KUP, &hisdk5_notifier_flush_dev);
- (void)hi_unregister_nvwa_notifier(POST_UPDATE_KERNEL, &hiudk_notifier_pre_update);
- (void)hi_unregister_nvwa_notifier(PRE_UPDATE_KERNEL, &hiudk_notifier_post_update);
-
- spin_lock_deinit(&g_hiudk_async_ctrl.lock);
-}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_vram_common.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_vram_common.c
deleted file mode 100644
index 95eb2a915..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hinic5_vram/hinic5_vram_common.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_vram_common.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Header File, hinic5_vram common
- */
-
-#include <linux/kallsyms.h>
-#include <linux/errno.h>
-#include <linux/version.h>
-
-#include "ossl_knl.h"
-#include "hinic5_typedef_inner.h"
-#include "hinic5_hinic5_vram_api.h"
-#include "hinic5_vram_common.h"
-
-#ifndef __UEFI__
-
-static int g_use_hinic5_vram;
-static int g_hinic5_in_kexec;
-
-STATIC register_nvwa_notifier_t _register_nvwa_notifier;
-STATIC unregister_nvwa_notifier_t _unregister_nvwa_notifier;
-STATIC register_euleros_reboot_notifier_t _register_euleros_reboot_notifier;
-STATIC unregister_euleros_reboot_notifier_t _unregister_euleros_reboot_notifier;
-STATIC hinic5_vram_kalloc_t _hinic5_vram_kalloc;
-STATIC vpmem_kalloc_node_t _hinic5_vram_kalloc_node;
-STATIC hinic5_vram_kfree_t _hinic5_vram_kfree;
-STATIC hinic5_vram_get_gfp_hinic5_vram_t _hinic5_vram_get_gfp_hinic5_vram;
-
-int hi_register_nvwa_notifier(int hook, struct notifier_block *nb)
-{
- if (_register_nvwa_notifier)
- return _register_nvwa_notifier(hook, nb);
-
- return -EINVAL;
-}
-
-int hi_unregister_nvwa_notifier(int hook, struct notifier_block *nb)
-{
- if (_unregister_nvwa_notifier)
- return _unregister_nvwa_notifier(hook, nb);
-
- return -EINVAL;
-}
-
-int hi_register_euleros_reboot_notifier(struct notifier_block *nb)
-{
- if (_register_euleros_reboot_notifier)
- return _register_euleros_reboot_notifier(nb);
-
- return -EINVAL;
-}
-
-int hi_unregister_euleros_reboot_notifier(struct notifier_block *nb)
-{
- if (_unregister_euleros_reboot_notifier)
- return _unregister_euleros_reboot_notifier(nb);
-
- return -EINVAL;
-}
-
-void __iomem *hinic5_hinic5_vram_kalloc(char *name, u64 size)
-{
- if (_hinic5_vram_kalloc && strnlen(name, HINIC5_VRAM_NAME_SIZE) < HINIC5_VRAM_NAME_SIZE)
- return _hinic5_vram_kalloc(name, size);
-
- return NULL;
-}
-EXPORT_SYMBOL(hinic5_hinic5_vram_kalloc);
-
-void __iomem *hinic5_hinic5_vram_kalloc_node(char *name, u64 size, u8 numa)
-{
- if (_hinic5_vram_kalloc_node &&
- strnlen(name, HINIC5_VRAM_NAME_SIZE) < HINIC5_VRAM_NAME_SIZE) {
- if (numa == HINIC5_VRAM_AFFINITY_NUMA || numa == HINIC5_VRAM_NO_NUMA)
- return _hinic5_vram_kalloc_node(name, size, numa);
- return _hinic5_vram_kalloc_node(name, size,
- numa >= nr_node_ids ? HINIC5_VRAM_NO_NUMA : numa);
- } else {
- return hinic5_hinic5_vram_kalloc(name, size);
- }
-}
-EXPORT_SYMBOL(hinic5_hinic5_vram_kalloc_node);
-
-void hinic5_hinic5_vram_kfree(void __iomem *vaddr, char *name, u64 size)
-{
- if (_hinic5_vram_kfree && vaddr &&
- strnlen(name, HINIC5_VRAM_NAME_SIZE) < HINIC5_VRAM_NAME_SIZE)
- _hinic5_vram_kfree(vaddr, name, size);
-}
-EXPORT_SYMBOL(hinic5_hinic5_vram_kfree);
-
-gfp_t hinic5_hinic5_vram_get_gfp_hinic5_vram(void)
-{
- if (_hinic5_vram_get_gfp_hinic5_vram)
- return _hinic5_vram_get_gfp_hinic5_vram();
- return 0;
-}
-EXPORT_SYMBOL(hinic5_hinic5_vram_get_gfp_hinic5_vram);
-
-void lookup_hinic5_vram_related_symbols(void)
-{
-#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
- _register_nvwa_notifier = (register_nvwa_notifier_t)
- kallsyms_lookup_name("register_nvwa_notifier");
-
- _unregister_nvwa_notifier = (unregister_nvwa_notifier_t)
- kallsyms_lookup_name("unregister_nvwa_notifier");
-
- _register_euleros_reboot_notifier = (register_euleros_reboot_notifier_t)
- kallsyms_lookup_name("register_euleros_reboot_notifier");
-
- _unregister_euleros_reboot_notifier = (unregister_euleros_reboot_notifier_t)
- kallsyms_lookup_name("unregister_euleros_reboot_notifier");
-
- _hinic5_vram_kalloc = (hinic5_vram_kalloc_t)
- kallsyms_lookup_name("hinic5_vram_kalloc");
-
- _hinic5_vram_kalloc_node = (vpmem_kalloc_node_t)
- kallsyms_lookup_name("vpmem_kalloc_node");
-
- _hinic5_vram_kfree = (hinic5_vram_kfree_t)
- kallsyms_lookup_name("hinic5_vram_kfree");
-
- _hinic5_vram_get_gfp_hinic5_vram = (hinic5_vram_get_gfp_hinic5_vram_t)
- kallsyms_lookup_name("hinic5_vram_get_hinic5_vram_gfp_t");
-#else
-/* only EulerOS and HCE have kallsyms_lookup_name_wrap */
-#if (defined(OS_EULER) || defined(OS_HCE))
- _register_nvwa_notifier = (register_nvwa_notifier_t)
- kallsyms_lookup_name_wrap("register_nvwa_notifier");
-
- _unregister_nvwa_notifier = (unregister_nvwa_notifier_t)
- kallsyms_lookup_name_wrap("unregister_nvwa_notifier");
-
- _register_euleros_reboot_notifier = (register_euleros_reboot_notifier_t)
- kallsyms_lookup_name_wrap("register_euleros_reboot_notifier");
-
- _unregister_euleros_reboot_notifier = (unregister_euleros_reboot_notifier_t)
- kallsyms_lookup_name_wrap("unregister_euleros_reboot_notifier");
-
- _hinic5_vram_kalloc = (hinic5_vram_kalloc_t)
- kallsyms_lookup_name_wrap("hinic5_vram_kalloc");
-
- _hinic5_vram_kalloc_node = (vpmem_kalloc_node_t)
- kallsyms_lookup_name_wrap("vpmem_kalloc_node");
-
- _hinic5_vram_kfree = (hinic5_vram_kfree_t)
- kallsyms_lookup_name_wrap("hinic5_vram_kfree");
-
- _hinic5_vram_get_gfp_hinic5_vram = (hinic5_vram_get_gfp_hinic5_vram_t)
- kallsyms_lookup_name_wrap("hinic5_vram_get_hinic5_vram_gfp_t");
-#endif
-#endif
-}
-EXPORT_SYMBOL(lookup_hinic5_vram_related_symbols);
-
-int hinic5_set_kexec_status(int status)
-{
- int *kexec_status_addr = NULL;
-
- kexec_status_addr = hinic5_hinic5_vram_kalloc(KEXEC_SIGN, HINIC5_VRAM_BLOCK_SIZE_2M);
- if (!kexec_status_addr) {
- pr_err("set kexec status hinic5_vram kalloc failed.\n");
- return -ENOMEM;
- }
-
- *kexec_status_addr = status;
- g_hinic5_in_kexec = *kexec_status_addr;
-
- return 0;
-}
-EXPORT_SYMBOL(hinic5_set_kexec_status);
-
-int hinic5_get_kexec_status(void)
-{
- int *kexec_status_addr = NULL;
-
- kexec_status_addr = hinic5_hinic5_vram_kalloc(KEXEC_SIGN, HINIC5_VRAM_BLOCK_SIZE_2M);
- if (!kexec_status_addr) {
- pr_err("get kexec status hinic5_vram kalloc failed.\n");
- return -ENOMEM;
- }
-
- g_hinic5_in_kexec = *kexec_status_addr;
- hinic5_hinic5_vram_kfree((void *)kexec_status_addr, KEXEC_SIGN, HINIC5_VRAM_BLOCK_SIZE_2M);
-
- return 0;
-}
-EXPORT_SYMBOL(hinic5_get_kexec_status);
-
-int get_use_hinic5_vram_flag(void)
-{
- return g_use_hinic5_vram;
-}
-EXPORT_SYMBOL(get_use_hinic5_vram_flag);
-
-void set_use_hinic5_vram_flag(bool flag)
-{
- g_use_hinic5_vram = flag;
-}
-EXPORT_SYMBOL(set_use_hinic5_vram_flag);
-
-int hinic5_vram_get_kexec_flag(void)
-{
- return g_hinic5_in_kexec;
-}
-EXPORT_SYMBOL(hinic5_vram_get_kexec_flag);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_api_cmd.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_api_cmd.c
index d4c9c076c..5b9e66bf1 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_api_cmd.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_api_cmd.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -26,46 +19,46 @@
#include "hinic5_common.h"
#include "hinic5_hwdev.h"
#include "hinic5_csr_inner.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_api_cmd.h"
-#define API_CMD_CHAIN_CELL_SIZE_SHIFT 6U
+#define API_CMD_CHAIN_CELL_SIZE_SHIFT 6U
-#define API_CMD_CELL_DESC_SIZE 8
-#define API_CMD_CELL_DATA_ADDR_SIZE 8
+#define API_CMD_CELL_DESC_SIZE 8
+#define API_CMD_CELL_DATA_ADDR_SIZE 8
-#define API_CHAIN_NUM_CELLS 32
-#define API_CHAIN_CELL_SIZE 128
-#define API_CHAIN_RSP_DATA_SIZE 128
+#define API_CHAIN_NUM_CELLS 32
+#define API_CHAIN_CELL_SIZE 128
+#define API_CHAIN_RSP_DATA_SIZE 128
-#define API_CMD_CELL_WB_ADDR_SIZE 8
+#define API_CMD_CELL_WB_ADDR_SIZE 8
-#define API_CHAIN_CELL_ALIGNMENT 8
+#define API_CHAIN_CELL_ALIGNMENT 8
-#define API_CMD_TIMEOUT 10000
-#define API_CMD_STATUS_TIMEOUT 10000
+#define API_CMD_TIMEOUT 10000
+#define API_CMD_STATUS_TIMEOUT 10000
-#define API_CMD_BUF_SIZE 2048ULL
+#define API_CMD_BUF_SIZE 2048ULL
-#define API_CMD_NODE_ALIGN_SIZE 512ULL
-#define API_PAYLOAD_ALIGN_SIZE 64ULL
+#define API_CMD_NODE_ALIGN_SIZE 512ULL
+#define API_PAYLOAD_ALIGN_SIZE 64ULL
-#define API_CHAIN_RESP_ALIGNMENT 128ULL
+#define API_CHAIN_RESP_ALIGNMENT 128ULL
-#define POLLING_COMPLETION_TIMEOUT_DEFAULT 1000U
+#define POLLING_COMPLETION_TIMEOUT_DEFAULT 1000U
-#define API_CMD_RESPONSE_DATA_PADDR(val) be64_to_cpu(*((u64 *)(val)))
+#define API_CMD_RESPONSE_DATA_PADDR(val) be64_to_cpu(*((u64 *)(val)))
-#define READ_API_CMD_PRIV_DATA(id, token) ((((u32)(id)) << 16) + (token))
-#define WRITE_API_CMD_PRIV_DATA(id) (((u8)(id)) << 16)
+#define READ_API_CMD_PRIV_DATA(id, token) ((((u32)(id)) << 16) + (token))
+#define WRITE_API_CMD_PRIV_DATA(id) (((u8)(id)) << 16)
-#define MASKED_IDX(chain, idx) ((idx) & ((chain)->num_cells - 1))
+#define MASKED_IDX(chain, idx) ((idx) & ((chain)->num_cells - 1))
-#define SIZE_4BYTES(size) (ALIGN((u32)(size), 4U) >> 2)
-#define SIZE_8BYTES(size) (ALIGN((u32)(size), 8U) >> 3)
+#define SIZE_4BYTES(size) (ALIGN((u32)(size), 4U) >> 2)
+#define SIZE_8BYTES(size) (ALIGN((u32)(size), 8U) >> 3)
enum api_cmd_data_format {
- SGL_DATA = 1,
+ SGL_DATA = 1,
};
enum api_cmd_type {
@@ -80,7 +73,7 @@ enum api_cmd_bypass {
enum api_cmd_resp_aeq {
NOT_TRIGGER = 0,
- TRIGGER = 1,
+ TRIGGER = 1,
};
enum api_cmd_chn_code {
@@ -111,7 +104,8 @@ static void set_prod_idx(struct hinic5_api_cmd_chain *chain)
{
enum hinic5_api_cmd_chain_type chain_type = chain->chain_type;
struct hinic5_hwif *hwif = chain->hwdev->hwif;
- u32 hw_prod_idx_addr = HINIC5_CSR_API_CMD_CHAIN_PI_ADDR((u32)chain_type);
+ u32 hw_prod_idx_addr =
+ HINIC5_CSR_API_CMD_CHAIN_PI_ADDR((u32)chain_type);
u32 prod_idx = chain->prod_idx;
hinic5_hwif_write_reg(hwif, hw_prod_idx_addr, prod_idx);
@@ -122,7 +116,7 @@ static u32 get_hw_cons_idx(struct hinic5_api_cmd_chain *chain)
u32 addr, val;
addr = HINIC5_CSR_API_CMD_STATUS_0_ADDR((u32)chain->chain_type);
- val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
+ val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
return HINIC5_API_CMD_STATUS_GET(val, CONS_IDX);
}
@@ -137,9 +131,10 @@ static void dump_api_chain_reg(struct hinic5_api_cmd_chain *chain)
#endif
addr = HINIC5_CSR_API_CMD_STATUS_0_ADDR((u32)chain->chain_type);
- val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
+ val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
- sdk_err(dev, "Chain type: 0x%x, cpld error: 0x%x, check error: 0x%x, current fsm: 0x%x\n",
+ sdk_err(dev,
+ "Chain type: 0x%x, cpld error: 0x%x, check error: 0x%x, current fsm: 0x%x\n",
chain->chain_type, HINIC5_API_CMD_STATUS_GET(val, CPLD_ERR),
HINIC5_API_CMD_STATUS_GET(val, CHKSUM_ERR),
HINIC5_API_CMD_STATUS_GET(val, FSM));
@@ -148,7 +143,7 @@ static void dump_api_chain_reg(struct hinic5_api_cmd_chain *chain)
HINIC5_API_CMD_STATUS_GET(val, CONS_IDX));
addr = HINIC5_CSR_API_CMD_CHAIN_PI_ADDR((u32)chain->chain_type);
- val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
+ val = hinic5_hwif_read_reg(chain->hwdev->hwif, addr);
sdk_err(dev, "Chain hw current pi: 0x%x\n", val);
#if defined(__LINUX__) && !defined(__UBUS_DRIVER__)
pdev = to_pci_dev(chain->hwdev->dev_hdl);
@@ -173,8 +168,10 @@ static int chain_busy(struct hinic5_api_cmd_chain *chain)
case HINIC5_API_CMD_MULTI_READ:
case HINIC5_API_CMD_POLL_READ:
resp_header = be64_to_cpu(ctxt->resp->header);
- if (ctxt->status != 0 || (HINIC5_API_CMD_RESP_HEADER_VALID(resp_header) == 0)) {
- sdk_err(dev, "Context(0x%x) busy!, pi: %u, resp_header: 0x%08x%08x\n",
+ if ((ctxt->status != 0) ||
+ (HINIC5_API_CMD_RESP_HEADER_VALID(resp_header) == 0)) {
+ sdk_err(dev,
+ "Context(0x%x) busy!, pi: %u, resp_header: 0x%08x%08x\n",
ctxt->status, chain->prod_idx,
upper_32_bits(resp_header),
lower_32_bits(resp_header));
@@ -188,7 +185,8 @@ static int chain_busy(struct hinic5_api_cmd_chain *chain)
chain->cons_idx = get_hw_cons_idx(chain);
if (chain->cons_idx == MASKED_IDX(chain, chain->prod_idx + 1)) {
- sdk_err(dev, "API CMD chain %d is busy, cons_idx = %u, prod_idx = %u\n",
+ sdk_err(dev,
+ "API CMD chain %d is busy, cons_idx = %u, prod_idx = %u\n",
chain->chain_type, chain->cons_idx,
chain->prod_idx);
dump_api_chain_reg(chain);
@@ -214,16 +212,16 @@ static u16 get_cell_data_size(enum hinic5_api_cmd_chain_type type)
switch (type) {
case HINIC5_API_CMD_POLL_READ:
cell_data_size = ALIGN(API_CMD_CELL_DESC_SIZE +
- API_CMD_CELL_WB_ADDR_SIZE +
- API_CMD_CELL_DATA_ADDR_SIZE,
- API_CHAIN_CELL_ALIGNMENT);
+ API_CMD_CELL_WB_ADDR_SIZE +
+ API_CMD_CELL_DATA_ADDR_SIZE,
+ API_CHAIN_CELL_ALIGNMENT);
break;
case HINIC5_API_CMD_WRITE_TO_MGMT_CPU:
case HINIC5_API_CMD_POLL_WRITE:
case HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU:
cell_data_size = ALIGN(API_CMD_CELL_DESC_SIZE +
- API_CMD_CELL_DATA_ADDR_SIZE,
+ API_CMD_CELL_DATA_ADDR_SIZE,
API_CHAIN_CELL_ALIGNMENT);
break;
default:
@@ -267,39 +265,44 @@ static void prepare_api_cmd(struct hinic5_api_cmd_chain *chain,
struct hinic5_api_cmd_cell *cell, u8 node_id,
const void *cmd, u16 cmd_size)
{
- struct hinic5_api_cmd_cell_ctxt *cell_ctxt = NULL;
+ struct hinic5_api_cmd_cell_ctxt *cell_ctxt = NULL;
u32 priv;
cell_ctxt = &chain->cell_ctxt[chain->prod_idx];
switch (chain->chain_type) {
case HINIC5_API_CMD_POLL_READ:
- priv = READ_API_CMD_PRIV_DATA(chain->chain_type, cell_ctxt->saved_prod_idx);
- cell->desc = HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
- HINIC5_API_CMD_DESC_SET(API_CMD_READ_TYPE, RD_WR) |
- HINIC5_API_CMD_DESC_SET(BYPASS, MGMT_BYPASS) |
- HINIC5_API_CMD_DESC_SET(NOT_TRIGGER, RESP_AEQE_EN) |
- HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
+ priv = READ_API_CMD_PRIV_DATA(chain->chain_type,
+ cell_ctxt->saved_prod_idx);
+ cell->desc =
+ HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
+ HINIC5_API_CMD_DESC_SET(API_CMD_READ_TYPE, RD_WR) |
+ HINIC5_API_CMD_DESC_SET(BYPASS, MGMT_BYPASS) |
+ HINIC5_API_CMD_DESC_SET(NOT_TRIGGER, RESP_AEQE_EN) |
+ HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
break;
case HINIC5_API_CMD_POLL_WRITE:
- priv = WRITE_API_CMD_PRIV_DATA(chain->chain_type);
- cell->desc = HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
- HINIC5_API_CMD_DESC_SET(API_CMD_WRITE_TYPE, RD_WR) |
- HINIC5_API_CMD_DESC_SET(BYPASS, MGMT_BYPASS) |
- HINIC5_API_CMD_DESC_SET(NOT_TRIGGER, RESP_AEQE_EN) |
- HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
+ priv = WRITE_API_CMD_PRIV_DATA(chain->chain_type);
+ cell->desc =
+ HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
+ HINIC5_API_CMD_DESC_SET(API_CMD_WRITE_TYPE, RD_WR) |
+ HINIC5_API_CMD_DESC_SET(BYPASS, MGMT_BYPASS) |
+ HINIC5_API_CMD_DESC_SET(NOT_TRIGGER, RESP_AEQE_EN) |
+ HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
break;
case HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU:
case HINIC5_API_CMD_WRITE_TO_MGMT_CPU:
- priv = WRITE_API_CMD_PRIV_DATA(chain->chain_type);
- cell->desc = HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
- HINIC5_API_CMD_DESC_SET(API_CMD_WRITE_TYPE, RD_WR) |
- HINIC5_API_CMD_DESC_SET(NOT_BYPASS, MGMT_BYPASS) |
- HINIC5_API_CMD_DESC_SET(TRIGGER, RESP_AEQE_EN) |
- HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
+ priv = WRITE_API_CMD_PRIV_DATA(chain->chain_type);
+ cell->desc =
+ HINIC5_API_CMD_DESC_SET(SGL_DATA, API_TYPE) |
+ HINIC5_API_CMD_DESC_SET(API_CMD_WRITE_TYPE, RD_WR) |
+ HINIC5_API_CMD_DESC_SET(NOT_BYPASS, MGMT_BYPASS) |
+ HINIC5_API_CMD_DESC_SET(TRIGGER, RESP_AEQE_EN) |
+ HINIC5_API_CMD_DESC_SET(priv, PRIV_DATA);
break;
default:
- sdk_err(chain->hwdev->dev_hdl, "Unknown Chain type: %d\n", chain->chain_type);
+ sdk_err(chain->hwdev->dev_hdl, "Unknown Chain type: %d\n",
+ chain->chain_type);
return;
}
@@ -309,13 +312,17 @@ static void prepare_api_cmd(struct hinic5_api_cmd_chain *chain,
cell->desc |= HINIC5_API_CMD_DESC_SET(node_id, DEST) |
HINIC5_API_CMD_DESC_SET(SIZE_4BYTES(cmd_size), SIZE);
- cell->desc |= HINIC5_API_CMD_DESC_SET(xor_chksum_set(&cell->desc,
- sizeof(cell->desc)), XOR_CHKSUM);
+ cell->desc |= HINIC5_API_CMD_DESC_SET(
+ xor_chksum_set(&cell->desc, sizeof(cell->desc)), XOR_CHKSUM);
/* The data in the HW should be in Big Endian Format */
cell->desc = cpu_to_be64(cell->desc);
- memcpy(cell_ctxt->api_cmd_vaddr, cmd, cmd_size);
+ if (memcpy_s(cell_ctxt->api_cmd_vaddr, chain->buf_size_align, cmd,
+ cmd_size) != 0) {
+ sdk_err(chain->hwdev->dev_hdl, "Memcpy cmd buf failed: %u.\n",
+ cmd_size);
+ }
}
/**
@@ -358,8 +365,8 @@ static void api_cmd_status_update(struct hinic5_api_cmd_chain *chain)
{
struct hinic5_api_cmd_status *wb_status = NULL;
enum hinic5_api_cmd_chain_type chain_type;
- u64 status_header;
- u32 buf_desc;
+ u64 status_header;
+ u32 buf_desc;
wb_status = chain->wb_status;
@@ -400,18 +407,20 @@ static enum hinic5_wait_return wait_for_status_poll_handler(void *priv_data)
**/
static int wait_for_status_poll(struct hinic5_api_cmd_chain *chain)
{
- return hinic5_wait_for_timeout(chain,
- wait_for_status_poll_handler,
- API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
+ return hinic5_wait_for_timeout(chain, wait_for_status_poll_handler,
+ API_CMD_STATUS_TIMEOUT,
+ 100); /* wait 100 us once */
}
static int copy_resp_data(struct hinic5_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic5_api_cmd_resp_fmt *resp = ctxt->resp;
- u16 rsp_size = (ack_size > API_CMD_BUF_SIZE) ? API_CMD_BUF_SIZE : ack_size;
+ u16 rsp_size = (ack_size > API_CMD_BUF_SIZE) ? API_CMD_BUF_SIZE :
+ ack_size;
- memcpy(ack, &resp->resp_data, rsp_size);
+ if (memcpy_s(ack, ack_size, &resp->resp_data, rsp_size) != 0)
+ return -ENOMEM;
ctxt->status = 0;
@@ -474,8 +483,11 @@ static int wait_for_api_cmd_completion(struct hinic5_api_cmd_chain *chain,
err = wait_for_resp_polling(ctxt);
if (err == 0) {
err = copy_resp_data(ctxt, ack, ack_size);
- if (err != 0)
- sdk_err(dev, "Copy resp data failed, ack_size: %u.\n", ack_size);
+ if (err != 0) {
+ sdk_err(dev,
+ "Copy resp data failed, ack_size: %u.\n",
+ ack_size);
+ }
} else {
ctxt->status = 0;
sdk_err(dev, "API CMD poll response timeout\n");
@@ -485,7 +497,8 @@ static int wait_for_api_cmd_completion(struct hinic5_api_cmd_chain *chain,
case HINIC5_API_CMD_WRITE_TO_MGMT_CPU:
err = wait_for_status_poll(chain);
if (err != 0) {
- sdk_err(dev, "API CMD Poll status timeout, chain type: %d\n",
+ sdk_err(dev,
+ "API CMD Poll status timeout, chain type: %d\n",
chain->chain_type);
break;
}
@@ -602,7 +615,8 @@ static enum hinic5_wait_return check_chain_restart_handler(void *priv_data)
if (!hinic5_is_chip_present(cmd_chain->hwdev))
return WAIT_PROCESS_ERR;
- reg_addr = HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR((u32)cmd_chain->chain_type);
+ reg_addr =
+ HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR((u32)cmd_chain->chain_type);
val = hinic5_hwif_read_reg(cmd_chain->hwdev->hwif, reg_addr);
if (HINIC5_API_CMD_CHAIN_REQ_GET(val, RESTART) == 0)
return WAIT_PROCESS_CPL;
@@ -620,7 +634,8 @@ static int api_cmd_hw_restart(struct hinic5_api_cmd_chain *cmd_chain)
u32 reg_addr, val;
/* Read Modify Write */
- reg_addr = HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR((u32)cmd_chain->chain_type);
+ reg_addr =
+ HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR((u32)cmd_chain->chain_type);
val = hinic5_hwif_read_reg(hwif, reg_addr);
val = HINIC5_API_CMD_CHAIN_REQ_CLEAR(val, RESTART);
@@ -650,7 +665,7 @@ static void api_cmd_ctrl_init(struct hinic5_api_cmd_chain *chain)
ctrl = hinic5_hwif_read_reg(hwif, reg_addr);
ctrl = HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, AEQE_EN) &
- HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, CELL_SIZE);
+ HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, CELL_SIZE);
ctrl |= HINIC5_API_CMD_CHAIN_CTRL_SET(0, AEQE_EN) |
HINIC5_API_CMD_CHAIN_CTRL_SET(size, CELL_SIZE);
@@ -686,7 +701,7 @@ static void api_cmd_set_num_cells(struct hinic5_api_cmd_chain *chain)
u32 addr, val;
addr = HINIC5_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR((u32)chain->chain_type);
- val = chain->num_cells;
+ val = chain->num_cells;
hinic5_hwif_write_reg(hwif, addr, val);
}
@@ -750,8 +765,8 @@ static void api_cmd_chain_hw_clean(struct hinic5_api_cmd_chain *chain)
ctrl = hinic5_hwif_read_reg(hwif, addr);
ctrl = HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, RESTART_EN) &
- HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_ERR) &
- HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, AEQE_EN) &
+ HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_ERR) &
+ HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, AEQE_EN) &
HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, XOR_CHK_EN) &
HINIC5_API_CMD_CHAIN_CTRL_CLEAR(ctrl, CELL_SIZE);
@@ -770,7 +785,8 @@ static int api_cmd_chain_hw_init(struct hinic5_api_cmd_chain *chain)
api_cmd_set_status_addr(chain);
if (api_cmd_hw_restart(chain) != 0) {
- sdk_err(chain->hwdev->dev_hdl, "Failed to restart api_cmd_hw\n");
+ sdk_err(chain->hwdev->dev_hdl,
+ "Failed to restart api_cmd_hw\n");
return -EBUSY;
}
@@ -798,9 +814,8 @@ static int alloc_cmd_buf(struct hinic5_api_cmd_chain *chain,
int err = 0;
buf_vaddr = (u8 *)(uintptr_t)((u64)(uintptr_t)chain->buf_vaddr_base +
- chain->buf_size_align * cell_idx);
- buf_paddr = chain->buf_paddr_base +
- chain->buf_size_align * cell_idx;
+ chain->buf_size_align * cell_idx);
+ buf_paddr = chain->buf_paddr_base + chain->buf_size_align * cell_idx;
cell_ctxt = &chain->cell_ctxt[cell_idx];
@@ -841,14 +856,14 @@ static void alloc_resp_buf(struct hinic5_api_cmd_chain *chain,
u64 resp_paddr;
resp_vaddr = (u8 *)(uintptr_t)((u64)(uintptr_t)chain->rsp_vaddr_base +
- chain->rsp_size_align * cell_idx);
- resp_paddr = chain->rsp_paddr_base +
- chain->rsp_size_align * cell_idx;
+ chain->rsp_size_align * cell_idx);
+ resp_paddr = chain->rsp_paddr_base + chain->rsp_size_align * cell_idx;
cell_ctxt = &chain->cell_ctxt[cell_idx];
cell_ctxt->resp = resp_vaddr;
- cell_ctxt->resp->header = cpu_to_be64(HINIC5_API_CMD_RESP_HEAD_VALID_CODE);
+ cell_ctxt->resp->header =
+ cpu_to_be64(HINIC5_API_CMD_RESP_HEAD_VALID_CODE);
cell->read.hw_wb_resp_paddr = cpu_to_be64(resp_paddr);
}
@@ -913,10 +928,10 @@ static int api_cmd_create_cell(struct hinic5_api_cmd_chain *chain, u32 cell_idx,
u64 cell_paddr;
int err;
- cell_vaddr = (void *)(uintptr_t)((u64)(uintptr_t)chain->cell_vaddr_base +
- chain->cell_size_align * cell_idx);
- cell_paddr = chain->cell_paddr_base +
- chain->cell_size_align * cell_idx;
+ cell_vaddr =
+ (void *)(uintptr_t)((u64)(uintptr_t)chain->cell_vaddr_base +
+ chain->cell_size_align * cell_idx);
+ cell_paddr = chain->cell_paddr_base + chain->cell_size_align * cell_idx;
cell_ctxt = &chain->cell_ctxt[cell_idx];
cell_ctxt->cell_vaddr = cell_vaddr;
@@ -992,13 +1007,13 @@ static int api_chain_init(struct hinic5_api_cmd_chain *chain,
size_t cells_buf_size;
int err;
- chain->chain_type = attr->chain_type;
+ chain->chain_type = attr->chain_type;
chain->num_cells = attr->num_cells;
chain->cell_size = attr->cell_size;
chain->rsp_size = attr->rsp_size;
- chain->prod_idx = 0;
- chain->cons_idx = 0;
+ chain->prod_idx = 0;
+ chain->cons_idx = 0;
if (chain->chain_type == HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_init(&chain->async_lock);
@@ -1014,12 +1029,12 @@ static int api_chain_init(struct hinic5_api_cmd_chain *chain,
chain->cell_ctxt = kzalloc(cell_ctxt_size, GFP_KERNEL);
if (!chain->cell_ctxt) {
+ sdk_err(dev, "Failed to allocate cell contexts for a chain\n");
err = -ENOMEM;
goto alloc_cell_ctxt_err;
}
- chain->wb_status = dma_zalloc_coherent(dev,
- sizeof(*chain->wb_status),
+ chain->wb_status = dma_zalloc_coherent(dev, sizeof(*chain->wb_status),
&chain->wb_status_paddr,
GFP_KERNEL);
if (!chain->wb_status) {
@@ -1028,19 +1043,19 @@ static int api_chain_init(struct hinic5_api_cmd_chain *chain,
goto alloc_wb_status_err;
}
- chain->cell_size_align = ALIGN((u64)chain->cell_size,
- API_CMD_NODE_ALIGN_SIZE);
- chain->rsp_size_align = ALIGN((u64)chain->rsp_size,
- API_CHAIN_RESP_ALIGNMENT);
+ chain->cell_size_align =
+ ALIGN((u64)chain->cell_size, API_CMD_NODE_ALIGN_SIZE);
+ chain->rsp_size_align =
+ ALIGN((u64)chain->rsp_size, API_CHAIN_RESP_ALIGNMENT);
chain->buf_size_align = ALIGN(API_CMD_BUF_SIZE, API_PAYLOAD_ALIGN_SIZE);
cells_buf_size = (chain->cell_size_align + chain->rsp_size_align +
- chain->buf_size_align) * chain->num_cells;
+ chain->buf_size_align) *
+ chain->num_cells;
err = hinic5_dma_zalloc_coherent_align(dev, cells_buf_size,
API_CMD_NODE_ALIGN_SIZE,
- GFP_KERNEL,
- &chain->cells_addr);
+ GFP_KERNEL, &chain->cells_addr);
if (err != 0) {
sdk_err(dev, "Failed to allocate API CMD cells buffer\n");
goto alloc_cells_buf_err;
@@ -1049,21 +1064,23 @@ static int api_chain_init(struct hinic5_api_cmd_chain *chain,
chain->cell_vaddr_base = chain->cells_addr.align_vaddr;
chain->cell_paddr_base = chain->cells_addr.align_paddr;
- chain->rsp_vaddr_base = (u8 *)(uintptr_t)((u64)(uintptr_t)chain->cell_vaddr_base +
- chain->cell_size_align * chain->num_cells);
+ chain->rsp_vaddr_base =
+ (u8 *)(uintptr_t)((u64)(uintptr_t)chain->cell_vaddr_base +
+ chain->cell_size_align * chain->num_cells);
chain->rsp_paddr_base = chain->cell_paddr_base +
- chain->cell_size_align * chain->num_cells;
+ chain->cell_size_align * chain->num_cells;
- chain->buf_vaddr_base = (u8 *)(uintptr_t)((u64)(uintptr_t)chain->rsp_vaddr_base +
- chain->rsp_size_align * chain->num_cells);
+ chain->buf_vaddr_base =
+ (u8 *)(uintptr_t)((u64)(uintptr_t)chain->rsp_vaddr_base +
+ chain->rsp_size_align * chain->num_cells);
chain->buf_paddr_base = chain->rsp_paddr_base +
- chain->rsp_size_align * chain->num_cells;
+ chain->rsp_size_align * chain->num_cells;
return 0;
alloc_cells_buf_err:
- dma_free_coherent(dev, sizeof(*chain->wb_status),
- chain->wb_status, chain->wb_status_paddr);
+ dma_free_coherent(dev, sizeof(*chain->wb_status), chain->wb_status,
+ chain->wb_status_paddr);
alloc_wb_status_err:
kfree(chain->cell_ctxt);
@@ -1087,8 +1104,8 @@ static void api_chain_free(struct hinic5_api_cmd_chain *chain)
hinic5_dma_free_coherent_align(dev, &chain->cells_addr);
- dma_free_coherent(dev, sizeof(*chain->wb_status),
- chain->wb_status, chain->wb_status_paddr);
+ dma_free_coherent(dev, sizeof(*chain->wb_status), chain->wb_status,
+ chain->wb_status_paddr);
kfree(chain->cell_ctxt);
if (chain->chain_type == HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
@@ -1111,7 +1128,8 @@ static int api_cmd_create_chain(struct hinic5_api_cmd_chain **cmd_chain,
int err;
if ((attr->num_cells & (attr->num_cells - 1)) != 0) {
- sdk_err(hwdev->dev_hdl, "Invalid number of cells, must be power of 2\n");
+ sdk_err(hwdev->dev_hdl,
+ "Invalid number of cells, must be power of 2\n");
return -EINVAL;
}
@@ -1129,7 +1147,8 @@ static int api_cmd_create_chain(struct hinic5_api_cmd_chain **cmd_chain,
err = api_cmd_create_cells(chain);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to create cells for API CMD chain\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to create cells for API CMD chain\n");
goto create_cells_err;
}
@@ -1179,9 +1198,9 @@ int hinic5_api_cmd_init(struct hinic5_hwdev *hwdev,
return 0;
attr.hwdev = hwdev;
- attr.num_cells = API_CHAIN_NUM_CELLS;
- attr.cell_size = API_CHAIN_CELL_SIZE;
- attr.rsp_size = API_CHAIN_RSP_DATA_SIZE;
+ attr.num_cells = API_CHAIN_NUM_CELLS;
+ attr.cell_size = API_CHAIN_CELL_SIZE;
+ attr.rsp_size = API_CHAIN_RSP_DATA_SIZE;
chain_type = HINIC5_API_CMD_WRITE_TO_MGMT_CPU;
for (; chain_type < (u8)HINIC5_API_CMD_MAX; chain_type++) {
@@ -1208,7 +1227,8 @@ int hinic5_api_cmd_init(struct hinic5_hwdev *hwdev,
* hinic5_api_cmd_free - free the API CMD chains
* @chain: the API CMD chains that will be freed
**/
-void hinic5_api_cmd_free(const struct hinic5_hwdev *hwdev, struct hinic5_api_cmd_chain **chain)
+void hinic5_api_cmd_free(const struct hinic5_hwdev *hwdev,
+ struct hinic5_api_cmd_chain **chain)
{
u8 chain_type;
@@ -1220,4 +1240,3 @@ void hinic5_api_cmd_free(const struct hinic5_hwdev *hwdev, struct hinic5_api_cmd
for (; chain_type < (u8)HINIC5_API_CMD_MAX; chain_type++)
api_cmd_destroy_chain(chain[chain_type]);
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_cmdq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_cmdq.c
index 7f8366575..7a6bb067a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_cmdq.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cmdq.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -31,165 +24,155 @@
#include "hinic5_common.h"
#include "hinic5_wq.h"
#include "hinic5_hw_comm.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "npu_cmdq_base_defs.h"
#include "hinic5_cmdq.h"
-#define CMDQ_CMD_RETRY_TIMEOUT 1000U
-
-#define UPPER_8_BITS(data) (((data) >> 8) & 0xFF)
-#define LOWER_8_BITS(data) ((data) & 0xFF)
-
-#define CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
-#define CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFFU
-#define CMDQ_DB_INFO_SET(val, member) \
- ((((u32)(val)) & CMDQ_DB_INFO_##member##_MASK) << \
- CMDQ_DB_INFO_##member##_SHIFT)
-
-#define CMDQ_DB_HEAD_QUEUE_TYPE_SHIFT 23
-#define CMDQ_DB_HEAD_CMDQ_TYPE_SHIFT 24
-#define CMDQ_DB_HEAD_SRC_TYPE_SHIFT 27
-#define CMDQ_DB_HEAD_QUEUE_TYPE_MASK 0x1U
-#define CMDQ_DB_HEAD_CMDQ_TYPE_MASK 0x7U
-#define CMDQ_DB_HEAD_SRC_TYPE_MASK 0x1FU
-#define CMDQ_DB_HEAD_SET(val, member) \
- ((((u32)(val)) & CMDQ_DB_HEAD_##member##_MASK) << \
- CMDQ_DB_HEAD_##member##_SHIFT)
-
-#define CMDQ_CTRL_PI_SHIFT 0
-#define CMDQ_CTRL_CMD_SHIFT 16
-#define CMDQ_CTRL_MOD_SHIFT 24
-#define CMDQ_CTRL_ACK_TYPE_SHIFT 29
-#define CMDQ_CTRL_HW_BUSY_BIT_SHIFT 31
-
-#define CMDQ_CTRL_PI_MASK 0xFFFFU
-#define CMDQ_CTRL_CMD_MASK 0xFFU
-#define CMDQ_CTRL_MOD_MASK 0x1FU
-#define CMDQ_CTRL_ACK_TYPE_MASK 0x3U
-#define CMDQ_CTRL_HW_BUSY_BIT_MASK 0x1U
+#define CMDQ_CMD_RETRY_TIMEOUT 1000U
+
+#define UPPER_8_BITS(data) (((data) >> 8) & 0xFF)
+#define LOWER_8_BITS(data) ((data)&0xFF)
+
+#define CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0
+#define CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFFU
+#define CMDQ_DB_INFO_SET(val, member) \
+ ((((u32)(val)) & CMDQ_DB_INFO_##member##_MASK) \
+ << CMDQ_DB_INFO_##member##_SHIFT)
-#define CMDQ_CTRL_SET(val, member) \
- ((((u32)(val)) & CMDQ_CTRL_##member##_MASK) << \
- CMDQ_CTRL_##member##_SHIFT)
+#define CMDQ_DB_HEAD_QUEUE_TYPE_SHIFT 23
+#define CMDQ_DB_HEAD_CMDQ_TYPE_SHIFT 24
+#define CMDQ_DB_HEAD_SRC_TYPE_SHIFT 27
+#define CMDQ_DB_HEAD_QUEUE_TYPE_MASK 0x1U
+#define CMDQ_DB_HEAD_CMDQ_TYPE_MASK 0x7U
+#define CMDQ_DB_HEAD_SRC_TYPE_MASK 0x1FU
+#define CMDQ_DB_HEAD_SET(val, member) \
+ ((((u32)(val)) & CMDQ_DB_HEAD_##member##_MASK) \
+ << CMDQ_DB_HEAD_##member##_SHIFT)
-#define CMDQ_CTRL_GET(val, member) \
- (((val) >> CMDQ_CTRL_##member##_SHIFT) & \
- CMDQ_CTRL_##member##_MASK)
+#define CMDQ_CTRL_PI_SHIFT 0
+#define CMDQ_CTRL_CMD_SHIFT 16
+#define CMDQ_CTRL_MOD_SHIFT 24
+#define CMDQ_CTRL_ACK_TYPE_SHIFT 29
+#define CMDQ_CTRL_HW_BUSY_BIT_SHIFT 31
-#define CMDQ_WQE_HEADER_BUFDESC_LEN_SHIFT 0
-#define CMDQ_WQE_HEADER_COMPLETE_FMT_SHIFT 15
-#define CMDQ_WQE_HEADER_DATA_FMT_SHIFT 22
-#define CMDQ_WQE_HEADER_COMPLETE_REQ_SHIFT 23
-#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_SHIFT 27
-#define CMDQ_WQE_HEADER_CTRL_LEN_SHIFT 29
-#define CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31
+#define CMDQ_CTRL_PI_MASK 0xFFFFU
+#define CMDQ_CTRL_CMD_MASK 0xFFU
+#define CMDQ_CTRL_MOD_MASK 0x1FU
+#define CMDQ_CTRL_ACK_TYPE_MASK 0x3U
+#define CMDQ_CTRL_HW_BUSY_BIT_MASK 0x1U
-#define CMDQ_WQE_HEADER_BUFDESC_LEN_MASK 0xFFU
-#define CMDQ_WQE_HEADER_COMPLETE_FMT_MASK 0x1U
-#define CMDQ_WQE_HEADER_DATA_FMT_MASK 0x1U
-#define CMDQ_WQE_HEADER_COMPLETE_REQ_MASK 0x1U
-#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_MASK 0x3U
-#define CMDQ_WQE_HEADER_CTRL_LEN_MASK 0x3U
-#define CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U
+#define CMDQ_CTRL_SET(val, member) \
+ ((((u32)(val)) & CMDQ_CTRL_##member##_MASK) \
+ << CMDQ_CTRL_##member##_SHIFT)
-#define CMDQ_WQE_HEADER_SET(val, member) \
- ((((u32)(val)) & CMDQ_WQE_HEADER_##member##_MASK) << \
- CMDQ_WQE_HEADER_##member##_SHIFT)
+#define CMDQ_CTRL_GET(val, member) \
+ (((val) >> CMDQ_CTRL_##member##_SHIFT) & CMDQ_CTRL_##member##_MASK)
-#define CMDQ_WQE_HEADER_GET(val, member) \
- (((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) & \
- CMDQ_WQE_HEADER_##member##_MASK)
+#define CMDQ_WQE_HEADER_BUFDESC_LEN_SHIFT 0
+#define CMDQ_WQE_HEADER_COMPLETE_FMT_SHIFT 15
+#define CMDQ_WQE_HEADER_DATA_FMT_SHIFT 22
+#define CMDQ_WQE_HEADER_COMPLETE_REQ_SHIFT 23
+#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_SHIFT 27
+#define CMDQ_WQE_HEADER_CTRL_LEN_SHIFT 29
+#define CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31
-#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
-#define CMDQ_CTXT_EQ_ID_SHIFT 53
-#define CMDQ_CTXT_CEQ_ARM_SHIFT 61
-#define CMDQ_CTXT_CEQ_EN_SHIFT 62
-#define CMDQ_CTXT_HW_BUSY_BIT_SHIFT 63
+#define CMDQ_WQE_HEADER_BUFDESC_LEN_MASK 0xFFU
+#define CMDQ_WQE_HEADER_COMPLETE_FMT_MASK 0x1U
+#define CMDQ_WQE_HEADER_DATA_FMT_MASK 0x1U
+#define CMDQ_WQE_HEADER_COMPLETE_REQ_MASK 0x1U
+#define CMDQ_WQE_HEADER_COMPLETE_SECT_LEN_MASK 0x3U
+#define CMDQ_WQE_HEADER_CTRL_LEN_MASK 0x3U
+#define CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U
-#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
-#define CMDQ_CTXT_EQ_ID_MASK 0xFF
-#define CMDQ_CTXT_CEQ_ARM_MASK 0x1
-#define CMDQ_CTXT_CEQ_EN_MASK 0x1
-#define CMDQ_CTXT_HW_BUSY_BIT_MASK 0x1
+#define CMDQ_WQE_HEADER_SET(val, member) \
+ ((((u32)(val)) & CMDQ_WQE_HEADER_##member##_MASK) \
+ << CMDQ_WQE_HEADER_##member##_SHIFT)
-#define CMDQ_CTXT_PAGE_INFO_SET(val, member) \
- (((u64)(val) & CMDQ_CTXT_##member##_MASK) << \
- CMDQ_CTXT_##member##_SHIFT)
+#define CMDQ_WQE_HEADER_GET(val, member) \
+ (((val) >> CMDQ_WQE_HEADER_##member##_SHIFT) & \
+ CMDQ_WQE_HEADER_##member##_MASK)
-#define CMDQ_CTXT_PAGE_INFO_GET(val, member) \
- (((u64)(val) >> CMDQ_CTXT_##member##_SHIFT) & \
- CMDQ_CTXT_##member##_MASK)
+#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0
+#define CMDQ_CTXT_EQ_ID_SHIFT 53
+#define CMDQ_CTXT_CEQ_ARM_SHIFT 61
+#define CMDQ_CTXT_CEQ_EN_SHIFT 62
+#define CMDQ_CTXT_HW_BUSY_BIT_SHIFT 63
-#define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
-#define CMDQ_CTXT_CI_SHIFT 52
+#define CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF
+#define CMDQ_CTXT_EQ_ID_MASK 0xFF
+#define CMDQ_CTXT_CEQ_ARM_MASK 0x1
+#define CMDQ_CTXT_CEQ_EN_MASK 0x1
+#define CMDQ_CTXT_HW_BUSY_BIT_MASK 0x1
-#define CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
-#define CMDQ_CTXT_CI_MASK 0xFFF
+#define CMDQ_CTXT_PAGE_INFO_SET(val, member) \
+ (((u64)(val)&CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
-#define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
- (((u64)(val) & CMDQ_CTXT_##member##_MASK) << \
- CMDQ_CTXT_##member##_SHIFT)
+#define CMDQ_CTXT_PAGE_INFO_GET(val, member) \
+ (((u64)(val) >> CMDQ_CTXT_##member##_SHIFT) & CMDQ_CTXT_##member##_MASK)
-#define CMDQ_CTXT_BLOCK_INFO_GET(val, member) \
- (((u64)(val) >> CMDQ_CTXT_##member##_SHIFT) & \
- CMDQ_CTXT_##member##_MASK)
+#define CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0
+#define CMDQ_CTXT_CI_SHIFT 52
-#define SAVED_DATA_ARM_SHIFT 31
+#define CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF
+#define CMDQ_CTXT_CI_MASK 0xFFF
-#define SAVED_DATA_ARM_MASK 0x1U
+#define CMDQ_CTXT_BLOCK_INFO_SET(val, member) \
+ (((u64)(val)&CMDQ_CTXT_##member##_MASK) << CMDQ_CTXT_##member##_SHIFT)
-#define SAVED_DATA_SET(val, member) \
- (((val) & SAVED_DATA_##member##_MASK) << \
- SAVED_DATA_##member##_SHIFT)
+#define CMDQ_CTXT_BLOCK_INFO_GET(val, member) \
+ (((u64)(val) >> CMDQ_CTXT_##member##_SHIFT) & CMDQ_CTXT_##member##_MASK)
-#define SAVED_DATA_CLEAR(val, member) \
- ((val) & (~(SAVED_DATA_##member##_MASK << \
- SAVED_DATA_##member##_SHIFT)))
+#define SAVED_DATA_ARM_SHIFT 31
-#define WQE_ERRCODE_VAL_SHIFT 0
+#define SAVED_DATA_ARM_MASK 0x1U
-#define WQE_ERRCODE_VAL_MASK 0x7FFFFFFF
+#define SAVED_DATA_SET(val, member) \
+ (((val)&SAVED_DATA_##member##_MASK) << SAVED_DATA_##member##_SHIFT)
-#define WQE_ERRCODE_GET(val, member) \
- (((val) >> WQE_ERRCODE_##member##_SHIFT) & \
- WQE_ERRCODE_##member##_MASK)
+#define SAVED_DATA_CLEAR(val, member) \
+ ((val) & (~(SAVED_DATA_##member##_MASK << SAVED_DATA_##member##_SHIFT)))
-#define CEQE_CMDQ_TYPE_SHIFT 0
+#define WQE_ERRCODE_VAL_SHIFT 0
-#define CEQE_CMDQ_TYPE_MASK 0x7
+#define WQE_ERRCODE_VAL_MASK 0x7FFFFFFF
-#define CEQE_CMDQ_GET(val, member) \
- (((val) >> CEQE_CMDQ_##member##_SHIFT) & \
- CEQE_CMDQ_##member##_MASK)
+#define WQE_ERRCODE_GET(val, member) \
+ (((val) >> WQE_ERRCODE_##member##_SHIFT) & WQE_ERRCODE_##member##_MASK)
-#define WQE_COMPLETED(ctrl_info) CMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT)
+#define CEQE_CMDQ_TYPE_SHIFT 0
-#define WQE_HEADER(wqe) ((struct hinic5_cmdq_header *)(wqe))
+#define CEQE_CMDQ_TYPE_MASK 0x7
-#define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3)
+#define CEQE_CMDQ_GET(val, member) \
+ (((val) >> CEQE_CMDQ_##member##_SHIFT) & CEQE_CMDQ_##member##_MASK)
-#define CMDQ_DB_ADDR(db_base, pi) \
- (((u8 *)(db_base)) + CMDQ_DB_PI_OFF(pi))
+#define WQE_COMPLETED(ctrl_info) CMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT)
-#define FIRST_DATA_TO_WRITE_LAST sizeof(u64)
+#define WQE_HEADER(wqe) ((struct hinic5_cmdq_header *)(wqe))
-#define WQE_LCMD_SIZE 64
-#define WQE_SCMD_SIZE 64
-#define WQE_ENHANCED_CMDQ_SIZE 32
+#define CMDQ_DB_PI_OFF(pi) (((u16)LOWER_8_BITS(pi)) << 3)
-#define COMPLETE_LEN 3
+#define CMDQ_DB_ADDR(db_base, pi) (((u8 *)(db_base)) + CMDQ_DB_PI_OFF(pi))
-#define CMDQ_WQEBB_SIZE 64
-#define CMDQ_WQE_SIZE 64
+#define FIRST_DATA_TO_WRITE_LAST sizeof(u64)
-#define ENHANCE_CMDQ_WQEBB_SIZE 16
+#define WQE_LCMD_SIZE 64
+#define WQE_SCMD_SIZE 64
+#define WQE_ENHANCED_CMDQ_SIZE 32
-#define cmdq_to_cmdqs(x) container_of((x) - ((u32)(x)->cmdq_type), \
- struct hinic5_cmdqs, cmdq[0])
+#define COMPLETE_LEN 3
-#define CMDQ_SEND_CMPT_CODE 10
-#define CMDQ_COMPLETE_CMPT_CODE 11
-#define CMDQ_FORCE_STOP_CMPT_CODE 12
+#define CMDQ_WQEBB_SIZE 64
+#define CMDQ_WQE_SIZE 64
+
+#define ENHANCE_CMDQ_WQEBB_SIZE 16
+
+#define cmdq_to_cmdqs(x) \
+ container_of((x) - ((u32)(x)->cmdq_type), struct hinic5_cmdqs, cmdq[0])
+
+#define CMDQ_SEND_CMPT_CODE 10
+#define CMDQ_COMPLETE_CMPT_CODE 11
+#define CMDQ_FORCE_STOP_CMPT_CODE 12
enum cmdq_scmd_type {
CMDQ_SET_ARM_CMD = 2,
@@ -214,8 +197,8 @@ enum completion_request {
CEQ_SET = 1,
};
-#define NUM_WQEBBS_FOR_CMDQ_WQE 1
-#define NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE 4
+#define NUM_WQEBBS_FOR_CMDQ_WQE 1
+#define NUM_WQEBBS_FOR_ENHANCE_CMDQ_WQE 4
bool hinic5_cmdq_idle(struct hinic5_cmdq *cmdq)
{
@@ -230,7 +213,8 @@ static void *cmdq_read_wqe(struct hinic5_wq *wq, u16 *ci)
return hinic5_wq_read_one_wqebb(wq, ci);
}
-static void *hinic5_wq_get_align_wqebbs(struct hinic5_wq *wq, u16 *pi, u16 wqebb_num)
+static void *hinic5_wq_get_align_wqebbs(struct hinic5_wq *wq, u16 *pi,
+ u16 wqebb_num)
{
*pi = WQ_MASK_IDX(wq, wq->prod_idx);
wq->prod_idx += wqebb_num;
@@ -261,16 +245,18 @@ struct hinic5_cmd_buf *hinic5_alloc_cmd_buf(void *hwdev)
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
dev = ((struct hinic5_hwdev *)hwdev)->dev_hdl;
- if (!cmdqs || !dev) {
+ if (cmdqs == NULL || dev == NULL) {
pr_err("Failed to alloc cmd buf, Invalid hwdev cmdqs or dev\n");
return NULL;
}
cmd_buf = kzalloc(sizeof(*cmd_buf), GFP_ATOMIC);
- if (!cmd_buf)
+ if (!cmd_buf) {
+ sdk_err(dev, "Failed to allocate cmd buf\n");
return NULL;
+ }
- // Allocated memory does not support default zeroing, caller should clear it as needed
+ // 申请到的内存不支持默认清零, 调用者根据需求进行清零
cmd_buf->buf = dma_pool_alloc(cmdqs->cmd_buf_pool, GFP_ATOMIC,
&cmd_buf->dma_addr);
if (!cmd_buf->buf) {
@@ -322,45 +308,49 @@ static void cmdq_set_lcmd_bufdesc(struct hinic5_cmdq_wqe_lcmd *wqe,
hinic5_set_sge(&wqe->buf_desc.sge, buf_in->dma_addr, buf_in->size);
}
-static void cmdq_fill_db(struct hinic5_cmdq_db *db,
- u8 cmdq_type, u16 prod_idx)
+static void cmdq_fill_db(struct hinic5_cmdq_db *db, u8 cmdq_type, u16 prod_idx)
{
db->db_info = CMDQ_DB_INFO_SET(UPPER_8_BITS(prod_idx), HI_PROD_IDX);
db->db_head = CMDQ_DB_HEAD_SET(HINIC5_DB_CMDQ_TYPE, QUEUE_TYPE) |
- CMDQ_DB_HEAD_SET(cmdq_type, CMDQ_TYPE) |
- CMDQ_DB_HEAD_SET(HINIC5_DB_SRC_CMDQ_TYPE, SRC_TYPE);
+ CMDQ_DB_HEAD_SET(cmdq_type, CMDQ_TYPE) |
+ CMDQ_DB_HEAD_SET(HINIC5_DB_SRC_CMDQ_TYPE, SRC_TYPE);
}
static void cmdq_set_db(struct hinic5_cmdq *cmdq,
enum hinic5_cmdq_type cmdq_type, u16 prod_idx)
{
- struct hinic5_cmdq_db db = {0};
+ struct hinic5_cmdq_db db = { 0 };
u8 *db_base = cmdq->hwdev->cmdqs->cmdqs_db_base;
- cmdq_fill_db(&db, ((u8)cmdq_type | cmdq->hwdev->cmdq_cos_offset), prod_idx);
+ cmdq_fill_db(&db, ((u8)cmdq_type | cmdq->hwdev->cmdq_cos_offset),
+ prod_idx);
/* The data that is written to HW should be in Big Endian Format */
db.db_info = hinic5_hw_be32(db.db_info);
db.db_head = hinic5_hw_be32(db.db_head);
- wmb(); /* write all before the doorbell */
+ wmb(); /* write all before the doorbell */
#ifndef __UEFI__
writeq(*((u64 *)(void *)&db), CMDQ_DB_ADDR(db_base, prod_idx));
#else
struct hinic5_hwdev *hwdev = cmdq->hwdev;
- writeq_uefi(hwdev->busdev_hdl,
- (u64)CMDQ_DB_ADDR(db_base, prod_idx),
+ writeq_uefi(hwdev->busdev_hdl, (u64)CMDQ_DB_ADDR(db_base, prod_idx),
HINIC5_DB_BAR, *((u64 *)&db));
#endif
}
static void cmdq_wqe_fill(void *dst, const void *src, int wqe_size)
{
- memcpy((u8 *)((uintptr_t)dst + FIRST_DATA_TO_WRITE_LAST),
- (u8 *)((uintptr_t)src + FIRST_DATA_TO_WRITE_LAST),
- (u32)wqe_size - FIRST_DATA_TO_WRITE_LAST);
+ int err;
+
+ err = memcpy_s((u8 *)((uintptr_t)dst + FIRST_DATA_TO_WRITE_LAST),
+ (u32)wqe_size - FIRST_DATA_TO_WRITE_LAST,
+ (u8 *)((uintptr_t)src + FIRST_DATA_TO_WRITE_LAST),
+ (u32)wqe_size - FIRST_DATA_TO_WRITE_LAST);
+ if (err != 0)
+ sdk_err(src, "Memcpy cmdq_wqe failed, err_code: %d.\n", err);
wmb(); /* The first 8 bytes should be written last */
@@ -381,24 +371,23 @@ static void cmdq_prepare_wqe_ctrl(struct hinic5_cmdq_wqe *wqe, int wrapped,
ctrl = &wqe_lcmd->ctrl;
ctrl_len = CTRL_SECT_LEN;
- ctrl->ctrl_info = CMDQ_CTRL_SET(prod_idx, PI) |
- CMDQ_CTRL_SET(cmd, CMD) |
- CMDQ_CTRL_SET(mod, MOD) |
- CMDQ_CTRL_SET(HINIC5_ACK_TYPE_CMDQ, ACK_TYPE);
+ ctrl->ctrl_info = CMDQ_CTRL_SET(prod_idx, PI) |
+ CMDQ_CTRL_SET(cmd, CMD) | CMDQ_CTRL_SET(mod, MOD) |
+ CMDQ_CTRL_SET(HINIC5_ACK_TYPE_CMDQ, ACK_TYPE);
WQE_HEADER((void *)wqe)->header_info =
- CMDQ_WQE_HEADER_SET(BUFDESC_LCMD_LEN, BUFDESC_LEN) |
+ CMDQ_WQE_HEADER_SET(BUFDESC_LCMD_LEN, BUFDESC_LEN) |
CMDQ_WQE_HEADER_SET(complete_format, COMPLETE_FMT) |
- CMDQ_WQE_HEADER_SET(DATA_SGE, DATA_FMT) |
- CMDQ_WQE_HEADER_SET(CEQ_SET, COMPLETE_REQ) |
+ CMDQ_WQE_HEADER_SET(DATA_SGE, DATA_FMT) |
+ CMDQ_WQE_HEADER_SET(CEQ_SET, COMPLETE_REQ) |
CMDQ_WQE_HEADER_SET(COMPLETE_LEN, COMPLETE_SECT_LEN) |
- CMDQ_WQE_HEADER_SET(ctrl_len, CTRL_LEN) |
+ CMDQ_WQE_HEADER_SET(ctrl_len, CTRL_LEN) |
CMDQ_WQE_HEADER_SET((u32)wrapped, HW_BUSY_BIT);
if (cmd == CMDQ_SET_ARM_CMD && mod == HINIC5_MOD_COMM) {
saved_data &= SAVED_DATA_CLEAR(saved_data, ARM);
- WQE_HEADER((void *)wqe)->saved_data = saved_data |
- SAVED_DATA_SET(1, ARM);
+ WQE_HEADER((void *)wqe)->saved_data = saved_data |
+ SAVED_DATA_SET(1, ARM);
} else {
saved_data &= SAVED_DATA_CLEAR(saved_data, ARM);
WQE_HEADER((void *)wqe)->saved_data = saved_data;
@@ -421,8 +410,7 @@ static void cmdq_set_lcmd_wqe(struct hinic5_cmdq_wqe *wqe,
case HINIC5_CMD_TYPE_SGE_RESP:
if (buf_out) {
complete_format = COMPLETE_SGE;
- cmdq_set_completion(&wqe_lcmd->completion,
- buf_out);
+ cmdq_set_completion(&wqe_lcmd->completion, buf_out);
}
break;
case HINIC5_CMD_TYPE_ASYNC:
@@ -433,7 +421,8 @@ static void cmdq_set_lcmd_wqe(struct hinic5_cmdq_wqe *wqe,
break;
}
- cmdq_prepare_wqe_ctrl(wqe, wrapped, mod, cmd, prod_idx, complete_format);
+ cmdq_prepare_wqe_ctrl(wqe, wrapped, mod, cmd, prod_idx,
+ complete_format);
cmdq_set_lcmd_bufdesc(wqe_lcmd, buf_in);
}
@@ -458,14 +447,18 @@ static void cmdq_update_cmd_status(struct hinic5_cmdq *cmdq, u16 prod_idx,
*cmd_info->errcode = WQE_ERRCODE_GET(status_info, VAL);
if (cmd_info->direct_resp) {
- *cmd_info->direct_resp = hinic5_hw_cpu32(wqe_lcmd->completion.direct_resp);
- if ((*cmd_info->errcode != 0) && (*cmd_info->direct_resp != 0)) {
- sdk_err(cmdq->hwdev->dev_hdl, "Cmdq resp err=0x%llx\n",
+ *cmd_info->direct_resp = hinic5_hw_cpu32(
+ wqe_lcmd->completion.direct_resp);
+ if ((*cmd_info->errcode != 0) &&
+ (*cmd_info->direct_resp != 0)) {
+ sdk_err(cmdq->hwdev->dev_hdl,
+ "Cmdq resp err=0x%llx\n",
*cmd_info->direct_resp);
}
}
} else {
- enhanced_cmdq_update_cmd_status(cmdq, cmd_info, &wqe->enhanced_cmdq_wqe);
+ enhanced_cmdq_update_cmd_status(cmdq, cmd_info,
+ &wqe->enhanced_cmdq_wqe);
}
}
@@ -483,13 +476,17 @@ static int hinic5_cmdq_sync_timeout_check(struct hinic5_cmdq *cmdq,
ctrl_info = hinic5_hw_cpu32((ctrl)->ctrl_info);
if (WQE_COMPLETED(ctrl_info) == 0) {
- sdk_info(cmdq->hwdev->dev_hdl, "Cmdq sync command check busy bit not set\n");
+ sdk_info(cmdq->hwdev->dev_hdl,
+ "Cmdq sync command check busy bit not set\n");
return -EFAULT;
}
} else {
- ctrl_info = hinic5_hw_cpu32(wqe->enhanced_cmdq_wqe.completion.cs_format);
+ ctrl_info = hinic5_hw_cpu32(
+ wqe->enhanced_cmdq_wqe.completion.cs_format);
if (ENHANCE_CMDQ_WQE_CS_GET(ctrl_info, HW_BUSY) == 0) {
- sdk_info(cmdq->hwdev->dev_hdl, "enhance Cmdq sync command check busy bit not set\n");
+ sdk_info(
+ cmdq->hwdev->dev_hdl,
+ "enhance Cmdq sync command check busy bit not set\n");
return -EFAULT;
}
}
@@ -531,7 +528,7 @@ static int wait_for_cmdq_timeout(struct hinic5_cmdq *cmdq,
return 0;
if (check_outbound_enable_handler(cmdq->hwdev) !=
- WAIT_PROCESS_CPL) {
+ WAIT_PROCESS_CPL) {
return -EPERM;
}
usleep_range(9, 10); /* sleep 9 us ~ 10 us */
@@ -583,12 +580,14 @@ static int cmdq_ceq_handler_status(struct hinic5_cmdq *cmdq,
return 0;
if (!cmdq->cmdqs->poll) {
- sdk_warn(cmdq->hwdev->dev_hdl,
- "Cmdq retry cmd(type %u, channel %u), msg_id %llu, pi %u\n",
- saved_cmd_info->cmd_type, saved_cmd_info->channel,
- curr_msg_id, curr_prod_idx);
-
- err = cmdq_retry_get_ack(cmdq, saved_cmd_info, HINIC5_CEQ_ID_CMDQ);
+ sdk_warn(
+ cmdq->hwdev->dev_hdl,
+ "Cmdq retry cmd(type %u, channel %u), msg_id %llu, pi %u\n",
+ saved_cmd_info->cmd_type, saved_cmd_info->channel,
+ curr_msg_id, curr_prod_idx);
+
+ err = cmdq_retry_get_ack(cmdq, saved_cmd_info,
+ HINIC5_CEQ_ID_CMDQ);
if (err == 0)
return 0;
}
@@ -599,7 +598,8 @@ static int cmdq_ceq_handler_status(struct hinic5_cmdq *cmdq,
cmd_info->cmpt_code = NULL;
if (*saved_cmd_info->cmpt_code == CMDQ_COMPLETE_CMPT_CODE) {
- sdk_info(cmdq->hwdev->dev_hdl, "Cmdq direct sync command has been completed\n");
+ sdk_info(cmdq->hwdev->dev_hdl,
+ "Cmdq direct sync command has been completed\n");
spin_unlock_bh(&cmdq->cmdq_lock);
return 0;
}
@@ -613,7 +613,8 @@ static int cmdq_ceq_handler_status(struct hinic5_cmdq *cmdq,
cmd_info->cmd_type = HINIC5_CMD_TYPE_FAKE_TIMEOUT;
} else {
err = -ETIMEDOUT;
- sdk_err(cmdq->hwdev->dev_hdl, "Cmdq sync command current msg id dismatch with cmd_info msg id\n");
+ sdk_err(cmdq->hwdev->dev_hdl,
+ "Cmdq sync command current msg id dismatch with cmd_info msg id\n");
}
clear_cmd_info(cmd_info, saved_cmd_info);
@@ -628,22 +629,20 @@ static int cmdq_ceq_handler_status(struct hinic5_cmdq *cmdq,
return -ETIMEDOUT;
}
-static int wait_cmdq_sync_cmd_completion(struct hinic5_cmdq *cmdq,
- struct hinic5_cmdq_cmd_info *cmd_info,
- struct hinic5_cmdq_cmd_info *saved_cmd_info,
- u64 curr_msg_id, u16 curr_prod_idx,
- struct hinic5_cmdq_wqe *curr_wqe, u32 timeout)
+static int wait_cmdq_sync_cmd_completion(
+ struct hinic5_cmdq *cmdq, struct hinic5_cmdq_cmd_info *cmd_info,
+ struct hinic5_cmdq_cmd_info *saved_cmd_info, u64 curr_msg_id,
+ u16 curr_prod_idx, struct hinic5_cmdq_wqe *curr_wqe, u32 timeout)
{
return cmdq_ceq_handler_status(cmdq, cmd_info, saved_cmd_info,
- curr_msg_id, curr_prod_idx,
- curr_wqe, timeout);
+ curr_msg_id, curr_prod_idx, curr_wqe,
+ timeout);
}
static int cmdq_msg_lock(struct hinic5_cmdq *cmdq, u16 channel)
{
struct hinic5_cmdqs *cmdqs = cmdq_to_cmdqs(cmdq);
-
- if (!cmdqs)
+ if (cmdqs == NULL)
return -EINVAL;
/* Keep wrapped and doorbell index correct. bh - for tasklet(ceq) */
@@ -675,8 +674,8 @@ static void cmdq_clear_cmd_buf(struct hinic5_cmdq_cmd_info *cmd_info,
cmd_info->buf_out = NULL;
}
-static void cmdq_update_next_prod_idx(struct hinic5_cmdq *cmdq, u16 curr_pi, u16 *next_pi,
- u16 wqebb_use_num)
+static void cmdq_update_next_prod_idx(struct hinic5_cmdq *cmdq, u16 curr_pi,
+ u16 *next_pi, u16 wqebb_use_num)
{
u16 q_depth = (u16)cmdq->wq.q_depth;
@@ -702,29 +701,36 @@ static void cmdq_set_cmd_buf(struct hinic5_cmdq_cmd_info *cmd_info,
atomic_inc(&buf_out->ref_cnt);
}
-static void cmdq_fill_inline_data(struct hinic5_cmdq *cmdq, u16 pi, const void *src, u32 size)
+static void cmdq_fill_inline_data(struct hinic5_cmdq *cmdq, u16 pi,
+ const void *src, u32 size)
{
struct hinic5_wq *wq = &cmdq->wq;
- u8 *dst = WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, pi), WQ_OFFSET_IN_PAGE(wq, pi));
+ u8 *dst = WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, pi),
+ WQ_OFFSET_IN_PAGE(wq, pi));
u32 copy_len = 0;
u16 pi_new = pi;
/* copy two path when dst_ptr + size > page_size */
- if (WQ_OFFSET_IN_PAGE(wq, pi) + (size >> wq->wqebb_size_shift) > wq->wqebbs_per_page) {
+ if (WQ_OFFSET_IN_PAGE(wq, pi) + (size >> wq->wqebb_size_shift) >
+ wq->wqebbs_per_page) {
copy_len = (wq->wqebbs_per_page - WQ_OFFSET_IN_PAGE(wq, pi))
<< wq->wqebb_size_shift;
if (copy_len != 0)
- memcpy(dst, src, copy_len);
+ (void)memcpy_s(dst, copy_len, src, copy_len);
- pi_new = WQ_MASK_IDX(wq, pi + (copy_len >> wq->wqebb_size_shift));
- dst = WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, pi_new), WQ_OFFSET_IN_PAGE(wq, pi_new));
+ pi_new = WQ_MASK_IDX(wq,
+ pi + (copy_len >> wq->wqebb_size_shift));
+ dst = WQ_GET_WQEBB_ADDR(wq, WQ_PAGE_IDX(wq, pi_new),
+ WQ_OFFSET_IN_PAGE(wq, pi_new));
}
- memcpy(dst, (u8 *)src + copy_len, size - copy_len);
+ (void)memcpy_s(dst, size - copy_len, (u8 *)src + copy_len,
+ size - copy_len);
}
static void cmdq_sync_wqe_prepare(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
- struct hinic5_cmd_buf *buf_in, struct hinic5_cmd_buf *buf_out,
+ struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out,
struct hinic5_cmdq_wqe *curr_wqe, u16 curr_pi,
enum hinic5_cmdq_cmd_type nic_cmd_type)
{
@@ -743,18 +749,19 @@ static void cmdq_sync_wqe_prepare(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
wqe_size = WQE_LCMD_SIZE;
}
- memset(&wqe, 0, (u32)wqe_size);
+ (void)memset_s(&wqe, (u32)wqe_size, 0, (u32)wqe_size);
wrapped = cmdq->wrapped;
if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
- cmdq_set_lcmd_wqe(&wqe, nic_cmd_type, buf_in, buf_out, wrapped, mod, cmd, curr_pi);
+ cmdq_set_lcmd_wqe(&wqe, nic_cmd_type, buf_in, buf_out, wrapped,
+ mod, cmd, curr_pi);
} else {
cmd_buf.buf_in = buf_in;
cmd_buf.buf_out = buf_out;
cmd_buf.cmd = cmd;
cmd_buf.mod = mod;
- hinic5_enhanced_cmdq_set_wqe(&wqe, nic_cmd_type, &cmd_buf, wrapped);
+ enhanced_cmdq_set_wqe(&wqe, nic_cmd_type, &cmd_buf, wrapped);
}
/* The data that is written to HW should be in Big Endian Format */
@@ -762,28 +769,34 @@ static void cmdq_sync_wqe_prepare(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
/* CMDQ WQE is not shadow, therefore wqe will be written to wq */
if (nic_cmd_type == HINIC5_CMD_TYPE_INLINE_DATA) {
- cmdq_fill_inline_data(cmdq, WQ_MASK_IDX(&cmdq->wq, curr_pi +
- HINIC5_CMDQ_WQE_INLINE_DATA_PI_OFFSET),
- wqe.enhanced_cmdq_wqe.inline_data,
- (u32)(wqe_size - WQE_ENHANCED_CMDQ_SIZE));
+ cmdq_fill_inline_data(
+ cmdq,
+ WQ_MASK_IDX(
+ &cmdq->wq,
+ curr_pi +
+ HINIC5_CMDQ_WQE_INLINE_DATA_PI_OFFSET),
+ wqe.enhanced_cmdq_wqe.inline_data,
+ (u32)(wqe_size - WQE_ENHANCED_CMDQ_SIZE));
cmdq_wqe_fill(curr_wqe, &wqe, WQE_ENHANCED_CMDQ_SIZE);
} else {
cmdq_wqe_fill(curr_wqe, &wqe, wqe_size);
}
}
-static inline void hinic5_cmdq_fill_cmd_info(struct hinic5_cmdq_cmd_info *cmd_info,
- enum hinic5_cmdq_cmd_type nic_cmd_type, u16 channel,
- u16 wqebb_use_num)
+static inline void
+hinic5_cmdq_fill_cmd_info(struct hinic5_cmdq_cmd_info *cmd_info,
+ enum hinic5_cmdq_cmd_type nic_cmd_type, u16 channel,
+ u16 wqebb_use_num)
{
cmd_info->cmd_type = nic_cmd_type;
cmd_info->channel = channel;
cmd_info->wqebb_use_num = wqebb_use_num;
}
-static inline void hinic5_cmdq_fill_completion_info(struct hinic5_cmdq_cmd_info *cmd_info,
- int *cmpt_code, struct completion *done,
- int *errcode, u64 *out_param)
+static inline void
+hinic5_cmdq_fill_completion_info(struct hinic5_cmdq_cmd_info *cmd_info,
+ int *cmpt_code, struct completion *done,
+ int *errcode, u64 *out_param)
{
cmd_info->done = done;
cmd_info->errcode = errcode;
@@ -792,8 +805,9 @@ static inline void hinic5_cmdq_fill_completion_info(struct hinic5_cmdq_cmd_info
}
static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
- struct hinic5_cmd_buf *buf_in, struct hinic5_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel,
+ struct hinic5_cmd_buf *buf_in,
+ struct hinic5_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel,
enum hinic5_cmdq_cmd_type nic_cmd_type)
{
struct hinic5_wq *wq = &cmdq->wq;
@@ -812,9 +826,10 @@ static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
return err;
wqebb_use_num = cmdq->cmdqs->wqebb_use_num;
- /* 4: 16B data per wqebb, - 2: 0 equal 32B */
if (nic_cmd_type == HINIC5_CMD_TYPE_INLINE_DATA)
- wqebb_use_num += ((buf_in->size >> 4) - 2);
+ wqebb_use_num +=
+ ((buf_in->size >> 4) -
+ 2); /* 4: 16B data per wqebb, - 2: 0 equal 32B */
curr_wqe = cmdq_get_wqe(wq, &curr_pi, wqebb_use_num);
if (!curr_wqe) {
@@ -824,13 +839,17 @@ static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
init_completion(&done);
cmd_info = &cmdq->cmd_infos[curr_pi];
- hinic5_cmdq_fill_cmd_info(cmd_info, nic_cmd_type, channel, wqebb_use_num);
- hinic5_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
+ hinic5_cmdq_fill_cmd_info(cmd_info, nic_cmd_type, channel,
+ wqebb_use_num);
+ hinic5_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode,
+ out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ (void)memcpy_s(&saved_cmd_info, sizeof(*cmd_info), cmd_info,
+ sizeof(*cmd_info));
- cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
+ cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe,
+ curr_pi, nic_cmd_type);
(cmd_info->cmdq_msg_id)++;
curr_msg_id = cmd_info->cmdq_msg_id;
@@ -840,19 +859,22 @@ static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
cmdq_msg_unlock(cmdq);
- real_timeout = (timeout != 0) ? timeout : cmdq->hwdev->timeout_info->cmdq_timeout;
- err = wait_cmdq_sync_cmd_completion(cmdq, cmd_info, &saved_cmd_info, curr_msg_id,
- curr_pi, curr_wqe, real_timeout);
+ real_timeout = (timeout != 0) ? timeout :
+ cmdq->hwdev->timeout_info->cmdq_timeout;
+ err = wait_cmdq_sync_cmd_completion(cmdq, cmd_info, &saved_cmd_info,
+ curr_msg_id, curr_pi, curr_wqe,
+ real_timeout);
if (err != 0) {
sdk_err(cmdq->hwdev->dev_hdl,
- "Cmdq sync cmd(mod: %u, cmd: %u) timeout, pi: 0x%x, \
- real_timeout: %u, expect_timeout: %u\n",
- mod, cmd, curr_pi, real_timeout, cmdq->hwdev->timeout_info->cmdq_timeout);
+ "Cmdq sync cmd(mod: %u, cmd: %u) timeout, pi: 0x%x, real_timeout: %u, expect_timeout: %u\n",
+ mod, cmd, curr_pi, real_timeout,
+ cmdq->hwdev->timeout_info->cmdq_timeout);
err = -ETIMEDOUT;
}
if (cmpt_code == CMDQ_FORCE_STOP_CMPT_CODE) {
- sdk_info(cmdq->hwdev->dev_hdl, "Force stop cmdq cmd, mod: %u, cmd: %u\n", mod, cmd);
+ sdk_info(cmdq->hwdev->dev_hdl,
+ "Force stop cmdq cmd, mod: %u, cmd: %u\n", mod, cmd);
err = -EAGAIN;
}
@@ -863,12 +885,11 @@ static int cmdq_sync_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
}
static int cmdq_sync_cmd_direct_resp(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
- struct hinic5_cmd_buf *buf_in, u64 *out_param,
- u32 timeout, u16 channel)
+ struct hinic5_cmd_buf *buf_in,
+ u64 *out_param, u32 timeout, u16 channel)
{
- return cmdq_sync_cmd(cmdq, mod, cmd, buf_in, NULL,
- out_param, timeout, channel,
- HINIC5_CMD_TYPE_DIRECT_RESP);
+ return cmdq_sync_cmd(cmdq, mod, cmd, buf_in, NULL, out_param, timeout,
+ channel, HINIC5_CMD_TYPE_DIRECT_RESP);
}
static int cmdq_sync_cmd_detail_resp(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
@@ -876,9 +897,8 @@ static int cmdq_sync_cmd_detail_resp(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
struct hinic5_cmd_buf *buf_out,
u64 *out_param, u32 timeout, u16 channel)
{
- return cmdq_sync_cmd(cmdq, mod, cmd, buf_in, buf_out,
- out_param, timeout, channel,
- HINIC5_CMD_TYPE_SGE_RESP);
+ return cmdq_sync_cmd(cmdq, mod, cmd, buf_in, buf_out, out_param,
+ timeout, channel, HINIC5_CMD_TYPE_SGE_RESP);
}
static int cmdq_async_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
@@ -893,7 +913,8 @@ static int cmdq_async_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
int wrapped, err;
wqe_size = cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ ?
- WQE_LCMD_SIZE : WQE_ENHANCED_CMDQ_SIZE;
+ WQE_LCMD_SIZE :
+ WQE_ENHANCED_CMDQ_SIZE;
/* enhance cmdq wqe_size aligned with 64 */
wqe_size = ALIGN((u32)wqe_size, 64);
@@ -909,21 +930,23 @@ static int cmdq_async_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
return -EBUSY;
}
- memset(&wqe, 0, sizeof(wqe));
+ (void)memset_s(&wqe, sizeof(wqe), 0, sizeof(wqe));
wrapped = cmdq->wrapped;
- cmdq_update_next_prod_idx(cmdq, curr_prod_idx, &next_prod_idx, wqebb_use_num);
+ cmdq_update_next_prod_idx(cmdq, curr_prod_idx, &next_prod_idx,
+ wqebb_use_num);
if (cmdq->cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
- cmdq_set_lcmd_wqe(&wqe, HINIC5_CMD_TYPE_ASYNC, buf_in, NULL, wrapped,
- mod, cmd, curr_prod_idx);
+ cmdq_set_lcmd_wqe(&wqe, HINIC5_CMD_TYPE_ASYNC, buf_in, NULL,
+ wrapped, mod, cmd, curr_prod_idx);
} else {
cmd_buf.buf_in = buf_in;
cmd_buf.buf_out = NULL;
cmd_buf.cmd = cmd;
cmd_buf.mod = mod;
- hinic5_enhanced_cmdq_set_wqe(&wqe, HINIC5_CMD_TYPE_ASYNC, &cmd_buf, wrapped);
+ enhanced_cmdq_set_wqe(&wqe, HINIC5_CMD_TYPE_ASYNC, &cmd_buf,
+ wrapped);
}
/* The data that is written to HW should be in Big Endian Format */
@@ -947,8 +970,9 @@ static int cmdq_async_cmd(struct hinic5_cmdq *cmdq, u8 mod, u8 cmd,
return 0;
}
-static int cmdq_inline_data_params_valid(const void *hwdev,
- const struct hinic5_cmdq_cmd_param *cmd_param)
+static int
+cmdq_inline_data_params_valid(const void *hwdev,
+ const struct hinic5_cmdq_cmd_param *cmd_param)
{
if (!cmd_param || !cmd_param->buf_in || !cmd_param->buf_out || !hwdev) {
pr_err("Invalid CMDQ buffer addr or hwdev\n");
@@ -956,20 +980,24 @@ static int cmdq_inline_data_params_valid(const void *hwdev,
}
if (cmd_param->buf_in->size > HINIC5_CMDQ_MAX_INLINE_DATA_SIZE ||
- (cmd_param->buf_in->size % 64) != 32) { /* % 64: inline data must be 32B/96B/160B */
- pr_err("Invalid CMDQ buffer in size: 0x%x\n", cmd_param->buf_in->size);
+ (cmd_param->buf_in->size % 64) !=
+ 32) { /* % 64: inline data must be 32B/96B/160B */
+ pr_err("Invalid CMDQ buffer in size: 0x%x\n",
+ cmd_param->buf_in->size);
return -EINVAL;
}
if (cmd_param->buf_out->size == 0 ||
cmd_param->buf_out->size > HINIC5_CMDQ_MAX_INLINE_DATA_SIZE) {
- pr_err("Invalid CMDQ buffer out size: 0x%x\n", cmd_param->buf_out->size);
+ pr_err("Invalid CMDQ buffer out size: 0x%x\n",
+ cmd_param->buf_out->size);
return -EINVAL;
}
return 0;
}
-static int cmdq_params_valid(const void *hwdev, const struct hinic5_cmd_buf *buf_in)
+static int cmdq_params_valid(const void *hwdev,
+ const struct hinic5_cmd_buf *buf_in)
{
struct hinic5_cmdqs *cmdqs = NULL;
@@ -979,28 +1007,29 @@ static int cmdq_params_valid(const void *hwdev, const struct hinic5_cmd_buf *buf
}
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
- if (!cmdqs || buf_in->size < HINIC5_CMDQ_MIN_BUF_SIZE ||
- buf_in->size > cmdqs->cmd_buf_size) {
- pr_err("Invalid cmdqs addr or CMDQ buffer size: 0x%x\n", buf_in->size);
+ if (!cmdqs || (buf_in->size < HINIC5_CMDQ_MIN_BUF_SIZE) ||
+ (buf_in->size > cmdqs->cmd_buf_size)) {
+ pr_err("Invalid cmdqs addr or CMDQ buffer size: 0x%x\n",
+ buf_in->size);
return -EINVAL;
}
return 0;
}
-#define WAIT_CMDQ_ENABLE_TIMEOUT 300
+#define WAIT_CMDQ_ENABLE_TIMEOUT 300
static int wait_cmdqs_enable(struct hinic5_cmdqs *cmdqs)
{
ulong end;
-
- if (!cmdqs)
+ if (cmdqs == NULL)
return -EINVAL;
end = jiffies + msecs_to_jiffies(WAIT_CMDQ_ENABLE_TIMEOUT);
do {
if ((cmdqs->status & HINIC5_CMDQ_ENABLE) != 0)
return 0;
- } while (time_before(jiffies, end) && hinic5_is_chip_present(cmdqs->hwdev) &&
+ } while (time_before(jiffies, end) &&
+ hinic5_is_chip_present(cmdqs->hwdev) &&
(cmdqs->disable_flag == 0));
cmdqs->disable_flag = 1;
@@ -1008,15 +1037,15 @@ static int wait_cmdqs_enable(struct hinic5_cmdqs *cmdqs)
return -EBUSY;
}
-static int check_cmdq_ready(struct hinic5_hwdev *hwdev, struct hinic5_cmdqs *cmdqs)
+static int check_cmdq_ready(struct hinic5_hwdev *hwdev,
+ struct hinic5_cmdqs *cmdqs)
{
int err;
- if (!hinic5_get_card_present_state(hwdev))
+ if (unlikely(!hinic5_is_chip_present(hwdev)))
return -EPERM;
- if (check_outbound_enable_handler(hwdev) !=
- WAIT_PROCESS_CPL) {
+ if (check_outbound_enable_handler(hwdev) != WAIT_PROCESS_CPL) {
return -EPERM;
}
@@ -1028,17 +1057,20 @@ static int check_cmdq_ready(struct hinic5_hwdev *hwdev, struct hinic5_cmdqs *cmd
return 0;
}
-static void cmdq_cmd_cost_time(struct hinic5_cmdqs *cmdqs, u8 mod, u8 cmd, struct timeval start)
+static void cmdq_cmd_cost_time(struct hinic5_cmdqs *cmdqs, u8 mod, u8 cmd,
+ struct timeval start)
{
- struct timeval end = {0};
+ struct timeval end = { 0 };
u64 cost_usec;
if (hinic5_get_perf_en(HINIC5_CMDQ_PERF)) {
do_gettimeofday(&end);
cost_usec = (u64)((end.tv_sec - start.tv_sec) * MSEC_PER_SEC *
- USEC_PER_MSEC + end.tv_usec - start.tv_usec);
+ USEC_PER_MSEC +
+ end.tv_usec - start.tv_usec);
sdk_info(cmdqs->hwdev->dev_hdl,
- "Cmdq mod: %u cmd: %u, cost time: %llu us\n", mod, cmd, cost_usec);
+ "Cmdq mod: %u cmd: %u, cost time: %llu us\n", mod, cmd,
+ cost_usec);
}
}
@@ -1047,7 +1079,7 @@ int hinic5_cos_id_direct_resp(void *hwdev, u8 mod, u8 cmd, u16 cos_id,
u32 timeout, u16 channel)
{
struct hinic5_cmdqs *cmdqs = NULL;
- struct timeval start = {0};
+ struct timeval start = { 0 };
int err;
if (hinic5_get_perf_en(HINIC5_CMDQ_PERF))
@@ -1061,8 +1093,9 @@ int hinic5_cos_id_direct_resp(void *hwdev, u8 mod, u8 cmd, u16 cos_id,
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
err = check_cmdq_ready((struct hinic5_hwdev *)hwdev, cmdqs);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
if (cos_id >= cmdqs->cmdq_num) {
sdk_err(cmdqs->hwdev->dev_hdl, "Cmdq id is invalid\n");
@@ -1087,16 +1120,17 @@ int hinic5_cmdq_direct_resp(void *hwdev, u8 mod, u8 cmd,
struct hinic5_cmd_buf *buf_in, u64 *out_param,
u32 timeout, u16 channel)
{
- return hinic5_cos_id_direct_resp(hwdev, mod, cmd, HINIC5_CMDQ_SYNC, buf_in, out_param,
- timeout, channel);
+ return hinic5_cos_id_direct_resp(hwdev, mod, cmd, HINIC5_CMDQ_SYNC,
+ buf_in, out_param, timeout, channel);
}
EXPORT_SYMBOL(hinic5_cmdq_direct_resp);
-int hinic5_cmdq_inline_data(void *hwdev, struct hinic5_cmdq_cmd_param *cmd_param,
+int hinic5_cmdq_inline_data(void *hwdev,
+ struct hinic5_cmdq_cmd_param *cmd_param,
u32 timeout, u16 channel)
{
struct hinic5_cmdqs *cmdqs = NULL;
- struct timeval start = {0};
+ struct timeval start = { 0 };
int err;
if (hinic5_get_perf_en(HINIC5_CMDQ_PERF))
@@ -1108,12 +1142,14 @@ int hinic5_cmdq_inline_data(void *hwdev, struct hinic5_cmdq_cmd_param *cmd_param
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
err = check_cmdq_ready((struct hinic5_hwdev *)hwdev, cmdqs);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
- err = cmdq_sync_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC],
- cmd_param->mod, cmd_param->cmd, cmd_param->buf_in, cmd_param->buf_out,
- cmd_param->out_param, timeout, channel, HINIC5_CMD_TYPE_INLINE_DATA);
+ err = cmdq_sync_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC], cmd_param->mod,
+ cmd_param->cmd, cmd_param->buf_in,
+ cmd_param->buf_out, cmd_param->out_param, timeout,
+ channel, HINIC5_CMD_TYPE_INLINE_DATA);
if (!hinic5_is_chip_present(hwdev))
return -ETIMEDOUT;
@@ -1124,20 +1160,22 @@ EXPORT_SYMBOL(hinic5_cmdq_inline_data);
int hinic5_cmdq_detail_resp(void *hwdev, u8 mod, u8 cmd,
struct hinic5_cmd_buf *buf_in,
- struct hinic5_cmd_buf *buf_out,
- u64 *out_param, u32 timeout, u16 channel)
+ struct hinic5_cmd_buf *buf_out, u64 *out_param,
+ u32 timeout, u16 channel)
{
return hinic5_cos_id_detail_resp(hwdev, mod, cmd, HINIC5_CMDQ_SYNC,
- buf_in, buf_out, out_param, timeout, channel);
+ buf_in, buf_out, out_param, timeout,
+ channel);
}
EXPORT_SYMBOL(hinic5_cmdq_detail_resp);
int hinic5_send_fast_msg_need_resp(void *hwdev, u8 mod, u8 cmd,
- struct hinic5_cmd_buf *buf_in, u64 *out_param)
+ struct hinic5_cmd_buf *buf_in,
+ u64 *out_param)
{
struct hinic5_hwdev *dev = hwdev;
struct hinic5_cmdqs *cmdqs = NULL;
- struct timeval start = {0};
+ struct timeval start = { 0 };
int err;
u32 fast_msg_qid = HINIC5_CMDQ_FAST_MSG;
@@ -1148,21 +1186,25 @@ int hinic5_send_fast_msg_need_resp(void *hwdev, u8 mod, u8 cmd,
if (err != 0)
return err;
- if ((!COMM_SUPPORT_FAST_MSG(dev)) || dev->glb_attr.cmdq_num < fast_msg_qid)
+ if ((!COMM_SUPPORT_FAST_MSG(dev)) ||
+ (dev->glb_attr.cmdq_num < fast_msg_qid)) {
return -EPERM;
+ }
- /* When cmdq number equals 2, fast_msg shares async queue */
- if (dev->glb_attr.cmdq_num == fast_msg_qid)
+ /* cmdq数量等于2时, fast_msg混用async queue */
+ if (dev->glb_attr.cmdq_num == fast_msg_qid) {
fast_msg_qid = HINIC5_CMDQ_ASYNC;
+ }
cmdqs = dev->cmdqs;
err = check_cmdq_ready(dev, cmdqs);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
- err = cmdq_sync_cmd_detail_resp(&cmdqs->cmdq[fast_msg_qid],
- mod, cmd, buf_in, buf_in, out_param,
- 0, HINIC5_CHANNEL_COMM);
+ err = cmdq_sync_cmd_detail_resp(&cmdqs->cmdq[fast_msg_qid], mod, cmd,
+ buf_in, buf_in, out_param, 0,
+ HINIC5_CHANNEL_COMM);
if (!hinic5_is_chip_present(dev))
return -ETIMEDOUT;
@@ -1176,7 +1218,7 @@ int hinic5_cos_id_detail_resp(void *hwdev, u8 mod, u8 cmd, u8 cos_id,
u32 timeout, u16 channel)
{
struct hinic5_cmdqs *cmdqs = NULL;
- struct timeval start = {0};
+ struct timeval start = { 0 };
int err;
if (hinic5_get_perf_en(HINIC5_CMDQ_PERF))
@@ -1188,17 +1230,17 @@ int hinic5_cos_id_detail_resp(void *hwdev, u8 mod, u8 cmd, u8 cos_id,
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
err = check_cmdq_ready((struct hinic5_hwdev *)hwdev, cmdqs);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
if (cos_id >= cmdqs->cmdq_num) {
sdk_err(cmdqs->hwdev->dev_hdl, "Cmdq id is invalid\n");
return -EINVAL;
}
- err = cmdq_sync_cmd_detail_resp(&cmdqs->cmdq[cos_id], mod, cmd,
- buf_in, buf_out, out_param,
- timeout, channel);
+ err = cmdq_sync_cmd_detail_resp(&cmdqs->cmdq[cos_id], mod, cmd, buf_in,
+ buf_out, out_param, timeout, channel);
if (!hinic5_is_chip_present(hwdev))
return -ETIMEDOUT;
@@ -1207,7 +1249,8 @@ int hinic5_cos_id_detail_resp(void *hwdev, u8 mod, u8 cmd, u8 cos_id,
}
EXPORT_SYMBOL(hinic5_cos_id_detail_resp);
-int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic5_cmd_buf *buf_in, u16 channel)
+int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd,
+ struct hinic5_cmd_buf *buf_in, u16 channel)
{
struct hinic5_cmdqs *cmdqs = NULL;
int err;
@@ -1219,11 +1262,12 @@ int hinic5_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic5_cmd_buf *buf_in
cmdqs = ((struct hinic5_hwdev *)hwdev)->cmdqs;
err = check_cmdq_ready((struct hinic5_hwdev *)hwdev, cmdqs);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
/* LB mode 1 compatible, cmdq 0 also for async, which is sync_no_wait */
- return cmdq_async_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC], mod,
- cmd, buf_in, channel);
+ return cmdq_async_cmd(&cmdqs->cmdq[HINIC5_CMDQ_SYNC], mod, cmd, buf_in,
+ channel);
}
EXPORT_SYMBOL(hinic5_cmdq_async);
@@ -1235,7 +1279,8 @@ static void clear_wqe_complete_bit(struct hinic5_cmdq *cmdq,
enum data_format df;
if (cmdq->hwdev->cmdq_mode == HINIC5_NORMAL_CMDQ) {
- header_info = hinic5_hw_cpu32(WQE_HEADER((void *)wqe)->header_info);
+ header_info =
+ hinic5_hw_cpu32(WQE_HEADER((void *)wqe)->header_info);
df = CMDQ_WQE_HEADER_GET(header_info, DATA_FMT);
if (df == DATA_SGE)
ctrl = &wqe->wqe_lcmd.ctrl;
@@ -1244,7 +1289,8 @@ static void clear_wqe_complete_bit(struct hinic5_cmdq *cmdq,
ctrl->ctrl_info = 0; /* clear HW busy bit */
} else {
- wqe->enhanced_cmdq_wqe.completion.cs_format = 0; /* clear HW busy bit */
+ wqe->enhanced_cmdq_wqe.completion.cs_format =
+ 0; /* clear HW busy bit */
}
cmdq->cmd_infos[ci].cmd_type = HINIC5_CMD_TYPE_NONE;
@@ -1291,7 +1337,7 @@ static void cmdq_async_cmd_handler(struct hinic5_hwdev *hwdev,
clear_wqe_complete_bit(cmdq, wqe, ci);
}
-#define HINIC5_CMDQ_WQE_HEAD_LEN 32
+#define HINIC5_CMDQ_WQE_HEAD_LEN 32
static void hinic5_dump_cmdq_wqe_head(struct hinic5_hwdev *hwdev,
struct hinic5_cmdq_wqe *wqe)
{
@@ -1299,7 +1345,8 @@ static void hinic5_dump_cmdq_wqe_head(struct hinic5_hwdev *hwdev,
u32 *data = (u32 *)(void *)wqe;
for (i = 0; i < (HINIC5_CMDQ_WQE_HEAD_LEN / sizeof(u32)); i += 0x4) {
- sdk_info(hwdev->dev_hdl, "wqe data: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ sdk_info(hwdev->dev_hdl,
+ "wqe data: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
*(data + i), *(data + i + 0x1), *(data + i + 0x2),
*(data + i + 0x3));
}
@@ -1330,9 +1377,9 @@ static int cmdq_type_default_ceq_handler(struct hinic5_hwdev *hwdev,
}
dma_rmb();
/* For FORCE_STOP cmd_type, we also need to wait for
- * the firmware processing to complete to prevent the
- * firmware from accessing the released cmd_buf
- */
+ * the firmware processing to complete to prevent the
+ * firmware from accessing the released cmd_buf
+ */
if (cmd_info->cmd_type == HINIC5_CMD_TYPE_FORCE_STOP) {
cmdq_clear_cmd_buf(cmd_info, hwdev);
clear_wqe_complete_bit(cmdq, wqe, ci);
@@ -1355,9 +1402,9 @@ void hinic5_cmdq_ceq_handler(void *handle, u32 ceqe_data)
struct hinic5_cmdq_cmd_info *cmd_info = NULL;
u16 ci;
int err;
-
if (cmdq_type >= HINIC5_MAX_CMDQ_TYPES) {
- sdk_err(hwdev->dev_hdl, "Cmdq type invalid, type: %u\n", cmdq_type);
+ sdk_err(hwdev->dev_hdl, "Cmdq type invalid, type: %u\n",
+ cmdq_type);
return;
}
cmdq = &cmdqs->cmdq[cmdq_type];
@@ -1368,7 +1415,9 @@ void hinic5_cmdq_ceq_handler(void *handle, u32 ceqe_data)
case HINIC5_CMD_TYPE_NONE:
return;
case HINIC5_CMD_TYPE_TIMEOUT:
- sdk_warn(hwdev->dev_hdl, "Cmdq timeout, q_id: %u, ci: %u\n", cmdq_type, ci);
+ sdk_warn(hwdev->dev_hdl,
+ "Cmdq timeout, q_id: %u, ci: %u\n", cmdq_type,
+ ci);
hinic5_dump_cmdq_wqe_head(hwdev, wqe);
cmdq_clear_cmd_buf(cmd_info, hwdev);
clear_wqe_complete_bit(cmdq, wqe, ci);
@@ -1378,7 +1427,8 @@ void hinic5_cmdq_ceq_handler(void *handle, u32 ceqe_data)
clear_wqe_complete_bit(cmdq, wqe, ci);
break;
default:
- err = cmdq_type_default_ceq_handler(hwdev, cmd_info, cmdq, wqe, ci);
+ err = cmdq_type_default_ceq_handler(hwdev, cmd_info,
+ cmdq, wqe, ci);
if (err != 0)
return;
break;
@@ -1399,11 +1449,11 @@ static void cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs,
ctxt_info->curr_wqe_page_pfn =
CMDQ_CTXT_PAGE_INFO_SET(1, HW_BUSY_BIT) |
#ifndef __UEFI__
- CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_EN) |
- CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_ARM) |
+ CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_EN) |
+ CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_ARM) |
#else
- CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_EN) |
- CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_ARM) |
+ CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_EN) |
+ CMDQ_CTXT_PAGE_INFO_SET(0, CEQ_ARM) |
#endif
CMDQ_CTXT_PAGE_INFO_SET(HINIC5_CEQ_ID_CMDQ, EQ_ID) |
CMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN);
@@ -1414,7 +1464,7 @@ static void cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs,
}
ctxt_info->wq_block_pfn = CMDQ_CTXT_BLOCK_INFO_SET(start_ci, CI) |
- CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN);
+ CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN);
}
static int init_cmdq(struct hinic5_cmdq *cmdq, struct hinic5_hwdev *hwdev,
@@ -1429,9 +1479,10 @@ static int init_cmdq(struct hinic5_cmdq *cmdq, struct hinic5_hwdev *hwdev,
spin_lock_init(&cmdq->cmdq_lock);
- cmdq->cmd_infos = kcalloc(cmdq->wq.q_depth, sizeof(*cmdq->cmd_infos),
- GFP_KERNEL);
+ cmdq->cmd_infos =
+ kcalloc(cmdq->wq.q_depth, sizeof(*cmdq->cmd_infos), GFP_KERNEL);
if (!cmdq->cmd_infos) {
+ sdk_err(hwdev->dev_hdl, "Failed to allocate cmdq infos\n");
err = -ENOMEM;
goto cmd_infos_err;
}
@@ -1460,11 +1511,13 @@ static int hinic5_set_cmdq_ctxts(struct hinic5_hwdev *hwdev)
cmdq_type = HINIC5_CMDQ_SYNC;
for (; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
if (cmdqs->cmdq_mode == HINIC5_NORMAL_CMDQ) {
- err = hinic5_set_cmdq_ctxt(hwdev, (u8)cmdq_type,
- &cmdqs->cmdq[cmdq_type].cmdq_ctxt);
+ err = hinic5_set_cmdq_ctxt(
+ hwdev, (u8)cmdq_type,
+ &cmdqs->cmdq[cmdq_type].cmdq_ctxt);
} else {
ctxt = &cmdqs->cmdq[cmdq_type].cmdq_enhance_ctxt;
- err = hinic5_set_enhance_cmdq_ctxt(hwdev, (u8)cmdq_type, ctxt);
+ err = hinic5_set_enhance_cmdq_ctxt(hwdev, (u8)cmdq_type,
+ ctxt);
}
if (err != 0)
return err;
@@ -1484,8 +1537,7 @@ static void cmdq_flush_sync_cmd(struct hinic5_cmdq_cmd_info *cmd_info)
cmd_info->cmd_type = HINIC5_CMD_TYPE_FORCE_STOP;
- if (cmd_info->cmpt_code &&
- *cmd_info->cmpt_code == CMDQ_SEND_CMPT_CODE)
+ if (cmd_info->cmpt_code && *cmd_info->cmpt_code == CMDQ_SEND_CMPT_CODE)
*cmd_info->cmpt_code = CMDQ_FORCE_STOP_CMPT_CODE;
if (cmd_info->done) {
@@ -1497,15 +1549,14 @@ static void cmdq_flush_sync_cmd(struct hinic5_cmdq_cmd_info *cmd_info)
}
}
-void hinic5_cmdq_flush_cmd(struct hinic5_hwdev *hwdev,
- struct hinic5_cmdq *cmdq)
+void hinic5_cmdq_flush_cmd(struct hinic5_hwdev *hwdev, struct hinic5_cmdq *cmdq)
{
struct hinic5_cmdq_cmd_info *cmd_info = NULL;
u16 ci = 0;
spin_lock_bh(&cmdq->cmdq_lock);
- while (cmdq_read_wqe(&cmdq->wq, &ci)) {
+ while (cmdq_read_wqe(&cmdq->wq, &ci) != NULL) {
cmd_info = &cmdq->cmd_infos[ci];
hinic5_wq_put_wqebbs(&cmdq->wq, cmd_info->wqebb_use_num);
@@ -1517,7 +1568,8 @@ void hinic5_cmdq_flush_cmd(struct hinic5_hwdev *hwdev,
spin_unlock_bh(&cmdq->cmdq_lock);
}
-static void hinic5_cmdq_flush_channel_sync_cmd(struct hinic5_hwdev *hwdev, u16 channel)
+static void hinic5_cmdq_flush_channel_sync_cmd(struct hinic5_hwdev *hwdev,
+ u16 channel)
{
struct hinic5_cmdq_cmd_info *cmd_info = NULL;
struct hinic5_cmdq *cmdq = NULL;
@@ -1533,8 +1585,8 @@ static void hinic5_cmdq_flush_channel_sync_cmd(struct hinic5_hwdev *hwdev, u16 c
wq = &cmdq->wq;
ci = wq->cons_idx;
- wqe_cnt = (u16)WQ_MASK_IDX(wq, wq->prod_idx +
- wq->q_depth - wq->cons_idx);
+ wqe_cnt =
+ (u16)WQ_MASK_IDX(wq, wq->prod_idx + wq->q_depth - wq->cons_idx);
for (i = 0; i < wqe_cnt; i++) {
cmd_info = &cmdq->cmd_infos[WQ_MASK_IDX(wq, ci + i)];
if (cmd_info->channel == channel)
@@ -1557,8 +1609,8 @@ void hinic5_cmdq_flush_sync_cmd(struct hinic5_hwdev *hwdev)
wq = &cmdq->wq;
ci = wq->cons_idx;
- wqe_cnt = (u16)WQ_MASK_IDX(wq, wq->prod_idx +
- wq->q_depth - wq->cons_idx);
+ wqe_cnt =
+ (u16)WQ_MASK_IDX(wq, wq->prod_idx + wq->q_depth - wq->cons_idx);
for (i = 0; i < wqe_cnt; i++) {
cmd_info = &cmdq->cmd_infos[WQ_MASK_IDX(wq, ci + i)];
cmdq_flush_sync_cmd(cmd_info);
@@ -1570,7 +1622,6 @@ void hinic5_cmdq_flush_sync_cmd(struct hinic5_hwdev *hwdev)
static void cmdq_reset_all_cmd_buff(struct hinic5_cmdq *cmdq)
{
u16 i;
-
if (!cmdq) {
pr_err("cmdq is null\n");
return;
@@ -1633,7 +1684,8 @@ static int create_cmdq_wq(struct hinic5_cmdqs *cmdqs)
err = hinic5_wq_create(cmdqs->hwdev, &cmdqs->cmdq[cmdq_type].wq,
HINIC5_CMDQ_DEPTH, cmdqs->wqebb_size);
if (err != 0) {
- sdk_err(cmdqs->hwdev->dev_hdl, "Failed to create cmdq wq\n");
+ sdk_err(cmdqs->hwdev->dev_hdl,
+ "Failed to create cmdq wq\n");
goto destroy_wq;
}
}
@@ -1641,11 +1693,12 @@ static int create_cmdq_wq(struct hinic5_cmdqs *cmdqs)
/* 1-level CLA must put all cmdq's wq page addr in one wq block */
if (!WQ_IS_0_LEVEL_CLA(&cmdqs->cmdq[HINIC5_CMDQ_SYNC].wq)) {
/* cmdq wq's CLA table is up to 512B */
-#define CMDQ_WQ_CLA_SIZE 512
+#define CMDQ_WQ_CLA_SIZE 512
if (cmdqs->cmdq[HINIC5_CMDQ_SYNC].wq.num_wq_pages >
CMDQ_WQ_CLA_SIZE / sizeof(u64)) {
err = -EINVAL;
- sdk_err(cmdqs->hwdev->dev_hdl, "Cmdq wq page exceed limit: %lu\n",
+ sdk_err(cmdqs->hwdev->dev_hdl,
+ "Cmdq wq page exceed limit: %lu\n",
CMDQ_WQ_CLA_SIZE / sizeof(u64));
goto destroy_wq;
}
@@ -1655,15 +1708,25 @@ static int create_cmdq_wq(struct hinic5_cmdqs *cmdqs)
&cmdqs->wq_block_paddr, GFP_KERNEL);
if (!cmdqs->wq_block_vaddr) {
err = -ENOMEM;
- sdk_err(cmdqs->hwdev->dev_hdl, "Failed to alloc cmdq wq block\n");
+ sdk_err(cmdqs->hwdev->dev_hdl,
+ "Failed to alloc cmdq wq block\n");
goto destroy_wq;
}
type = HINIC5_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++) {
- memcpy((u8 *)cmdqs->wq_block_vaddr + ((u64)type *CMDQ_WQ_CLA_SIZE),
- cmdqs->cmdq[type].wq.wq_block_vaddr,
- cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
+ err = memcpy_s((u8 *)cmdqs->wq_block_vaddr +
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
+ PAGE_SIZE - CMDQ_WQ_CLA_SIZE * type,
+ cmdqs->cmdq[type].wq.wq_block_vaddr,
+ cmdqs->cmdq[type].wq.num_wq_pages *
+ sizeof(u64));
+ if (err != 0) {
+ sdk_err(cmdqs->hwdev->dev_hdl,
+ "Memcpy cmdq failed, type: %u.\n",
+ type);
+ goto destroy_wq;
+ }
}
}
@@ -1700,13 +1763,15 @@ static int init_cmdqs(struct hinic5_hwdev *hwdev)
hwdev->cmdqs = cmdqs;
cmdqs->hwdev = hwdev;
- if (HINIC5_HWIF_NUM_CEQS(hwdev->hwif) == 0 || hwdev->poll != 0)
+ if (HINIC5_HWIF_NUM_CEQS(hwdev->hwif) == 0 || hwdev->poll != 0) {
cmdqs->poll = true;
+ }
- if (COMM_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev))
+ if (COMM_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev)) {
cmdqs->cmdq_mode = HINIC5_ENHANCE_CMDQ;
- else
+ } else {
cmdqs->cmdq_mode = HINIC5_NORMAL_CMDQ;
+ }
hwdev->cmdq_mode = cmdqs->cmdq_mode;
@@ -1720,22 +1785,26 @@ static int init_cmdqs(struct hinic5_hwdev *hwdev)
cmdqs->cmdq_num = HINIC5_MAX_CMDQ_TYPES;
if (COMM_SUPPORT_CMDQ_NUM(hwdev)) {
- if (hwdev->glb_attr.cmdq_num <= HINIC5_MAX_CMDQ_TYPES)
+ if (hwdev->glb_attr.cmdq_num <= HINIC5_MAX_CMDQ_TYPES) {
cmdqs->cmdq_num = hwdev->glb_attr.cmdq_num;
- else
- sdk_warn(hwdev->dev_hdl, "Adjust cmdq num to %d\n", HINIC5_MAX_CMDQ_TYPES);
+ } else {
+ sdk_warn(hwdev->dev_hdl, "Adjust cmdq num to %d\n",
+ HINIC5_MAX_CMDQ_TYPES);
+ }
}
cmdqs->cmd_buf_size = HINIC5_CMDQ_MAX_BUF_SIZE;
if (COMM_SUPPORT_CMD_BUF_SIZE(hwdev)) {
- if (hwdev->glb_attr.cmd_buf_size <= HINIC5_CMDQ_MAX_BUF_SIZE)
+ if (hwdev->glb_attr.cmd_buf_size <= HINIC5_CMDQ_MAX_BUF_SIZE) {
cmdqs->cmd_buf_size = hwdev->glb_attr.cmd_buf_size;
- else
- sdk_warn(hwdev->dev_hdl,
- "Adjust cmd buf size to %d\n", HINIC5_CMDQ_MAX_BUF_SIZE);
+ } else {
+ sdk_warn(hwdev->dev_hdl, "Adjust cmd buf size to %d\n",
+ HINIC5_CMDQ_MAX_BUF_SIZE);
+ }
}
- cmdqs->cmd_buf_pool = dma_pool_create("hinic5_cmdq", hwdev->dev_hdl, cmdqs->cmd_buf_size,
+ cmdqs->cmd_buf_pool = dma_pool_create("hinic5_cmdq", hwdev->dev_hdl,
+ cmdqs->cmd_buf_size,
HINIC5_CMDQ_BUF_ALIGN, 0ULL);
if (!cmdqs->cmd_buf_pool) {
sdk_err(hwdev->dev_hdl, "Failed to create cmdq buffer pool\n");
@@ -1765,15 +1834,19 @@ int hinic5_cmdqs_init(struct hinic5_hwdev *hwdev)
err = hinic5_alloc_db_addr(hwdev, &db_base, NULL);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to allocate doorbell address\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to allocate doorbell address\n");
goto alloc_db_err;
}
cmdqs->cmdqs_db_base = (u8 *)db_base;
- for (cmdq_type = HINIC5_CMDQ_SYNC; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
+ for (cmdq_type = HINIC5_CMDQ_SYNC; cmdq_type < cmdqs->cmdq_num;
+ cmdq_type++) {
err = init_cmdq(&cmdqs->cmdq[cmdq_type], hwdev, cmdq_type);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to initialize cmdq type :%u\n", cmdq_type);
+ sdk_err(hwdev->dev_hdl,
+ "Failed to initialize cmdq type :%u\n",
+ cmdq_type);
goto init_cmdq_err;
}
@@ -1781,7 +1854,8 @@ int hinic5_cmdqs_init(struct hinic5_hwdev *hwdev)
cmdq_init_queue_ctxt(cmdqs, &cmdqs->cmdq[cmdq_type],
&cmdqs->cmdq[cmdq_type].cmdq_ctxt);
else /* HINIC5_ENHANCE_CMDQ */
- hinic5_enhanced_cmdq_init_queue_ctxt(cmdqs, &cmdqs->cmdq[cmdq_type]);
+ enhanced_cmdq_init_queue_ctxt(cmdqs,
+ &cmdqs->cmdq[cmdq_type]);
}
err = hinic5_set_cmdq_ctxts(hwdev);
@@ -1825,4 +1899,4 @@ void hinic5_cmdqs_free(struct hinic5_hwdev *hwdev)
dma_pool_destroy(cmdqs->cmd_buf_pool);
kfree(cmdqs);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_common.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_common.c
index b9f9735aa..eca12e7c5 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_common.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_common.c
@@ -1,18 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_common.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include <linux/kernel.h>
#include <linux/io-mapping.h>
#include <linux/delay.h>
#include "ossl_knl.h"
+#include "hisdk5_hwif.h"
#include "hinic5_common.h"
int hinic5_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -46,7 +40,8 @@ int hinic5_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
return -ENOMEM;
align_paddr = ALIGN(paddr, align);
- align_vaddr = (void *)(uintptr_t)((u64)(uintptr_t)vaddr + (align_paddr - paddr));
+ align_vaddr = (void *)(uintptr_t)((u64)(uintptr_t)vaddr +
+ (align_paddr - paddr));
out:
mem_align->real_size = (u32)real_size;
@@ -66,8 +61,8 @@ void hinic5_dma_free_coherent_align(void *dev_hdl,
pr_err("mem_align is null\n");
return;
}
- dma_free_coherent(dev_hdl, mem_align->real_size,
- mem_align->ori_vaddr, mem_align->ori_paddr);
+ dma_free_coherent(dev_hdl, mem_align->real_size, mem_align->ori_vaddr,
+ mem_align->ori_paddr);
}
EXPORT_SYMBOL(hinic5_dma_free_coherent_align);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_enhance_cmdq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_enhance_cmdq.c
index c927ad1e7..9a7b7819f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_enhance_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_enhance_cmdq.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_enhance_cmdq.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -33,7 +26,8 @@
#include "hinic5_hw_comm.h"
#include "hinic5_cmdq.h"
-void hinic5_enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs, struct hinic5_cmdq *cmdq)
+void enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs,
+ struct hinic5_cmdq *cmdq)
{
struct enhance_cmdq_ctxt_info *ctxt_info = &cmdq->cmdq_enhance_ctxt;
struct hinic5_wq *wq = &cmdq->wq;
@@ -60,11 +54,10 @@ void hinic5_enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs, struct hin
ENHANCED_CMDQ_SET(1, CTXT0_HW_BUSY_BIT);
}
- ctxt_info->dfx_pi_ci =
- ENHANCED_CMDQ_SET(0, CTXT1_Q_DIS) |
- ENHANCED_CMDQ_SET(0, CTXT1_ERR_CODE) |
- ENHANCED_CMDQ_SET(start_pi, CTXT1_PI) |
- ENHANCED_CMDQ_SET(start_ci, CTXT1_CI);
+ ctxt_info->dfx_pi_ci = ENHANCED_CMDQ_SET(0, CTXT1_Q_DIS) |
+ ENHANCED_CMDQ_SET(0, CTXT1_ERR_CODE) |
+ ENHANCED_CMDQ_SET(start_pi, CTXT1_PI) |
+ ENHANCED_CMDQ_SET(start_ci, CTXT1_CI);
/* second part 16B */
ctxt_info->pft_thd =
@@ -73,9 +66,8 @@ void hinic5_enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs, struct hin
ENHANCED_CMDQ_SET(WQ_PREFETCH_MIN, CTXT2_PFT_MIN) |
ENHANCED_CMDQ_SET(WQ_PREFETCH_MAX, CTXT2_PFT_MAX) |
ENHANCED_CMDQ_SET(WQ_PREFETCH_THRESHOLD, CTXT2_PFT_THD);
- ctxt_info->pft_ci =
- ENHANCED_CMDQ_SET(pfn, CTXT3_PFT_CI_ADDR) |
- ENHANCED_CMDQ_SET(start_ci, CTXT3_PFT_CI);
+ ctxt_info->pft_ci = ENHANCED_CMDQ_SET(pfn, CTXT3_PFT_CI_ADDR) |
+ ENHANCED_CMDQ_SET(start_ci, CTXT3_PFT_CI);
/* third part 16B */
cmdq_first_block_paddr = cmdqs->wq_block_paddr;
@@ -84,8 +76,9 @@ void hinic5_enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs, struct hin
ctxt_info->ci_cla_addr = ENHANCED_CMDQ_SET(pfn, CTXT4_CI_CLA_ADDR);
}
-static void enhance_cmdq_set_completion(union hinic5_cmdq_enhance_completion *completion,
- const struct hinic5_cmd_buf *buf_out)
+static void
+enhance_cmdq_set_completion(union hinic5_cmdq_enhance_completion *completion,
+ const struct hinic5_cmd_buf *buf_out)
{
completion->sge_resp_hi_addr = upper_32_bits(buf_out->dma_addr);
completion->sge_resp_lo_addr = lower_32_bits(buf_out->dma_addr);
@@ -93,24 +86,31 @@ static void enhance_cmdq_set_completion(union hinic5_cmdq_enhance_completion *co
}
static void cmdq_set_wqe_buf_desc(struct hinic5_enhanced_cmdq_wqe *enhanced_wqe,
- const struct hinic5_cmdq_cmd_param *cmd_buf, u32 len)
+ const struct hinic5_cmdq_cmd_param *cmd_buf,
+ u32 len)
{
- enhanced_wqe->buf_desc[0].sge_send_hi_addr = upper_32_bits(cmd_buf->buf_in->dma_addr + len);
- enhanced_wqe->buf_desc[0].sge_send_lo_addr = lower_32_bits(cmd_buf->buf_in->dma_addr + len);
+ enhanced_wqe->buf_desc[0].sge_send_hi_addr =
+ upper_32_bits(cmd_buf->buf_in->dma_addr + len);
+ enhanced_wqe->buf_desc[0].sge_send_lo_addr =
+ lower_32_bits(cmd_buf->buf_in->dma_addr + len);
enhanced_wqe->buf_desc[0].len = len;
enhanced_wqe->buf_desc[1].sge_send_hi_addr =
upper_32_bits(cmd_buf->buf_in->dma_addr + (len << 1));
enhanced_wqe->buf_desc[1].sge_send_lo_addr =
lower_32_bits(cmd_buf->buf_in->dma_addr + (len << 1));
- enhanced_wqe->buf_desc[1].len = cmd_buf->buf_in->size - (len << 1); /* remain data len */
+ enhanced_wqe->buf_desc[1].len =
+ cmd_buf->buf_in->size - (len << 1); /* remain data len */
}
-void hinic5_enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe, enum hinic5_cmdq_cmd_type cmd_type,
- const struct hinic5_cmdq_cmd_param *cmd_buf, int wrapped)
+void enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe,
+ enum hinic5_cmdq_cmd_type cmd_type,
+ const struct hinic5_cmdq_cmd_param *cmd_buf,
+ int wrapped)
{
struct hinic5_enhanced_cmdq_wqe *enhanced_wqe = NULL;
u32 len = 0;
+ int ret;
if (!wqe || !cmd_buf || !cmd_buf->buf_in) {
pr_err("wqe or buf_in is null\n");
@@ -119,85 +119,98 @@ void hinic5_enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe, enum hinic5_cmdq_
enhanced_wqe = &wqe->enhanced_cmdq_wqe;
/* Wqe should be 64B aligned, so we fill 3 sges
- * split data len as three parts carried with ctrl sec and two bdsl
- */
+ split data len as three parts carried with ctrl sec and two bdsl */
len = cmd_buf->buf_in->size / 3;
if (cmd_type != HINIC5_CMD_TYPE_INLINE_DATA) {
- enhanced_wqe->ctrl_sec.header = ENHANCE_CMDQ_WQE_HEADER_SET(len, SEND_SGE_LEN) |
- ENHANCE_CMDQ_WQE_HEADER_SET(BUFDESC_ENHANCE_CMD_LEN, BDSL) |
+ enhanced_wqe->ctrl_sec.header =
+ ENHANCE_CMDQ_WQE_HEADER_SET(len, SEND_SGE_LEN) |
+ ENHANCE_CMDQ_WQE_HEADER_SET(BUFDESC_ENHANCE_CMD_LEN,
+ BDSL) |
ENHANCE_CMDQ_WQE_HEADER_SET(DATA_SGE, DF) |
ENHANCE_CMDQ_WQE_HEADER_SET(NORMAL_WQE_TYPE, DN) |
ENHANCE_CMDQ_WQE_HEADER_SET(COMPACT_WQE_TYPE, EC) |
ENHANCE_CMDQ_WQE_HEADER_SET((u32)wrapped, HW_BUSY_BIT);
- enhanced_wqe->ctrl_sec.sge_send_hi_addr = upper_32_bits(cmd_buf->buf_in->dma_addr);
- enhanced_wqe->ctrl_sec.sge_send_lo_addr = lower_32_bits(cmd_buf->buf_in->dma_addr);
+ enhanced_wqe->ctrl_sec.sge_send_hi_addr =
+ upper_32_bits(cmd_buf->buf_in->dma_addr);
+ enhanced_wqe->ctrl_sec.sge_send_lo_addr =
+ lower_32_bits(cmd_buf->buf_in->dma_addr);
cmdq_set_wqe_buf_desc(enhanced_wqe, cmd_buf, len);
} else {
enhanced_wqe->ctrl_sec.header =
- ENHANCE_CMDQ_WQE_HEADER_SET(cmd_buf->buf_in->size, BDSL) | /* 64B ALIGNED */
+ ENHANCE_CMDQ_WQE_HEADER_SET(cmd_buf->buf_in->size,
+ BDSL) | /* 64B ALIGNED */
ENHANCE_CMDQ_WQE_HEADER_SET(DATA_DIRECT, DF) |
ENHANCE_CMDQ_WQE_HEADER_SET(NORMAL_WQE_TYPE, DN) |
ENHANCE_CMDQ_WQE_HEADER_SET(COMPACT_WQE_TYPE, EC) |
ENHANCE_CMDQ_WQE_HEADER_SET((u32)wrapped, HW_BUSY_BIT);
}
- enhanced_wqe->completion.cs_format = ENHANCE_CMDQ_WQE_CS_SET(cmd_buf->cmd, CMD) |
+ enhanced_wqe->completion.cs_format =
+ ENHANCE_CMDQ_WQE_CS_SET(cmd_buf->cmd, CMD) |
ENHANCE_CMDQ_WQE_CS_SET(HINIC5_ACK_TYPE_CMDQ, ACK_TYPE) |
ENHANCE_CMDQ_WQE_CS_SET((cmd_buf->mod == HINIC5_MOD_ROCE), RN) |
- ENHANCE_CMDQ_WQE_CS_SET((cmd_buf->mod == HINIC5_MOD_HIHTR), RN) |
+ ENHANCE_CMDQ_WQE_CS_SET((cmd_buf->mod == HINIC5_MOD_HIHTR),
+ RN) |
ENHANCE_CMDQ_WQE_CS_SET(cmd_buf->mod, MOD);
switch (cmd_type) {
case HINIC5_CMD_TYPE_DIRECT_RESP:
- enhanced_wqe->completion.cs_format |= ENHANCE_CMDQ_WQE_CS_SET(INLINE_DATA, CF);
+ enhanced_wqe->completion.cs_format |=
+ ENHANCE_CMDQ_WQE_CS_SET(INLINE_DATA, CF);
break;
case HINIC5_CMD_TYPE_SGE_RESP:
if (cmd_buf->buf_out) {
enhanced_wqe->completion.cs_format |=
ENHANCE_CMDQ_WQE_CS_SET(SGE_RESPONSE, CF);
- enhance_cmdq_set_completion(&enhanced_wqe->completion, cmd_buf->buf_out);
+ enhance_cmdq_set_completion(&enhanced_wqe->completion,
+ cmd_buf->buf_out);
}
break;
case HINIC5_CMD_TYPE_ASYNC:
break;
case HINIC5_CMD_TYPE_INLINE_DATA:
- enhance_cmdq_set_completion(&enhanced_wqe->completion, cmd_buf->buf_out);
- memcpy(enhanced_wqe->inline_data, cmd_buf->buf_in->buf, cmd_buf->buf_in->size);
+ enhance_cmdq_set_completion(&enhanced_wqe->completion,
+ cmd_buf->buf_out);
+ ret = memcpy_s(enhanced_wqe->inline_data,
+ HINIC5_CMDQ_MAX_INLINE_DATA_SIZE,
+ cmd_buf->buf_in->buf, cmd_buf->buf_in->size);
+ if (ret != 0) {
+ pr_err("enhance cmdq: memcpy failed\n");
+ }
break;
default:
break;
}
}
-static inline u32 enhanced_cmdq_completion_get_error_code
- (union hinic5_cmdq_enhance_completion *completion)
+static inline u32 enhanced_cmdq_completion_get_error_code(
+ union hinic5_cmdq_enhance_completion *completion)
{
u32 cs_dw0 = hinic5_hw_cpu32(completion->dw[0]);
-
return ENHANCE_CMDQ_WQE_CS_GET(cs_dw0, ERR_CODE);
}
-static inline u32 enhanced_cmdq_completion_get_error_status
- (union hinic5_cmdq_enhance_completion *completion)
+static inline u32 enhanced_cmdq_completion_get_error_status(
+ union hinic5_cmdq_enhance_completion *completion)
{
u32 cs_dw0, cs_dw3, error_status;
cs_dw0 = hinic5_hw_cpu32(completion->dw[0]);
cs_dw3 = hinic5_hw_cpu32(completion->dw[0x3]);
- error_status = ENHANCE_CMDQ_WQE_CS_GET(cs_dw0, ERR_STATUS_28_18) <<
- ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_OFFSET;
+ error_status = ENHANCE_CMDQ_WQE_CS_GET(cs_dw0, ERR_STATUS_28_18)
+ << ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_OFFSET;
error_status |= ENHANCE_CMDQ_WQE_CS_GET(cs_dw3, ERR_STATUS_17_0);
return error_status;
}
-static inline u64 enhanced_cmdq_completion_get_udata
- (union hinic5_cmdq_enhance_completion *completion,
- struct hinic5_cmdq *cmdq)
+static inline u64 enhanced_cmdq_completion_get_udata(
+ union hinic5_cmdq_enhance_completion *completion,
+ struct hinic5_cmdq *cmdq)
{
u64 udata_l, udata_h;
@@ -219,9 +232,8 @@ void enhanced_cmdq_update_cmd_status(struct hinic5_cmdq *cmdq,
errcode = enhanced_cmdq_completion_get_error_code(completion);
if (errcode != 0) {
- error_status = enhanced_cmdq_completion_get_error_status(completion);
- sdk_err(cmdq->hwdev->dev_hdl, "Cmdq error code 0x%x, error status 0x%x\n",
- errcode, error_status);
+ error_status =
+ enhanced_cmdq_completion_get_error_status(completion);
}
if (COMM_SUPPORT_HTN_CMD(cmdq->hwdev)) {
@@ -230,16 +242,16 @@ void enhanced_cmdq_update_cmd_status(struct hinic5_cmdq *cmdq,
*cmd_info->direct_resp = error_status;
} else {
/* Non-HTN enhanced CMDQ errcode try to align with normal CMDQ.
- * [30:29] is errcode from completion, which actually has only 1 bit,
- * [28:0] is error_status from completion
- */
- errcode = (errcode & HINIC5_CMDQ_CQE_DW0_ERR_CODE_MASK) <<
- HINIC5_CMDQ_CQE_DW0_ERR_CODE_SHIFT;
+ [30:29] is errcode from completion, which actually has only 1 bit,
+ [28:0] is error_status from completion */
+ errcode = (errcode & HINIC5_CMDQ_CQE_DW0_ERR_CODE_MASK)
+ << HINIC5_CMDQ_CQE_DW0_ERR_CODE_SHIFT;
errcode |= error_status & HINIC5_CMDQ_CQE_DW0_ERR_STATUS_MASK;
*cmd_info->errcode = (int)errcode;
if (cmd_info->direct_resp)
*cmd_info->direct_resp =
- enhanced_cmdq_completion_get_udata(completion, cmdq);
+ enhanced_cmdq_completion_get_udata(completion,
+ cmdq);
}
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_eqs.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_eqs.c
index 4bfbedb31..1341dc916 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_eqs.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_eqs.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -23,241 +16,228 @@
#include <linux/cpumask.h>
#endif
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
#include "ossl_knl.h"
#include "hinic5_crm.h"
#include "hinic5_hw.h"
#include "hinic5_common.h"
#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_hw.h"
#include "hinic5_csr_inner.h"
#include "hinic5_hw_comm.h"
#include "hinic5_prof_adap.h"
#include "hinic5_eqs.h"
-#define HINIC5_EQS_WQ_NAME "hinic5_eqs"
+#define HINIC5_EQS_WQ_NAME "hinic5_eqs"
-#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
-#define AEQ_CTRL_0_DMA_ATTR_SHIFT 12
-#define AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20
-#define AEQ_CTRL_0_INTR_MODE_SHIFT 31
+#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
+#define AEQ_CTRL_0_DMA_ATTR_SHIFT 12
+#define AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20
+#define AEQ_CTRL_0_INTR_MODE_SHIFT 31
-#define AEQ_CTRL_0_INTR_IDX_MASK 0x3FFU
-#define AEQ_CTRL_0_DMA_ATTR_MASK 0x3FU
-#define AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x7U
-#define AEQ_CTRL_0_INTR_MODE_MASK 0x1U
+#define AEQ_CTRL_0_INTR_IDX_MASK 0x3FFU
+#define AEQ_CTRL_0_DMA_ATTR_MASK 0x3FU
+#define AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x7U
+#define AEQ_CTRL_0_INTR_MODE_MASK 0x1U
-#define AEQ_CTRL_0_SET(val, member) \
- (((val) & AEQ_CTRL_0_##member##_MASK) << \
- AEQ_CTRL_0_##member##_SHIFT)
+#define AEQ_CTRL_0_SET(val, member) \
+ (((val)&AEQ_CTRL_0_##member##_MASK) << AEQ_CTRL_0_##member##_SHIFT)
-#define AEQ_CTRL_0_CLEAR(val, member) \
- ((val) & (~(AEQ_CTRL_0_##member##_MASK << \
- AEQ_CTRL_0_##member##_SHIFT)))
+#define AEQ_CTRL_0_CLEAR(val, member) \
+ ((val) & (~(AEQ_CTRL_0_##member##_MASK << AEQ_CTRL_0_##member##_SHIFT)))
-#define AEQ_CTRL_1_LEN_SHIFT 0
-#define AEQ_CTRL_1_ELEM_SIZE_SHIFT 24
-#define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28
+#define AEQ_CTRL_1_LEN_SHIFT 0
+#define AEQ_CTRL_1_ELEM_SIZE_SHIFT 24
+#define AEQ_CTRL_1_PAGE_SIZE_SHIFT 28
-#define AEQ_CTRL_1_LEN_MASK 0x1FFFFFU
-#define AEQ_CTRL_1_ELEM_SIZE_MASK 0x3U
-#define AEQ_CTRL_1_PAGE_SIZE_MASK 0xFU
+#define AEQ_CTRL_1_LEN_MASK 0x1FFFFFU
+#define AEQ_CTRL_1_ELEM_SIZE_MASK 0x3U
+#define AEQ_CTRL_1_PAGE_SIZE_MASK 0xFU
-#define AEQ_CTRL_1_SET(val, member) \
- (((val) & AEQ_CTRL_1_##member##_MASK) << \
- AEQ_CTRL_1_##member##_SHIFT)
+#define AEQ_CTRL_1_SET(val, member) \
+ (((val)&AEQ_CTRL_1_##member##_MASK) << AEQ_CTRL_1_##member##_SHIFT)
-#define AEQ_CTRL_1_CLEAR(val, member) \
- ((val) & (~(AEQ_CTRL_1_##member##_MASK << \
- AEQ_CTRL_1_##member##_SHIFT)))
+#define AEQ_CTRL_1_CLEAR(val, member) \
+ ((val) & (~(AEQ_CTRL_1_##member##_MASK << AEQ_CTRL_1_##member##_SHIFT)))
-#define HINIC5_EQ_PROD_IDX_MASK 0xFFFFF
-#define HINIC5_TASK_PROCESS_EQE_LIMIT 1024
-#define HINIC5_EQ_UPDATE_CI_STEP 64
+#define HINIC5_EQ_PROD_IDX_MASK 0xFFFFF
+#define HINIC5_TASK_PROCESS_EQE_LIMIT 1024
+#define HINIC5_EQ_UPDATE_CI_STEP 64
static u32 g_aeq_len = HINIC5_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
-MODULE_PARM_DESC(g_aeq_len,
- "aeq depth, valid range is " __stringify(HINIC5_MIN_AEQ_LEN)
- " - " __stringify(HINIC5_MAX_AEQ_LEN));
+MODULE_PARM_DESC(
+ g_aeq_len,
+ "aeq depth, valid range is " __stringify(
+ HINIC5_MIN_AEQ_LEN) " - " __stringify(HINIC5_MAX_AEQ_LEN));
static u32 g_ceq_len = HINIC5_DEFAULT_CEQ_LEN;
module_param(g_ceq_len, uint, 0444);
-MODULE_PARM_DESC(g_ceq_len,
- "ceq depth, valid range is " __stringify(HINIC5_MIN_CEQ_LEN)
- " - " __stringify(HINIC5_MAX_CEQ_LEN));
+MODULE_PARM_DESC(
+ g_ceq_len,
+ "ceq depth, valid range is " __stringify(
+ HINIC5_MIN_CEQ_LEN) " - " __stringify(HINIC5_MAX_CEQ_LEN));
static u32 g_num_ceqe_in_tasklet = HINIC5_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
-MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
- "The max number of ceqe can be processed in tasklet, default = 1024");
+MODULE_PARM_DESC(
+ g_num_ceqe_in_tasklet,
+ "The max number of ceqe can be processed in tasklet, default = 1024");
static int g_aeq_cpu_affinity[HINIC5_AEQ_CPU_AFFINITY_MAX];
-static unsigned int g_aeq_cpu_affinity_nargs;
-module_param_array_named(aeq_cpu_affinity, g_aeq_cpu_affinity,
- int, &g_aeq_cpu_affinity_nargs, 0444);
+static unsigned int g_aeq_cpu_affinity_nargs = 0;
+module_param_array_named(aeq_cpu_affinity, g_aeq_cpu_affinity, int,
+ &g_aeq_cpu_affinity_nargs, 0444);
MODULE_PARM_DESC(aeq_cpu_affinity, "Aeqs cpu affinity, max num 16");
-#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
-#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
-#define CEQ_CTRL_0_LIMIT_KICK_SHIFT 20
-#define CEQ_CTRL_0_PCI_INTF_IDX_SHIFT 24
-#define CEQ_CTRL_0_PAGE_SIZE_SHIFT 27
-#define CEQ_CTRL_0_INTR_MODE_SHIFT 31
-
-#define CEQ_CTRL_0_INTR_IDX_MASK 0x3FFU
-#define CEQ_CTRL_0_DMA_ATTR_MASK 0x3FU
-#define CEQ_CTRL_0_LIMIT_KICK_MASK 0xFU
-#define CEQ_CTRL_0_PCI_INTF_IDX_MASK 0x7U
-#define CEQ_CTRL_0_PAGE_SIZE_MASK 0xF
-#define CEQ_CTRL_0_INTR_MODE_MASK 0x1U
-
-#define CEQ_CTRL_0_SET(val, member) \
- (((val) & CEQ_CTRL_0_##member##_MASK) << \
- CEQ_CTRL_0_##member##_SHIFT)
-
-#define CEQ_CTRL_1_LEN_SHIFT 0
-#define CEQ_CTRL_1_GLB_FUNC_ID_SHIFT 20
-
-#define CEQ_CTRL_1_LEN_MASK 0xFFFFFU
-#define CEQ_CTRL_1_GLB_FUNC_ID_MASK 0xFFFU
-
-#define CEQ_CTRL_1_SET(val, member) \
- (((val) & CEQ_CTRL_1_##member##_MASK) << \
- CEQ_CTRL_1_##member##_SHIFT)
-
-#define EQ_ELEM_DESC_TYPE_SHIFT 0
-#define EQ_ELEM_DESC_SRC_SHIFT 7
-#define EQ_ELEM_DESC_SIZE_SHIFT 8
-#define EQ_ELEM_DESC_WRAPPED_SHIFT 31
-
-#define EQ_ELEM_DESC_TYPE_MASK 0x7FU
-#define EQ_ELEM_DESC_SRC_MASK 0x1U
-#define EQ_ELEM_DESC_SIZE_MASK 0xFFU
-#define EQ_ELEM_DESC_WRAPPED_MASK 0x1U
-
-#define EQ_ELEM_DESC_GET(val, member) \
- (((val) >> EQ_ELEM_DESC_##member##_SHIFT) & \
- EQ_ELEM_DESC_##member##_MASK)
-
-#define EQ_CONS_IDX_CONS_IDX_SHIFT 0
-#define EQ_CONS_IDX_INT_ARMED_SHIFT 31
-
-#define EQ_CONS_IDX_CONS_IDX_MASK 0x1FFFFFU
-#define EQ_CONS_IDX_INT_ARMED_MASK 0x1U
-
-#define EQ_CONS_IDX_SET(val, member) \
- (((val) & EQ_CONS_IDX_##member##_MASK) << \
- EQ_CONS_IDX_##member##_SHIFT)
-
-#define EQ_CONS_IDX_CLEAR(val, member) \
- ((val) & (~(EQ_CONS_IDX_##member##_MASK << \
- EQ_CONS_IDX_##member##_SHIFT)))
-
-#define EQ_CI_SIMPLE_INDIR_CI_SHIFT 0
-#define EQ_CI_SIMPLE_INDIR_ARMED_SHIFT 21
-#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_SHIFT 30
-#define EQ_CI_SIMPLE_INDIR_CEQ_IDX_SHIFT 24
-
-#define EQ_CI_SIMPLE_INDIR_CI_MASK 0x1FFFFFU
-#define EQ_CI_SIMPLE_INDIR_ARMED_MASK 0x1U
-#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_MASK 0x3U
-#define EQ_CI_SIMPLE_INDIR_CEQ_IDX_MASK 0xFFU
-
-#define EQ_CI_SIMPLE_INDIR_SET(val, member) \
- (((val) & EQ_CI_SIMPLE_INDIR_##member##_MASK) << \
- EQ_CI_SIMPLE_INDIR_##member##_SHIFT)
-
-#define EQ_CI_SIMPLE_INDIR_CLEAR(val, member) \
- ((val) & (~(EQ_CI_SIMPLE_INDIR_##member##_MASK << \
- EQ_CI_SIMPLE_INDIR_##member##_SHIFT)))
-
-#define EQ_WRAPPED(eq) ((u32)(eq)->wrapped << EQ_VALID_SHIFT)
-
-#define EQ_CONS_IDX(eq) ((eq)->cons_idx | \
- ((u32)(eq)->wrapped << EQ_WRAPPED_SHIFT))
-
-#define EQ_CONS_IDX_REG_ADDR(eq) \
- (((eq)->type == HINIC5_AEQ) ? \
- HINIC5_CSR_AEQ_CONS_IDX_ADDR : \
- HINIC5_CSR_CEQ_CONS_IDX_ADDR)
-#define EQ_CI_SIMPLE_INDIR_REG_ADDR(eq) \
- (((eq)->type == HINIC5_AEQ) ? \
- HINIC5_CSR_AEQ_CI_SIMPLE_INDIR_ADDR : \
- HINIC5_CSR_CEQ_CI_SIMPLE_INDIR_ADDR)
-
-#define EQ_PROD_IDX_REG_ADDR(eq) \
- (((eq)->type == HINIC5_AEQ) ? \
- HINIC5_CSR_AEQ_PROD_IDX_ADDR : \
- HINIC5_CSR_CEQ_PROD_IDX_ADDR)
-
-#define HINIC5_EQ_HI_PHYS_ADDR_REG(type, pg_num) \
- ((u32)((type == HINIC5_AEQ) ? \
- HINIC5_AEQ_HI_PHYS_ADDR_REG(pg_num) : \
- HINIC5_CEQ_HI_PHYS_ADDR_REG(pg_num)))
-
-#define HINIC5_EQ_LO_PHYS_ADDR_REG(type, pg_num) \
- ((u32)((type == HINIC5_AEQ) ? \
- HINIC5_AEQ_LO_PHYS_ADDR_REG(pg_num) : \
- HINIC5_CEQ_LO_PHYS_ADDR_REG(pg_num)))
-
-#define GET_EQ_NUM_PAGES(eq, size) \
- ((u16)(ALIGN((u32)((eq)->eq_len * (eq)->elem_size), \
- (size)) / (size)))
-
-#define HINIC5_EQ_MAX_PAGES(eq) \
- ((eq)->type == HINIC5_AEQ ? HINIC5_AEQ_MAX_PAGES : \
- HINIC5_CEQ_MAX_PAGES)
-
-#define GET_EQ_NUM_ELEMS(eq, pg_size) ((pg_size) / (u32)(eq)->elem_size)
+#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
+#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
+#define CEQ_CTRL_0_LIMIT_KICK_SHIFT 20
+#define CEQ_CTRL_0_PCI_INTF_IDX_SHIFT 24
+#define CEQ_CTRL_0_PAGE_SIZE_SHIFT 27
+#define CEQ_CTRL_0_INTR_MODE_SHIFT 31
-#define GET_EQ_ELEMENT(eq, idx) \
+#define CEQ_CTRL_0_INTR_IDX_MASK 0x3FFU
+#define CEQ_CTRL_0_DMA_ATTR_MASK 0x3FU
+#define CEQ_CTRL_0_LIMIT_KICK_MASK 0xFU
+#define CEQ_CTRL_0_PCI_INTF_IDX_MASK 0x7U
+#define CEQ_CTRL_0_PAGE_SIZE_MASK 0xF
+#define CEQ_CTRL_0_INTR_MODE_MASK 0x1U
+
+#define CEQ_CTRL_0_SET(val, member) \
+ (((val)&CEQ_CTRL_0_##member##_MASK) << CEQ_CTRL_0_##member##_SHIFT)
+
+#define CEQ_CTRL_1_LEN_SHIFT 0
+#define CEQ_CTRL_1_GLB_FUNC_ID_SHIFT 20
+
+#define CEQ_CTRL_1_LEN_MASK 0xFFFFFU
+#define CEQ_CTRL_1_GLB_FUNC_ID_MASK 0xFFFU
+
+#define CEQ_CTRL_1_SET(val, member) \
+ (((val)&CEQ_CTRL_1_##member##_MASK) << CEQ_CTRL_1_##member##_SHIFT)
+
+#define EQ_ELEM_DESC_TYPE_SHIFT 0
+#define EQ_ELEM_DESC_SRC_SHIFT 7
+#define EQ_ELEM_DESC_SIZE_SHIFT 8
+#define EQ_ELEM_DESC_WRAPPED_SHIFT 31
+
+#define EQ_ELEM_DESC_TYPE_MASK 0x7FU
+#define EQ_ELEM_DESC_SRC_MASK 0x1U
+#define EQ_ELEM_DESC_SIZE_MASK 0xFFU
+#define EQ_ELEM_DESC_WRAPPED_MASK 0x1U
+
+#define EQ_ELEM_DESC_GET(val, member) \
+ (((val) >> EQ_ELEM_DESC_##member##_SHIFT) & \
+ EQ_ELEM_DESC_##member##_MASK)
+
+#define EQ_CONS_IDX_CONS_IDX_SHIFT 0
+#define EQ_CONS_IDX_INT_ARMED_SHIFT 31
+
+#define EQ_CONS_IDX_CONS_IDX_MASK 0x1FFFFFU
+#define EQ_CONS_IDX_INT_ARMED_MASK 0x1U
+
+#define EQ_CONS_IDX_SET(val, member) \
+ (((val)&EQ_CONS_IDX_##member##_MASK) << EQ_CONS_IDX_##member##_SHIFT)
+
+#define EQ_CONS_IDX_CLEAR(val, member) \
+ ((val) & \
+ (~(EQ_CONS_IDX_##member##_MASK << EQ_CONS_IDX_##member##_SHIFT)))
+
+#define EQ_CI_SIMPLE_INDIR_CI_SHIFT 0
+#define EQ_CI_SIMPLE_INDIR_ARMED_SHIFT 21
+#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_SHIFT 30
+#define EQ_CI_SIMPLE_INDIR_CEQ_IDX_SHIFT 24
+
+#define EQ_CI_SIMPLE_INDIR_CI_MASK 0x1FFFFFU
+#define EQ_CI_SIMPLE_INDIR_ARMED_MASK 0x1U
+#define EQ_CI_SIMPLE_INDIR_AEQ_IDX_MASK 0x3U
+#define EQ_CI_SIMPLE_INDIR_CEQ_IDX_MASK 0xFFU
+
+#define EQ_CI_SIMPLE_INDIR_SET(val, member) \
+ (((val)&EQ_CI_SIMPLE_INDIR_##member##_MASK) \
+ << EQ_CI_SIMPLE_INDIR_##member##_SHIFT)
+
+#define EQ_CI_SIMPLE_INDIR_CLEAR(val, member) \
+ ((val) & (~(EQ_CI_SIMPLE_INDIR_##member##_MASK \
+ << EQ_CI_SIMPLE_INDIR_##member##_SHIFT)))
+
+#define EQ_WRAPPED(eq) ((u32)(eq)->wrapped << EQ_VALID_SHIFT)
+
+#define EQ_CONS_IDX(eq) \
+ ((eq)->cons_idx | ((u32)(eq)->wrapped << EQ_WRAPPED_SHIFT))
+
+#define EQ_CONS_IDX_REG_ADDR(eq) \
+ (((eq)->type == HINIC5_AEQ) ? HINIC5_CSR_AEQ_CONS_IDX_ADDR : \
+ HINIC5_CSR_CEQ_CONS_IDX_ADDR)
+#define EQ_CI_SIMPLE_INDIR_REG_ADDR(eq) \
+ (((eq)->type == HINIC5_AEQ) ? HINIC5_CSR_AEQ_CI_SIMPLE_INDIR_ADDR : \
+ HINIC5_CSR_CEQ_CI_SIMPLE_INDIR_ADDR)
+
+#define EQ_PROD_IDX_REG_ADDR(eq) \
+ (((eq)->type == HINIC5_AEQ) ? HINIC5_CSR_AEQ_PROD_IDX_ADDR : \
+ HINIC5_CSR_CEQ_PROD_IDX_ADDR)
+
+#define HINIC5_EQ_HI_PHYS_ADDR_REG(type, pg_num) \
+ ((u32)((type == HINIC5_AEQ) ? HINIC5_AEQ_HI_PHYS_ADDR_REG(pg_num) : \
+ HINIC5_CEQ_HI_PHYS_ADDR_REG(pg_num)))
+
+#define HINIC5_EQ_LO_PHYS_ADDR_REG(type, pg_num) \
+ ((u32)((type == HINIC5_AEQ) ? HINIC5_AEQ_LO_PHYS_ADDR_REG(pg_num) : \
+ HINIC5_CEQ_LO_PHYS_ADDR_REG(pg_num)))
+
+#define GET_EQ_NUM_PAGES(eq, size) \
+ ((u16)(ALIGN((u32)((eq)->eq_len * (eq)->elem_size), (size)) / (size)))
+
+#define HINIC5_EQ_MAX_PAGES(eq) \
+ ((eq)->type == HINIC5_AEQ ? HINIC5_AEQ_MAX_PAGES : HINIC5_CEQ_MAX_PAGES)
+
+#define GET_EQ_NUM_ELEMS(eq, pg_size) ((pg_size) / (u32)(eq)->elem_size)
+
+#define GET_EQ_ELEMENT(eq, idx) \
(((u8 *)(eq)->eq_pages[(idx) / (eq)->num_elem_in_pg].align_vaddr) + \
(u32)(((idx) & ((eq)->num_elem_in_pg - 1)) * (eq)->elem_size))
-#define GET_AEQ_ELEM(eq, idx) \
- ((struct hinic5_aeq_elem *)GET_EQ_ELEMENT((eq), (idx)))
+#define GET_AEQ_ELEM(eq, idx) \
+ ((struct hinic5_aeq_elem *)GET_EQ_ELEMENT((eq), (idx)))
-#define GET_CEQ_ELEM(eq, idx) ((u32 *)GET_EQ_ELEMENT((eq), (idx)))
+#define GET_CEQ_ELEM(eq, idx) ((u32 *)GET_EQ_ELEMENT((eq), (idx)))
-#define GET_CURR_AEQ_ELEM(eq) GET_AEQ_ELEM((eq), (eq)->cons_idx)
+#define GET_CURR_AEQ_ELEM(eq) GET_AEQ_ELEM((eq), (eq)->cons_idx)
-#define GET_CURR_CEQ_ELEM(eq) GET_CEQ_ELEM((eq), (eq)->cons_idx)
+#define GET_CURR_CEQ_ELEM(eq) GET_CEQ_ELEM((eq), (eq)->cons_idx)
-#define PAGE_IN_4K(page_size) ((page_size) >> 12)
-#define EQ_SET_HW_PAGE_SIZE_VAL(eq) \
- ((u32)ilog2(PAGE_IN_4K((eq)->page_size)))
+#define PAGE_IN_4K(page_size) ((page_size) >> 12)
+#define EQ_SET_HW_PAGE_SIZE_VAL(eq) ((u32)ilog2(PAGE_IN_4K((eq)->page_size)))
-#define ELEMENT_SIZE_IN_32B(eq) (((eq)->elem_size) >> 5)
-#define EQ_SET_HW_ELEM_SIZE_VAL(eq) ((u32)ilog2(ELEMENT_SIZE_IN_32B(eq)))
+#define ELEMENT_SIZE_IN_32B(eq) (((eq)->elem_size) >> 5)
+#define EQ_SET_HW_ELEM_SIZE_VAL(eq) ((u32)ilog2(ELEMENT_SIZE_IN_32B(eq)))
-#define AEQ_DMA_ATTR_DEFAULT 0
-#define CEQ_DMA_ATTR_DEFAULT 0
+#define AEQ_DMA_ATTR_DEFAULT 0
+#define CEQ_DMA_ATTR_DEFAULT 0
-#define CEQ_LMT_KICK_DEFAULT 0
+#define CEQ_LMT_KICK_DEFAULT 0
-#define EQ_MSIX_RESEND_TIMER_CLEAR 1
+#define EQ_MSIX_RESEND_TIMER_CLEAR 1
-#define EQ_WRAPPED_SHIFT 20
+#define EQ_WRAPPED_SHIFT 20
-#define EQ_VALID_SHIFT 31
+#define EQ_VALID_SHIFT 31
-#define CEQE_TYPE_SHIFT 23
-#define CEQE_TYPE_MASK 0x7
+#define CEQE_TYPE_SHIFT 23
+#define CEQE_TYPE_MASK 0x7
-#define CEQE_TYPE(type) (((type) >> CEQE_TYPE_SHIFT) & \
- CEQE_TYPE_MASK)
+#define CEQE_TYPE(type) (((type) >> CEQE_TYPE_SHIFT) & CEQE_TYPE_MASK)
-#define CEQE_DATA_MASK 0x3FFFFFF
-#define CEQE_DATA(data) ((data) & CEQE_DATA_MASK)
+#define CEQE_DATA_MASK 0x3FFFFFF
+#define CEQE_DATA(data) ((data)&CEQE_DATA_MASK)
#define aeq_to_aeqs(eq) \
- container_of((eq) - (eq)->q_id, struct hinic5_aeqs, aeq[0])
+ container_of((eq) - (eq)->q_id, struct hinic5_aeqs, aeq[0])
#define ceq_to_ceqs(eq) \
- container_of((eq) - (eq)->q_id, struct hinic5_ceqs, ceq[0])
+ container_of((eq) - (eq)->q_id, struct hinic5_ceqs, ceq[0])
#ifdef __VMWARE__
static void ceq_interrupt(void *data, u32 irq);
@@ -276,7 +256,8 @@ static void ceq_tasklet(ulong ceq_data);
* @event: event for the handler
* @hw_cb: callback function
**/
-int hinic5_aeq_register_hw_cb(void *hwdev, void *pri_handle, enum hinic5_aeq_type event,
+int hinic5_aeq_register_hw_cb(void *hwdev, void *pri_handle,
+ enum hinic5_aeq_type event,
hinic5_aeq_hwe_cb hwe_cb)
{
struct hinic5_aeqs *aeqs = NULL;
@@ -330,7 +311,8 @@ void hinic5_aeq_unregister_hw_cb(void *hwdev, enum hinic5_aeq_type event)
* @event: soft event for the handler
* @sw_cb: callback function
**/
-int hinic5_aeq_register_swe_cb(void *hwdev, void *pri_handle, enum hinic5_aeq_sw_type event,
+int hinic5_aeq_register_swe_cb(void *hwdev, void *pri_handle,
+ enum hinic5_aeq_sw_type event,
hinic5_aeq_swe_cb aeq_swe_cb)
{
struct hinic5_aeqs *aeqs = NULL;
@@ -384,7 +366,8 @@ void hinic5_aeq_unregister_swe_cb(void *hwdev, enum hinic5_aeq_sw_type event)
* @event: event for the handler
* @ceq_cb: callback function
**/
-int hinic5_ceq_register_cb(void *hwdev, void *pri_handle, enum hinic5_ceq_event event,
+int hinic5_ceq_register_cb(void *hwdev, void *pri_handle,
+ enum hinic5_ceq_event event,
hinic5_ceq_event_cb callback)
{
struct hinic5_ceqs *ceqs = NULL;
@@ -393,12 +376,14 @@ int hinic5_ceq_register_cb(void *hwdev, void *pri_handle, enum hinic5_ceq_event
return 0;
#endif
- if (!hwdev || event >= HINIC5_MAX_CEQ_EVENTS)
+ if (!hwdev || event >= HINIC5_MAX_CEQ_EVENTS) {
return -EINVAL;
+ }
ceqs = ((struct hinic5_hwdev *)hwdev)->ceqs;
- if (!ceqs)
+ if (!ceqs) {
return 0;
+ }
ceqs->ceq_cb[event] = callback;
ceqs->ceq_cb_data[event] = pri_handle;
@@ -422,17 +407,20 @@ void hinic5_ceq_unregister_cb(void *hwdev, enum hinic5_ceq_event event)
return;
#endif
- if (!hwdev || event >= HINIC5_MAX_CEQ_EVENTS)
+ if (!hwdev || event >= HINIC5_MAX_CEQ_EVENTS) {
return;
+ }
ceqs = ((struct hinic5_hwdev *)hwdev)->ceqs;
- if (!ceqs)
+ if (!ceqs) {
return;
+ }
clear_bit(HINIC5_CEQ_CB_REG, &ceqs->ceq_cb_state[event]);
- while (test_bit(HINIC5_CEQ_CB_RUNNING, &ceqs->ceq_cb_state[event]))
+ while (test_bit(HINIC5_CEQ_CB_RUNNING, &ceqs->ceq_cb_state[event])) {
usleep_range(EQ_USLEEP_LOW_BOUND, EQ_USLEEP_HIG_BOUND);
+ }
ceqs->ceq_cb[event] = NULL;
}
@@ -458,13 +446,11 @@ static void set_eq_cons_idx(struct hinic5_eq *eq, u32 arm_state)
#endif
val = EQ_CI_SIMPLE_INDIR_SET(arm_state, ARMED);
if (eq->type == HINIC5_AEQ) {
- val = val |
- EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) |
- EQ_CI_SIMPLE_INDIR_SET(eq->q_id, AEQ_IDX);
+ val = val | EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) |
+ EQ_CI_SIMPLE_INDIR_SET(eq->q_id, AEQ_IDX);
} else {
- val = val |
- EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) |
- EQ_CI_SIMPLE_INDIR_SET(eq->q_id, CEQ_IDX);
+ val = val | EQ_CI_SIMPLE_INDIR_SET(eq_wrap_ci, CI) |
+ EQ_CI_SIMPLE_INDIR_SET(eq->q_id, CEQ_IDX);
}
hinic5_hwif_write_reg(eq->hwdev->hwif, addr, val);
@@ -482,8 +468,9 @@ static void ceq_event_handler(struct hinic5_ceqs *ceqs, u32 ceqe)
u32 ceqe_data = CEQE_DATA(ceqe);
if (event >= HINIC5_MAX_CEQ_EVENTS) {
- sdk_err(hwdev->dev_hdl, "Ceq unknown event:%d, ceqe date: 0x%x\n",
- event, ceqe_data);
+ sdk_err(hwdev->dev_hdl,
+ "Ceq unknown event:%d, ceqe date: 0x%x\n", event,
+ ceqe_data);
return;
}
@@ -513,16 +500,19 @@ static void aeq_elem_handler(struct hinic5_eq *eq, u32 aeqe_desc)
if (EQ_ELEM_DESC_GET(aeqe_desc, SRC) != 0) {
sw_event = event;
sw_type = sw_event >= HINIC5_NIC_FATAL_ERROR_MAX ?
- HINIC5_STATEFUL_EVENT : HINIC5_STATELESS_EVENT;
+ HINIC5_STATEFUL_EVENT :
+ HINIC5_STATELESS_EVENT;
/* SW event uses only the first 8B */
- memcpy(data, aeqe_pos->aeqe_data, HINIC5_AEQE_DATA_SIZE);
+ (void)memcpy_s(data, HINIC5_AEQE_DATA_SIZE, aeqe_pos->aeqe_data,
+ HINIC5_AEQE_DATA_SIZE);
hinic5_be32_to_cpu(data, HINIC5_AEQE_DATA_SIZE);
set_bit(HINIC5_AEQ_SW_CB_RUNNING,
&aeqs->aeq_sw_cb_state[sw_type]);
if (aeqs->aeq_swe_cb[sw_type] &&
test_bit(HINIC5_AEQ_SW_CB_REG,
&aeqs->aeq_sw_cb_state[sw_type]))
- aeqs->aeq_swe_cb[sw_type](aeqs->aeq_swe_cb_data[sw_type], event, data);
+ aeqs->aeq_swe_cb[sw_type](
+ aeqs->aeq_swe_cb_data[sw_type], event, data);
clear_bit(HINIC5_AEQ_SW_CB_RUNNING,
&aeqs->aeq_sw_cb_state[sw_type]);
@@ -530,7 +520,8 @@ static void aeq_elem_handler(struct hinic5_eq *eq, u32 aeqe_desc)
}
if (event < HINIC5_MAX_AEQ_EVENTS) {
- memcpy(data, aeqe_pos->aeqe_data, HINIC5_AEQE_DATA_SIZE);
+ (void)memcpy_s(data, HINIC5_AEQE_DATA_SIZE, aeqe_pos->aeqe_data,
+ HINIC5_AEQE_DATA_SIZE);
hinic5_be32_to_cpu(data, HINIC5_AEQE_DATA_SIZE);
size = EQ_ELEM_DESC_GET(aeqe_desc, SIZE);
@@ -539,7 +530,8 @@ static void aeq_elem_handler(struct hinic5_eq *eq, u32 aeqe_desc)
if (aeqs->aeq_hwe_cb[event] &&
test_bit(HINIC5_AEQ_HW_CB_REG,
&aeqs->aeq_hw_cb_state[event]))
- aeqs->aeq_hwe_cb[event](aeqs->aeq_hwe_cb_data[event], data, size);
+ aeqs->aeq_hwe_cb[event](aeqs->aeq_hwe_cb_data[event],
+ data, size);
clear_bit(HINIC5_AEQ_HW_CB_RUNNING,
&aeqs->aeq_hw_cb_state[event]);
return;
@@ -628,7 +620,8 @@ static void reschedule_eq_handler(struct hinic5_eq *eq)
if (eq->type == HINIC5_AEQ) {
struct hinic5_aeqs *aeqs = aeq_to_aeqs(eq);
- queue_work_on(hisdk5_get_work_cpu_affinity(eq->hwdev, WORK_TYPE_AEQ),
+ queue_work_on(hisdk5_get_work_cpu_affinity(eq->hwdev,
+ WORK_TYPE_AEQ),
aeqs->workq, &eq->aeq_work);
} else {
tasklet_schedule(&eq->ceq_tasklet);
@@ -642,12 +635,12 @@ int hinic5_reschedule_eq(struct hinic5_hwdev *hwdev, enum hinic5_eq_type type,
if (eq_id >= hwdev->aeqs->num_aeqs)
return -EINVAL;
- reschedule_eq_handler(&hwdev->aeqs->aeq[eq_id]);
+ reschedule_eq_handler(&(hwdev->aeqs->aeq[eq_id]));
} else {
if (eq_id >= hwdev->ceqs->num_ceqs)
return -EINVAL;
- reschedule_eq_handler(&hwdev->ceqs->ceq[eq_id]);
+ reschedule_eq_handler(&(hwdev->ceqs->ceq[eq_id]));
}
return 0;
@@ -667,8 +660,8 @@ static bool eq_irq_handler(void *data)
else
uncompleted = ceq_irq_handler(eq);
- set_eq_cons_idx(eq, uncompleted ? HINIC5_EQ_NOT_ARMED :
- HINIC5_EQ_ARMED);
+ set_eq_cons_idx(eq,
+ uncompleted ? HINIC5_EQ_NOT_ARMED : HINIC5_EQ_ARMED);
return uncompleted;
}
@@ -708,8 +701,9 @@ static struct hinic5_eq *find_eq(struct hinic5_hwdev *hwdev, int msix_entry_idx)
return eq;
}
- if (!ceqs)
+ if (ceqs == NULL) {
return NULL;
+ }
for (i = 0; i < ceqs->num_ceqs; i++) {
struct hinic5_eq *eq = &ceqs->ceq[i];
@@ -845,9 +839,9 @@ static int set_eq_ctrls(struct hinic5_eq *eq)
val = hinic5_hwif_read_reg(hwif, addr);
val = AEQ_CTRL_0_CLEAR(val, INTR_IDX) &
- AEQ_CTRL_0_CLEAR(val, DMA_ATTR) &
- AEQ_CTRL_0_CLEAR(val, PCI_INTF_IDX) &
- AEQ_CTRL_0_CLEAR(val, INTR_MODE);
+ AEQ_CTRL_0_CLEAR(val, DMA_ATTR) &
+ AEQ_CTRL_0_CLEAR(val, PCI_INTF_IDX) &
+ AEQ_CTRL_0_CLEAR(val, INTR_MODE);
ctrl0 = AEQ_CTRL_0_SET(eq_irq->msix_entry_idx, INTR_IDX) |
AEQ_CTRL_0_SET(AEQ_DMA_ATTR_DEFAULT, DMA_ATTR) |
@@ -864,15 +858,15 @@ static int set_eq_ctrls(struct hinic5_eq *eq)
page_size_val = EQ_SET_HW_PAGE_SIZE_VAL(eq);
elem_size = EQ_SET_HW_ELEM_SIZE_VAL(eq);
- ctrl1 = AEQ_CTRL_1_SET(eq->eq_len, LEN) |
- AEQ_CTRL_1_SET(elem_size, ELEM_SIZE) |
+ ctrl1 = AEQ_CTRL_1_SET(eq->eq_len, LEN) |
+ AEQ_CTRL_1_SET(elem_size, ELEM_SIZE) |
AEQ_CTRL_1_SET(page_size_val, PAGE_SIZE);
hinic5_hwif_write_reg(hwif, addr, ctrl1);
} else {
page_size_val = EQ_SET_HW_PAGE_SIZE_VAL(eq);
ctrl0 = CEQ_CTRL_0_SET(eq_irq->msix_entry_idx, INTR_IDX) |
- CEQ_CTRL_0_SET(CEQ_DMA_ATTR_DEFAULT, DMA_ATTR) |
+ CEQ_CTRL_0_SET(CEQ_DMA_ATTR_DEFAULT, DMA_ATTR) |
CEQ_CTRL_0_SET(CEQ_LMT_KICK_DEFAULT, LIMIT_KICK) |
CEQ_CTRL_0_SET(pci_intf_idx, PCI_INTF_IDX) |
CEQ_CTRL_0_SET(page_size_val, PAGE_SIZE) |
@@ -905,7 +899,7 @@ static void ceq_elements_init(struct hinic5_eq *eq, u32 init_val)
*(ceqe) = cpu_to_be32(init_val);
}
- wmb(); /* Write the init values */
+ wmb(); /* Write the init values */
}
/**
@@ -923,7 +917,7 @@ static void aeq_elements_init(struct hinic5_eq *eq, u32 init_val)
aeqe->desc = cpu_to_be32(init_val);
}
- wmb(); /* Write the init values */
+ wmb(); /* Write the init values */
}
static void eq_elements_init(struct hinic5_eq *eq, u32 init_val)
@@ -945,24 +939,28 @@ static int alloc_eq_pages(struct hinic5_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
- gfp_t gfp_hinic5_vram;
+ gfp_t gfp_vram;
- eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
- GFP_KERNEL);
- if (!eq->eq_pages)
+ eq->eq_pages =
+ kcalloc(eq->num_pages, sizeof(*eq->eq_pages), GFP_KERNEL);
+ if (!eq->eq_pages) {
+ sdk_err(eq->hwdev->dev_hdl,
+ "Failed to alloc eq pages description\n");
return -ENOMEM;
+ }
- gfp_hinic5_vram = hinic5_hinic5_vram_get_gfp_hinic5_vram();
+ gfp_vram = hi5_vram_get_gfp_vram();
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic5_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC5_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL | gfp_hinic5_vram,
+ GFP_KERNEL | gfp_vram,
eq_page);
if (err != 0) {
- sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
+ sdk_err(eq->hwdev->dev_hdl,
+ "Failed to alloc eq page, page index: %hu\n",
pg_idx);
goto dma_alloc_err;
}
@@ -978,7 +976,8 @@ static int alloc_eq_pages(struct hinic5_eq *eq)
eq->num_elem_in_pg = GET_EQ_NUM_ELEMS(eq, eq->page_size);
if ((eq->num_elem_in_pg & (eq->num_elem_in_pg - 1)) != 0) {
- sdk_err(eq->hwdev->dev_hdl, "Number element in eq page != power of 2\n");
+ sdk_err(eq->hwdev->dev_hdl,
+ "Number element in eq page != power of 2\n");
err = -EINVAL;
goto dma_alloc_err;
}
@@ -1018,13 +1017,14 @@ static inline u32 get_page_size(const struct hinic5_eq *eq)
u32 total_size;
u32 count;
- total_size = ALIGN((eq->eq_len * eq->elem_size),
- HINIC5_MIN_EQ_PAGE_SIZE);
+ total_size =
+ ALIGN((eq->eq_len * eq->elem_size), HINIC5_MIN_EQ_PAGE_SIZE);
if (total_size <= (HINIC5_EQ_MAX_PAGES(eq) * HINIC5_MIN_EQ_PAGE_SIZE))
return HINIC5_MIN_EQ_PAGE_SIZE;
count = (u32)(ALIGN((total_size / HINIC5_EQ_MAX_PAGES(eq)),
- HINIC5_MIN_EQ_PAGE_SIZE) / HINIC5_MIN_EQ_PAGE_SIZE);
+ HINIC5_MIN_EQ_PAGE_SIZE) /
+ HINIC5_MIN_EQ_PAGE_SIZE);
/* round up to nearest power of two */
count = 1U << (u8)fls(count - 1);
@@ -1033,7 +1033,8 @@ static inline u32 get_page_size(const struct hinic5_eq *eq)
}
#ifdef __VMWARE__
-static VMK_ReturnStatus eq_intr_ack_handler(void *data, vmk_intr_cookie intr_cookie)
+static VMK_ReturnStatus eq_intr_ack_handler(void *data,
+ vmk_IntrCookie intrCookie)
{
return VMK_OK;
}
@@ -1049,11 +1050,14 @@ static int request_eq_irq(struct hinic5_eq *eq, struct irq_info *entry)
if (eq->type == HINIC5_AEQ)
INIT_WORK(&eq->aeq_work, eq_irq_work);
else
- tasklet_init(&eq->ceq_tasklet, ceq_tasklet, (ulong)(uintptr_t)eq);
+ tasklet_init(&eq->ceq_tasklet, ceq_tasklet,
+ (ulong)(uintptr_t)eq);
if (eq->type == HINIC5_AEQ) {
- snprintf(eq->irq_name, sizeof(eq->irq_name),
- "hinic5_aeq%u@dev:%s", eq->q_id, dev_name(eq->hwdev->dev_hdl));
+ if (sprintf_s(eq->irq_name, sizeof(eq->irq_name),
+ "hinic5_aeq%u@dev:%s", eq->q_id,
+ dev_name(eq->hwdev->dev_hdl)) < 0)
+ return -EFAULT;
#ifdef __VMWARE__
st = request_irq(eq->hwdev->adapter_hdl, entry->irq_id,
eq_intr_ack_handler, aeq_interrupt,
@@ -1068,8 +1072,10 @@ static int request_eq_irq(struct hinic5_eq *eq, struct irq_info *entry)
eq->irq_name, eq);
#endif
} else {
- snprintf(eq->irq_name, sizeof(eq->irq_name),
- "hinic5_ceq%u@dev:%s", eq->q_id, dev_name(eq->hwdev->dev_hdl));
+ if (sprintf_s(eq->irq_name, sizeof(eq->irq_name),
+ "hinic5_ceq%u@dev:%s", eq->q_id,
+ dev_name(eq->hwdev->dev_hdl)) < 0)
+ return -EFAULT;
#ifdef __VMWARE__
st = request_irq(eq->hwdev->adapter_hdl, entry->irq_id,
eq_intr_ack_handler, ceq_interrupt,
@@ -1109,9 +1115,10 @@ static void set_eq_cpu(struct hinic5_eq *eq, struct hinic5_hwdev *hwdev)
eq->cpu = WORK_CPU_UNBOUND;
- if (eq->type == HINIC5_AEQ && aeqs->aeq_cpu_affinity_nargs > 0) {
+ if ((eq->type == HINIC5_AEQ) && (aeqs->aeq_cpu_affinity_nargs > 0)) {
i = hinic5_global_func_id(hwdev) + eq->q_id;
- eq->cpu = aeqs->aeq_cpu_affinity[i % aeqs->aeq_cpu_affinity_nargs];
+ eq->cpu =
+ aeqs->aeq_cpu_affinity[i % aeqs->aeq_cpu_affinity_nargs];
}
}
@@ -1145,14 +1152,16 @@ static int init_eq(struct hinic5_eq *eq, struct hinic5_hwdev *hwdev, u16 q_id,
eq->cons_idx = 0;
eq->wrapped = 0;
- eq->elem_size = (type == HINIC5_AEQ) ? HINIC5_AEQE_SIZE : HINIC5_CEQE_SIZE;
+ eq->elem_size = (type == HINIC5_AEQ) ? HINIC5_AEQE_SIZE :
+ HINIC5_CEQE_SIZE;
eq->page_size = get_page_size(eq);
eq->orig_page_size = eq->page_size;
eq->num_pages = GET_EQ_NUM_PAGES(eq, eq->page_size);
if (eq->num_pages > HINIC5_EQ_MAX_PAGES(eq)) {
- sdk_err(hwdev->dev_hdl, "Number pages: %u too many pages for eq\n",
+ sdk_err(hwdev->dev_hdl,
+ "Number pages: %u too many pages for eq\n",
eq->num_pages);
return -EINVAL;
}
@@ -1209,8 +1218,7 @@ static void remove_eq(struct hinic5_eq *eq)
/* Indirect access should set q_id first */
hinic5_hwif_write_reg(eq->hwdev->hwif,
- HINIC5_EQ_INDIR_IDX_ADDR(eq->type),
- eq->q_id);
+ HINIC5_EQ_INDIR_IDX_ADDR(eq->type), eq->q_id);
wmb(); /* write index before config */
@@ -1227,8 +1235,8 @@ static void remove_eq(struct hinic5_eq *eq)
}
/* update cons_idx to avoid invalid interrupt */
- eq->cons_idx = hinic5_hwif_read_reg(eq->hwdev->hwif,
- EQ_PROD_IDX_REG_ADDR(eq));
+ eq->cons_idx =
+ hinic5_hwif_read_reg(eq->hwdev->hwif, EQ_PROD_IDX_REG_ADDR(eq));
set_eq_cons_idx(eq, HINIC5_EQ_NOT_ARMED);
free_eq_pages(eq);
@@ -1237,9 +1245,10 @@ static void remove_eq(struct hinic5_eq *eq)
void hinic5_aeqs_valid_params(struct hinic5_hwdev *hwdev)
{
if (g_aeq_len < HINIC5_MIN_AEQ_LEN || g_aeq_len > HINIC5_MAX_AEQ_LEN) {
- sdk_warn(hwdev->dev_hdl,
- "Module Parameter g_aeq_len value %u out of range, resetting to %d\n",
- g_aeq_len, HINIC5_DEFAULT_AEQ_LEN);
+ sdk_warn(
+ hwdev->dev_hdl,
+ "Module Parameter g_aeq_len value %u out of range, resetting to %d\n",
+ g_aeq_len, HINIC5_DEFAULT_AEQ_LEN);
g_aeq_len = HINIC5_DEFAULT_AEQ_LEN;
}
}
@@ -1256,7 +1265,7 @@ static void hinic5_aeqs_dump_cpu_affinity(struct hinic5_hwdev *hwdev)
pr_info("func %u aeq cpu affinity:", hinic5_global_func_id(hwdev));
for (q_id = 0; q_id < aeqs->num_aeqs; q_id++)
- pr_info(" %d", aeqs->aeq[q_id].cpu);
+ pr_cont(" %d", aeqs->aeq[q_id].cpu);
}
void hinic5_filter_online_cpus(int *cpus, unsigned int *cpus_nargs)
@@ -1271,7 +1280,7 @@ void hinic5_filter_online_cpus(int *cpus, unsigned int *cpus_nargs)
j = 0;
for (i = 0; i < n; i++) {
cpu = cpus[i];
- if (cpu >= 0 && cpu < num_possible_cpus() && (cpu_online(cpu) != 0)) {
+ if ((cpu >= 0) && (cpu < NR_CPUS) && (cpu_online(cpu) != 0)) {
cpus[j] = cpus[i];
j++;
}
@@ -1287,9 +1296,10 @@ static void hinic5_filter_aeq_cpu_affinity(struct hinic5_hwdev *hwdev)
if (aeqs->aeq_cpu_affinity_nargs > 0) {
hinic5_filter_online_cpus(aeqs->aeq_cpu_affinity,
&aeqs->aeq_cpu_affinity_nargs);
- pr_info("aeq cpu candidates (%u):", aeqs->aeq_cpu_affinity_nargs);
+ pr_info("aeq cpu candidates (%u):",
+ aeqs->aeq_cpu_affinity_nargs);
for (i = 0; i < aeqs->aeq_cpu_affinity_nargs; ++i)
- pr_info(" %d", aeqs->aeq_cpu_affinity[i]);
+ pr_cont(" %d", aeqs->aeq_cpu_affinity[i]);
}
}
#endif
@@ -1301,8 +1311,10 @@ void hinic5_set_aeq_cpu_affinity(struct hinic5_hwdev *hwdev)
aeqs->aeq_cpu_affinity_nargs = 0;
if (g_aeq_cpu_affinity_nargs > 0) {
- memcpy(aeqs->aeq_cpu_affinity, g_aeq_cpu_affinity,
- sizeof(int) * HINIC5_AEQ_CPU_AFFINITY_MAX);
+ (void)memcpy_s(aeqs->aeq_cpu_affinity,
+ sizeof(int) * HINIC5_AEQ_CPU_AFFINITY_MAX,
+ g_aeq_cpu_affinity,
+ sizeof(int) * HINIC5_AEQ_CPU_AFFINITY_MAX);
aeqs->aeq_cpu_affinity_nargs = g_aeq_cpu_affinity_nargs;
#ifndef __UEFI__
hinic5_filter_aeq_cpu_affinity(hwdev);
@@ -1390,10 +1402,12 @@ void hinic5_aeqs_free(struct hinic5_hwdev *hwdev)
remove_eq(&aeqs->aeq[q_id]);
for (; sw_aeq_event < (u32)HINIC5_MAX_AEQ_SW_EVENTS; sw_aeq_event++)
- hinic5_aeq_unregister_swe_cb(hwdev, (enum hinic5_aeq_sw_type)sw_aeq_event);
+ hinic5_aeq_unregister_swe_cb(
+ hwdev, (enum hinic5_aeq_sw_type)sw_aeq_event);
for (; aeq_event < (u32)HINIC5_MAX_AEQ_EVENTS; aeq_event++)
- hinic5_aeq_unregister_hw_cb(hwdev, (enum hinic5_aeq_type)aeq_event);
+ hinic5_aeq_unregister_hw_cb(hwdev,
+ (enum hinic5_aeq_type)aeq_event);
destroy_workqueue(aeqs->workq);
@@ -1413,7 +1427,8 @@ u8 hinic5_nic_sw_aeqe_stats(void *hwdev, u8 event, u8 *data)
if (!dev)
return 0;
- sdk_err(dev->dev_hdl, "Received nic ucode aeq event type: 0x%x, data: 0x%llx\n",
+ sdk_err(dev->dev_hdl,
+ "Received nic ucode aeq event type: 0x%x, data: 0x%llx\n",
event, *((u64 *)data));
if (event < HINIC5_NIC_FATAL_ERROR_MAX)
@@ -1457,10 +1472,12 @@ void hinic5_stateless_aeqs_free(void *hwdev)
return;
stateless_aeqs = dev->stateless_aeqs;
- if (!stateless_aeqs)
+ if (!stateless_aeqs) {
return;
+ }
- clear_bit(HINIC5_AEQ_SW_CB_REG, &stateless_aeqs->stateless_aeq_sw_cb_state);
+ clear_bit(HINIC5_AEQ_SW_CB_REG,
+ &stateless_aeqs->stateless_aeq_sw_cb_state);
while (test_bit(HINIC5_AEQ_SW_CB_RUNNING,
&stateless_aeqs->stateless_aeq_sw_cb_state))
@@ -1490,7 +1507,8 @@ int hinic5_register_stateless_aeqs(void *hwdev, void *pri_handle,
stateless_aeqs->stateless_aeq_swe_cb = stateless_aeq_swe_cb;
stateless_aeqs->stateless_aeq_swe_cb_data = pri_handle;
- set_bit(HINIC5_AEQ_SW_CB_REG, &stateless_aeqs->stateless_aeq_sw_cb_state);
+ set_bit(HINIC5_AEQ_SW_CB_REG,
+ &stateless_aeqs->stateless_aeq_sw_cb_state);
return 0;
}
@@ -1509,10 +1527,12 @@ void hinic5_unregister_stateless_aeqs(void *hwdev)
return;
stateless_aeqs = dev->stateless_aeqs;
- if (!stateless_aeqs)
+ if (!stateless_aeqs) {
return;
+ }
- clear_bit(HINIC5_AEQ_SW_CB_REG, &stateless_aeqs->stateless_aeq_sw_cb_state);
+ clear_bit(HINIC5_AEQ_SW_CB_REG,
+ &stateless_aeqs->stateless_aeq_sw_cb_state);
while (test_bit(HINIC5_AEQ_SW_CB_RUNNING,
&stateless_aeqs->stateless_aeq_sw_cb_state))
@@ -1520,6 +1540,8 @@ void hinic5_unregister_stateless_aeqs(void *hwdev)
stateless_aeqs->stateless_aeq_swe_cb = NULL;
stateless_aeqs->stateless_aeq_swe_cb_data = NULL;
+
+ return;
}
EXPORT_SYMBOL(hinic5_unregister_stateless_aeqs);
@@ -1538,8 +1560,8 @@ u8 hinic5_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
if (stateless_aeqs->stateless_aeq_swe_cb &&
test_bit(HINIC5_AEQ_SW_CB_REG,
&stateless_aeqs->stateless_aeq_sw_cb_state))
- stateless_aeqs->stateless_aeq_swe_cb(stateless_aeqs->stateless_aeq_swe_cb_data,
- event, data);
+ stateless_aeqs->stateless_aeq_swe_cb(
+ stateless_aeqs->stateless_aeq_swe_cb_data, event, data);
clear_bit(HINIC5_AEQ_SW_CB_RUNNING,
&stateless_aeqs->stateless_aeq_sw_cb_state);
@@ -1571,14 +1593,18 @@ int hinic5_ceqs_init(struct hinic5_hwdev *hwdev, u16 num_ceqs,
ceqs->num_ceqs = num_ceqs;
if (g_ceq_len < HINIC5_MIN_CEQ_LEN || g_ceq_len > HINIC5_MAX_CEQ_LEN) {
- sdk_warn(hwdev->dev_hdl, "Module Parameter g_ceq_len value %u out of range, resetting to %d\n",
- g_ceq_len, HINIC5_DEFAULT_CEQ_LEN);
+ sdk_warn(
+ hwdev->dev_hdl,
+ "Module Parameter g_ceq_len value %u out of range, resetting to %d\n",
+ g_ceq_len, HINIC5_DEFAULT_CEQ_LEN);
g_ceq_len = HINIC5_DEFAULT_CEQ_LEN;
}
if (g_num_ceqe_in_tasklet == 0) {
- sdk_warn(hwdev->dev_hdl, "Module Parameter g_num_ceqe_in_tasklet can not be zero, resetting to %d\n",
- HINIC5_TASK_PROCESS_EQE_LIMIT);
+ sdk_warn(
+ hwdev->dev_hdl,
+ "Module Parameter g_num_ceqe_in_tasklet can not be zero, resetting to %d\n",
+ HINIC5_TASK_PROCESS_EQE_LIMIT);
g_num_ceqe_in_tasklet = HINIC5_TASK_PROCESS_EQE_LIMIT;
}
for (q_id = 0; q_id < num_ceqs; q_id++) {
@@ -1622,7 +1648,8 @@ void hinic5_ceqs_free(struct hinic5_hwdev *hwdev)
remove_eq(&ceqs->ceq[q_id]);
for (; ceq_event < (u32)HINIC5_MAX_CEQ_EVENTS; ceq_event++)
- hinic5_ceq_unregister_cb(hwdev, (enum hinic5_ceq_event)ceq_event);
+ hinic5_ceq_unregister_cb(hwdev,
+ (enum hinic5_ceq_event)ceq_event);
kfree(ceqs);
}
@@ -1667,7 +1694,8 @@ void hinic5_dump_aeq_info(struct hinic5_hwdev *hwdev)
for (q_id = 0; q_id < hwdev->aeqs->num_aeqs; q_id++) {
eq = &hwdev->aeqs->aeq[q_id];
/* Indirect access should set q_id first */
- hinic5_hwif_write_reg(eq->hwdev->hwif, HINIC5_EQ_INDIR_IDX_ADDR(eq->type),
+ hinic5_hwif_write_reg(eq->hwdev->hwif,
+ HINIC5_EQ_INDIR_IDX_ADDR(eq->type),
eq->q_id);
wmb(); /* write index before config */
@@ -1675,7 +1703,8 @@ void hinic5_dump_aeq_info(struct hinic5_hwdev *hwdev)
ctrl0 = hinic5_hwif_read_reg(hwdev->hwif, addr);
- idx = hinic5_hwif_read_reg(hwdev->hwif, HINIC5_EQ_INDIR_IDX_ADDR(eq->type));
+ idx = hinic5_hwif_read_reg(hwdev->hwif,
+ HINIC5_EQ_INDIR_IDX_ADDR(eq->type));
addr = EQ_CONS_IDX_REG_ADDR(eq);
ci = hinic5_hwif_read_reg(hwdev->hwif, addr);
@@ -1685,7 +1714,7 @@ void hinic5_dump_aeq_info(struct hinic5_hwdev *hwdev)
sdk_err(hwdev->dev_hdl,
"Aeq id: %d, idx: %u, ctrl0: 0x%08x, ci: 0x%08x, pi: 0x%x, work_state: 0x%x, wrap: %u, desc: 0x%x swci:0x%x\n",
q_id, idx, ctrl0, ci, pi, work_busy(&eq->aeq_work),
- eq->wrapped, be32_to_cpu(aeqe_pos->desc), eq->cons_idx);
+ eq->wrapped, be32_to_cpu(aeqe_pos->desc), eq->cons_idx);
}
hinic5_show_chip_err_info(hwdev);
@@ -1715,12 +1744,14 @@ void hinic5_dump_ceq_info(struct hinic5_hwdev *hwdev)
sdk_err(hwdev->dev_hdl,
"Ceq id: %d, ci: 0x%08x, sw_ci: 0x%08x, pi: 0x%x, tasklet_state: 0x%lx, wrap: %u, ceqe: 0x%x\n",
q_id, ci, eq->cons_idx, pi,
- tasklet_state(&eq->ceq_tasklet),
- eq->wrapped, be32_to_cpu(*(GET_CURR_CEQ_ELEM(eq))));
+ tasklet_state(&eq->ceq_tasklet), eq->wrapped,
+ be32_to_cpu(*(GET_CURR_CEQ_ELEM(eq))));
- sdk_err(hwdev->dev_hdl, "Ceq last response hard interrupt time: %u\n",
+ sdk_err(hwdev->dev_hdl,
+ "Ceq last response hard interrupt time: %u\n",
jiffies_to_msecs(jiffies - eq->hard_intr_jif));
- sdk_err(hwdev->dev_hdl, "Ceq last response soft interrupt time: %u\n",
+ sdk_err(hwdev->dev_hdl,
+ "Ceq last response soft interrupt time: %u\n",
jiffies_to_msecs(jiffies - eq->soft_intr_jif));
}
@@ -1731,6 +1762,7 @@ int hinic5_get_ceq_info(void *hwdev, u16 q_id, struct hinic5_ceq_info *ceq_info)
{
struct hinic5_hwdev *dev = hwdev;
struct hinic5_eq *eq = NULL;
+ int page_idx;
if (!hwdev || !ceq_info)
return -EINVAL;
@@ -1739,13 +1771,25 @@ int hinic5_get_ceq_info(void *hwdev, u16 q_id, struct hinic5_ceq_info *ceq_info)
return -EINVAL;
eq = &dev->ceqs->ceq[q_id];
+ if (eq->num_pages > HINIC5_CEQ_MAX_PAGES) {
+ sdk_err(dev->dev_hdl,
+ "get_ceq_info failed, num_pages(%d) is bigger than max_ceq_pages(%d)\n",
+ eq->num_pages, HINIC5_CEQ_MAX_PAGES);
+ return -EINVAL;
+ }
ceq_info->q_len = eq->eq_len;
ceq_info->num_pages = eq->num_pages;
ceq_info->page_size = eq->page_size;
ceq_info->num_elem_in_pg = eq->num_elem_in_pg;
ceq_info->elem_size = eq->elem_size;
- sdk_info(dev->dev_hdl, "get_ceq_info: qid=0x%x page_size=%u\n",
- q_id, eq->page_size);
+ for (page_idx = 0; page_idx < eq->num_pages; page_idx++) {
+ ceq_info->ceq_addr[page_idx].align_vaddr =
+ eq->eq_pages[page_idx].align_vaddr;
+ ceq_info->ceq_addr[page_idx].align_paddr =
+ eq->eq_pages[page_idx].align_paddr;
+ }
+ sdk_info(dev->dev_hdl, "get_ceq_info: qid=0x%x page_size=%u\n", q_id,
+ eq->page_size);
return 0;
}
@@ -1757,7 +1801,7 @@ int hinic5_init_single_ceq_status(void *hwdev, u16 q_id)
struct hinic5_hwdev *dev = hwdev;
struct hinic5_eq *eq = NULL;
- if (!hwdev) {
+ if (hwdev == NULL) {
pr_err("%s(%d), hwdev is null\n", __func__, __LINE__);
return -EINVAL;
}
@@ -1770,7 +1814,8 @@ int hinic5_init_single_ceq_status(void *hwdev, u16 q_id)
eq = &dev->ceqs->ceq[q_id];
/* Indirect access should set q_id first */
- hinic5_hwif_write_reg(dev->hwif, HINIC5_EQ_INDIR_IDX_ADDR(eq->type), eq->q_id);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_EQ_INDIR_IDX_ADDR(eq->type),
+ eq->q_id);
wmb(); /* write index before config */
reset_eq(eq);
@@ -1786,8 +1831,8 @@ int hinic5_init_single_ceq_status(void *hwdev, u16 q_id)
}
EXPORT_SYMBOL(hinic5_init_single_ceq_status);
-int hinic5_get_ceq_page_phy_addr(void *hwdev, u16 q_id,
- u16 page_idx, u64 *page_phy_addr)
+int hinic5_get_ceq_page_phy_addr(void *hwdev, u16 q_id, u16 page_idx,
+ u64 *page_phy_addr)
{
struct hinic5_hwdev *dev = hwdev;
struct hinic5_eq *eq = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hw_api.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hw_api.c
index ce124ba07..bfc9e82f6 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hw_api.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_api.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include "ossl_knl.h"
#include "hinic5_hw.h"
@@ -15,17 +8,15 @@
#include "hinic5_api_cmd.h"
#include "hinic5_mgmt.h"
#include "hinic5_hw_api.h"
- #ifndef HTONL
-#define HTONL(x) \
- ((((x) & 0x000000ff) << 24) \
- | (((x) & 0x0000ff00) << 8) \
- | (((x) & 0x00ff0000) >> 8) \
- | (((x) & 0xff000000) >> 24))
+#ifndef HTONL
+#define HTONL(x) \
+ ((((x)&0x000000ff) << 24) | (((x)&0x0000ff00) << 8) | \
+ (((x)&0x00ff0000) >> 8) | (((x)&0xff000000) >> 24))
#endif
static void hinic5_sml_ctr_read_build_req(struct chipif_sml_ctr_rd_req *msg,
- u8 instance_id, u8 op_id,
- u8 ack, u32 ctr_id)
+ u8 instance_id, u8 op_id, u8 ack,
+ u32 ctr_id)
{
msg->head.value = 0;
msg->head.bs.instance = instance_id;
@@ -69,14 +60,13 @@ int hinic5_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&req, 0, sizeof(req));
+ (void)memset_s(&req, sizeof(req), 0, sizeof(req));
hinic5_sml_ctr_read_build_req(&req, instance, CHIPIF_SM_CTR_OP_READ,
CHIPIF_ACK, ctr_id);
ret = hinic5_api_cmd_read_ack(hwdev, node, (u8 *)&req,
- (unsigned short)sizeof(req),
- (void *)&rsp,
+ (unsigned short)sizeof(req), (void *)&rsp,
(unsigned short)sizeof(rsp));
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
@@ -110,14 +100,13 @@ int hinic5_sm_ctr_rd32(void *hwdev, u8 node, u8 instance, u32 ctr_id,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&req, 0, sizeof(req));
+ (void)memset_s(&req, sizeof(req), 0, sizeof(req));
hinic5_sml_ctr_read_build_req(&req, instance, CHIPIF_SM_CTR_OP_READ,
CHIPIF_ACK, ctr_id);
ret = hinic5_api_cmd_read_ack(hwdev, node, (u8 *)&req,
- (unsigned short)sizeof(req),
- (void *)&rsp,
+ (unsigned short)sizeof(req), (void *)&rsp,
(unsigned short)sizeof(rsp));
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
@@ -139,8 +128,8 @@ int hinic5_sm_ctr_rd32(void *hwdev, u8 node, u8 instance, u32 ctr_id,
* Return: 0 - success, negative - failure
* according to ACN error code (ERR_OK, ERR_PARAM, ERR_FAILED...etc)
**/
-int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u32 *value)
+int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u32 *value)
{
struct chipif_sml_ctr_rd_req req;
union ctr_rd_rsp rsp;
@@ -152,15 +141,14 @@ int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&req, 0, sizeof(req));
+ (void)memset_s(&req, sizeof(req), 0, sizeof(req));
hinic5_sml_ctr_read_build_req(&req, instance,
- CHIPIF_SM_CTR_OP_READ_CLEAR,
- CHIPIF_ACK, ctr_id);
+ CHIPIF_SM_CTR_OP_READ_CLEAR, CHIPIF_ACK,
+ ctr_id);
ret = hinic5_api_cmd_read_ack(hwdev, node, (u8 *)&req,
- (unsigned short)sizeof(req),
- (void *)&rsp,
+ (unsigned short)sizeof(req), (void *)&rsp,
(unsigned short)sizeof(rsp));
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
@@ -182,8 +170,8 @@ int hinic5_sm_ctr_rd32_clear(void *hwdev, u8 node, u8 instance,
* @value2: read counter value ptr
* Return: 0 - success, negative - failure
**/
-int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance,
- u32 ctr_id, u64 *value1, u64 *value2)
+int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u64 *value1, u64 *value2)
{
struct chipif_sml_ctr_rd_req req;
union ctr_rd_rsp rsp;
@@ -208,7 +196,7 @@ int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&req, 0, sizeof(req));
+ (void)memset_s(&req, sizeof(req), 0, sizeof(req));
hinic5_sml_ctr_read_build_req(&req, instance, CHIPIF_SM_CTR_OP_READ,
CHIPIF_ACK, ctr_id);
@@ -222,8 +210,10 @@ int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance,
return ret;
}
sml_ctr_htonl_n((u32 *)(void *)&rsp, sizeof(rsp) / sizeof(u32));
- *value1 = ((u64)rsp.bs_bp64_rsp.val1_h << BIT_32) | rsp.bs_bp64_rsp.val1_l;
- *value2 = ((u64)rsp.bs_bp64_rsp.val2_h << BIT_32) | rsp.bs_bp64_rsp.val2_l;
+ *value1 = ((u64)rsp.bs_bp64_rsp.val1_h << BIT_32) |
+ rsp.bs_bp64_rsp.val1_l;
+ *value2 = ((u64)rsp.bs_bp64_rsp.val2_h << BIT_32) |
+ rsp.bs_bp64_rsp.val2_l;
return 0;
}
@@ -240,12 +230,13 @@ int hinic5_sm_ctr_rd64_pair(void *hwdev, u8 node, u8 instance,
int hinic5_sm_ctr_rd64_pair_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
u64 *value1, u64 *value2)
{
- struct chipif_sml_ctr_rd_req req = {0};
+ struct chipif_sml_ctr_rd_req req = { 0 };
union ctr_rd_rsp rsp;
int ret;
if (!hwdev || !value1 || !value2 || ((ctr_id & 0x1) != 0)) {
- pr_err("Hwdev or value1 or value2 is NULL or ctr_id(%u) is odd number\n", ctr_id);
+ pr_err("Hwdev or value1 or value2 is NULL or ctr_id(%u) is odd number\n",
+ ctr_id);
return -EINVAL;
}
@@ -253,8 +244,8 @@ int hinic5_sm_ctr_rd64_pair_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return -EPERM;
hinic5_sml_ctr_read_build_req(&req, instance,
- CHIPIF_SM_CTR_OP_READ_CLEAR,
- CHIPIF_ACK, ctr_id);
+ CHIPIF_SM_CTR_OP_READ_CLEAR, CHIPIF_ACK,
+ ctr_id);
ret = hinic5_api_cmd_read_ack(hwdev, node, (u8 *)&req,
(unsigned short)sizeof(req), (void *)&rsp,
@@ -265,8 +256,10 @@ int hinic5_sm_ctr_rd64_pair_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return ret;
}
sml_ctr_htonl_n((u32 *)(void *)&rsp, sizeof(rsp) / sizeof(u32));
- *value1 = ((u64)rsp.bs_bp64_rsp.val1_h << BIT_32) | rsp.bs_bp64_rsp.val1_l;
- *value2 = ((u64)rsp.bs_bp64_rsp.val2_h << BIT_32) | rsp.bs_bp64_rsp.val2_l;
+ *value1 = ((u64)rsp.bs_bp64_rsp.val1_h << BIT_32) |
+ rsp.bs_bp64_rsp.val1_l;
+ *value2 = ((u64)rsp.bs_bp64_rsp.val2_h << BIT_32) |
+ rsp.bs_bp64_rsp.val2_l;
return 0;
}
@@ -292,7 +285,7 @@ int hinic5_sm_ctr_rd64(void *hwdev, u8 node, u8 instance, u32 ctr_id,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&req, 0, sizeof(req));
+ (void)memset_s(&req, sizeof(req), 0, sizeof(req));
hinic5_sml_ctr_read_build_req(&req, instance, CHIPIF_SM_CTR_OP_READ,
CHIPIF_ACK, ctr_id);
@@ -306,7 +299,8 @@ int hinic5_sm_ctr_rd64(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return ret;
}
sml_ctr_htonl_n((u32 *)(void *)&rsp, sizeof(rsp) / sizeof(u32));
- *value = ((u64)rsp.bs_bs64_rsp.value1 << BIT_32) | rsp.bs_bs64_rsp.value2;
+ *value = ((u64)rsp.bs_bs64_rsp.value1 << BIT_32) |
+ rsp.bs_bs64_rsp.value2;
return 0;
}
@@ -323,7 +317,7 @@ EXPORT_SYMBOL(hinic5_sm_ctr_rd64);
int hinic5_sm_ctr_rd64_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
u64 *value)
{
- struct chipif_sml_ctr_rd_req req = {0};
+ struct chipif_sml_ctr_rd_req req = { 0 };
union ctr_rd_rsp rsp;
int ret;
@@ -334,8 +328,8 @@ int hinic5_sm_ctr_rd64_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return -EPERM;
hinic5_sml_ctr_read_build_req(&req, instance,
- CHIPIF_SM_CTR_OP_READ_CLEAR,
- CHIPIF_ACK, ctr_id);
+ CHIPIF_SM_CTR_OP_READ_CLEAR, CHIPIF_ACK,
+ ctr_id);
ret = hinic5_api_cmd_read_ack(hwdev, node, (u8 *)&req,
(unsigned short)sizeof(req), (void *)&rsp,
@@ -346,14 +340,15 @@ int hinic5_sm_ctr_rd64_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return ret;
}
sml_ctr_htonl_n((u32 *)(void *)&rsp, sizeof(rsp) / sizeof(u32));
- *value = ((u64)rsp.bs_bs64_rsp.value1 << BIT_32) | rsp.bs_bs64_rsp.value2;
+ *value = ((u64)rsp.bs_bs64_rsp.value1 << BIT_32) |
+ rsp.bs_bs64_rsp.value2;
return 0;
}
int hinic5_api_csr_rd32(void *hwdev, u8 dest, u32 addr, u32 *val)
{
- struct hinic5_csr_request_api_data api_data = {0};
+ struct hinic5_csr_request_api_data api_data = { 0 };
u32 csr_val = 0;
u16 in_size = sizeof(api_data);
int ret;
@@ -364,7 +359,8 @@ int hinic5_api_csr_rd32(void *hwdev, u8 dest, u32 addr, u32 *val)
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&api_data, 0, sizeof(struct hinic5_csr_request_api_data));
+ (void)memset_s(&api_data, sizeof(struct hinic5_csr_request_api_data), 0,
+ sizeof(struct hinic5_csr_request_api_data));
api_data.dw0 = 0;
api_data.dw1.bits.operation_id = HINIC5_CSR_OPERATION_READ_CSR;
api_data.dw1.bits.need_response = HINIC5_CSR_NEED_RESP_DATA;
@@ -373,8 +369,8 @@ int hinic5_api_csr_rd32(void *hwdev, u8 dest, u32 addr, u32 *val)
api_data.dw2.bits.csr_addr = addr;
api_data.dw2.val32 = cpu_to_be32(api_data.dw2.val32);
- ret = hinic5_api_cmd_read_ack(hwdev, dest, (u8 *)(&api_data),
- in_size, &csr_val, 0x4);
+ ret = hinic5_api_cmd_read_ack(hwdev, dest, (u8 *)(&api_data), in_size,
+ &csr_val, 0x4);
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"Read 32 bit csr fail, dest %u addr 0x%x, ret: 0x%x\n",
@@ -399,7 +395,8 @@ int hinic5_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val)
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&api_data, 0, sizeof(struct hinic5_csr_request_api_data));
+ (void)memset_s(&api_data, sizeof(struct hinic5_csr_request_api_data), 0,
+ sizeof(struct hinic5_csr_request_api_data));
api_data.dw1.bits.operation_id = HINIC5_CSR_OPERATION_WRITE_CSR;
api_data.dw1.bits.need_response = HINIC5_CSR_NO_RESP_DATA;
api_data.dw1.bits.data_size = HINIC5_CSR_DATA_SZ_32;
@@ -423,7 +420,7 @@ int hinic5_api_csr_wr32(void *hwdev, u8 dest, u32 addr, u32 val)
int hinic5_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val)
{
- struct hinic5_csr_request_api_data api_data = {0};
+ struct hinic5_csr_request_api_data api_data = { 0 };
u64 csr_val = 0;
u16 in_size = sizeof(api_data);
int ret;
@@ -434,7 +431,8 @@ int hinic5_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val)
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- memset(&api_data, 0, sizeof(struct hinic5_csr_request_api_data));
+ (void)memset_s(&api_data, sizeof(struct hinic5_csr_request_api_data), 0,
+ sizeof(struct hinic5_csr_request_api_data));
api_data.dw0 = 0;
api_data.dw1.bits.operation_id = HINIC5_CSR_OPERATION_READ_CSR;
api_data.dw1.bits.need_response = HINIC5_CSR_NEED_RESP_DATA;
@@ -443,12 +441,12 @@ int hinic5_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val)
api_data.dw2.bits.csr_addr = addr;
api_data.dw2.val32 = cpu_to_be32(api_data.dw2.val32);
- ret = hinic5_api_cmd_read_ack(hwdev, dest, (u8 *)(&api_data),
- in_size, &csr_val, 0x8);
+ ret = hinic5_api_cmd_read_ack(hwdev, dest, (u8 *)(&api_data), in_size,
+ &csr_val, 0x8);
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "Read 64 bit csr fail, dest %u addr 0x%x\n",
- dest, addr);
+ "Read 64 bit csr fail, dest %u addr 0x%x\n", dest,
+ addr);
return ret;
}
@@ -457,4 +455,3 @@ int hinic5_api_csr_rd64(void *hwdev, u8 dest, u32 addr, u64 *val)
return 0;
}
EXPORT_SYMBOL(hinic5_api_csr_rd64);
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hwif.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hwif.c
index 020754bbd..b28dbefef 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_hwif.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hwif.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -20,174 +13,174 @@
#include "hinic5_hw.h"
#include "hinic5_common.h"
#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
-#define WAIT_HWIF_READY_TIMEOUT 30000
-#define MAX_TS_UP_EN_RETRY_CNT 100
+#define WAIT_HWIF_READY_TIMEOUT 30000
+#define MAX_TS_UP_EN_RETRY_CNT 100
-#define HINIC5_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT 180000
+#define HINIC5_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT 180000
#define MAX_MSIX_ENTRY 2048
-#define DB_IDX(db, db_base) \
- ((u32)(((ulong)(db) - (ulong)(db_base)) / \
- HINIC5_DB_PAGE_SIZE))
+#define DB_IDX(db, db_base) \
+ ((u32)(((ulong)(db) - (ulong)(db_base)) / HINIC5_DB_PAGE_SIZE))
-#define HINIC5_AF0_FUNC_GLOBAL_IDX_SHIFT 0
-#define HINIC5_AF0_P2P_IDX_SHIFT 12
-#define HINIC5_AF0_PCI_INTF_IDX_SHIFT 17
-#define HINIC5_AF0_VF_IN_PF_SHIFT 20
-#define HINIC5_AF0_FUNC_TYPE_SHIFT 28
+#define HINIC5_AF0_FUNC_GLOBAL_IDX_SHIFT 0
+#define HINIC5_AF0_P2P_IDX_SHIFT 12
+#define HINIC5_AF0_PCI_INTF_IDX_SHIFT 17
+#define HINIC5_AF0_VF_IN_PF_SHIFT 20
+#define HINIC5_AF0_FUNC_TYPE_SHIFT 28
-#define HINIC5_AF0_FUNC_GLOBAL_IDX_MASK 0xFFF
-#define HINIC5_AF0_P2P_IDX_MASK 0x1F
-#define HINIC5_AF0_PCI_INTF_IDX_MASK 0x7
-#define HINIC5_AF0_VF_IN_PF_MASK 0xFF
-#define HINIC5_AF0_FUNC_TYPE_MASK 0x1
+#define HINIC5_AF0_FUNC_GLOBAL_IDX_MASK 0xFFF
+#define HINIC5_AF0_P2P_IDX_MASK 0x1F
+#define HINIC5_AF0_PCI_INTF_IDX_MASK 0x7
+#define HINIC5_AF0_VF_IN_PF_MASK 0xFF
+#define HINIC5_AF0_FUNC_TYPE_MASK 0x1
-#define HINIC5_AF0_GET(val, member) \
+#define HINIC5_AF0_GET(val, member) \
(((val) >> HINIC5_AF0_##member##_SHIFT) & HINIC5_AF0_##member##_MASK)
-#define HINIC5_AF1_PPF_IDX_SHIFT 0
-#define HINIC5_AF1_AEQS_PER_FUNC_SHIFT 8
-#define HINIC5_AF1_MGMT_INIT_STATUS_SHIFT 30
-#define HINIC5_AF1_PF_INIT_STATUS_SHIFT 31
+#define HINIC5_AF1_PPF_IDX_SHIFT 0
+#define HINIC5_AF1_AEQS_PER_FUNC_SHIFT 8
+#define HINIC5_AF1_MGMT_INIT_STATUS_SHIFT 30
+#define HINIC5_AF1_PF_INIT_STATUS_SHIFT 31
-#define HINIC5_AF1_PPF_IDX_MASK 0x3F
-#define HINIC5_AF1_AEQS_PER_FUNC_MASK 0x3
-#define HINIC5_AF1_MGMT_INIT_STATUS_MASK 0x1
-#define HINIC5_AF1_PF_INIT_STATUS_MASK 0x1
+#define HINIC5_AF1_PPF_IDX_MASK 0x3F
+#define HINIC5_AF1_AEQS_PER_FUNC_MASK 0x3
+#define HINIC5_AF1_MGMT_INIT_STATUS_MASK 0x1
+#define HINIC5_AF1_PF_INIT_STATUS_MASK 0x1
-#define HINIC5_AF1_GET(val, member) \
+#define HINIC5_AF1_GET(val, member) \
(((val) >> HINIC5_AF1_##member##_SHIFT) & HINIC5_AF1_##member##_MASK)
-#define HINIC5_AF2_CEQS_PER_FUNC_SHIFT 0
-#define HINIC5_AF2_DMA_ATTR_PER_FUNC_SHIFT 9
-#define HINIC5_AF2_IRQS_PER_FUNC_SHIFT 16
+#define HINIC5_AF2_CEQS_PER_FUNC_SHIFT 0
+#define HINIC5_AF2_DMA_ATTR_PER_FUNC_SHIFT 9
+#define HINIC5_AF2_IRQS_PER_FUNC_SHIFT 16
-#define HINIC5_AF2_CEQS_PER_FUNC_MASK 0x1FF
-#define HINIC5_AF2_DMA_ATTR_PER_FUNC_MASK 0x7
-#define HINIC5_AF2_IRQS_PER_FUNC_MASK 0x7FF
+#define HINIC5_AF2_CEQS_PER_FUNC_MASK 0x1FF
+#define HINIC5_AF2_DMA_ATTR_PER_FUNC_MASK 0x7
+#define HINIC5_AF2_IRQS_PER_FUNC_MASK 0x7FF
-#define HINIC5_AF2_GET(val, member) \
+#define HINIC5_AF2_GET(val, member) \
(((val) >> HINIC5_AF2_##member##_SHIFT) & HINIC5_AF2_##member##_MASK)
-#define HINIC5_AF3_GLOBAL_VF_ID_OF_NXT_PF_SHIFT 0
-#define HINIC5_AF3_GLOBAL_VF_ID_OF_PF_SHIFT 16
+#define HINIC5_AF3_GLOBAL_VF_ID_OF_NXT_PF_SHIFT 0
+#define HINIC5_AF3_GLOBAL_VF_ID_OF_PF_SHIFT 16
-#define HINIC5_AF3_GLOBAL_VF_ID_OF_NXT_PF_MASK 0xFFF
-#define HINIC5_AF3_GLOBAL_VF_ID_OF_PF_MASK 0xFFF
+#define HINIC5_AF3_GLOBAL_VF_ID_OF_NXT_PF_MASK 0xFFF
+#define HINIC5_AF3_GLOBAL_VF_ID_OF_PF_MASK 0xFFF
-#define HINIC5_AF3_GET(val, member) \
+#define HINIC5_AF3_GET(val, member) \
(((val) >> HINIC5_AF3_##member##_SHIFT) & HINIC5_AF3_##member##_MASK)
-#define HINIC5_AF4_DOORBELL_CTRL_SHIFT 0
-#define HINIC5_AF4_DOORBELL_CTRL_MASK 0x1
+#define HINIC5_AF4_DOORBELL_CTRL_SHIFT 0
+#define HINIC5_AF4_DOORBELL_CTRL_MASK 0x1
-#define HINIC5_AF4_GET(val, member) \
+#define HINIC5_AF4_GET(val, member) \
(((val) >> HINIC5_AF4_##member##_SHIFT) & HINIC5_AF4_##member##_MASK)
-#define HINIC5_AF4_SET(val, member) \
- (((val) & HINIC5_AF4_##member##_MASK) << HINIC5_AF4_##member##_SHIFT)
+#define HINIC5_AF4_SET(val, member) \
+ (((val)&HINIC5_AF4_##member##_MASK) << HINIC5_AF4_##member##_SHIFT)
-#define HINIC5_AF4_CLEAR(val, member) \
+#define HINIC5_AF4_CLEAR(val, member) \
((val) & (~(HINIC5_AF4_##member##_MASK << HINIC5_AF4_##member##_SHIFT)))
-#define HINIC5_AF5_OUTBOUND_CTRL_SHIFT 0
-#define HINIC5_AF5_OUTBOUND_CTRL_MASK 0x1
+#define HINIC5_AF5_OUTBOUND_CTRL_SHIFT 0
+#define HINIC5_AF5_OUTBOUND_CTRL_MASK 0x1
-#define HINIC5_AF5_GET(val, member) \
+#define HINIC5_AF5_GET(val, member) \
(((val) >> HINIC5_AF5_##member##_SHIFT) & HINIC5_AF5_##member##_MASK)
-#define HINIC5_AF5_SET(val, member) \
- (((val) & HINIC5_AF5_##member##_MASK) << HINIC5_AF5_##member##_SHIFT)
+#define HINIC5_AF5_SET(val, member) \
+ (((val)&HINIC5_AF5_##member##_MASK) << HINIC5_AF5_##member##_SHIFT)
-#define HINIC5_AF5_CLEAR(val, member) \
+#define HINIC5_AF5_CLEAR(val, member) \
((val) & (~(HINIC5_AF5_##member##_MASK << HINIC5_AF5_##member##_SHIFT)))
-#define HINIC5_AF6_PF_STATUS_SHIFT 0
-#define HINIC5_AF6_PF_STATUS_MASK 0xFFFF
+#define HINIC5_AF6_PF_STATUS_SHIFT 0
+#define HINIC5_AF6_PF_STATUS_MASK 0xFFFF
-#define HINIC5_AF6_FUNC_MAX_SQ_SHIFT 23
-#define HINIC5_AF6_FUNC_MAX_SQ_MASK 0x1FF
+#define HINIC5_AF6_FUNC_MAX_SQ_SHIFT 23
+#define HINIC5_AF6_FUNC_MAX_SQ_MASK 0x1FF
-#define HINIC5_AF6_MSIX_FLEX_EN_SHIFT 22
-#define HINIC5_AF6_MSIX_FLEX_EN_MASK 0x1
+#define HINIC5_AF6_MSIX_FLEX_EN_SHIFT 22
+#define HINIC5_AF6_MSIX_FLEX_EN_MASK 0x1
-#define HINIC5_AF6_HW_TYPE_SHIFT 17
-#define HINIC5_AF6_HW_TYPE_MASK 0x3
+#define HINIC5_AF6_HW_TYPE_SHIFT 17
+#define HINIC5_AF6_HW_TYPE_MASK 0x3
-#define HINIC5_TASK1_MBOX_TIMEOUT_SHIFT 0
-#define HINIC5_TASK1_MBOX_TIMEOUT_MASK 0x1
+#define HINIC5_TASK1_MBOX_TIMEOUT_SHIFT 0
+#define HINIC5_TASK1_MBOX_TIMEOUT_MASK 0x1
-#define HINIC5_AF6_SET(val, member) \
- ((((u32)(val)) & HINIC5_AF6_##member##_MASK) << \
- HINIC5_AF6_##member##_SHIFT)
+#define HINIC5_AF6_SET(val, member) \
+ ((((u32)(val)) & HINIC5_AF6_##member##_MASK) \
+ << HINIC5_AF6_##member##_SHIFT)
-#define HINIC5_AF6_GET(val, member) \
- (((u32)(val) >> HINIC5_AF6_##member##_SHIFT) & HINIC5_AF6_##member##_MASK)
+#define HINIC5_AF6_GET(val, member) \
+ (((u32)(val) >> HINIC5_AF6_##member##_SHIFT) & \
+ HINIC5_AF6_##member##_MASK)
-#define HINIC5_AF6_CLEAR(val, member) \
- ((u32)(val) & (~(HINIC5_AF6_##member##_MASK << \
- HINIC5_AF6_##member##_SHIFT)))
+#define HINIC5_AF6_CLEAR(val, member) \
+ ((u32)(val) & \
+ (~(HINIC5_AF6_##member##_MASK << HINIC5_AF6_##member##_SHIFT)))
-#define HINIC5_TASK1_SET(val, member) \
- ((((u32)(val)) & HINIC5_TASK1_##member##_MASK) << \
- HINIC5_TASK1_##member##_SHIFT)
+#define HINIC5_TASK1_SET(val, member) \
+ ((((u32)(val)) & HINIC5_TASK1_##member##_MASK) \
+ << HINIC5_TASK1_##member##_SHIFT)
-#define HINIC5_TASK1_CLEAR(val, member) \
- ((u32)(val) & (~(HINIC5_TASK1_##member##_MASK << \
- HINIC5_TASK1_##member##_SHIFT)))
+#define HINIC5_TASK1_CLEAR(val, member) \
+ ((u32)(val) & \
+ (~(HINIC5_TASK1_##member##_MASK << HINIC5_TASK1_##member##_SHIFT)))
-#define HINIC5_PPF_ELECT_PORT_IDX_SHIFT 0
+#define HINIC5_PPF_ELECT_PORT_IDX_SHIFT 0
-#define HINIC5_PPF_ELECT_PORT_IDX_MASK 0x3F
+#define HINIC5_PPF_ELECT_PORT_IDX_MASK 0x3F
-#define HINIC5_PPF_ELECT_PORT_GET(val, member) \
- (((val) >> HINIC5_PPF_ELECT_PORT_##member##_SHIFT) & \
+#define HINIC5_PPF_ELECT_PORT_GET(val, member) \
+ (((val) >> HINIC5_PPF_ELECT_PORT_##member##_SHIFT) & \
HINIC5_PPF_ELECT_PORT_##member##_MASK)
-#define HINIC5_PPF_ELECTION_IDX_SHIFT 0
+#define HINIC5_PPF_ELECTION_IDX_SHIFT 0
-#define HINIC5_PPF_ELECTION_IDX_MASK 0x3F
+#define HINIC5_PPF_ELECTION_IDX_MASK 0x3F
-#define HINIC5_PPF_ELECTION_SET(val, member) \
- (((val) & HINIC5_PPF_ELECTION_##member##_MASK) << \
- HINIC5_PPF_ELECTION_##member##_SHIFT)
+#define HINIC5_PPF_ELECTION_SET(val, member) \
+ (((val)&HINIC5_PPF_ELECTION_##member##_MASK) \
+ << HINIC5_PPF_ELECTION_##member##_SHIFT)
-#define HINIC5_PPF_ELECTION_GET(val, member) \
- (((val) >> HINIC5_PPF_ELECTION_##member##_SHIFT) & \
+#define HINIC5_PPF_ELECTION_GET(val, member) \
+ (((val) >> HINIC5_PPF_ELECTION_##member##_SHIFT) & \
HINIC5_PPF_ELECTION_##member##_MASK)
-#define HINIC5_PPF_ELECTION_CLEAR(val, member) \
- ((val) & (~(HINIC5_PPF_ELECTION_##member##_MASK << \
- HINIC5_PPF_ELECTION_##member##_SHIFT)))
+#define HINIC5_PPF_ELECTION_CLEAR(val, member) \
+ ((val) & (~(HINIC5_PPF_ELECTION_##member##_MASK \
+ << HINIC5_PPF_ELECTION_##member##_SHIFT)))
-#define HINIC5_MPF_ELECTION_IDX_SHIFT 0
+#define HINIC5_MPF_ELECTION_IDX_SHIFT 0
-#define HINIC5_MPF_ELECTION_IDX_MASK 0x1F
+#define HINIC5_MPF_ELECTION_IDX_MASK 0x1F
-#define HINIC5_MPF_ELECTION_SET(val, member) \
- (((val) & HINIC5_MPF_ELECTION_##member##_MASK) << \
- HINIC5_MPF_ELECTION_##member##_SHIFT)
+#define HINIC5_MPF_ELECTION_SET(val, member) \
+ (((val)&HINIC5_MPF_ELECTION_##member##_MASK) \
+ << HINIC5_MPF_ELECTION_##member##_SHIFT)
-#define HINIC5_MPF_ELECTION_GET(val, member) \
- (((val) >> HINIC5_MPF_ELECTION_##member##_SHIFT) & \
+#define HINIC5_MPF_ELECTION_GET(val, member) \
+ (((val) >> HINIC5_MPF_ELECTION_##member##_SHIFT) & \
HINIC5_MPF_ELECTION_##member##_MASK)
-#define HINIC5_MPF_ELECTION_CLEAR(val, member) \
- ((val) & (~(HINIC5_MPF_ELECTION_##member##_MASK << \
- HINIC5_MPF_ELECTION_##member##_SHIFT)))
+#define HINIC5_MPF_ELECTION_CLEAR(val, member) \
+ ((val) & (~(HINIC5_MPF_ELECTION_##member##_MASK \
+ << HINIC5_MPF_ELECTION_##member##_SHIFT)))
-#define HINIC5_GET_REG_FLAG(reg) ((reg) & (~(HINIC5_REGS_FLAG_MASK)))
+#define HINIC5_GET_REG_FLAG(reg) ((reg) & (~(HINIC5_REGS_FLAG_MASK)))
-#define HINIC5_GET_REG_ADDR(reg) ((reg) & (HINIC5_REGS_FLAG_MASK))
+#define HINIC5_GET_REG_ADDR(reg) ((reg) & (HINIC5_REGS_FLAG_MASK))
-#define HINIC5_MPU_BOOT_CAUSE_MAX_NUM 3
+#define HINIC5_MPU_BOOT_CAUSE_MAX_NUM 3
-#define SPU_HOST_ID_BASE 4
-#define SPU_HOST_NUM 2
-#define SPU_HOST_ID_MAX (SPU_HOST_ID_BASE + SPU_HOST_NUM - 1)
+#define SPU_HOST_ID_BASE 4
+#define SPU_HOST_NUM 2
+#define SPU_HOST_ID_MAX (SPU_HOST_ID_BASE + SPU_HOST_NUM - 1)
enum {
UBC_SW_HANDSHAKE_VALID,
@@ -204,15 +197,15 @@ u32 hinic5_hwif_read_reg(struct hinic5_hwif *hwif, u32 reg)
return be32_to_cpu(readl(hwif->cfg_regs_base +
HINIC5_GET_REG_ADDR((u64)reg)));
#else
- UINT8 bar_idx;
+ UINT8 Bar_Idx;
if (HINIC5_GET_REG_FLAG(reg) == HINIC5_MGMT_REGS_FLAG)
- bar_idx = HINIC5_MGMT_BAR;
+ Bar_Idx = HINIC5_MGMT_BAR;
else
- bar_idx = HINIC5_CFG_BAR;
+ Bar_Idx = HINIC5_CFG_BAR;
- return be32_to_cpu(readl_uefi(hwif->bus_dev, HINIC5_GET_REG_ADDR(reg),
- bar_idx));
+ return be32_to_cpu(
+ readl_uefi(hwif->bus_dev, HINIC5_GET_REG_ADDR(reg), Bar_Idx));
#endif
}
@@ -226,24 +219,25 @@ void hinic5_hwif_write_reg(struct hinic5_hwif *hwif, u32 reg, u32 val)
writel(cpu_to_be32(val),
hwif->cfg_regs_base + HINIC5_GET_REG_ADDR((u64)reg));
#else
- UINT8 bar_idx;
+ UINT8 Bar_Idx;
if (HINIC5_GET_REG_FLAG(reg) == HINIC5_MGMT_REGS_FLAG)
- bar_idx = HINIC5_MGMT_BAR;
+ Bar_Idx = HINIC5_MGMT_BAR;
else
- bar_idx = HINIC5_CFG_BAR;
+ Bar_Idx = HINIC5_CFG_BAR;
- writel_uefi(hwif->bus_dev, HINIC5_GET_REG_ADDR(reg), bar_idx,
+ writel_uefi(hwif->bus_dev, HINIC5_GET_REG_ADDR(reg), Bar_Idx,
be32_to_cpu(val));
#endif
}
-bool hinic5_get_card_present_state(struct hinic5_hwdev *hwdev)
+bool get_card_present_state(struct hinic5_hwdev *hwdev)
{
u32 attr1;
- if (!get_handshake_state(hwdev))
+ if (!get_handshake_state(hwdev)) {
return false;
+ }
attr1 = hinic5_hwif_read_reg(hwdev->hwif, HINIC5_CSR_FUNC_ATTR1_ADDR);
if (attr1 == HINIC5_BUS_LINK_DOWN) {
@@ -275,14 +269,17 @@ bool get_handshake_state(struct hinic5_hwdev *hwdev)
#ifndef __UEFI__
u32 sw_handshake_chk;
- if (!hinic5_check_htn_device_id(hwdev))
+ if (!hinic5_check_htn_device_id(hwdev)) {
return true;
+ }
- sw_handshake_chk = readl(hwdev->hwif->fers2_reg_base +
- HINIC5_GET_REG_ADDR \
- ((u64)HINIC5_CSR_INTC_BAR_SW_HANDSHAKE_0_CSR0_REG));
- if (sw_handshake_chk == UBC_SW_HANDSHAKE_NO_VALID)
+ sw_handshake_chk =
+ readl(hwdev->hwif->fers2_reg_base +
+ HINIC5_GET_REG_ADDR((
+ u64)HINIC5_CSR_INTC_BAR_SW_HANDSHAKE_0_CSR0_REG));
+ if (sw_handshake_chk == UBC_SW_HANDSHAKE_NO_VALID) {
return false;
+ }
#endif
return true;
@@ -308,9 +305,10 @@ u32 hinic5_get_heartbeat_status(void *hwdev)
}
EXPORT_SYMBOL(hinic5_get_heartbeat_status);
-#define MIGRATE_HOST_STATUS_CLEAR(host_id, val) ((val) & (~(1U << (host_id))))
-#define MIGRATE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
-#define MIGRATE_HOST_STATUS_GET(host_id, val) (((val) & (1U << (host_id))) != 0)
+#define MIGRATE_HOST_STATUS_CLEAR(host_id, val) ((val) & (~(1U << (host_id))))
+#define MIGRATE_HOST_STATUS_SET(host_id, enable) \
+ (((u8)(enable)&1U) << (host_id))
+#define MIGRATE_HOST_STATUS_GET(host_id, val) (((val) & (1U << (host_id))) != 0)
static inline int hinic5_hwdev_check(struct hinic5_hwdev *dev)
{
@@ -329,18 +327,20 @@ int hinic5_set_host_migrate_enable(void *hwdev, u8 host_id, bool enable)
u32 reg_val;
int ret = hinic5_hwdev_check(dev);
-
if (ret != 0)
return ret;
- reg_val = hinic5_hwif_read_reg(dev->hwif, HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR);
+ reg_val = hinic5_hwif_read_reg(dev->hwif,
+ HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR);
reg_val = MIGRATE_HOST_STATUS_CLEAR(host_id, reg_val);
reg_val |= MIGRATE_HOST_STATUS_SET(host_id, enable);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR, reg_val);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR,
+ reg_val);
- sdk_info(dev->dev_hdl, "Set migrate host %u status %d, reg value: 0x%x\n",
- host_id, enable, reg_val);
+ sdk_info(dev->dev_hdl,
+ "Set migrate host %u status %d, reg value: 0x%x\n", host_id,
+ enable, reg_val);
return 0;
}
@@ -352,11 +352,11 @@ int hinic5_get_host_migrate_enable(void *hwdev, u8 host_id, u8 *migrate_en)
u32 reg_val;
int ret = hinic5_hwdev_check(dev);
-
if (ret != 0)
return ret;
- reg_val = hinic5_hwif_read_reg(dev->hwif, HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR);
+ reg_val = hinic5_hwif_read_reg(dev->hwif,
+ HINIC5_MULT_MIGRATE_HOST_STATUS_ADDR);
*migrate_en = MIGRATE_HOST_STATUS_GET(host_id, reg_val);
return 0;
@@ -418,32 +418,35 @@ static void set_hwif_attr(struct hinic5_hwif *hwif, u32 attr0, u32 attr1,
hwif->attr.num_dma_attr = BIT(HINIC5_AF2_GET(attr2, DMA_ATTR_PER_FUNC));
- hwif->attr.global_vf_id_of_pf = HINIC5_AF3_GET(attr3,
- GLOBAL_VF_ID_OF_PF);
+ hwif->attr.global_vf_id_of_pf =
+ HINIC5_AF3_GET(attr3, GLOBAL_VF_ID_OF_PF);
hwif->attr.num_sq = HINIC5_AF6_GET(attr6, FUNC_MAX_SQ);
hwif->attr.msix_flex_en = HINIC5_AF6_GET(attr6, MSIX_FLEX_EN);
hwif->attr.hw_type = HINIC5_AF6_GET(attr6, HW_TYPE);
- sdk_info(hwdev->dev_hdl,
- "func_global_idx: 0x%x, port_to_port_idx: 0x%x, pci_intf_idx: 0x%x\n",
- hwif->attr.func_global_idx, hwif->attr.port_to_port_idx,
- hwif->attr.pci_intf_idx);
+ sdk_info(
+ hwdev->dev_hdl,
+ "func_global_idx: 0x%x, port_to_port_idx: 0x%x, pci_intf_idx: 0x%x\n",
+ hwif->attr.func_global_idx, hwif->attr.port_to_port_idx,
+ hwif->attr.pci_intf_idx);
sdk_info(hwdev->dev_hdl,
"vf_in_pf: 0x%x, func_type: %d msix_flex_en %u\n",
hwif->attr.vf_in_pf, hwif->attr.func_type,
hwif->attr.msix_flex_en);
- sdk_info(hwdev->dev_hdl,
- "ppf_idx: 0x%x, num_aeqs: 0x%x, num_ceqs: 0x%x, num_irqs: 0x%x\n",
- hwif->attr.ppf_idx, hwif->attr.num_aeqs,
- hwif->attr.num_ceqs, hwif->attr.num_irqs);
-
- sdk_info(hwdev->dev_hdl,
- "num_sq: 0x%x, num_dma_attr: 0x%x, global_vf_id_of_pf: %u, hw_type: %u\n",
- hwif->attr.num_sq, hwif->attr.num_dma_attr,
- hwif->attr.global_vf_id_of_pf, hwif->attr.hw_type);
+ sdk_info(
+ hwdev->dev_hdl,
+ "ppf_idx: 0x%x, num_aeqs: 0x%x, num_ceqs: 0x%x, num_irqs: 0x%x\n",
+ hwif->attr.ppf_idx, hwif->attr.num_aeqs, hwif->attr.num_ceqs,
+ hwif->attr.num_irqs);
+
+ sdk_info(
+ hwdev->dev_hdl,
+ "num_sq: 0x%x, num_dma_attr: 0x%x, global_vf_id_of_pf: %u, hw_type: %u\n",
+ hwif->attr.num_sq, hwif->attr.num_dma_attr,
+ hwif->attr.global_vf_id_of_pf, hwif->attr.hw_type);
}
/**
@@ -455,34 +458,35 @@ static int get_hwif_attr(struct hinic5_hwif *hwif)
struct hinic5_hwdev *hwdev = hwif->hwdev;
u32 addr, attr0, attr1, attr2, attr3, attr6;
- addr = HINIC5_CSR_FUNC_ATTR0_ADDR;
- attr0 = hinic5_hwif_read_reg(hwif, addr);
+ addr = HINIC5_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic5_hwif_read_reg(hwif, addr);
if (attr0 == HINIC5_BUS_LINK_DOWN)
return -EFAULT;
- addr = HINIC5_CSR_FUNC_ATTR1_ADDR;
- attr1 = hinic5_hwif_read_reg(hwif, addr);
+ addr = HINIC5_CSR_FUNC_ATTR1_ADDR;
+ attr1 = hinic5_hwif_read_reg(hwif, addr);
if (attr1 == HINIC5_BUS_LINK_DOWN)
return -EFAULT;
- addr = HINIC5_CSR_FUNC_ATTR2_ADDR;
- attr2 = hinic5_hwif_read_reg(hwif, addr);
+ addr = HINIC5_CSR_FUNC_ATTR2_ADDR;
+ attr2 = hinic5_hwif_read_reg(hwif, addr);
if (attr2 == HINIC5_BUS_LINK_DOWN)
return -EFAULT;
- addr = HINIC5_CSR_FUNC_ATTR3_ADDR;
- attr3 = hinic5_hwif_read_reg(hwif, addr);
+ addr = HINIC5_CSR_FUNC_ATTR3_ADDR;
+ attr3 = hinic5_hwif_read_reg(hwif, addr);
if (attr3 == HINIC5_BUS_LINK_DOWN)
return -EFAULT;
- addr = HINIC5_CSR_FUNC_ATTR6_ADDR;
- attr6 = hinic5_hwif_read_reg(hwif, addr);
+ addr = HINIC5_CSR_FUNC_ATTR6_ADDR;
+ attr6 = hinic5_hwif_read_reg(hwif, addr);
if (attr6 == HINIC5_BUS_LINK_DOWN)
return -EFAULT;
- sdk_info(hwdev->dev_hdl,
- "attr0: 0x%08x, attr1: 0x%08x, attr2: 0x%08x, attr3: 0x%08x, attr6: 0x%08x\n",
- attr0, attr1, attr2, attr3, attr6);
+ sdk_info(
+ hwdev->dev_hdl,
+ "attr0: 0x%08x, attr1: 0x%08x, attr2: 0x%08x, attr3: 0x%08x, attr6: 0x%08x\n",
+ attr0, attr1, attr2, attr3, attr6);
set_hwif_attr(hwif, attr0, attr1, attr2, attr3, attr6);
return 0;
@@ -506,14 +510,16 @@ enum hinic5_pf_status hinic5_get_pf_status(struct hinic5_hwif *hwif)
return HINIC5_AF6_GET(attr6, PF_STATUS);
}
-static inline enum doorbell_flush_state hinic5_get_doorbell_ctrl_status(struct hinic5_hwif *hwif)
+static inline enum doorbell_flush_state
+hinic5_get_doorbell_ctrl_status(struct hinic5_hwif *hwif)
{
u32 attr4 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR4_ADDR);
return HINIC5_AF4_GET(attr4, DOORBELL_CTRL);
}
-static inline enum outbound_flush_state hinic5_get_outbound_ctrl_status(struct hinic5_hwif *hwif)
+static inline enum outbound_flush_state
+hinic5_get_outbound_ctrl_status(struct hinic5_hwif *hwif)
{
u32 attr5 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR5_ADDR);
@@ -556,12 +562,12 @@ static void set_ppf(struct hinic5_hwif *hwif)
u32 addr, val, ppf_election;
/* Read Modify Write */
- addr = HINIC5_CSR_PPF_ELECTION_ADDR;
+ addr = HINIC5_CSR_PPF_ELECTION_ADDR;
val = hinic5_hwif_read_reg(hwif, addr);
val = HINIC5_PPF_ELECTION_CLEAR(val, IDX);
- ppf_election = HINIC5_PPF_ELECTION_SET(attr->func_global_idx, IDX);
+ ppf_election = HINIC5_PPF_ELECTION_SET(attr->func_global_idx, IDX);
val |= ppf_election;
hinic5_hwif_write_reg(hwif, addr, val);
@@ -599,7 +605,7 @@ static void set_mpf(struct hinic5_hwif *hwif)
u32 addr, val, mpf_election;
/* Read Modify Write */
- addr = HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR;
+ addr = HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR;
val = hinic5_hwif_read_reg(hwif, addr);
@@ -629,7 +635,8 @@ static int init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base,
hwif->fers2_reg_base = fers2_reg_base;
/* if function is VF, mgmt_regs_base will be NULL */
hwif->cfg_regs_base = mgmt_regs_base ? cfg_reg_base :
- (u8 *)((uintptr_t)cfg_reg_base + HINIC5_VF_CFG_REG_OFFSET);
+ (u8 *)((uintptr_t)cfg_reg_base +
+ HINIC5_VF_CFG_REG_OFFSET);
hwif->intr_regs_base = intr_reg_base;
hwif->mgmt_regs_base = mgmt_regs_base;
@@ -639,8 +646,8 @@ static int init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base,
return 0;
}
-static int init_db_area_idx(struct hinic5_hwif *hwif, u64 db_base_phy, u8 *db_base,
- u64 db_dwqe_len)
+static int init_db_area_idx(struct hinic5_hwif *hwif, u64 db_base_phy,
+ u8 *db_base, u64 db_dwqe_len)
{
struct hinic5_free_db_area *free_db_area = &hwif->free_db_area;
u32 db_max_areas;
@@ -650,8 +657,8 @@ static int init_db_area_idx(struct hinic5_hwif *hwif, u64 db_base_phy, u8 *db_ba
hwif->db_dwqe_len = db_dwqe_len;
db_max_areas = (db_dwqe_len > HINIC5_DB_DWQE_SIZE) ?
- HINIC5_DB_MAX_AREAS :
- (u32)(db_dwqe_len / HINIC5_DB_PAGE_SIZE);
+ HINIC5_DB_MAX_AREAS :
+ (u32)(db_dwqe_len / HINIC5_DB_PAGE_SIZE);
free_db_area->db_bitmap_array = bitmap_zalloc(db_max_areas, GFP_KERNEL);
if (!free_db_area->db_bitmap_array) {
pr_err("Failed to allocate db area.\n");
@@ -725,8 +732,8 @@ int hinic5_alloc_db_addr(void *hwdev, void __iomem **db_base,
struct hinic5_hwif *hwif = NULL;
u32 idx = 0;
#ifdef __HIFC__
-#define HIFC3_DB_ADDR_RSVD 12
-#define HIFC3_DB_MASK 128
+#define HIFC5_DB_ADDR_RSVD 12
+#define HIFC5_DB_MASK 128
u64 db_base_phy_fc;
if (!hwdev || !db_base)
@@ -734,10 +741,10 @@ int hinic5_alloc_db_addr(void *hwdev, void __iomem **db_base,
hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
- db_base_phy_fc = hwif->db_base_phy >> HIFC3_DB_ADDR_RSVD;
+ db_base_phy_fc = hwif->db_base_phy >> HIFC5_DB_ADDR_RSVD;
- if (db_base_phy_fc & (HIFC3_DB_MASK - 1))
- idx = HIFC3_DB_MASK - (db_base_phy_fc && (HIFC3_DB_MASK - 1));
+ if (db_base_phy_fc & (HIFC5_DB_MASK - 1))
+ idx = HIFC5_DB_MASK - (db_base_phy_fc && (HIFC5_DB_MASK - 1));
#else
int err;
@@ -874,19 +881,20 @@ static enum hinic5_wait_return check_db_outbound_enable_handler(void *priv_data)
db_ctrl = hinic5_get_doorbell_ctrl_status(hwif);
outbound_ctrl = hinic5_get_outbound_ctrl_status(hwif);
- if (outbound_ctrl == OUTBOUND_FLUSH_DISABLED && db_ctrl == DOORBELL_FLUSH_DISABLED)
+ if (outbound_ctrl == OUTBOUND_FLUSH_DISABLED &&
+ db_ctrl == DOORBELL_FLUSH_DISABLED)
return WAIT_PROCESS_CPL;
return WAIT_PROCESS_WAITING;
}
-enum hinic5_wait_return check_outbound_enable_handler(struct hinic5_hwdev *hwdev)
+enum hinic5_wait_return
+check_outbound_enable_handler(struct hinic5_hwdev *hwdev)
{
enum outbound_flush_state outbound_ctrl;
- /* bypass counter is non-zero, indicates a flow that may cause
- * outbound_ctrl_status to be non-zero is being executed, cmdq and mbox do not check
- */
- if (atomic_read(&hwdev->check_ob_flush_bypass_ref_cnt) > 0)
+ /* bypass 计数非零, 表示正在执行可能导致outbound_ctrl_status非零的流程, cmdq和mbox不检测 */
+ if (atomic_read(&hwdev->check_ob_flush_bypass_ref_cnt) > 0) {
return WAIT_PROCESS_CPL;
+ }
outbound_ctrl = hinic5_get_outbound_ctrl_status(hwdev->hwif);
if (outbound_ctrl == OUTBOUND_FLUSH_DISABLED)
@@ -896,7 +904,8 @@ enum hinic5_wait_return check_outbound_enable_handler(struct hinic5_hwdev *hwdev
static int wait_until_doorbell_and_outbound_enabled(struct hinic5_hwif *hwif)
{
- return hinic5_wait_for_timeout(hwif, check_db_outbound_enable_handler,
+ return hinic5_wait_for_timeout(
+ hwif, check_db_outbound_enable_handler,
HINIC5_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT, USEC_PER_MSEC);
}
@@ -919,15 +928,17 @@ static void select_ppf_mpf(struct hinic5_hwdev *hwdev)
* @hwif: the hardware interface of a pci/ubus function device
* Return: 0 - success, negative - failure
**/
-int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base, void *cfg_reg_base,
- void *intr_reg_base, void *mgmt_regs_base, u64 db_base_phy,
- void *db_base, u64 db_dwqe_len)
+int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base,
+ void *cfg_reg_base, void *intr_reg_base,
+ void *mgmt_regs_base, u64 db_base_phy, void *db_base,
+ u64 db_dwqe_len)
{
struct hinic5_hwif *hwif = NULL;
u32 attr1, attr4, attr5;
int err;
- err = init_hwif(hwdev, fers2_reg_base, cfg_reg_base, intr_reg_base, mgmt_regs_base);
+ err = init_hwif(hwdev, fers2_reg_base, cfg_reg_base, intr_reg_base,
+ mgmt_regs_base);
if (err != 0)
return err;
@@ -942,7 +953,8 @@ int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base, void *cfg
err = wait_hwif_ready(hwdev);
if (err != 0) {
attr1 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR1_ADDR);
- sdk_err(hwdev->dev_hdl, "Chip status is not ready, attr1:0x%x\n", attr1);
+ sdk_err(hwdev->dev_hdl,
+ "Chip status is not ready, attr1:0x%x\n", attr1);
goto hwif_ready_err;
}
@@ -956,7 +968,8 @@ int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base, void *cfg
if (err != 0) {
attr4 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR4_ADDR);
attr5 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR5_ADDR);
- sdk_err(hwdev->dev_hdl, "Hw doorbell/outbound is disabled, attr4 0x%x attr5 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "Hw doorbell/outbound is disabled, attr4 0x%x attr5 0x%x\n",
attr4, attr5);
goto hwif_ready_err;
}
@@ -967,9 +980,12 @@ int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base, void *cfg
/* disable mgmt cpu report any event */
hinic5_set_pf_status(hwdev->hwif, HINIC5_PF_STATUS_INIT);
- sdk_info(hwdev->dev_hdl, "global_func_idx: %u, func_type: %d, host_id: %u, ppf: %u, mpf: %u\n",
- hwif->attr.func_global_idx, hwif->attr.func_type, hwif->attr.pci_intf_idx,
- hwif->attr.ppf_idx, hwif->attr.mpf_idx);
+ sdk_info(
+ hwdev->dev_hdl,
+ "global_func_idx: %u, func_type: %d, host_id: %u, ppf: %u, mpf: %u\n",
+ hwif->attr.func_global_idx, hwif->attr.func_type,
+ hwif->attr.pci_intf_idx, hwif->attr.ppf_idx,
+ hwif->attr.mpf_idx);
return 0;
@@ -1055,7 +1071,6 @@ EXPORT_SYMBOL(hinic5_pcie_itf_id);
bool hinic5_in_spu(void *hwdev)
{
const u8 host_id = hinic5_pcie_itf_id(hwdev);
-
return SPU_HOST_ID_BASE <= host_id && host_id <= SPU_HOST_ID_MAX;
}
EXPORT_SYMBOL(hinic5_in_spu);
@@ -1146,7 +1161,8 @@ int hinic5_ts_up_en(void *hwdev, u32 flags)
hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN), flags);
for (retry_cnt = 0; retry_cnt < MAX_TS_UP_EN_RETRY_CNT; retry_cnt++) {
- if ((hinic5_hwif_read_reg(dev->hwif, HINIC5_PTP_REG(UP_EN)) & flags) == 0)
+ if ((hinic5_hwif_read_reg(dev->hwif, HINIC5_PTP_REG(UP_EN)) &
+ flags) == 0)
return 0;
udelay(1);
@@ -1180,9 +1196,12 @@ void hinic5_write_ts_data(void *hwdev, const struct timespec64 *ts)
return;
second = (u64)ts->tv_sec;
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA2), (u32)ts->tv_nsec);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA1), second & 0xFFFFFFFF);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA0), upper_32_bits(second));
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA2),
+ (u32)ts->tv_nsec);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA1),
+ second & 0xFFFFFFFF);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(WR_DATA0),
+ upper_32_bits(second));
hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN), 1);
for (retry_cnt = 0; retry_cnt < MAX_TS_UP_EN_RETRY_CNT; retry_cnt++) {
if (hinic5_hwif_read_reg(dev->hwif, HINIC5_PTP_REG(UP_EN)) == 0)
@@ -1193,8 +1212,8 @@ void hinic5_write_ts_data(void *hwdev, const struct timespec64 *ts)
}
EXPORT_SYMBOL(hinic5_write_ts_data);
-#define PTP_INC_CFG_UP_EN_FLAG BIT(2)
-#define PTP_DELTA_UP_EN_FLAG BIT(3)
+#define PTP_INC_CFG_UP_EN_FLAG BIT(2)
+#define PTP_DELTA_UP_EN_FLAG BIT(3)
void hinic5_set_ptp_inc(void *hwdev, u32 inc_val)
{
u32 retry_cnt;
@@ -1204,7 +1223,8 @@ void hinic5_set_ptp_inc(void *hwdev, u32 inc_val)
return;
hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(INC_CFG), inc_val);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN), PTP_INC_CFG_UP_EN_FLAG);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN),
+ PTP_INC_CFG_UP_EN_FLAG);
for (retry_cnt = 0; retry_cnt < MAX_TS_UP_EN_RETRY_CNT; retry_cnt++) {
if (hinic5_hwif_read_reg(dev->hwif, HINIC5_PTP_REG(UP_EN)) == 0)
break;
@@ -1214,7 +1234,7 @@ void hinic5_set_ptp_inc(void *hwdev, u32 inc_val)
}
EXPORT_SYMBOL(hinic5_set_ptp_inc);
-#define PTP_NS_DELTA_OP_ADD BIT(31)
+#define PTP_NS_DELTA_OP_ADD BIT(31)
void hinic5_ptp_ts_update(void *hwdev, s32 delta_ns)
{
u32 retry_cnt;
@@ -1231,8 +1251,10 @@ void hinic5_ptp_ts_update(void *hwdev, s32 delta_ns)
update_cfg_val |= PTP_NS_DELTA_OP_ADD;
}
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UPDT_CFG), update_cfg_val);
- hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN), PTP_DELTA_UP_EN_FLAG);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UPDT_CFG),
+ update_cfg_val);
+ hinic5_hwif_write_reg(dev->hwif, HINIC5_PTP_REG(UP_EN),
+ PTP_DELTA_UP_EN_FLAG);
for (retry_cnt = 0; retry_cnt < MAX_TS_UP_EN_RETRY_CNT; retry_cnt++) {
if (hinic5_hwif_read_reg(dev->hwif, HINIC5_PTP_REG(UP_EN)) == 0)
break;
@@ -1255,28 +1277,30 @@ int hinic5_read_n_ptp_ts_data(struct hinic5_hwdev *hwdev, u64 *time_ns)
/* 80 bit non-ptp TimeStamp */
/* | [79 : 64] | [63 : 32] | [31 : 29] | [28 : 0] |
- * | hi | mid | rsv | lo |
- */
+ | hi | mid | rsv | lo | */
lo = hinic5_hwif_read_reg(hwdev->hwif, HINIC5_N_PTP_REG(RD_DATA2));
mid = hinic5_hwif_read_reg(hwdev->hwif, HINIC5_N_PTP_REG(RD_DATA1));
hi = hinic5_hwif_read_reg(hwdev->hwif, HINIC5_N_PTP_REG(RD_DATA0));
/* 64 bit nsec_lo */
/* | [63 : 61] | [60 : 29] | [28 : 0] |
- * | hi[2 : 0] | mid | lo |
- */
- *time_ns = (((u64)(lo & HINIC5_N_PTP_LOW_MASK)) | (((u64)mid) << HINIC5_N_PTP_MID_SHIFT) |
- (((u64)(hi & HINIC5_N_PTP_HIGH_MASK)) << HINIC5_N_PTP_HIGH_SHIFT));
+ | hi[2 : 0] | mid | lo | */
+ *time_ns = (((u64)(lo & HINIC5_N_PTP_LOW_MASK)) |
+ (((u64)mid) << HINIC5_N_PTP_MID_SHIFT) |
+ (((u64)(hi & HINIC5_N_PTP_HIGH_MASK))
+ << HINIC5_N_PTP_HIGH_SHIFT));
return 0;
}
-static inline int hinic5_hwif_wait_n_ptp_up_en(struct hinic5_hwif *hwif, u32 flags)
+static inline int hinic5_hwif_wait_n_ptp_up_en(struct hinic5_hwif *hwif,
+ u32 flags)
{
u32 retry_cnt;
-
for (retry_cnt = 0; retry_cnt < MAX_TS_UP_EN_RETRY_CNT; retry_cnt++) {
- if ((hinic5_hwif_read_reg(hwif, HINIC5_N_PTP_REG(UP_EN)) & flags) == 0)
+ if ((hinic5_hwif_read_reg(hwif, HINIC5_N_PTP_REG(UP_EN)) &
+ flags) == 0) {
return 0;
+ }
udelay(1);
}
return -EBUSY;
@@ -1306,17 +1330,31 @@ u8 hinic5_host_ppf_idx(struct hinic5_hwdev *hwdev, u8 host_id)
return HINIC5_PPF_ELECT_PORT_GET(val, IDX);
}
-u32 hinic5_hinic5_get_self_test_result(void *hwdev)
+u32 hinic5_get_self_test_result(void *hwdev)
{
struct hinic5_hwif *hwif = ((struct hinic5_hwdev *)hwdev)->hwif;
return hinic5_hwif_read_reg(hwif, HINIC5_MGMT_HEALTH_STATUS_ADDR);
}
+static inline enum func_type hisdk5_get_func_type(struct hinic5_hwif *hwif)
+{
+ u32 attr0;
+ enum func_type func_type = hwif->attr.func_type;
+ if (func_type != TYPE_UNKNOWN) {
+ return func_type;
+ }
+
+ attr0 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR0_ADDR);
+ if (attr0 == HINIC5_BUS_LINK_DOWN)
+ return TYPE_UNKNOWN;
+ return HINIC5_AF0_GET(attr0, FUNC_TYPE);
+}
+
void hinic5_show_chip_err_info(struct hinic5_hwdev *hwdev)
{
- const enum func_type func_type = hinic5_func_type(hwdev);
struct hinic5_hwif *hwif = hwdev->hwif;
+ enum func_type func_type = hisdk5_get_func_type(hwif);
u32 value;
if (func_type != TYPE_PPF && func_type != TYPE_PF)
@@ -1339,4 +1377,4 @@ void hinic5_show_chip_err_info(struct hinic5_hwdev *hwdev)
sdk_warn(hwdev->dev_hdl, "Chip exception info1: 0x%08x\n", value);
value = hinic5_hwif_read_reg(hwif, HINIC5_ERR_INFO2_ADDR);
sdk_warn(hwdev->dev_hdl, "Chip exception info2: 0x%08x\n", value);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mbox.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mbox.c
index 2f1f4d184..c05f40bd8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mbox.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mbox.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -19,93 +12,92 @@
#include "ossl_knl.h"
#include "comm_defs.h"
#include "mpu_inband_cmd.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_hw.h"
#include "hinic5_hwdev.h"
#include "hinic5_csr_inner.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_eqs.h"
#include "hinic5_prof_adap.h"
#include "hinic5_common.h"
#include "hinic5_chip_info.h"
#include "hinic5_mbox.h"
-#define HINIC5_MBOX_INT_DST_AEQN_SHIFT 10
-#define HINIC5_MBOX_INT_SRC_RESP_AEQN_SHIFT 12
-#define HINIC5_MBOX_INT_STAT_DMA_SHIFT 14
+#define HINIC5_MBOX_INT_DST_AEQN_SHIFT 10
+#define HINIC5_MBOX_INT_SRC_RESP_AEQN_SHIFT 12
+#define HINIC5_MBOX_INT_STAT_DMA_SHIFT 14
/* The size of data to be send (unit of 4 bytes) */
-#define HINIC5_MBOX_INT_TX_SIZE_SHIFT 20
+#define HINIC5_MBOX_INT_TX_SIZE_SHIFT 20
/* SO_RO(strong order, relax order) */
-#define HINIC5_MBOX_INT_STAT_DMA_SO_RO_SHIFT 25
-#define HINIC5_MBOX_INT_WB_EN_SHIFT 28
+#define HINIC5_MBOX_INT_STAT_DMA_SO_RO_SHIFT 25
+#define HINIC5_MBOX_INT_WB_EN_SHIFT 28
-#define HINIC5_MBOX_INT_DST_AEQN_MASK 0x3
-#define HINIC5_MBOX_INT_SRC_RESP_AEQN_MASK 0x3
-#define HINIC5_MBOX_INT_STAT_DMA_MASK 0x3F
-#define HINIC5_MBOX_INT_TX_SIZE_MASK 0x1F
-#define HINIC5_MBOX_INT_STAT_DMA_SO_RO_MASK 0x3
-#define HINIC5_MBOX_INT_WB_EN_MASK 0x1
+#define HINIC5_MBOX_INT_DST_AEQN_MASK 0x3
+#define HINIC5_MBOX_INT_SRC_RESP_AEQN_MASK 0x3
+#define HINIC5_MBOX_INT_STAT_DMA_MASK 0x3F
+#define HINIC5_MBOX_INT_TX_SIZE_MASK 0x1F
+#define HINIC5_MBOX_INT_STAT_DMA_SO_RO_MASK 0x3
+#define HINIC5_MBOX_INT_WB_EN_MASK 0x1
-#define WAIT_USEC_50 50
+#define WAIT_USEC_50 50
-#define HINIC5_MBOX_INT_SET(val, field) \
- (((u32)(val) & HINIC5_MBOX_INT_##field##_MASK) << \
- HINIC5_MBOX_INT_##field##_SHIFT)
+#define HINIC5_MBOX_INT_SET(val, field) \
+ (((u32)(val)&HINIC5_MBOX_INT_##field##_MASK) \
+ << HINIC5_MBOX_INT_##field##_SHIFT)
enum hinic5_mbox_tx_status {
- TX_DONE = 0,
+ TX_DONE = 0,
TX_NOT_DONE = 1,
};
-#define HINIC5_MBOX_CTRL_TRIGGER_AEQE_SHIFT 0
+#define HINIC5_MBOX_CTRL_TRIGGER_AEQE_SHIFT 0
/* specifies the issue request for the message data.
* 0 - Tx request is done;
* 1 - Tx request is in process.
*/
-#define HINIC5_MBOX_CTRL_TX_STATUS_SHIFT 1
-#define HINIC5_MBOX_CTRL_DST_FUNC_SHIFT 16
+#define HINIC5_MBOX_CTRL_TX_STATUS_SHIFT 1
+#define HINIC5_MBOX_CTRL_DST_FUNC_SHIFT 16
-#define HINIC5_MBOX_CTRL_TRIGGER_AEQE_MASK 0x1
-#define HINIC5_MBOX_CTRL_TX_STATUS_MASK 0x1
-#define HINIC5_MBOX_CTRL_DST_FUNC_MASK 0x1FFF
+#define HINIC5_MBOX_CTRL_TRIGGER_AEQE_MASK 0x1
+#define HINIC5_MBOX_CTRL_TX_STATUS_MASK 0x1
+#define HINIC5_MBOX_CTRL_DST_FUNC_MASK 0x1FFF
-#define HINIC5_MBOX_CTRL_GET(val, field) \
- (((val) >> HINIC5_MBOX_CTRL_##field##_SHIFT) & \
- HINIC5_MBOX_CTRL_##field##_MASK)
-#define HINIC5_MBOX_CTRL_SET(val, field) \
- (((val) & HINIC5_MBOX_CTRL_##field##_MASK) << \
- HINIC5_MBOX_CTRL_##field##_SHIFT)
+#define HINIC5_MBOX_CTRL_GET(val, field) \
+ (((val) >> HINIC5_MBOX_CTRL_##field##_SHIFT) & \
+ HINIC5_MBOX_CTRL_##field##_MASK)
+#define HINIC5_MBOX_CTRL_SET(val, field) \
+ (((val)&HINIC5_MBOX_CTRL_##field##_MASK) \
+ << HINIC5_MBOX_CTRL_##field##_SHIFT)
-#define MBOX_MSG_WAIT_ONCE_TIME_US 10
-#define MBOX_MSG_RETRY_ACK_TIMEOUT 1000U
-#define WAIT_MGMT_UNBUSY_TIMEOUT 4000U /* temp value */
+#define MBOX_MSG_WAIT_ONCE_TIME_US 10
+#define MBOX_MSG_RETRY_ACK_TIMEOUT 1000U
+#define WAIT_MGMT_UNBUSY_TIMEOUT 4000U /* temp value */
-#define MBOX_MAX_BUF_SZ 2048U
-#define MBOX_HEADER_SZ 8
-#define HINIC5_MBOX_DATA_SIZE (MBOX_MAX_BUF_SZ - MBOX_HEADER_SZ)
+#define MBOX_MAX_BUF_SZ 2048U
+#define MBOX_HEADER_SZ 8
+#define HINIC5_MBOX_DATA_SIZE (MBOX_MAX_BUF_SZ - MBOX_HEADER_SZ)
/* MBOX size is 64B, 8B for mbox_header, 8B reserved */
-#define MBOX_SEG_LEN 48
-#define MBOX_SEG_LEN_ALIGN 4
-#define MBOX_WB_STATUS_LEN 16UL
+#define MBOX_SEG_LEN 48
+#define MBOX_SEG_LEN_ALIGN 4
+#define MBOX_WB_STATUS_LEN 16UL
-#define SEQ_ID_START_VAL 0
-#define SEQ_ID_MAX_VAL 42
-#define MBOX_LAST_SEG_MAX_LEN (MBOX_MAX_BUF_SZ - \
- SEQ_ID_MAX_VAL * MBOX_SEG_LEN)
+#define SEQ_ID_START_VAL 0
+#define SEQ_ID_MAX_VAL 42
+#define MBOX_LAST_SEG_MAX_LEN (MBOX_MAX_BUF_SZ - SEQ_ID_MAX_VAL * MBOX_SEG_LEN)
/* Mbox write back status is 16B, only first 2B is used */
-#define MBOX_WB_STATUS_ERRCODE_MASK 0xFFFF
-#define MBOX_WB_STATUS_MASK 0xFF
-#define MBOX_WB_ERROR_CODE_MASK 0xFF00
-#define MBOX_WB_STATUS_FINISHED_SUCCESS 0xFF
-#define MBOX_WB_STATUS_FINISHED_WITH_ERR 0xFE
-#define MBOX_WB_STATUS_NOT_FINISHED 0x00
-
-#define MBOX_STATUS_FINISHED(wb) \
- (((wb) & MBOX_WB_STATUS_MASK) != MBOX_WB_STATUS_NOT_FINISHED)
-#define MBOX_STATUS_SUCCESS(wb) \
- (((wb) & MBOX_WB_STATUS_MASK) == MBOX_WB_STATUS_FINISHED_SUCCESS)
+#define MBOX_WB_STATUS_ERRCODE_MASK 0xFFFF
+#define MBOX_WB_STATUS_MASK 0xFF
+#define MBOX_WB_ERROR_CODE_MASK 0xFF00
+#define MBOX_WB_STATUS_FINISHED_SUCCESS 0xFF
+#define MBOX_WB_STATUS_FINISHED_WITH_ERR 0xFE
+#define MBOX_WB_STATUS_NOT_FINISHED 0x00
+
+#define MBOX_STATUS_FINISHED(wb) \
+ (((wb)&MBOX_WB_STATUS_MASK) != MBOX_WB_STATUS_NOT_FINISHED)
+#define MBOX_STATUS_SUCCESS(wb) \
+ (((wb)&MBOX_WB_STATUS_MASK) == MBOX_WB_STATUS_FINISHED_SUCCESS)
/*
* The errcode is specified as:
@@ -117,73 +109,74 @@ enum hinic5_mbox_tx_status {
* 5 - The sender function attribute has not been learned by CPI hardware.
* 6 - The receiver function attribute has not been learned by CPI hardware.
*/
-#define MBOX_STATUS_ERRCODE(wb) \
- ((wb) & MBOX_WB_ERROR_CODE_MASK)
+#define MBOX_STATUS_ERRCODE(wb) ((wb)&MBOX_WB_ERROR_CODE_MASK)
-#define DST_AEQ_IDX_DEFAULT_VAL 0
-#define SRC_AEQ_IDX_DEFAULT_VAL 0
-#define NO_DMA_ATTRIBUTE_VAL 0
+#define DST_AEQ_IDX_DEFAULT_VAL 0
+#define SRC_AEQ_IDX_DEFAULT_VAL 0
+#define NO_DMA_ATTRIBUTE_VAL 0
-#define MBOX_MSG_NO_DATA_LEN 1
+#define MBOX_MSG_NO_DATA_LEN 1
-#define MBOX_BODY_FROM_HDR(header) ((u8 *)(header) + MBOX_HEADER_SZ)
-#define MBOX_AREA(hwif) \
+#define MBOX_BODY_FROM_HDR(header) ((u8 *)(header) + MBOX_HEADER_SZ)
+#define MBOX_AREA(hwif) \
((hwif)->cfg_regs_base + HINIC5_FUNC_CSR_MAILBOX_DATA_OFF)
-#define MBOX_DMA_MSG_QUEUE_DEPTH 32
+#define MBOX_DMA_MSG_QUEUE_DEPTH 32
-#define MBOX_MQ_CI_OFFSET (HINIC5_CFG_REGS_FLAG + HINIC5_FUNC_CSR_MAILBOX_DATA_OFF + \
- MBOX_HEADER_SZ + MBOX_SEG_LEN)
-#define MBOX_MQ_CI_SIZE 4
+#define MBOX_MQ_CI_OFFSET \
+ (HINIC5_CFG_REGS_FLAG + HINIC5_FUNC_CSR_MAILBOX_DATA_OFF + \
+ MBOX_HEADER_SZ + MBOX_SEG_LEN)
+#define MBOX_MQ_CI_SIZE 4
-#define MBOX_MQ_SYNC_CI_SHIFT 0
-#define MBOX_MQ_ASYNC_CI_SHIFT 8
+#define MBOX_MQ_SYNC_CI_SHIFT 0
+#define MBOX_MQ_ASYNC_CI_SHIFT 8
-#define MBOX_MQ_SYNC_CI_MASK 0xFF
-#define MBOX_MQ_ASYNC_CI_MASK 0xFF
+#define MBOX_MQ_SYNC_CI_MASK 0xFF
+#define MBOX_MQ_ASYNC_CI_MASK 0xFF
-#define MBOX_MQ_CI_SET(val, field) \
- (((val) & MBOX_MQ_##field##_CI_MASK) << MBOX_MQ_##field##_CI_SHIFT)
-#define MBOX_MQ_CI_GET(val, field) \
- (((val) >> MBOX_MQ_##field##_CI_SHIFT) & MBOX_MQ_##field##_CI_MASK)
-#define MBOX_MQ_CI_CLEAR(val, field) \
- ((val) & (~(MBOX_MQ_##field##_CI_MASK << MBOX_MQ_##field##_CI_SHIFT)))
+#define MBOX_MQ_CI_SET(val, field) \
+ (((val)&MBOX_MQ_##field##_CI_MASK) << MBOX_MQ_##field##_CI_SHIFT)
+#define MBOX_MQ_CI_GET(val, field) \
+ (((val) >> MBOX_MQ_##field##_CI_SHIFT) & MBOX_MQ_##field##_CI_MASK)
+#define MBOX_MQ_CI_CLEAR(val, field) \
+ ((val) & (~(MBOX_MQ_##field##_CI_MASK << MBOX_MQ_##field##_CI_SHIFT)))
-#define MBOX_EXT_CSR_OFFSET (MBOX_MQ_CI_OFFSET + MBOX_MQ_CI_SIZE)
+#define MBOX_EXT_CSR_OFFSET (MBOX_MQ_CI_OFFSET + MBOX_MQ_CI_SIZE)
-#define MBOX_EXT_MGMT_BUSY_SHIFT 0
+#define MBOX_EXT_MGMT_BUSY_SHIFT 0
-#define MBOX_EXT_MGMT_BUSY_MASK 0x1
+#define MBOX_EXT_MGMT_BUSY_MASK 0x1
-#define MBOX_EXT_SET(val, field) \
- (((val) & MBOX_EXT_##field##_MASK) << MBOX_EXT_##field##_SHIFT)
-#define MBOX_EXT_GET(val, field) \
- (((val) >> MBOX_EXT_##field##_SHIFT) & MBOX_EXT_##field##_MASK)
-#define MBOX_EXT_CLEAR(val, field) \
- ((val) & (~(MBOX_EXT_##field##_MASK << MBOX_EXT_##field##_SHIFT)))
+#define MBOX_EXT_SET(val, field) \
+ (((val)&MBOX_EXT_##field##_MASK) << MBOX_EXT_##field##_SHIFT)
+#define MBOX_EXT_GET(val, field) \
+ (((val) >> MBOX_EXT_##field##_SHIFT) & MBOX_EXT_##field##_MASK)
+#define MBOX_EXT_CLEAR(val, field) \
+ ((val) & (~(MBOX_EXT_##field##_MASK << MBOX_EXT_##field##_SHIFT)))
-#define IS_PF_OR_PPF_SRC(hwdev, src_func_idx) \
+#define IS_PF_OR_PPF_SRC(hwdev, src_func_idx) \
((src_func_idx) < HINIC5_MAX_PF_NUM(hwdev))
-#define MBOX_RESPONSE_ERROR 0x1
-#define MBOX_MSG_ID_MASK 0xF
+#define MBOX_RESPONSE_ERROR 0x1
+#define MBOX_MSG_ID_MASK 0xF
static inline u8 inc_mbox_send_msg_id(struct hinic5_mbox *func_to_func)
{
- func_to_func->send_msg_id = (func_to_func->send_msg_id + 1) & MBOX_MSG_ID_MASK;
- /* Consistent with old implementation, numbering starts from 1; otherwise dt is used for blocking,
- * it is speculated that some test cases may have assumed a specific starting msg_id
- */
+ func_to_func->send_msg_id = (func_to_func->send_msg_id + 1) &
+ MBOX_MSG_ID_MASK;
+ /* 与旧实现保持一致,从1开始编号;否则dt用来阻塞,推测可能是部分用例对起始msg_id做了假设 */
return func_to_func->send_msg_id;
}
/* max message counter wait to process for one function */
-#define HINIC5_MAX_MSG_CNT_TO_PROCESS 10
+#define HINIC5_MAX_MSG_CNT_TO_PROCESS 10
-#define MBOX_MSG_CHANNEL_STOP(func_to_func) \
- ((((func_to_func)->lock_channel_en) && \
- test_bit((func_to_func)->cur_msg_channel, \
- &(func_to_func)->channel_stop)) ? true : false)
+#define MBOX_MSG_CHANNEL_STOP(func_to_func) \
+ ((((func_to_func)->lock_channel_en) && \
+ test_bit((func_to_func)->cur_msg_channel, \
+ &(func_to_func)->channel_stop)) ? \
+ true : \
+ false)
enum mbox_ordering_type {
STRONG_ORDER,
@@ -204,8 +197,8 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
enum hinic5_msg_ack_type ack_type,
struct mbox_msg_info *msg_info);
-static struct hinic5_msg_desc *get_mbox_msg_desc(struct hinic5_mbox *func_to_func,
- u64 dir, u64 src_func_id);
+static struct hinic5_msg_desc *
+get_mbox_msg_desc(struct hinic5_mbox *func_to_func, u64 dir, u64 src_func_id);
/**
* hinic5_register_ppf_mbox_cb - register mbox callback for ppf
@@ -340,7 +333,8 @@ void hinic5_unregister_pf_mbox_cb(void *hwdev, u8 mod)
clear_bit(HINIC5_PF_MBOX_CB_REG, &func_to_func->pf_mbox_cb_state[mod]);
- while (test_bit(HINIC5_PF_MBOX_CB_RUNNING, &func_to_func->pf_mbox_cb_state[mod]) != 0)
+ while (test_bit(HINIC5_PF_MBOX_CB_RUNNING,
+ &func_to_func->pf_mbox_cb_state[mod]) != 0)
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
func_to_func->pf_mbox_data[mod] = NULL;
@@ -366,7 +360,8 @@ void hinic5_unregister_vf_mbox_cb(void *hwdev, u8 mod)
clear_bit(HINIC5_VF_MBOX_CB_REG, &func_to_func->vf_mbox_cb_state[mod]);
- while (test_bit(HINIC5_VF_MBOX_CB_RUNNING, &func_to_func->vf_mbox_cb_state[mod]) != 0)
+ while (test_bit(HINIC5_VF_MBOX_CB_RUNNING,
+ &func_to_func->vf_mbox_cb_state[mod]) != 0)
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
func_to_func->vf_mbox_data[mod] = NULL;
@@ -409,7 +404,8 @@ static int recv_vf_mbox_handler(struct hinic5_mbox *func_to_func,
int ret;
if (recv_mbox->mod >= HINIC5_MOD_MAX) {
- sdk_warn(func_to_func->hwdev->dev_hdl, "Receive illegal mbox message, mod = %u\n",
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "Receive illegal mbox message, mod = %hhu\n",
recv_mbox->mod);
return -EINVAL;
}
@@ -421,10 +417,11 @@ static int recv_vf_mbox_handler(struct hinic5_mbox *func_to_func,
if (cb && test_bit(HINIC5_VF_MBOX_CB_REG,
&func_to_func->vf_mbox_cb_state[recv_mbox->mod])) {
ret = cb(func_to_func->vf_mbox_data[recv_mbox->mod],
- recv_mbox->cmd, recv_mbox->msg,
- recv_mbox->msg_len, buf_out, out_size);
+ recv_mbox->cmd, recv_mbox->msg, recv_mbox->msg_len,
+ buf_out, out_size);
} else {
- sdk_warn(func_to_func->hwdev->dev_hdl, "VF mbox cb is not registered\n");
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "VF mbox cb is not registered\n");
ret = -EINVAL;
}
@@ -438,13 +435,13 @@ static int recv_pf_from_ppf_handler(struct hinic5_mbox *func_to_func,
struct hinic5_recv_mbox *recv_mbox,
void *buf_out, u16 *out_size)
{
- hinic5_pf_recv_from_ppf_mbox_cb cb = NULL;
+ hinic5_pf_recv_from_ppf_mbox_cb cb = NULL;
enum hinic5_mod_type mod = recv_mbox->mod;
int ret;
if (mod >= HINIC5_MOD_MAX) {
- sdk_warn(func_to_func->hwdev->dev_hdl, "Receive illegal mbox message, mod = %d\n",
- mod);
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "Receive illegal mbox message, mod = %d\n", mod);
return -EINVAL;
}
@@ -458,7 +455,8 @@ static int recv_pf_from_ppf_handler(struct hinic5_mbox *func_to_func,
recv_mbox->cmd, recv_mbox->msg, recv_mbox->msg_len,
buf_out, out_size);
} else {
- sdk_warn(func_to_func->hwdev->dev_hdl, "PF receive ppf mailbox callback is not registered\n");
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "PF receive ppf mailbox callback is not registered\n");
ret = -EINVAL;
}
@@ -469,15 +467,16 @@ static int recv_pf_from_ppf_handler(struct hinic5_mbox *func_to_func,
}
static int recv_ppf_mbox_handler(struct hinic5_mbox *func_to_func,
- struct hinic5_recv_mbox *recv_mbox,
- u8 pf_id, void *buf_out, u16 *out_size)
+ struct hinic5_recv_mbox *recv_mbox, u8 pf_id,
+ void *buf_out, u16 *out_size)
{
hinic5_ppf_mbox_cb cb = NULL;
u16 vf_id = 0;
int ret;
if (recv_mbox->mod >= HINIC5_MOD_MAX) {
- sdk_warn(func_to_func->hwdev->dev_hdl, "Receive illegal mbox message, mod = %u\n",
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "Receive illegal mbox message, mod = %hhu\n",
recv_mbox->mod);
return -EINVAL;
}
@@ -488,11 +487,12 @@ static int recv_ppf_mbox_handler(struct hinic5_mbox *func_to_func,
cb = func_to_func->ppf_mbox_cb[recv_mbox->mod];
if (cb && test_bit(HINIC5_PPF_MBOX_CB_REG,
&func_to_func->ppf_mbox_cb_state[recv_mbox->mod])) {
- ret = cb(func_to_func->ppf_mbox_data[recv_mbox->mod],
- pf_id, vf_id, recv_mbox->cmd, recv_mbox->msg,
+ ret = cb(func_to_func->ppf_mbox_data[recv_mbox->mod], pf_id,
+ vf_id, recv_mbox->cmd, recv_mbox->msg,
recv_mbox->msg_len, buf_out, out_size);
} else {
- sdk_warn(func_to_func->hwdev->dev_hdl, "PPF mbox cb is not registered, mod = %u\n",
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "PPF mbox cb is not registered, mod = %hhu\n",
recv_mbox->mod);
ret = -EINVAL;
}
@@ -513,7 +513,8 @@ static int recv_pf_from_vf_mbox_handler(struct hinic5_mbox *func_to_func,
int ret;
if (recv_mbox->mod >= HINIC5_MOD_MAX) {
- sdk_warn(func_to_func->hwdev->dev_hdl, "Receive illegal mbox message, mod = %u\n",
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "Receive illegal mbox message, mod = %hhu\n",
recv_mbox->mod);
return -EINVAL;
}
@@ -522,15 +523,17 @@ static int recv_pf_from_vf_mbox_handler(struct hinic5_mbox *func_to_func,
&func_to_func->pf_mbox_cb_state[recv_mbox->mod]);
cb = func_to_func->pf_mbox_cb[recv_mbox->mod];
- if (cb && test_bit(HINIC5_PF_MBOX_CB_REG,
- &func_to_func->pf_mbox_cb_state[recv_mbox->mod]) != 0) {
+ if (cb &&
+ test_bit(HINIC5_PF_MBOX_CB_REG,
+ &func_to_func->pf_mbox_cb_state[recv_mbox->mod]) != 0) {
vf_id = src_func_idx -
hinic5_glb_pf_vf_offset(func_to_func->hwdev);
- ret = cb(func_to_func->pf_mbox_data[recv_mbox->mod],
- vf_id, recv_mbox->cmd, recv_mbox->msg,
- recv_mbox->msg_len, buf_out, out_size);
+ ret = cb(func_to_func->pf_mbox_data[recv_mbox->mod], vf_id,
+ recv_mbox->cmd, recv_mbox->msg, recv_mbox->msg_len,
+ buf_out, out_size);
} else {
- sdk_warn(func_to_func->hwdev->dev_hdl, "PF mbox mod(0x%x) cb is not registered\n",
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "PF mbox mod(0x%x) cb is not registered\n",
recv_mbox->mod);
ret = -EINVAL;
}
@@ -545,7 +548,7 @@ static void response_for_recv_func_mbox(struct hinic5_mbox *func_to_func,
struct hinic5_recv_mbox *recv_mbox,
int err, u16 out_size, u16 src_func_idx)
{
- struct mbox_msg_info msg_info = {0};
+ struct mbox_msg_info msg_info = { 0 };
u16 size = out_size;
msg_info.msg_id = recv_mbox->msg_id;
@@ -554,12 +557,13 @@ static void response_for_recv_func_mbox(struct hinic5_mbox *func_to_func,
msg_info.status = HINIC5_MBOX_PF_SEND_ERR;
/* if not data need to response, set out_size to 1 */
- if (out_size == 0 || err != 0)
+ if ((out_size == 0) || (err != 0))
size = MBOX_MSG_NO_DATA_LEN;
if (size > HINIC5_MBOX_DATA_SIZE) {
- sdk_err(func_to_func->hwdev->dev_hdl, "Response msg len(%u) exceed limit(%u)\n",
- size, HINIC5_MBOX_DATA_SIZE);
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Response msg len(%hu) exceed limit(%u)\n", size,
+ HINIC5_MBOX_DATA_SIZE);
size = HINIC5_MBOX_DATA_SIZE;
}
@@ -578,28 +582,33 @@ static void recv_func_mbox_handler(struct hinic5_mbox *func_to_func,
int err = 0;
if (HINIC5_IS_VF(dev)) {
- err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out, &out_size);
+ err = recv_vf_mbox_handler(func_to_func, recv_mbox, buf_out,
+ &out_size);
goto out;
}
/* pf/ppf process */
if (IS_PF_OR_PPF_SRC(dev, src_func_idx)) {
if (HINIC5_IS_PPF(dev)) {
err = recv_ppf_mbox_handler(func_to_func, recv_mbox,
- (u8)src_func_idx, buf_out, &out_size);
- goto out;
+ (u8)src_func_idx, buf_out,
+ &out_size);
+ goto out;
} else {
- err = recv_pf_from_ppf_handler(func_to_func, recv_mbox, buf_out, &out_size);
- goto out;
+ err = recv_pf_from_ppf_handler(func_to_func, recv_mbox,
+ buf_out, &out_size);
+ goto out;
}
- /* The source is neither PF nor PPF, so it is from VF */
+ /* The source is neither PF nor PPF, so it is from VF */
} else {
err = recv_pf_from_vf_mbox_handler(func_to_func, recv_mbox,
- src_func_idx, buf_out, &out_size);
+ src_func_idx, buf_out,
+ &out_size);
}
out:
if (recv_mbox->ack_type == HINIC5_MSG_ACK)
- response_for_recv_func_mbox(func_to_func, recv_mbox, err, out_size, src_func_idx);
+ response_for_recv_func_mbox(func_to_func, recv_mbox, err,
+ out_size, src_func_idx);
}
static struct hinic5_recv_mbox *alloc_recv_mbox(void)
@@ -639,7 +648,7 @@ static void free_recv_mbox(struct hinic5_recv_mbox *recv_msg)
static void recv_func_mbox_work_handler(struct work_struct *work)
{
struct hinic5_mbox_work *mbox_work =
- container_of(work, struct hinic5_mbox_work, work);
+ container_of(work, struct hinic5_mbox_work, work);
recv_func_mbox_handler(mbox_work->func_to_func, mbox_work->recv_mbox);
@@ -683,18 +692,26 @@ static void recv_mbox_msg_handler(struct hinic5_mbox *func_to_func,
if (atomic_read(&msg_ch->recv_msg_cnt) >
HINIC5_MAX_MSG_CNT_TO_PROCESS) {
- sdk_warn(hwdev->dev_hdl, "This function(%u) have %d message wait to process, can't add to work queue\n",
- src_func_idx, atomic_read(&msg_ch->recv_msg_cnt));
+ sdk_warn(
+ hwdev->dev_hdl,
+ "This function(%u) have %d message wait to process, can't add to work queue\n",
+ src_func_idx, atomic_read(&msg_ch->recv_msg_cnt));
return;
}
recv_msg = alloc_recv_mbox();
if (!recv_msg) {
- sdk_err(hwdev->dev_hdl, "Failed to alloc receive mbox message buffer\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to alloc receive mbox message buffer\n");
return;
}
recv_msg->msg_len = msg_desc->msg_len;
- memcpy(recv_msg->msg, msg_desc->msg, recv_msg->msg_len);
+ if (memcpy_s(recv_msg->msg, MBOX_MAX_BUF_SZ, msg_desc->msg,
+ recv_msg->msg_len) != 0) {
+ sdk_err(hwdev->dev_hdl, "Copy mbox work memory failed.\n");
+ free_recv_mbox(recv_msg);
+ return;
+ }
version = hinic5_mbox_get_version(hwdev, &mbox_header);
recv_msg->msg_id = msg_desc->msg_info.msg_id;
recv_msg->mod = hinic5_mbox_get_mod_id(version, &mbox_header);
@@ -704,6 +721,7 @@ static void recv_mbox_msg_handler(struct hinic5_mbox *func_to_func,
mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL);
if (!mbox_work) {
+ sdk_err(hwdev->dev_hdl, "Allocate mbox work memory failed.\n");
free_recv_mbox(recv_msg);
return;
}
@@ -744,7 +762,8 @@ static bool check_mbox_segment(struct hinic5_mbox *func_to_func,
msg_desc->mod = mod;
msg_desc->cmd = cmd;
} else {
- if (seq_id != msg_desc->seq_id + 1 || msg_id != msg_desc->msg_info.msg_id ||
+ if (seq_id != msg_desc->seq_id + 1 ||
+ msg_id != msg_desc->msg_info.msg_id ||
mod != msg_desc->mod || cmd != msg_desc->cmd)
goto seg_err;
@@ -755,7 +774,8 @@ static bool check_mbox_segment(struct hinic5_mbox *func_to_func,
seg_err:
sdk_err(func_to_func->hwdev->dev_hdl,
- "Mailbox segment check failed, src func id: 0x%x, front seg info: seq id: 0x%x, msg id: 0x%x, mod: 0x%x, cmd: 0x%x\n",
+ "Mailbox segment check failed, src func id: 0x%x, "
+ "front seg info: seq id: 0x%x, msg id: 0x%x, mod: 0x%x, cmd: 0x%x\n",
src_func_idx, msg_desc->seq_id, msg_desc->msg_info.msg_id,
msg_desc->mod, msg_desc->cmd);
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -765,15 +785,16 @@ static bool check_mbox_segment(struct hinic5_mbox *func_to_func,
return false;
}
-static void recv_mbox_handler(struct hinic5_mbox *func_to_func,
- u64 *header, struct hinic5_msg_desc *msg_desc)
+static void recv_mbox_handler(struct hinic5_mbox *func_to_func, u64 *header,
+ struct hinic5_msg_desc *msg_desc)
{
u64 mbox_header = *header;
void *mbox_body = MBOX_BODY_FROM_HDR(((void *)header));
u8 seq_id, seg_len, version;
int pos;
- if (!check_mbox_segment(func_to_func, msg_desc, mbox_header, mbox_body)) {
+ if (!check_mbox_segment(func_to_func, msg_desc, mbox_header,
+ mbox_body)) {
msg_desc->seq_id = SEQ_ID_MAX_VAL;
return;
}
@@ -782,7 +803,12 @@ static void recv_mbox_handler(struct hinic5_mbox *func_to_func,
seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
seg_len = hinic5_mbox_get_seg_len(version, &mbox_header);
pos = seq_id * MBOX_SEG_LEN;
- memcpy((u8 *)msg_desc->msg + pos, mbox_body, seg_len);
+ if (memcpy_s((u8 *)msg_desc->msg + pos, (MBOX_MAX_BUF_SZ - pos),
+ mbox_body, seg_len) != 0) {
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Memcpy mbox body failed, %u.\n", seg_len);
+ return;
+ }
if (HINIC5_MSG_HEADER_GET(mbox_header, LAST) == 0)
return;
@@ -825,7 +851,8 @@ void hinic5_mbox_func_aeqe_handler(void *handle, u8 *header, u8 size)
recv_mbox_handler(func_to_func, (u64 *)header, msg_desc);
}
-static int init_mbox_dma_queue(struct hinic5_hwdev *hwdev, struct mbox_dma_queue *mq)
+static int init_mbox_dma_queue(struct hinic5_hwdev *hwdev,
+ struct mbox_dma_queue *mq)
{
u32 size;
@@ -834,8 +861,8 @@ static int init_mbox_dma_queue(struct hinic5_hwdev *hwdev, struct mbox_dma_queue
mq->cons_idx = 0;
size = mq->depth * MBOX_MAX_BUF_SZ;
- mq->dma_buff_vaddr = dma_zalloc_coherent(hwdev->dev_hdl, size, &mq->dma_buff_paddr,
- GFP_KERNEL);
+ mq->dma_buff_vaddr = dma_zalloc_coherent(
+ hwdev->dev_hdl, size, &mq->dma_buff_paddr, GFP_KERNEL);
if (!mq->dma_buff_vaddr) {
sdk_err(hwdev->dev_hdl, "Failed to alloc dma_buffer\n");
return -ENOMEM;
@@ -844,7 +871,8 @@ static int init_mbox_dma_queue(struct hinic5_hwdev *hwdev, struct mbox_dma_queue
return 0;
}
-static void deinit_mbox_dma_queue(struct hinic5_hwdev *hwdev, struct mbox_dma_queue *mq)
+static void deinit_mbox_dma_queue(struct hinic5_hwdev *hwdev,
+ struct mbox_dma_queue *mq)
{
dma_free_coherent(hwdev->dev_hdl, mq->depth * MBOX_MAX_BUF_SZ,
mq->dma_buff_vaddr, mq->dma_buff_paddr);
@@ -855,32 +883,39 @@ static int hinic5_init_mbox_dma_queue(struct hinic5_mbox *func_to_func)
u32 val;
int err;
- err = init_mbox_dma_queue(func_to_func->hwdev, &func_to_func->sync_msg_queue);
+ err = init_mbox_dma_queue(func_to_func->hwdev,
+ &func_to_func->sync_msg_queue);
if (err != 0)
return err;
- err = init_mbox_dma_queue(func_to_func->hwdev, &func_to_func->async_msg_queue);
+ err = init_mbox_dma_queue(func_to_func->hwdev,
+ &func_to_func->async_msg_queue);
if (err != 0) {
- deinit_mbox_dma_queue(func_to_func->hwdev, &func_to_func->sync_msg_queue);
+ deinit_mbox_dma_queue(func_to_func->hwdev,
+ &func_to_func->sync_msg_queue);
return err;
}
- val = hinic5_hwif_read_reg(func_to_func->hwdev->hwif, MBOX_MQ_CI_OFFSET);
+ val = hinic5_hwif_read_reg(func_to_func->hwdev->hwif,
+ MBOX_MQ_CI_OFFSET);
val = MBOX_MQ_CI_CLEAR(val, SYNC);
val = MBOX_MQ_CI_CLEAR(val, ASYNC);
- hinic5_hwif_write_reg(func_to_func->hwdev->hwif, MBOX_MQ_CI_OFFSET, val);
+ hinic5_hwif_write_reg(func_to_func->hwdev->hwif, MBOX_MQ_CI_OFFSET,
+ val);
return 0;
}
static void hinic5_deinit_mbox_dma_queue(struct hinic5_mbox *func_to_func)
{
- deinit_mbox_dma_queue(func_to_func->hwdev, &func_to_func->sync_msg_queue);
- deinit_mbox_dma_queue(func_to_func->hwdev, &func_to_func->async_msg_queue);
+ deinit_mbox_dma_queue(func_to_func->hwdev,
+ &func_to_func->sync_msg_queue);
+ deinit_mbox_dma_queue(func_to_func->hwdev,
+ &func_to_func->async_msg_queue);
}
-#define MBOX_DMA_MSG_INIT_XOR_VAL 0x5a5a5a5a
-#define MBOX_XOR_DATA_ALIGN 4
+#define MBOX_DMA_MSG_INIT_XOR_VAL 0x5a5a5a5a
+#define MBOX_XOR_DATA_ALIGN 4
static u32 mbox_dma_msg_xor(u32 *data, u16 msg_len)
{
u32 xor = MBOX_DMA_MSG_INIT_XOR_VAL;
@@ -893,19 +928,22 @@ static u32 mbox_dma_msg_xor(u32 *data, u16 msg_len)
return xor;
}
-#define MQ_ID_MASK(mq, idx) ((idx) & ((mq)->depth - 1))
-#define IS_MSG_QUEUE_FULL(mq) (MQ_ID_MASK(mq, (mq)->prod_idx + 1) == \
- MQ_ID_MASK(mq, (mq)->cons_idx))
+#define MQ_ID_MASK(mq, idx) ((idx) & ((mq)->depth - 1))
+#define IS_MSG_QUEUE_FULL(mq) \
+ (MQ_ID_MASK(mq, (mq)->prod_idx + 1) == MQ_ID_MASK(mq, (mq)->cons_idx))
-static int mbox_prepare_dma_entry(const struct hinic5_mbox *func_to_func, struct mbox_dma_queue *mq,
- struct mbox_dma_msg *dma_msg, const void *msg, u16 msg_len)
+static int mbox_prepare_dma_entry(const struct hinic5_mbox *func_to_func,
+ struct mbox_dma_queue *mq,
+ struct mbox_dma_msg *dma_msg, const void *msg,
+ u16 msg_len)
{
u64 dma_addr, offset;
void *dma_vaddr = NULL;
+ int ret;
if (IS_MSG_QUEUE_FULL(mq)) {
sdk_err(func_to_func->hwdev->dev_hdl,
- "Mbox sync message queue is busy, pi: %u, ci: %d\n",
+ "Mbox sync message queue is busy, pi: %hu, ci: %d\n",
mq->prod_idx, MQ_ID_MASK(mq, mq->cons_idx));
return -EBUSY;
}
@@ -913,14 +951,20 @@ static int mbox_prepare_dma_entry(const struct hinic5_mbox *func_to_func, struct
/* copy data to DMA buffer */
offset = mq->prod_idx * MBOX_MAX_BUF_SZ;
dma_vaddr = (u8 *)mq->dma_buff_vaddr + offset;
- memcpy(dma_vaddr, msg, msg_len);
+ ret = memcpy_s(dma_vaddr, MBOX_MAX_BUF_SZ, msg, msg_len);
+ if (ret != 0) {
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Memcpy msg failed: %u.\n", msg_len);
+ return -ENOMEM;
+ }
dma_addr = mq->dma_buff_paddr + offset;
dma_msg->dma_addr_high = upper_32_bits(dma_addr);
dma_msg->dma_addr_low = lower_32_bits(dma_addr);
dma_msg->msg_len = msg_len;
/* The firmware obtains message based on 4B alignment. */
- dma_msg->xor = mbox_dma_msg_xor(dma_vaddr, ALIGN(msg_len, MBOX_XOR_DATA_ALIGN));
+ dma_msg->xor = mbox_dma_msg_xor(dma_vaddr,
+ ALIGN(msg_len, MBOX_XOR_DATA_ALIGN));
mq->prod_idx++;
mq->prod_idx = MQ_ID_MASK(mq, mq->prod_idx);
@@ -928,13 +972,16 @@ static int mbox_prepare_dma_entry(const struct hinic5_mbox *func_to_func, struct
return 0;
}
-static int mbox_prepare_dma_msg(struct hinic5_mbox *func_to_func, enum hinic5_msg_ack_type ack_type,
- struct mbox_dma_msg *dma_msg, void *msg, u16 msg_len)
+static int mbox_prepare_dma_msg(struct hinic5_mbox *func_to_func,
+ enum hinic5_msg_ack_type ack_type,
+ struct mbox_dma_msg *dma_msg, void *msg,
+ u16 msg_len)
{
struct mbox_dma_queue *mq = NULL;
u32 val;
- val = hinic5_hwif_read_reg(func_to_func->hwdev->hwif, MBOX_MQ_CI_OFFSET);
+ val = hinic5_hwif_read_reg(func_to_func->hwdev->hwif,
+ MBOX_MQ_CI_OFFSET);
if (ack_type == HINIC5_MSG_ACK) {
mq = &func_to_func->sync_msg_queue;
mq->cons_idx = MBOX_MQ_CI_GET(val, SYNC);
@@ -949,22 +996,22 @@ static int mbox_prepare_dma_msg(struct hinic5_mbox *func_to_func, enum hinic5_ms
#ifdef __UEFI__
static void write_mbox_reg(struct hinic5_hwif *hwif, u32 offset, u32 val)
{
- BUS_IO_PROTOCOL *bus_io = hwif->bus_dev;
+ BUS_IO_PROTOCOL *BusIo = hwif->bus_dev;
EFI_STATUS Status;
u32 mbox_reg = HINIC5_FUNC_CSR_MAILBOX_DATA_OFF + offset;
- if (!bus_io) {
- DebugPrint(DEBUG_ERROR, "Write_reg() bus_io == NULL\n");
+ if (!BusIo) {
+ DebugPrint(DEBUG_ERROR, "Write_reg() BusIo == NULL\n");
return;
}
MemoryFence();
- Status = bus_io->Mem.Write(bus_io, EfiBusIoWidthUint32, HINIC5_CFG_BAR,
+ Status = BusIo->Mem.Write(BusIo, EfiBusIoWidthUint32, HINIC5_CFG_BAR,
mbox_reg, 1, (void *)(&val));
MemoryFence();
if (EFI_ERROR(Status))
- DebugPrint(DEBUG_ERROR,
- "bus_io->Mem.Write() fails: %r\n", Status);
+ DebugPrint(DEBUG_ERROR, "BusIo->Mem.Write() fails: %r\n",
+ Status);
}
#endif
@@ -992,11 +1039,14 @@ static int mbox_copy_send_data(struct hinic5_hwdev *hwdev,
u32 *data = seg;
u32 data_len, chk_sz = sizeof(u32);
u32 i, idx_max;
- u8 mbox_max_buf[MBOX_SEG_LEN] = {0};
+ u8 mbox_max_buf[MBOX_SEG_LEN] = { 0 };
/* The mbox message should be aligned in 4 bytes. */
if ((seg_len % chk_sz) != 0) {
- memcpy(mbox_max_buf, seg, seg_len);
+ if (memcpy_s(mbox_max_buf, MBOX_SEG_LEN, seg, seg_len) != 0) {
+ sdk_err(hwdev->dev_hdl, "Copy mbox buf failed.\n");
+ return -ENOMEM;
+ }
data = (u32 *)mbox_max_buf;
}
@@ -1016,8 +1066,8 @@ static int mbox_copy_send_data(struct hinic5_hwdev *hwdev,
return 0;
}
-static void write_mbox_msg_attr(struct hinic5_mbox *func_to_func,
- u16 dst_func, u16 dst_aeqn, u16 seg_len)
+static void write_mbox_msg_attr(struct hinic5_mbox *func_to_func, u16 dst_func,
+ u16 dst_aeqn, u16 seg_len)
{
u32 mbox_int, mbox_ctrl;
u16 func = dst_func;
@@ -1030,14 +1080,15 @@ static void write_mbox_msg_attr(struct hinic5_mbox *func_to_func,
HINIC5_MBOX_INT_SET(0, SRC_RESP_AEQN) |
HINIC5_MBOX_INT_SET(NO_DMA_ATTRIBUTE_VAL, STAT_DMA) |
HINIC5_MBOX_INT_SET(ALIGN((u32)seg_len + MBOX_HEADER_SZ,
- MBOX_SEG_LEN_ALIGN) >> 2,
- TX_SIZE) |
+ MBOX_SEG_LEN_ALIGN) >>
+ 2,
+ TX_SIZE) |
HINIC5_MBOX_INT_SET(STRONG_ORDER, STAT_DMA_SO_RO) |
HINIC5_MBOX_INT_SET(WRITE_BACK, WB_EN);
hinic5_hwif_write_reg(func_to_func->hwdev->hwif,
HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF, mbox_int);
- wmb(); // Ensure all previous writes are completed before signaling the hardware
+ wmb();
mbox_ctrl = HINIC5_MBOX_CTRL_SET(TX_NOT_DONE, TX_STATUS) |
HINIC5_MBOX_CTRL_SET(NOT_TRIGGER, TRIGGER_AEQE) |
@@ -1071,16 +1122,18 @@ static enum hinic5_wait_return check_mbox_wb_status(void *priv_data)
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
u16 wb_status;
- if (MBOX_MSG_CHANNEL_STOP(func_to_func) || !hinic5_is_chip_present(hwdev))
+ if (MBOX_MSG_CHANNEL_STOP(func_to_func) ||
+ !hinic5_is_chip_present(hwdev))
return WAIT_PROCESS_ERR;
- if (check_outbound_enable_handler(hwdev) != WAIT_PROCESS_CPL)
+ if (check_outbound_enable_handler(hwdev) != WAIT_PROCESS_CPL) {
return WAIT_PROCESS_ERR;
+ }
wb_status = get_mbox_status(&func_to_func->send_mbox);
- return MBOX_STATUS_FINISHED(wb_status) ?
- WAIT_PROCESS_CPL : WAIT_PROCESS_WAITING;
+ return MBOX_STATUS_FINISHED(wb_status) ? WAIT_PROCESS_CPL :
+ WAIT_PROCESS_WAITING;
}
static int wait_mbox_completed(struct hinic5_mbox *func_to_func)
@@ -1100,7 +1153,8 @@ static int wait_mbox_completed(struct hinic5_mbox *func_to_func)
if (likely(err == 0))
return 0;
- mbox_ctrl = hinic5_hwif_read_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF);
+ mbox_ctrl =
+ hinic5_hwif_read_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF);
if (mbox_ctrl == HINIC5_BUS_LINK_DOWN) {
sdk_err(dev, "Send mailbox segment fail, link down.\n");
return -EIO;
@@ -1112,32 +1166,41 @@ static int wait_mbox_completed(struct hinic5_mbox *func_to_func)
*/
tx_done = HINIC5_MBOX_CTRL_GET(mbox_ctrl, TX_STATUS) == TX_DONE;
if (!tx_done)
- hinic5_hwif_write_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF, 0);
+ hinic5_hwif_write_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF,
+ 0);
/* Mailbox completed before request cancellation. */
wb_status = get_mbox_status(send_mbox);
if (unlikely(MBOX_STATUS_FINISHED(wb_status))) {
- sdk_warn(dev, "Mailbox segment send completed at the last monent.\n");
+ sdk_warn(
+ dev,
+ "Mailbox segment send completed at the last monent.\n");
return 0;
}
/* Mbox send timeout */
- mbox_int_off = hinic5_hwif_read_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);
- mbox_wb_h = hinic5_hwif_read_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF);
- mbox_wb_l = hinic5_hwif_read_reg(hwif, HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF);
- func_attr5 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR5_ADDR);
-
- sdk_err(dev, "Send mailbox segment timeout, wb status 0x%x, tx done %d.\n",
+ mbox_int_off = hinic5_hwif_read_reg(
+ hwif, HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF);
+ mbox_wb_h = hinic5_hwif_read_reg(hwif,
+ HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF);
+ mbox_wb_l = hinic5_hwif_read_reg(hwif,
+ HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF);
+ func_attr5 = hinic5_hwif_read_reg(hwif, HINIC5_CSR_FUNC_ATTR5_ADDR);
+
+ sdk_err(dev,
+ "Send mailbox segment timeout, wb status 0x%x, tx done %d.\n",
wb_status, tx_done);
sdk_err(dev, "Mailbox control reg 0x%x\n", mbox_ctrl);
sdk_err(dev, "Mailbox interrupt offset 0x%x\n", mbox_int_off);
- sdk_err(dev, "Mailbox result back 0x%x-0x%x (0x%lx)\n",
- mbox_wb_h, mbox_wb_l, (uintptr_t)send_mbox->wb_paddr);
- sdk_err(dev, "Function attr5 0x%x\n", func_attr5); /* for func/port outbound flush */
+ sdk_err(dev, "Mailbox result back 0x%x-0x%x (0x%lx)\n", mbox_wb_h,
+ mbox_wb_l, (uintptr_t)send_mbox->wb_paddr);
+ sdk_err(dev, "Function attr5 0x%x\n",
+ func_attr5); /* for func/port outbound flush */
/* CPI dma write fail */
if (tx_done)
- sdk_err(dev, "Mailbox segment send completed but no result back\n");
+ sdk_err(dev,
+ "Mailbox segment send completed but no result back\n");
/* Write back address changed unexpectedly; may be caused by FLR. */
if (mbox_wb_h != upper_32_bits(send_mbox->wb_paddr) ||
@@ -1160,7 +1223,8 @@ static int send_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
/* mbox to mgmt cpu, hardware don't care dst aeq id */
if (num_aeqs > HINIC5_MBOX_RSP_MSG_AEQ)
dst_aeqn = (seq_dir == HINIC5_MSG_DIRECT_SEND) ?
- HINIC5_ASYNC_MSG_AEQ : HINIC5_MBOX_RSP_MSG_AEQ;
+ HINIC5_ASYNC_MSG_AEQ :
+ HINIC5_MBOX_RSP_MSG_AEQ;
else
dst_aeqn = 0;
@@ -1173,7 +1237,7 @@ static int send_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
return err;
write_mbox_msg_attr(func_to_func, dst_func, dst_aeqn, seg_len);
- wmb(); // Ensure all previous writes are completed before signaling the hardware
+ wmb();
err = wait_mbox_completed(func_to_func);
if (err != 0)
@@ -1181,7 +1245,8 @@ static int send_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
wb_status = get_mbox_status(send_mbox);
if (!MBOX_STATUS_SUCCESS(wb_status)) {
- sdk_err(hwdev->dev_hdl, "Send mailbox segment to function %u unsuccess, wb status: 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "Send mailbox segment to function %u unsuccess, wb status: 0x%x\n",
dst_func, wb_status);
errcode = MBOX_STATUS_ERRCODE(wb_status);
return (errcode != 0) ? errcode : -EFAULT;
@@ -1190,15 +1255,16 @@ static int send_mbox_seg(struct hinic5_mbox *func_to_func, u64 header,
return 0;
}
-static void mbox_msg_header_set_pre(u64 *header, const struct mbox_msg_info *msg_info,
+static void mbox_msg_header_set_pre(u64 *header,
+ const struct mbox_msg_info *msg_info,
enum hinic5_msg_ack_type ack_type,
struct hinic5_hwdev *hwdev)
{
- *header |=
- HINIC5_MSG_HEADER_SET(msg_info->msg_id, MSG_ID) |
- HINIC5_MSG_HEADER_SET((msg_info->status != 0), STATUS) |
- HINIC5_MSG_HEADER_SET(hinic5_global_func_id(hwdev), SRC_GLB_FUNC_IDX) |
- HINIC5_MSG_HEADER_SET(ack_type, NO_ACK);
+ *header |= HINIC5_MSG_HEADER_SET(msg_info->msg_id, MSG_ID) |
+ HINIC5_MSG_HEADER_SET(msg_info->status != 0, STATUS) |
+ HINIC5_MSG_HEADER_SET(hinic5_global_func_id(hwdev),
+ SRC_GLB_FUNC_IDX) |
+ HINIC5_MSG_HEADER_SET(ack_type, NO_ACK);
}
static void mbox_msg_header_set_mid(u64 *header, u16 rsp_aeq_id, u16 cmd,
@@ -1214,8 +1280,8 @@ static void mbox_msg_header_set_mid(u64 *header, u16 rsp_aeq_id, u16 cmd,
HINIC5_MSG_HEADER_SET(HINIC5_MSG_FROM_MBOX, SOURCE);
}
-void mbox_msg_header_set_last(u64 *header, u16 msg_len, u8 mod,
- u16 seg_len, struct hinic5_hwdev *hwdev)
+void mbox_msg_header_set_last(u64 *header, u16 msg_len, u8 mod, u16 seg_len,
+ struct hinic5_hwdev *hwdev)
{
u8 version = hinic5_mbox_get_send_version(hwdev, mod);
*header |= hinic5_mbox_set_msg_len(version, msg_len) |
@@ -1227,7 +1293,8 @@ void mbox_msg_header_set_last(u64 *header, u16 msg_len, u8 mod,
static inline u16 mbox_msg_rsp_aeq(const struct hinic5_hwdev *hwdev)
{
return (hwdev->poll || hwdev->hwif->attr.num_aeqs >= 0x2) ?
- HINIC5_MBOX_RSP_MSG_AEQ : HINIC5_ASYNC_MSG_AEQ;
+ HINIC5_MBOX_RSP_MSG_AEQ :
+ HINIC5_ASYNC_MSG_AEQ;
}
static inline void dump_mbox_header(struct hinic5_hwdev *hwdev, u64 header)
@@ -1250,7 +1317,7 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
struct mbox_msg_info *msg_info)
{
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
- struct mbox_dma_msg dma_msg = {0};
+ struct mbox_dma_msg dma_msg = { 0 };
enum hinic5_data_type data_type = HINIC5_DATA_INLINE;
bool using_dma_msg = support_dma_msg(hwdev, dst_func);
int err = 0;
@@ -1262,10 +1329,12 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
u16 msg_len_tmp = msg_len;
u8 version = hinic5_mbox_get_send_version(hwdev, mod);
- if (!COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) && mod >= V0_MOD_ID_MAX)
+ if (!COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) && mod >= V0_MOD_ID_MAX) {
return -EINVAL;
+ }
- if (unlikely(dst_func == HINIC5_MGMT_SRC_ID && hinic5_is_chip_error(hwdev))) {
+ if (unlikely(dst_func == HINIC5_MGMT_SRC_ID &&
+ hinic5_is_chip_error(hwdev))) {
/* Stop VF sending mailbox to the Mgmt when chip is error */
if (HINIC5_IS_VF(hwdev)) {
sdk_err(hwdev->dev_hdl,
@@ -1283,7 +1352,8 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
mutex_lock(&func_to_func->msg_send_lock);
if (using_dma_msg) {
- err = mbox_prepare_dma_msg(func_to_func, ack_type, &dma_msg, msg, msg_len_tmp);
+ err = mbox_prepare_dma_msg(func_to_func, ack_type, &dma_msg,
+ msg, msg_len_tmp);
if (err != 0)
goto send_err;
@@ -1303,15 +1373,17 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
if (left <= MBOX_SEG_LEN) {
header &= ~(hinic5_mbox_get_seg_len_mask(version));
header |= (hinic5_mbox_set_seg_len(version, left) |
- HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST));
+ HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST));
seg_len = left;
}
msg_info->header = header;
- err = send_mbox_seg(func_to_func, header, dst_func, msg_seg, seg_len, msg_info);
+ err = send_mbox_seg(func_to_func, header, dst_func, msg_seg,
+ seg_len, msg_info);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Send mbox seg unsuccess, seq_id=0x%llx\n",
+ sdk_err(hwdev->dev_hdl,
+ "Send mbox seg unsuccess, seq_id=0x%llx\n",
HINIC5_MSG_HEADER_GET(header, SEQID));
dump_mbox_header(hwdev, header);
goto send_err;
@@ -1323,7 +1395,8 @@ static int send_mbox_msg(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
msg_seg += MBOX_SEG_LEN;
seq_id++;
- header &= ~(HINIC5_MSG_HEADER_SET(HINIC5_MSG_HEADER_SEQID_MASK, SEQID));
+ header &= ~(HINIC5_MSG_HEADER_SET(HINIC5_MSG_HEADER_SEQID_MASK,
+ SEQID));
header |= HINIC5_MSG_HEADER_SET(seq_id, SEQID);
}
@@ -1348,7 +1421,6 @@ static void set_mbox_to_func_event(struct hinic5_mbox *func_to_func,
static inline bool is_mgmt_busy(struct hinic5_hwif *hwif)
{
u32 val = hinic5_hwif_read_reg(hwif, MBOX_EXT_CSR_OFFSET);
-
return MBOX_EXT_GET(val, MGMT_BUSY) != 0;
}
@@ -1361,7 +1433,7 @@ static enum hinic5_wait_return check_mgmt_busy(void *priv_data)
return WAIT_PROCESS_ERR;
if (unlikely(check_outbound_enable_handler(hwdev) !=
- WAIT_PROCESS_CPL)) {
+ WAIT_PROCESS_CPL)) {
return WAIT_PROCESS_ERR;
}
@@ -1371,9 +1443,11 @@ static enum hinic5_wait_return check_mgmt_busy(void *priv_data)
return WAIT_PROCESS_CPL;
}
-static inline int wait_mgmt_unbusy(struct hinic5_mbox *func_to_func, u32 timeout)
+static inline int wait_mgmt_unbusy(struct hinic5_mbox *func_to_func,
+ u32 timeout)
{
- return hinic5_wait_for_timeout(func_to_func, check_mgmt_busy, timeout, WAIT_USEC_50);
+ return hinic5_wait_for_timeout(func_to_func, check_mgmt_busy, timeout,
+ WAIT_USEC_50);
}
static enum hinic5_wait_return check_mbox_msg_finish(void *priv_data)
@@ -1381,11 +1455,13 @@ static enum hinic5_wait_return check_mbox_msg_finish(void *priv_data)
struct hinic5_mbox *func_to_func = priv_data;
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
- if (MBOX_MSG_CHANNEL_STOP(func_to_func) || !hinic5_is_chip_present(hwdev))
+ if (MBOX_MSG_CHANNEL_STOP(func_to_func) ||
+ !hinic5_is_chip_present(hwdev))
return WAIT_PROCESS_ERR;
- if (check_outbound_enable_handler(hwdev) != WAIT_PROCESS_CPL)
+ if (check_outbound_enable_handler(hwdev) != WAIT_PROCESS_CPL) {
return WAIT_PROCESS_ERR;
+ }
if (hwdev->poll) {
#if defined(__UEFI__) || defined(__VMWARE__)
@@ -1394,7 +1470,8 @@ static enum hinic5_wait_return check_mbox_msg_finish(void *priv_data)
}
return (func_to_func->event_flag == EVENT_SUCCESS) ?
- WAIT_PROCESS_CPL : WAIT_PROCESS_WAITING;
+ WAIT_PROCESS_CPL :
+ WAIT_PROCESS_WAITING;
}
static int wait_mbox_msg_completion(struct hinic5_mbox *func_to_func,
@@ -1404,23 +1481,30 @@ static int wait_mbox_msg_completion(struct hinic5_mbox *func_to_func,
u16 rsp_aeq_id;
int err;
- wait_time = (timeout != 0) ? timeout : func_to_func->hwdev->timeout_info->mbox_timeout;
+ wait_time = (timeout != 0) ?
+ timeout :
+ func_to_func->hwdev->timeout_info->mbox_timeout;
err = hinic5_wait_for_timeout(func_to_func, check_mbox_msg_finish,
wait_time, WAIT_USEC_50);
if (err == 0)
goto success;
if (!func_to_func->hwdev->poll) {
- sdk_warn(func_to_func->hwdev->dev_hdl, "Retry mbox msg, timeout: %u, expect_timeout: %u\n",
- wait_time, func_to_func->hwdev->timeout_info->mbox_timeout);
+ sdk_warn(func_to_func->hwdev->dev_hdl,
+ "Retry mbox msg, timeout: %u, expect_timeout: %u\n",
+ wait_time,
+ func_to_func->hwdev->timeout_info->mbox_timeout);
rsp_aeq_id = mbox_msg_rsp_aeq(func_to_func->hwdev);
- err = hinic5_reschedule_eq(func_to_func->hwdev, HINIC5_AEQ, rsp_aeq_id);
+ err = hinic5_reschedule_eq(func_to_func->hwdev, HINIC5_AEQ,
+ rsp_aeq_id);
if (err != 0)
goto timeout;
- err = hinic5_wait_for_timeout(func_to_func, check_mbox_msg_finish,
- MBOX_MSG_RETRY_ACK_TIMEOUT, WAIT_USEC_50);
+ err = hinic5_wait_for_timeout(func_to_func,
+ check_mbox_msg_finish,
+ MBOX_MSG_RETRY_ACK_TIMEOUT,
+ WAIT_USEC_50);
if (err == 0)
goto success;
}
@@ -1434,7 +1518,7 @@ static int wait_mbox_msg_completion(struct hinic5_mbox *func_to_func,
return 0;
}
-#define TRY_MBOX_LOCK_SLEPP 1000
+#define TRY_MBOX_LOCK_SLEPP 1000
static int send_mbox_msg_lock(struct hinic5_mbox *func_to_func, u16 channel)
{
if (!func_to_func->lock_channel_en) {
@@ -1457,17 +1541,20 @@ static void send_mbox_msg_unlock(struct hinic5_mbox *func_to_func)
mutex_unlock(&func_to_func->mbox_send_lock);
}
-static void mbox_cmd_cost_time(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd, struct timeval start)
+static void mbox_cmd_cost_time(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
+ struct timeval start)
{
- struct timeval end = {0};
+ struct timeval end = { 0 };
u64 cost_usec;
if (hinic5_get_perf_en(HINIC5_MAILBOX_PERF)) {
do_gettimeofday(&end);
- cost_usec = (u64)((end.tv_sec - start.tv_sec) * MSEC_PER_SEC * USEC_PER_MSEC +
+ cost_usec = (u64)((end.tv_sec - start.tv_sec) * MSEC_PER_SEC *
+ USEC_PER_MSEC +
end.tv_usec - start.tv_usec);
sdk_info(hwdev->dev_hdl,
- "Mailbox mod: %u cmd: %u, cost time: %llu us\n", mod, cmd, cost_usec);
+ "Mailbox mod: %u cmd: %u, cost time: %llu us\n", mod,
+ cmd, cost_usec);
}
}
@@ -1478,8 +1565,8 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
/* use mbox_resp to hole data which responsed from other function */
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
struct hinic5_msg_desc *msg_desc = NULL;
- struct mbox_msg_info msg_info = {0};
- struct timeval start = {0};
+ struct mbox_msg_info msg_info = { 0 };
+ struct timeval start = { 0 };
int err;
if (hinic5_get_perf_en(HINIC5_MAILBOX_PERF))
@@ -1489,7 +1576,8 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
return -EPERM;
/* expect response message */
- msg_desc = get_mbox_msg_desc(func_to_func, HINIC5_MSG_RESPONSE, dst_func);
+ msg_desc =
+ get_mbox_msg_desc(func_to_func, HINIC5_MSG_RESPONSE, dst_func);
if (!msg_desc)
return -EFAULT;
@@ -1514,7 +1602,8 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
err = send_mbox_msg(func_to_func, mod, cmd, buf_in, in_size, dst_func,
HINIC5_MSG_DIRECT_SEND, HINIC5_MSG_ACK, &msg_info);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Send mailbox mod %u, cmd %u failed, msg_id: %u, err: %d\n",
+ sdk_err(hwdev->dev_hdl,
+ "Send mailbox mod %u, cmd %u failed, msg_id: %u, err: %d\n",
mod, cmd, msg_info.msg_id, err);
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
@@ -1522,7 +1611,8 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
- sdk_err(hwdev->dev_hdl, "Wait for mbox mod: %u, cmd: %u msg response timeout, msg_id: %u\n",
+ sdk_err(hwdev->dev_hdl,
+ "Wait for mbox mod: %u, cmd: %u msg response timeout, msg_id: %u\n",
mod, cmd, msg_info.msg_id);
dump_mbox_header(hwdev, msg_info.header);
hinic5_dump_aeq_info(hwdev);
@@ -1546,12 +1636,18 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
goto send_err;
}
- if (!buf_out || !out_size) {
- /* Scenario where no data needs to be transmitted */
+ if ((!buf_out) || (!out_size)) {
+ /* 无需传输数据的场景 */
goto send_err;
}
- memcpy(buf_out, msg_desc->msg, msg_desc->msg_len);
+ err = memcpy_s(buf_out, *out_size, msg_desc->msg, msg_desc->msg_len);
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl,
+ "Memcpy mesg len %d to buff_out len %d failed: errcode is %d\n",
+ msg_desc->msg_len, *out_size, err);
+ goto send_err;
+ }
*out_size = msg_desc->msg_len;
send_err:
@@ -1564,13 +1660,13 @@ int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
static int mbox_func_params_valid(struct hinic5_mbox *func_to_func,
const void *buf_in, u16 in_size, u16 channel)
{
- if (!func_to_func || !buf_in || in_size == 0)
+ if (!func_to_func || !buf_in || (in_size == 0))
return -EINVAL;
if (in_size > HINIC5_MBOX_DATA_SIZE) {
sdk_err(func_to_func->hwdev->dev_hdl,
- "Mbox msg len %u exceed limit: [1, %u]\n",
- in_size, HINIC5_MBOX_DATA_SIZE);
+ "Mbox msg len %u exceed limit: [1, %u]\n", in_size,
+ HINIC5_MBOX_DATA_SIZE);
return -EINVAL;
}
@@ -1584,11 +1680,11 @@ static int mbox_func_params_valid(struct hinic5_mbox *func_to_func,
}
static int hinic5_mbox_to_func_no_ack(struct hinic5_hwdev *hwdev, u16 func_idx,
- u8 mod, u16 cmd, void *buf_in, u16 in_size,
- u16 channel)
+ u8 mod, u16 cmd, void *buf_in,
+ u16 in_size, u16 channel)
{
- struct mbox_msg_info msg_info = {0};
- struct timeval start = {0};
+ struct mbox_msg_info msg_info = { 0 };
+ struct timeval start = { 0 };
int err;
if (hinic5_get_perf_en(HINIC5_MAILBOX_PERF))
@@ -1604,8 +1700,8 @@ static int hinic5_mbox_to_func_no_ack(struct hinic5_hwdev *hwdev, u16 func_idx,
return err;
err = send_mbox_msg(hwdev->func_to_func, mod, cmd, buf_in, in_size,
- func_idx, HINIC5_MSG_DIRECT_SEND,
- HINIC5_MSG_NO_ACK, &msg_info);
+ func_idx, HINIC5_MSG_DIRECT_SEND, HINIC5_MSG_NO_ACK,
+ &msg_info);
if (err != 0)
sdk_err(hwdev->dev_hdl, "Send mailbox no ack unsuccess\n");
@@ -1620,8 +1716,8 @@ int hinic5_send_mbox_to_mgmt(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
u16 *out_size, u32 timeout, u16 channel)
{
struct hinic5_mbox *func_to_func = hwdev->func_to_func;
- int err = mbox_func_params_valid(func_to_func, buf_in, in_size,
- channel);
+ int err =
+ mbox_func_params_valid(func_to_func, buf_in, in_size, channel);
if (err != 0)
return err;
@@ -1650,16 +1746,18 @@ void hinic5_response_mbox_to_mgmt(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
err = send_mbox_msg(hwdev->func_to_func, mod, cmd, buf_in, in_size,
HINIC5_MGMT_SRC_ID, HINIC5_MSG_RESPONSE,
HINIC5_MSG_NO_ACK, &msg_info);
- if (err != 0)
- sdk_err(hwdev->dev_hdl, "Failed to send mbox msg, err: %d\n", err);
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl, "Failed to send mbox msg, err: %d\n",
+ err);
+ }
}
int hinic5_send_mbox_to_mgmt_no_ack(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
void *buf_in, u16 in_size, u16 channel)
{
struct hinic5_mbox *func_to_func = hwdev->func_to_func;
- int err = mbox_func_params_valid(func_to_func, buf_in, in_size,
- channel);
+ int err =
+ mbox_func_params_valid(func_to_func, buf_in, in_size, channel);
if (err != 0)
return err;
@@ -1687,7 +1785,8 @@ int hinic5_mbox_ppf_to_host(void *hwdev, u8 mod, u16 cmd, u8 host_id,
return err;
if (!HINIC5_IS_PPF(dev)) {
- sdk_err(dev->dev_hdl, "Params error, only ppf support send mbox to ppf. func_type: %d\n",
+ sdk_err(dev->dev_hdl,
+ "Params error, only ppf support send mbox to ppf. func_type: %d\n",
hinic5_func_type(dev));
return -EINVAL;
}
@@ -1700,20 +1799,20 @@ int hinic5_mbox_ppf_to_host(void *hwdev, u8 mod, u16 cmd, u8 host_id,
dst_ppf_func = hinic5_host_ppf_idx(dev, host_id);
if (dst_ppf_func >= HINIC5_MAX_PF_NUM(dev)) {
- sdk_err(dev->dev_hdl, "Dest host(%u) have not elect ppf(0x%x).\n",
- host_id, dst_ppf_func);
+ sdk_err(dev->dev_hdl,
+ "Dest host(%u) have not elect ppf(0x%x).\n", host_id,
+ dst_ppf_func);
return -EINVAL;
}
- return hinic5_mbox_to_func(dev->func_to_func, mod, cmd,
- dst_ppf_func, buf_in, in_size,
- buf_out, out_size, timeout, channel);
+ return hinic5_mbox_to_func(dev->func_to_func, mod, cmd, dst_ppf_func,
+ buf_in, in_size, buf_out, out_size, timeout,
+ channel);
}
EXPORT_SYMBOL(hinic5_mbox_ppf_to_host);
-int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size,
- u32 timeout, u16 channel)
+int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size, u32 timeout, u16 channel)
{
struct hinic5_hwdev *dev = hwdev;
int err;
@@ -1736,8 +1835,8 @@ int hinic5_mbox_to_pf(void *hwdev, u8 mod, u16 cmd, void *buf_in,
}
return hinic5_mbox_to_func(dev->func_to_func, mod, cmd,
- hinic5_pf_id_of_vf(dev), buf_in, in_size,
- buf_out, out_size, timeout, channel);
+ hinic5_pf_id_of_vf(dev), buf_in, in_size,
+ buf_out, out_size, timeout, channel);
}
EXPORT_SYMBOL(hinic5_mbox_to_pf);
@@ -1761,7 +1860,8 @@ int hinic5_mbox_to_vf(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in,
return err;
if (HINIC5_IS_VF((struct hinic5_hwdev *)hwdev)) {
- sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl, "Params error, func_type: %d\n",
+ sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "Params error, func_type: %d\n",
hinic5_func_type(hwdev));
return -EINVAL;
}
@@ -1784,7 +1884,7 @@ int hinic5_mbox_to_vf(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in,
EXPORT_SYMBOL(hinic5_mbox_to_vf);
int hinic5_mbox_to_vf_without_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
- void *buf_in, u16 in_size, u16 channel)
+ void *buf_in, u16 in_size, u16 channel)
{
struct hinic5_mbox *func_to_func = NULL;
int err = 0;
@@ -1802,7 +1902,8 @@ int hinic5_mbox_to_vf_without_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
return err;
if (HINIC5_IS_VF((struct hinic5_hwdev *)hwdev)) {
- sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl, "Params error, func_type: %d\n",
+ sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "Params error, func_type: %d\n",
hinic5_func_type(hwdev));
return -EINVAL;
}
@@ -1818,16 +1919,18 @@ int hinic5_mbox_to_vf_without_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
*/
dst_func_idx = hinic5_glb_pf_vf_offset(hwdev) + vf_id;
- return hinic5_mbox_to_func_no_ack(hwdev, dst_func_idx, mod, cmd,
- buf_in, in_size, channel);
+ return hinic5_mbox_to_func_no_ack(hwdev, dst_func_idx, mod, cmd, buf_in,
+ in_size, channel);
}
EXPORT_SYMBOL(hinic5_mbox_to_vf_without_ack);
/* This is an old API, which is to be deprecated. */
-int hinic5_mbox_to_vf_no_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size, u16 channel)
+int hinic5_mbox_to_vf_no_ack(void *hwdev, u16 vf_id, u8 mod, u16 cmd,
+ void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u16 channel)
{
- return hinic5_mbox_to_vf_without_ack(hwdev, vf_id, mod, cmd, buf_in, in_size, channel);
+ return hinic5_mbox_to_vf_without_ack(hwdev, vf_id, mod, cmd, buf_in,
+ in_size, channel);
}
EXPORT_SYMBOL(hinic5_mbox_to_vf_no_ack);
@@ -1889,13 +1992,15 @@ static int init_mgmt_msg_channel(struct hinic5_mbox *func_to_func)
err = alloc_mbox_msg_channel(&func_to_func->mgmt_msg);
if (err != 0) {
- sdk_err(func_to_func->hwdev->dev_hdl, "Failed to alloc mgmt message channel\n");
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Failed to alloc mgmt message channel\n");
return err;
}
err = hinic5_init_mbox_dma_queue(func_to_func);
if (err != 0) {
- sdk_err(func_to_func->hwdev->dev_hdl, "Failed to init mbox dma queue\n");
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Failed to init mbox dma queue\n");
free_mbox_msg_channel(&func_to_func->mgmt_msg);
}
@@ -1917,11 +2022,11 @@ int hinic5_mbox_init_host_msg_channel(struct hinic5_hwdev *hwdev)
if (host_num == 0)
return 0;
- func_to_func->host_msg = kcalloc(host_num,
- sizeof(*func_to_func->host_msg),
- GFP_KERNEL);
+ func_to_func->host_msg =
+ kcalloc(host_num, sizeof(*func_to_func->host_msg), GFP_KERNEL);
if (!func_to_func->host_msg) {
- sdk_err(func_to_func->hwdev->dev_hdl, "Failed to alloc host message array\n");
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Failed to alloc host message array\n");
return -ENOMEM;
}
@@ -1970,7 +2075,7 @@ int hinic5_init_func_mbox_msg_channel(void *hwdev, u16 num_func)
u16 func_id, i;
int err;
- if (!hwdev || num_func == 0 || num_func > HINIC5_MAX_FUNCTIONS)
+ if (!hwdev || (num_func == 0) || num_func > HINIC5_MAX_FUNCTIONS)
return -EINVAL;
func_to_func = dev->func_to_func;
@@ -1980,7 +2085,8 @@ int hinic5_init_func_mbox_msg_channel(void *hwdev, u16 num_func)
func_to_func->func_msg =
kcalloc(num_func, sizeof(*func_to_func->func_msg), GFP_KERNEL);
if (!func_to_func->func_msg) {
- sdk_err(func_to_func->hwdev->dev_hdl, "Failed to alloc func message array\n");
+ sdk_err(func_to_func->hwdev->dev_hdl,
+ "Failed to alloc func message array\n");
return -ENOMEM;
}
@@ -1988,7 +2094,7 @@ int hinic5_init_func_mbox_msg_channel(void *hwdev, u16 num_func)
err = alloc_mbox_msg_channel(&func_to_func->func_msg[func_id]);
if (err != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
- "Failed to alloc func %u message channel\n",
+ "Failed to alloc func %hu message channel\n",
func_id);
goto alloc_msg_ch_err;
}
@@ -2023,8 +2129,8 @@ static void hinic5_deinit_func_mbox_msg_channel(struct hinic5_hwdev *hwdev)
func_to_func->func_msg = NULL;
}
-static struct hinic5_msg_desc *get_mbox_msg_desc(struct hinic5_mbox *func_to_func,
- u64 dir, u64 src_func_id)
+static struct hinic5_msg_desc *
+get_mbox_msg_desc(struct hinic5_mbox *func_to_func, u64 dir, u64 src_func_id)
{
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
struct hinic5_msg_channel *msg_ch = NULL;
@@ -2060,8 +2166,8 @@ static struct hinic5_msg_desc *get_mbox_msg_desc(struct hinic5_mbox *func_to_fun
msg_ch = &func_to_func->host_msg[id];
}
- return (dir == HINIC5_MSG_DIRECT_SEND) ?
- &msg_ch->recv_msg : &msg_ch->resp_msg;
+ return (dir == HINIC5_MSG_DIRECT_SEND) ? &msg_ch->recv_msg :
+ &msg_ch->resp_msg;
}
static void prepare_send_mbox(struct hinic5_mbox *func_to_func)
@@ -2077,10 +2183,9 @@ static int alloc_mbox_wb_result(struct hinic5_mbox *func_to_func)
struct hinic5_hwdev *hwdev = func_to_func->hwdev;
u32 addr_h, addr_l;
- send_mbox->wb_vaddr = dma_zalloc_coherent(hwdev->dev_hdl,
- MBOX_WB_STATUS_LEN,
- &send_mbox->wb_paddr,
- GFP_KERNEL);
+ send_mbox->wb_vaddr =
+ dma_zalloc_coherent(hwdev->dev_hdl, MBOX_WB_STATUS_LEN,
+ &send_mbox->wb_paddr, GFP_KERNEL);
if (!send_mbox->wb_vaddr)
return -ENOMEM;
@@ -2126,9 +2231,11 @@ int hinic5_func_to_func_init(struct hinic5_hwdev *hwdev)
mutex_init(&func_to_func->mbox_send_lock);
mutex_init(&func_to_func->msg_send_lock);
spin_lock_init(&func_to_func->mbox_lock);
- func_to_func->workq = create_singlethread_workqueue(HINIC5_MBOX_WQ_NAME);
+ func_to_func->workq =
+ create_singlethread_workqueue(HINIC5_MBOX_WQ_NAME);
if (!func_to_func->workq) {
- sdk_err(hwdev->dev_hdl, "Failed to initialize MBOX workqueue\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to initialize MBOX workqueue\n");
goto create_mbox_workq_err;
}
@@ -2145,7 +2252,8 @@ int hinic5_func_to_func_init(struct hinic5_hwdev *hwdev)
err = alloc_mbox_wb_result(func_to_func);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to alloc mbox write back status\n");
+ sdk_err(hwdev->dev_hdl,
+ "Failed to alloc mbox write back status\n");
goto alloc_wb_status_err;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mgmt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mgmt.c
index 2252f3f95..5bfe55e59 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_mgmt.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mgmt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -34,47 +27,49 @@
#include "hinic5_csr_inner.h"
#include "hinic5_mgmt.h"
-#define HINIC5_MSG_TO_MGMT_MAX_LEN 2016
+#define HINIC5_MSG_TO_MGMT_MAX_LEN 2016
-#define HINIC5_API_CHAIN_AEQ_ID 2
-#define MAX_PF_MGMT_BUF_SIZE 2048UL
-#define SEGMENT_LEN 48
-#define ASYNC_MSG_FLAG 0x8
-#define MGMT_MSG_MAX_SEQ_ID (ALIGN(HINIC5_MSG_TO_MGMT_MAX_LEN, \
- SEGMENT_LEN) / SEGMENT_LEN)
+#define HINIC5_API_CHAIN_AEQ_ID 2
+#define MAX_PF_MGMT_BUF_SIZE 2048UL
+#define SEGMENT_LEN 48
+#define ASYNC_MSG_FLAG 0x8
+#define MGMT_MSG_MAX_SEQ_ID \
+ (ALIGN(HINIC5_MSG_TO_MGMT_MAX_LEN, SEGMENT_LEN) / SEGMENT_LEN)
-#define MGMT_MSG_LAST_SEG_MAX_LEN (MAX_PF_MGMT_BUF_SIZE - \
- SEGMENT_LEN * MGMT_MSG_MAX_SEQ_ID)
+#define MGMT_MSG_LAST_SEG_MAX_LEN \
+ (MAX_PF_MGMT_BUF_SIZE - SEGMENT_LEN * MGMT_MSG_MAX_SEQ_ID)
-#define BUF_OUT_DEFAULT_SIZE 1
+#define BUF_OUT_DEFAULT_SIZE 1
-#define MGMT_MSG_SIZE_MIN 20
-#define MGMT_MSG_SIZE_STEP 16
-#define MGMT_MSG_RSVD_FOR_DEV 8
+#define MGMT_MSG_SIZE_MIN 20
+#define MGMT_MSG_SIZE_STEP 16
+#define MGMT_MSG_RSVD_FOR_DEV 8
-#define SYNC_MSG_ID_MASK 0x7
-#define ASYNC_MSG_ID_MASK 0x7
+#define SYNC_MSG_ID_MASK 0x7
+#define ASYNC_MSG_ID_MASK 0x7
-#define SYNC_FLAG 0
-#define ASYNC_FLAG 1
+#define SYNC_FLAG 0
+#define ASYNC_FLAG 1
-#define MSG_NO_RESP 0xFFFF
+#define MSG_NO_RESP 0xFFFF
#ifdef PLATFORM_MODE_FPGA
-#define MGMT_MSG_TIMEOUT 200000
+#define MGMT_MSG_TIMEOUT 200000
#else
-#define MGMT_MSG_TIMEOUT 20000
+#define MGMT_MSG_TIMEOUT 20000
#endif
-#define SYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->sync_msg_id)
+#define SYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->sync_msg_id)
-#define SYNC_MSG_ID_INC(pf_to_mgmt) (SYNC_MSG_ID(pf_to_mgmt) = \
- (SYNC_MSG_ID(pf_to_mgmt) + 1) & SYNC_MSG_ID_MASK)
-#define ASYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->async_msg_id)
+#define SYNC_MSG_ID_INC(pf_to_mgmt) \
+ (SYNC_MSG_ID(pf_to_mgmt) = (SYNC_MSG_ID(pf_to_mgmt) + 1) & \
+ SYNC_MSG_ID_MASK)
+#define ASYNC_MSG_ID(pf_to_mgmt) ((pf_to_mgmt)->async_msg_id)
-#define ASYNC_MSG_ID_INC(pf_to_mgmt) (ASYNC_MSG_ID(pf_to_mgmt) = \
- ((ASYNC_MSG_ID(pf_to_mgmt) + 1) & ASYNC_MSG_ID_MASK) \
- | ASYNC_MSG_FLAG)
+#define ASYNC_MSG_ID_INC(pf_to_mgmt) \
+ (ASYNC_MSG_ID(pf_to_mgmt) = \
+ ((ASYNC_MSG_ID(pf_to_mgmt) + 1) & ASYNC_MSG_ID_MASK) | \
+ ASYNC_MSG_FLAG)
static void pf_to_mgmt_send_event_set(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
int event_flag)
@@ -153,8 +148,8 @@ static u16 mgmt_msg_len(u16 msg_data_len)
if (msg_size > MGMT_MSG_SIZE_MIN)
msg_size = MGMT_MSG_SIZE_MIN +
- ALIGN((msg_size - MGMT_MSG_SIZE_MIN),
- MGMT_MSG_SIZE_STEP);
+ ALIGN((msg_size - MGMT_MSG_SIZE_MIN),
+ MGMT_MSG_SIZE_STEP);
else
msg_size = MGMT_MSG_SIZE_MIN;
@@ -177,38 +172,38 @@ static void prepare_header(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
{
struct hinic5_hwif *hwif = pf_to_mgmt->hwdev->hwif;
- mbox_msg_header_set_last(header, msg_len, mod, msg_len, pf_to_mgmt->hwdev);
+ mbox_msg_header_set_last(header, msg_len, mod, msg_len,
+ pf_to_mgmt->hwdev);
*header |= HINIC5_MSG_HEADER_SET(ack_type, NO_ACK) |
- HINIC5_MSG_HEADER_SET(HINIC5_DATA_INLINE, DATA_TYPE) |
- HINIC5_MSG_HEADER_SET(0, SEQID) |
- HINIC5_MSG_HEADER_SET(HINIC5_API_CHAIN_AEQ_ID, AEQ_ID) |
- HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
- HINIC5_MSG_HEADER_SET(HINIC5_MSG_DIRECT_SEND, DIRECTION) |
- HINIC5_MSG_HEADER_SET(cmd, CMD) |
- HINIC5_MSG_HEADER_SET(HINIC5_MSG_FROM_MGMT, SOURCE) |
- HINIC5_MSG_HEADER_SET(hwif->attr.func_global_idx,
- SRC_GLB_FUNC_IDX) |
- HINIC5_MSG_HEADER_SET(msg_id, MSG_ID);
+ HINIC5_MSG_HEADER_SET(HINIC5_DATA_INLINE, DATA_TYPE) |
+ HINIC5_MSG_HEADER_SET(0, SEQID) |
+ HINIC5_MSG_HEADER_SET(HINIC5_API_CHAIN_AEQ_ID, AEQ_ID) |
+ HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
+ HINIC5_MSG_HEADER_SET(HINIC5_MSG_DIRECT_SEND, DIRECTION) |
+ HINIC5_MSG_HEADER_SET(cmd, CMD) |
+ HINIC5_MSG_HEADER_SET(HINIC5_MSG_FROM_MGMT, SOURCE) |
+ HINIC5_MSG_HEADER_SET(hwif->attr.func_global_idx,
+ SRC_GLB_FUNC_IDX) |
+ HINIC5_MSG_HEADER_SET(msg_id, MSG_ID);
}
static void clp_prepare_header(struct hinic5_hwdev *hwdev, u64 *header,
- u16 msg_len, u8 mod,
- enum hinic5_mgmt_cmd cmd)
+ u16 msg_len, u8 mod, enum hinic5_mgmt_cmd cmd)
{
struct hinic5_hwif *hwif = hwdev->hwif;
mbox_msg_header_set_last(header, msg_len, mod, msg_len, hwdev);
*header |= HINIC5_MSG_HEADER_SET(0, NO_ACK) |
- HINIC5_MSG_HEADER_SET(HINIC5_DATA_INLINE, DATA_TYPE) |
- HINIC5_MSG_HEADER_SET(0, SEQID) |
- HINIC5_MSG_HEADER_SET(HINIC5_API_CHAIN_AEQ_ID, AEQ_ID) |
- HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
- HINIC5_MSG_HEADER_SET(0, DIRECTION) |
- HINIC5_MSG_HEADER_SET(cmd, CMD) |
- HINIC5_MSG_HEADER_SET(hwif->attr.func_global_idx,
- SRC_GLB_FUNC_IDX) |
- HINIC5_MSG_HEADER_SET(0, MSG_ID);
+ HINIC5_MSG_HEADER_SET(HINIC5_DATA_INLINE, DATA_TYPE) |
+ HINIC5_MSG_HEADER_SET(0, SEQID) |
+ HINIC5_MSG_HEADER_SET(HINIC5_API_CHAIN_AEQ_ID, AEQ_ID) |
+ HINIC5_MSG_HEADER_SET(LAST_SEGMENT, LAST) |
+ HINIC5_MSG_HEADER_SET(0, DIRECTION) |
+ HINIC5_MSG_HEADER_SET(cmd, CMD) |
+ HINIC5_MSG_HEADER_SET(hwif->attr.func_global_idx,
+ SRC_GLB_FUNC_IDX) |
+ HINIC5_MSG_HEADER_SET(0, MSG_ID);
}
/**
@@ -223,13 +218,21 @@ static int prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, const void *msg,
{
u8 *mgmt_cmd_new = mgmt_cmd;
- memset(mgmt_cmd_new, 0, MGMT_MSG_RSVD_FOR_DEV);
+ (void)memset_s(mgmt_cmd_new, MGMT_MSG_RSVD_FOR_DEV, 0,
+ MGMT_MSG_RSVD_FOR_DEV);
mgmt_cmd_new += MGMT_MSG_RSVD_FOR_DEV;
- memcpy(mgmt_cmd_new, header, sizeof(*header));
+ if (memcpy_s(mgmt_cmd_new,
+ (MAX_PF_MGMT_BUF_SIZE - MGMT_MSG_RSVD_FOR_DEV), header,
+ sizeof(*header)) != 0)
+ return -ENOMEM;
mgmt_cmd_new += sizeof(*header);
- memcpy(mgmt_cmd_new, msg, (size_t)(u32)msg_len);
+ if (memcpy_s(mgmt_cmd_new,
+ (MAX_PF_MGMT_BUF_SIZE - MGMT_MSG_RSVD_FOR_DEV -
+ sizeof(*header)),
+ msg, (size_t)(u32)msg_len) != 0)
+ return -ENOMEM;
return 0;
}
@@ -261,8 +264,8 @@ static int send_msg_to_mgmt_sync(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
if (cmd_size > HINIC5_MSG_TO_MGMT_MAX_LEN)
return -EFAULT;
- prepare_header(pf_to_mgmt, &header, msg_len, mod, HINIC5_MSG_ACK,
- cmd, SYNC_MSG_ID_INC(pf_to_mgmt));
+ prepare_header(pf_to_mgmt, &header, msg_len, mod, HINIC5_MSG_ACK, cmd,
+ SYNC_MSG_ID_INC(pf_to_mgmt));
chain = pf_to_mgmt->cmd_chain[HINIC5_API_CMD_WRITE_TO_MGMT_CPU];
pf_to_mgmt_send_event_set(pf_to_mgmt, SEND_EVENT_START);
@@ -345,7 +348,8 @@ static int msg_to_mgmt_wait_completion(void *hwdev, u32 timeout)
ret = wait_for_completion_timeout(&recv_msg->recv_done, timeo);
if (ret == 0) {
- sdk_err(dev, "Mgmt response sync cmd timeout, sync_msg_id: %u\n",
+ sdk_err(dev,
+ "Mgmt response sync cmd timeout, sync_msg_id: %u\n",
pf_to_mgmt->sync_msg_id);
hinic5_dump_aeq_info((struct hinic5_hwdev *)hwdev);
pf_to_mgmt_send_event_set(pf_to_mgmt, SEND_EVENT_TIMEOUT);
@@ -368,7 +372,8 @@ static int msg_to_mgmt_wait_completion(void *hwdev, u32 timeout)
}
int hinic5_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size, u32 timeout)
+ u16 in_size, void *buf_out, u16 *out_size,
+ u32 timeout)
{
struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
void *dev = ((struct hinic5_hwdev *)hwdev)->dev_hdl;
@@ -379,7 +384,7 @@ int hinic5_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
err = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -397,7 +402,8 @@ int hinic5_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
err = send_msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size);
if (err != 0) {
- sdk_err(dev, "Failed to send sync msg to mgmt, sync_msg_id: %u\n",
+ sdk_err(dev,
+ "Failed to send sync msg to mgmt, sync_msg_id: %u\n",
pf_to_mgmt->sync_msg_id);
pf_to_mgmt_send_event_set(pf_to_mgmt, SEND_EVENT_FAIL);
goto unlock_sync_msg;
@@ -409,14 +415,20 @@ int hinic5_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (buf_out && out_size) {
if (*out_size < recv_msg->msg_len) {
- sdk_err(dev, "Invalid response message length: %u for mod %u cmd %u from mgmt, should less than: %u\n",
+ sdk_err(dev,
+ "Invalid response message length: %u for mod %u cmd %u from mgmt, should less than: %u\n",
recv_msg->msg_len, mod, cmd, *out_size);
err = -EFAULT;
goto unlock_sync_msg;
}
- if (recv_msg->msg_len != 0)
- memcpy(buf_out, recv_msg->msg, recv_msg->msg_len);
+ if (recv_msg->msg_len != 0) {
+ if (memcpy_s(buf_out, *out_size, recv_msg->msg,
+ recv_msg->msg_len) != 0) {
+ err = -ENOMEM;
+ goto unlock_sync_msg;
+ }
+ }
*out_size = recv_msg->msg_len;
}
@@ -470,8 +482,8 @@ int hinic5_pf_msg_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
return -EPERM;
- return hinic5_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in, in_size,
- buf_out, out_size, timeout);
+ return hinic5_pf_to_mgmt_sync(hwdev, mod, cmd, buf_in, in_size, buf_out,
+ out_size, timeout);
}
int hinic5_msg_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
@@ -498,8 +510,8 @@ int hinic5_msg_to_mgmt_no_ack(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (hinic5_get_chip_present_flag(hwdev) == 0)
return -EPERM;
- return hinic5_send_mbox_to_mgmt_no_ack(hwdev, mod, cmd, buf_in,
- in_size, channel);
+ return hinic5_send_mbox_to_mgmt_no_ack(hwdev, mod, cmd, buf_in, in_size,
+ channel);
}
EXPORT_SYMBOL(hinic5_msg_to_mgmt_no_ack);
@@ -562,7 +574,9 @@ bool hinic5_is_multi_bm(void *hwdev)
if (!hwdev)
return false;
- return ((IS_BMGW_SLAVE_HOST(hw_dev)) || (IS_BMGW_MASTER_HOST(hw_dev))) ? true : false;
+ return ((IS_BMGW_SLAVE_HOST(hw_dev)) || (IS_BMGW_MASTER_HOST(hw_dev))) ?
+ true :
+ false;
}
EXPORT_SYMBOL(hinic5_is_multi_bm);
@@ -575,7 +589,9 @@ bool hinic5_is_slave_host(void *hwdev)
return false;
}
- return ((IS_BMGW_SLAVE_HOST(hw_dev)) || (IS_VM_SLAVE_HOST(hw_dev))) ? true : false;
+ return ((IS_BMGW_SLAVE_HOST(hw_dev)) || (IS_VM_SLAVE_HOST(hw_dev))) ?
+ true :
+ false;
}
EXPORT_SYMBOL(hinic5_is_slave_host);
@@ -588,13 +604,14 @@ bool hinic5_is_master_host(void *hwdev)
return false;
}
- return ((IS_BMGW_MASTER_HOST(hw_dev)) || (IS_VM_MASTER_HOST(hw_dev))) ? true : false;
+ return ((IS_BMGW_MASTER_HOST(hw_dev)) || (IS_VM_MASTER_HOST(hw_dev))) ?
+ true :
+ false;
}
EXPORT_SYMBOL(hinic5_is_master_host);
-static void send_mgmt_ack(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
- u8 mod, u16 cmd, void *buf_in, u16 in_size,
- u16 msg_id)
+static void send_mgmt_ack(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt, u8 mod,
+ u16 cmd, void *buf_in, u16 in_size, u16 msg_id)
{
u16 buf_size;
@@ -616,10 +633,11 @@ static void mgmt_recv_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
enum hinic5_mod_type tmp_mod = mod;
u16 out_size = 0;
- memset(buf_out, 0, MAX_PF_MGMT_BUF_SIZE);
+ (void)memset_s(buf_out, MAX_PF_MGMT_BUF_SIZE, 0, MAX_PF_MGMT_BUF_SIZE);
if (mod >= HINIC5_MOD_HW_MAX) {
- sdk_warn(dev, "Receive illegal message from mgmt cpu, mod = %u\n",
+ sdk_warn(dev,
+ "Receive illegal message from mgmt cpu, mod = %u\n",
mod);
goto unsupported;
}
@@ -629,16 +647,18 @@ static void mgmt_recv_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
if (!pf_to_mgmt->recv_mgmt_msg_cb[mod] ||
!test_bit(HINIC5_MGMT_MSG_CB_REG,
- &pf_to_mgmt->mgmt_msg_cb_state[tmp_mod])) {
- sdk_warn(dev, "Receive mgmt callback is null, mod = %u, cmd=%u\n", mod, cmd);
+ &pf_to_mgmt->mgmt_msg_cb_state[tmp_mod])) {
+ sdk_warn(dev,
+ "Receive mgmt callback is null, mod = %u, cmd=%u\n",
+ mod, cmd);
clear_bit(HINIC5_MGMT_MSG_CB_RUNNING,
&pf_to_mgmt->mgmt_msg_cb_state[tmp_mod]);
goto unsupported;
}
- pf_to_mgmt->recv_mgmt_msg_cb[tmp_mod](pf_to_mgmt->recv_mgmt_msg_data[tmp_mod],
- cmd, buf_in, in_size,
- buf_out, &out_size);
+ pf_to_mgmt->recv_mgmt_msg_cb[tmp_mod](
+ pf_to_mgmt->recv_mgmt_msg_data[tmp_mod], cmd, buf_in, in_size,
+ buf_out, &out_size);
clear_bit(HINIC5_MGMT_MSG_CB_RUNNING,
&pf_to_mgmt->mgmt_msg_cb_state[tmp_mod]);
@@ -674,11 +694,13 @@ static void mgmt_resp_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
pf_to_mgmt->event_flag = SEND_EVENT_SUCCESS;
complete(&recv_msg->recv_done);
} else if (recv_msg->msg_id != pf_to_mgmt->sync_msg_id) {
- sdk_err(dev, "Send msg id(0x%x) recv msg id(0x%x) dismatch, event state=%d\n",
+ sdk_err(dev,
+ "Send msg id(0x%x) recv msg id(0x%x) dismatch, event state=%d\n",
pf_to_mgmt->sync_msg_id, recv_msg->msg_id,
pf_to_mgmt->event_flag);
} else {
- sdk_err(dev, "Wait timeout, send msg id(0x%x) recv msg id(0x%x), event state=%d!\n",
+ sdk_err(dev,
+ "Wait timeout, send msg id(0x%x) recv msg id(0x%x), event state=%d!\n",
pf_to_mgmt->sync_msg_id, recv_msg->msg_id,
pf_to_mgmt->event_flag);
}
@@ -701,18 +723,20 @@ static void recv_mgmt_msg_work_handler(struct work_struct *work)
kfree(mgmt_work);
}
-static bool check_mgmt_head_info(struct hinic5_recv_msg *recv_msg,
- u8 seq_id, u8 seg_len, u16 msg_id)
+static bool check_mgmt_head_info(struct hinic5_recv_msg *recv_msg, u8 seq_id,
+ u8 seg_len, u16 msg_id)
{
if (seq_id > MGMT_MSG_MAX_SEQ_ID || seg_len > SEGMENT_LEN ||
- (seq_id == MGMT_MSG_MAX_SEQ_ID && seg_len > MGMT_MSG_LAST_SEG_MAX_LEN))
+ (seq_id == MGMT_MSG_MAX_SEQ_ID &&
+ seg_len > MGMT_MSG_LAST_SEG_MAX_LEN))
return false;
if (seq_id == 0) {
recv_msg->seq_id = seq_id;
recv_msg->msg_id = msg_id;
} else {
- if (seq_id != recv_msg->seq_id + 1 || msg_id != recv_msg->msg_id)
+ if (seq_id != recv_msg->seq_id + 1 ||
+ msg_id != recv_msg->msg_id)
return false;
recv_msg->seq_id = seq_id;
@@ -724,22 +748,35 @@ static bool check_mgmt_head_info(struct hinic5_recv_msg *recv_msg,
static void init_mgmt_msg_work(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
struct hinic5_recv_msg *recv_msg)
{
+ int err;
struct hinic5_mgmt_msg_handle_work *mgmt_work = NULL;
struct hinic5_hwdev *hwdev = pf_to_mgmt->hwdev;
mgmt_work = kzalloc(sizeof(*mgmt_work), GFP_KERNEL);
- if (!mgmt_work)
+ if (!mgmt_work) {
+ sdk_err(hwdev->dev_hdl, "Allocate mgmt work memory failed\n");
return;
+ }
if (recv_msg->msg_len != 0) {
mgmt_work->msg = kzalloc(recv_msg->msg_len, GFP_KERNEL);
- if (!mgmt_work->msg)
+ if (!mgmt_work->msg) {
+ sdk_err(hwdev->dev_hdl,
+ "Allocate mgmt msg memory failed\n");
goto msg_alloc_err;
+ }
}
mgmt_work->pf_to_mgmt = pf_to_mgmt;
mgmt_work->msg_len = recv_msg->msg_len;
- memcpy(mgmt_work->msg, recv_msg->msg, recv_msg->msg_len);
+ err = memcpy_s(mgmt_work->msg, mgmt_work->msg_len, recv_msg->msg,
+ recv_msg->msg_len);
+ if (err != 0) {
+ sdk_err(hwdev->dev_hdl,
+ "Memcpy failed: mgmt_work->msg_len = %u, recv_msg->msg = %u, errcode is %d\n",
+ mgmt_work->msg_len, recv_msg->msg_len, err);
+ goto memcpy_err;
+ }
mgmt_work->msg_id = recv_msg->msg_id;
mgmt_work->mod = recv_msg->mod;
@@ -751,6 +788,11 @@ static void init_mgmt_msg_work(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
pf_to_mgmt->workq, &mgmt_work->work);
return;
+memcpy_err:
+ if (recv_msg->msg_len != 0) {
+ kfree(mgmt_work->msg);
+ }
+
msg_alloc_err:
kfree(mgmt_work);
}
@@ -775,33 +817,39 @@ static void recv_mgmt_msg_handler(struct hinic5_msg_pf_to_mgmt *pf_to_mgmt,
version = hinic5_mbox_get_version(hwdev, &mbox_header);
/* Don't need to get anything from hw when cmd is async */
dir = HINIC5_MSG_HEADER_GET(mbox_header, DIRECTION);
- if (dir == HINIC5_MSG_RESPONSE &&
- ((HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID) & ASYNC_MSG_FLAG) != 0))
+ if ((dir == HINIC5_MSG_RESPONSE) &&
+ ((HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID) & ASYNC_MSG_FLAG) !=
+ 0))
return;
seq_len = hinic5_mbox_get_seg_len(version, &mbox_header);
- seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
+ seq_id = HINIC5_MSG_HEADER_GET(mbox_header, SEQID);
msg_id = HINIC5_MSG_HEADER_GET(mbox_header, MSG_ID);
if (!check_mgmt_head_info(recv_msg, seq_id, seq_len, msg_id)) {
- sdk_err(hwdev->dev_hdl, "Mgmt msg sequence id and segment length check failed\n");
+ sdk_err(hwdev->dev_hdl,
+ "Mgmt msg sequence id and segment length check failed\n");
sdk_err(hwdev->dev_hdl,
"Front seq_id: 0x%x,current seq_id: 0x%x, seg len: 0x%x, front msg_id: %u, cur: %u\n",
- recv_msg->seq_id, seq_id, seq_len, recv_msg->msg_id, msg_id);
+ recv_msg->seq_id, seq_id, seq_len, recv_msg->msg_id,
+ msg_id);
/* set seq_id to invalid seq_id */
recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
return;
}
- offset = seq_id * SEGMENT_LEN;
- memcpy((u8 *)recv_msg->msg + offset, msg_body, seq_len);
+ offset = seq_id * SEGMENT_LEN;
+ if (memcpy_s((u8 *)recv_msg->msg + offset,
+ (MAX_PF_MGMT_BUF_SIZE - offset), msg_body, seq_len) != 0) {
+ sdk_err(hwdev->dev_hdl, "Memcpy msg failed, %u.\n", seq_len);
+ return;
+ }
if (HINIC5_MSG_HEADER_GET(mbox_header, LAST) == 0)
return;
recv_msg->cmd = HINIC5_MSG_HEADER_GET(mbox_header, CMD);
recv_msg->mod = hinic5_mbox_get_mod_id(version, &mbox_header);
- recv_msg->async_mgmt_to_pf = HINIC5_MSG_HEADER_GET(mbox_header,
- NO_ACK);
+ recv_msg->async_mgmt_to_pf = HINIC5_MSG_HEADER_GET(mbox_header, NO_ACK);
recv_msg->msg_len = hinic5_mbox_get_msg_len(version, &mbox_header);
recv_msg->msg_id = msg_id;
recv_msg->seq_id = MGMT_MSG_MAX_SEQ_ID;
@@ -839,10 +887,12 @@ void hinic5_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size)
return;
is_send_dir = (HINIC5_MSG_HEADER_GET(*(u64 *)header, DIRECTION) ==
- HINIC5_MSG_DIRECT_SEND) ? true : false;
+ HINIC5_MSG_DIRECT_SEND) ?
+ true :
+ false;
recv_msg = is_send_dir ? &pf_to_mgmt->recv_msg_from_mgmt :
- &pf_to_mgmt->recv_resp_msg_from_mgmt;
+ &pf_to_mgmt->recv_resp_msg_from_mgmt;
recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg);
}
@@ -1030,13 +1080,14 @@ void hinic5_flush_mgmt_workq(void *hwdev)
flush_workqueue(dev->pf_to_mgmt->workq);
}
-int hinic5_api_cmd_read_ack(void *hwdev, u8 dest, const void *cmd,
- u16 size, void *ack, u16 ack_size)
+int hinic5_api_cmd_read_ack(void *hwdev, u8 dest, const void *cmd, u16 size,
+ void *ack, u16 ack_size)
{
struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
struct hinic5_api_cmd_chain *chain = NULL;
- if (!hwdev || !cmd || (ack_size != 0 && !ack) || size > MAX_PF_MGMT_BUF_SIZE)
+ if (!hwdev || !cmd || ((ack_size != 0) && !ack) ||
+ size > MAX_PF_MGMT_BUF_SIZE)
return -EINVAL;
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
@@ -1063,7 +1114,7 @@ int hinic5_api_cmd_write_nack(void *hwdev, u8 dest, const void *cmd, u16 size)
struct hinic5_msg_pf_to_mgmt *pf_to_mgmt = NULL;
struct hinic5_api_cmd_chain *chain = NULL;
- if (!hwdev || size == 0 || !cmd || size > MAX_PF_MGMT_BUF_SIZE)
+ if (!hwdev || (size == 0) || !cmd || size > MAX_PF_MGMT_BUF_SIZE)
return -EINVAL;
if (!COMM_SUPPORT_API_CHAIN((struct hinic5_hwdev *)hwdev))
@@ -1084,8 +1135,8 @@ static int get_clp_reg(void *hwdev, enum clp_data_type data_type,
switch (reg_type) {
case HINIC5_CLP_BA_HOST:
*reg_addr = (data_type == HINIC5_CLP_REQ_HOST) ?
- HINIC5_CLP_REG(REQBASE) :
- HINIC5_CLP_REG(RSPBASE);
+ HINIC5_CLP_REG(REQBASE) :
+ HINIC5_CLP_REG(RSPBASE);
break;
case HINIC5_CLP_SIZE_HOST:
@@ -1094,7 +1145,8 @@ static int get_clp_reg(void *hwdev, enum clp_data_type data_type,
case HINIC5_CLP_LEN_HOST:
*reg_addr = (data_type == HINIC5_CLP_REQ_HOST) ?
- HINIC5_CLP_REG(REQ) : HINIC5_CLP_REG(RSP);
+ HINIC5_CLP_REG(REQ) :
+ HINIC5_CLP_REG(RSP);
break;
case HINIC5_CLP_START_REQ_HOST:
@@ -1141,31 +1193,31 @@ static u32 get_clp_reg_value(struct hinic5_hwdev *hwdev,
switch (reg_type) {
case HINIC5_CLP_BA_HOST:
value = ((value >> HINIC5_CLP_OFFSET(BASE)) &
- HINIC5_CLP_MASK(BASE));
+ HINIC5_CLP_MASK(BASE));
break;
case HINIC5_CLP_SIZE_HOST:
if (data_type == HINIC5_CLP_REQ_HOST)
value = ((value >> HINIC5_CLP_OFFSET(REQ_SIZE)) &
- HINIC5_CLP_MASK(SIZE));
+ HINIC5_CLP_MASK(SIZE));
else
value = ((value >> HINIC5_CLP_OFFSET(RSP_SIZE)) &
- HINIC5_CLP_MASK(SIZE));
+ HINIC5_CLP_MASK(SIZE));
break;
case HINIC5_CLP_LEN_HOST:
value = ((value >> HINIC5_CLP_OFFSET(LEN)) &
- HINIC5_CLP_MASK(LEN));
+ HINIC5_CLP_MASK(LEN));
break;
case HINIC5_CLP_START_REQ_HOST:
value = ((value >> HINIC5_CLP_OFFSET(START)) &
- HINIC5_CLP_MASK(START));
+ HINIC5_CLP_MASK(START));
break;
case HINIC5_CLP_READY_RSP_HOST:
value = ((value >> HINIC5_CLP_OFFSET(READY)) &
- HINIC5_CLP_MASK(READY));
+ HINIC5_CLP_MASK(READY));
break;
default:
@@ -1218,8 +1270,7 @@ static int check_reg_value(enum clp_reg_type reg_type, u32 value)
value > HINIC5_CLP_SRAM_SIZE_REG_MAX)
return -EINVAL;
- if (reg_type == HINIC5_CLP_LEN_HOST &&
- value > HINIC5_CLP_LEN_REG_MAX)
+ if (reg_type == HINIC5_CLP_LEN_HOST && value > HINIC5_CLP_LEN_REG_MAX)
return -EINVAL;
if ((reg_type == HINIC5_CLP_START_REQ_HOST ||
@@ -1237,7 +1288,7 @@ static int hinic5_check_clp_init_status(struct hinic5_hwdev *hwdev)
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
HINIC5_CLP_BA_HOST, ®_value);
- if (err != 0 || reg_value == 0) {
+ if ((err != 0) || (reg_value == 0)) {
sdk_err(hwdev->dev_hdl, "Wrong req ba value: 0x%x\n",
reg_value);
return -EINVAL;
@@ -1245,7 +1296,7 @@ static int hinic5_check_clp_init_status(struct hinic5_hwdev *hwdev)
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_RSP_HOST,
HINIC5_CLP_BA_HOST, ®_value);
- if (err != 0 || reg_value == 0) {
+ if ((err != 0) || (reg_value == 0)) {
sdk_err(hwdev->dev_hdl, "Wrong rsp ba value: 0x%x\n",
reg_value);
return -EINVAL;
@@ -1253,14 +1304,14 @@ static int hinic5_check_clp_init_status(struct hinic5_hwdev *hwdev)
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
HINIC5_CLP_SIZE_HOST, ®_value);
- if (err != 0 || reg_value == 0) {
+ if ((err != 0) || (reg_value == 0)) {
sdk_err(hwdev->dev_hdl, "Wrong req size\n");
return -EINVAL;
}
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_RSP_HOST,
HINIC5_CLP_SIZE_HOST, ®_value);
- if (err != 0 || reg_value == 0) {
+ if ((err != 0) || (reg_value == 0)) {
sdk_err(hwdev->dev_hdl, "Wrong rsp size\n");
return -EINVAL;
}
@@ -1293,16 +1344,14 @@ static void hinic5_write_clp_reg(struct hinic5_hwdev *hwdev,
break;
case HINIC5_CLP_START_REQ_HOST:
- reg_value = reg_value &
- (~(HINIC5_CLP_MASK(START) <<
- HINIC5_CLP_OFFSET(START)));
+ reg_value = reg_value & (~(HINIC5_CLP_MASK(START)
+ << HINIC5_CLP_OFFSET(START)));
reg_value = reg_value | (value << HINIC5_CLP_OFFSET(START));
break;
case HINIC5_CLP_READY_RSP_HOST:
- reg_value = reg_value &
- (~(HINIC5_CLP_MASK(READY) <<
- HINIC5_CLP_OFFSET(READY)));
+ reg_value = reg_value & (~(HINIC5_CLP_MASK(READY)
+ << HINIC5_CLP_OFFSET(READY)));
reg_value = reg_value | (value << HINIC5_CLP_OFFSET(READY));
break;
@@ -1313,8 +1362,8 @@ static void hinic5_write_clp_reg(struct hinic5_hwdev *hwdev,
hinic5_hwif_write_reg(hwdev->hwif, reg_addr, reg_value);
}
-static int hinic5_read_clp_data(struct hinic5_hwdev *hwdev,
- void *buf_out, u16 *out_size)
+static int hinic5_read_clp_data(struct hinic5_hwdev *hwdev, void *buf_out,
+ u16 *out_size)
{
int err;
u32 reg = HINIC5_CLP_DATA(RSP);
@@ -1333,7 +1382,7 @@ static int hinic5_read_clp_data(struct hinic5_hwdev *hwdev,
delay_cnt++;
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_RSP_HOST,
HINIC5_CLP_READY_RSP_HOST, &ready);
- if (err != 0 || delay_cnt > HINIC5_CLP_DELAY_CNT_MAX) {
+ if ((err != 0) || delay_cnt > HINIC5_CLP_DELAY_CNT_MAX) {
sdk_err(hwdev->dev_hdl, "Timeout with delay_cnt: %u\n",
delay_cnt);
return -EINVAL;
@@ -1345,7 +1394,8 @@ static int hinic5_read_clp_data(struct hinic5_hwdev *hwdev,
if (err != 0)
return err;
- if (temp_out_size > HINIC5_CLP_SRAM_SIZE_REG_MAX || temp_out_size == 0) {
+ if (temp_out_size > HINIC5_CLP_SRAM_SIZE_REG_MAX ||
+ (temp_out_size == 0)) {
sdk_err(hwdev->dev_hdl, "Invalid temp_out_size: %u\n",
temp_out_size);
return -EINVAL;
@@ -1367,8 +1417,8 @@ static int hinic5_read_clp_data(struct hinic5_hwdev *hwdev,
return 0;
}
-static int hinic5_write_clp_data(struct hinic5_hwdev *hwdev,
- void *buf_in, u16 in_size)
+static int hinic5_write_clp_data(struct hinic5_hwdev *hwdev, void *buf_in,
+ u16 in_size)
{
int err;
u32 reg = HINIC5_CLP_DATA(REQ);
@@ -1387,14 +1437,12 @@ static int hinic5_write_clp_data(struct hinic5_hwdev *hwdev,
delay_cnt++;
err = hinic5_read_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
HINIC5_CLP_START_REQ_HOST, &start);
- if (err != 0 || delay_cnt > HINIC5_CLP_DELAY_CNT_MAX)
+ if ((err != 0) || delay_cnt > HINIC5_CLP_DELAY_CNT_MAX)
return -EINVAL;
}
- hinic5_write_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
- HINIC5_CLP_LEN_HOST, size_in);
- hinic5_write_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
- HINIC5_CLP_START_REQ_HOST, (u32)0x1);
+ hinic5_write_clp_reg(hwdev, HINIC5_CLP_REQ_HOST, HINIC5_CLP_LEN_HOST,
+ size_in);
for (; size_in > 0; size_in--) {
hinic5_hwif_write_reg(hwdev->hwif, reg, *ptr);
@@ -1402,14 +1450,17 @@ static int hinic5_write_clp_data(struct hinic5_hwdev *hwdev,
reg = reg + sizeof(u32);
}
+ hinic5_write_clp_reg(hwdev, HINIC5_CLP_REQ_HOST,
+ HINIC5_CLP_START_REQ_HOST, (u32)0x1);
+
return 0;
}
static void hinic5_clear_clp_data(struct hinic5_hwdev *hwdev,
enum clp_data_type data_type)
{
- u32 reg = (data_type == HINIC5_CLP_REQ_HOST) ?
- HINIC5_CLP_DATA(REQ) : HINIC5_CLP_DATA(RSP);
+ u32 reg = (data_type == HINIC5_CLP_REQ_HOST) ? HINIC5_CLP_DATA(REQ) :
+ HINIC5_CLP_DATA(RSP);
u32 count = HINIC5_CLP_INPUT_BUF_LEN_HOST / HINIC5_CLP_DATA_UNIT_HOST;
for (; count > 0; count--) {
@@ -1426,9 +1477,11 @@ static int clp_to_mgmt_response(void *hwdev, void *buf_out, const u16 *out_size)
u16 real_size = 0;
int ret;
- clp_msg_buf = ((struct hinic5_hwdev *)hwdev)->clp_pf_to_mgmt->clp_msg_buf;
+ clp_msg_buf =
+ ((struct hinic5_hwdev *)hwdev)->clp_pf_to_mgmt->clp_msg_buf;
- memset(clp_msg_buf, 0x0, HINIC5_CLP_INPUT_BUF_LEN_HOST);
+ (void)memset_s(clp_msg_buf, HINIC5_CLP_INPUT_BUF_LEN_HOST, 0x0,
+ HINIC5_CLP_INPUT_BUF_LEN_HOST);
ret = hinic5_read_clp_data(hwdev, clp_msg_buf, &real_size);
hinic5_clear_clp_data(dev, HINIC5_CLP_RSP_HOST);
if (ret != 0) {
@@ -1437,17 +1490,20 @@ static int clp_to_mgmt_response(void *hwdev, void *buf_out, const u16 *out_size)
}
real_size = (u16)((real_size * HINIC5_CLP_DATA_UNIT_HOST) & 0xffff);
- if (real_size <= sizeof(header) || real_size > HINIC5_CLP_INPUT_BUF_LEN_HOST) {
+ if (real_size <= sizeof(header) ||
+ real_size > HINIC5_CLP_INPUT_BUF_LEN_HOST) {
sdk_err(dev->dev_hdl, "Invalid response size: %u", real_size);
return -EINVAL;
}
real_size = real_size - sizeof(header);
if (real_size != *out_size) {
- sdk_err(dev->dev_hdl, "Invalid real_size:%u, out_size: %u\n", real_size, *out_size);
+ sdk_err(dev->dev_hdl, "Invalid real_size:%u, out_size: %u\n",
+ real_size, *out_size);
return -EINVAL;
}
- memcpy(buf_out, (clp_msg_buf + sizeof(header)), real_size);
+ (void)memcpy_s(buf_out, *out_size, (clp_msg_buf + sizeof(header)),
+ real_size);
return 0;
}
@@ -1472,10 +1528,13 @@ int hinic5_pf_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in,
/* 4 bytes alignment */
real_size = in_size + (u16)sizeof(header) +
- (((in_size % HINIC5_CLP_DATA_UNIT_HOST) != 0) ? HINIC5_CLP_DATA_UNIT_HOST : 0);
+ (((in_size % HINIC5_CLP_DATA_UNIT_HOST) != 0) ?
+ HINIC5_CLP_DATA_UNIT_HOST :
+ 0);
real_size = real_size / HINIC5_CLP_DATA_UNIT_HOST;
- if (real_size > (HINIC5_CLP_INPUT_BUF_LEN_HOST / HINIC5_CLP_DATA_UNIT_HOST)) {
+ if (real_size >
+ (HINIC5_CLP_INPUT_BUF_LEN_HOST / HINIC5_CLP_DATA_UNIT_HOST)) {
sdk_err(dev->dev_hdl, "Invalid real_size: %u\n", real_size);
return -EINVAL;
}
@@ -1488,19 +1547,31 @@ int hinic5_pf_clp_to_mgmt(void *hwdev, u8 mod, u16 cmd, const void *buf_in,
}
hinic5_clear_clp_data(dev, HINIC5_CLP_RSP_HOST);
- hinic5_write_clp_reg(dev, HINIC5_CLP_RSP_HOST, HINIC5_CLP_READY_RSP_HOST, 0x0);
+ hinic5_write_clp_reg(dev, HINIC5_CLP_RSP_HOST,
+ HINIC5_CLP_READY_RSP_HOST, 0x0);
/* Send request */
- memset(clp_msg_buf, 0x0, HINIC5_CLP_INPUT_BUF_LEN_HOST);
+ (void)memset_s(clp_msg_buf, HINIC5_CLP_INPUT_BUF_LEN_HOST, 0x0,
+ HINIC5_CLP_INPUT_BUF_LEN_HOST);
clp_prepare_header(dev, &header, in_size, mod, cmd);
- memcpy(clp_msg_buf, &header, sizeof(header));
+ if (memcpy_s(clp_msg_buf, HINIC5_CLP_INPUT_BUF_LEN_HOST, &header,
+ sizeof(header)) != 0) {
+ err = -ENOMEM;
+ goto unlock_clp_msg;
+ }
clp_msg_buf += sizeof(header);
- memcpy(clp_msg_buf, buf_in, in_size);
+ if (memcpy_s(clp_msg_buf,
+ (HINIC5_CLP_INPUT_BUF_LEN_HOST - sizeof(header)), buf_in,
+ in_size) != 0) {
+ err = -ENOMEM;
+ goto unlock_clp_msg;
+ }
hinic5_clear_clp_data(dev, HINIC5_CLP_REQ_HOST);
- if (hinic5_write_clp_data(hwdev, clp_pf_to_mgmt->clp_msg_buf, real_size) != 0) {
+ if (hinic5_write_clp_data(hwdev, clp_pf_to_mgmt->clp_msg_buf,
+ real_size) != 0) {
sdk_err(dev->dev_hdl, "Send clp request failed\n");
err = -EINVAL;
goto unlock_clp_msg;
@@ -1550,8 +1621,8 @@ int hinic5_clp_pf_to_mgmt_init(struct hinic5_hwdev *hwdev)
if (!clp_pf_to_mgmt)
return -ENOMEM;
- clp_pf_to_mgmt->clp_msg_buf = kzalloc(HINIC5_CLP_INPUT_BUF_LEN_HOST,
- GFP_KERNEL);
+ clp_pf_to_mgmt->clp_msg_buf =
+ kzalloc(HINIC5_CLP_INPUT_BUF_LEN_HOST, GFP_KERNEL);
if (!clp_pf_to_mgmt->clp_msg_buf) {
kfree(clp_pf_to_mgmt);
return -ENOMEM;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sm_lt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sm_lt.h
index 1ac7c8165..f53ce9df0 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sm_lt.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sm_lt.h
@@ -1,49 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sm_lt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef CHIPIF_SM_LT_H
#define CHIPIF_SM_LT_H
#include <linux/types.h>
-#define SM_LT_LOAD (0x12)
-#define SM_LT_STORE (0x14)
+#define SM_LT_LOAD (0x12)
+#define SM_LT_STORE (0x14)
-#define SM_LT_NUM_OFFSET 13
-#define SM_LT_ABUF_FLG_OFFSET 12
-#define SM_LT_BC_OFFSET 11
+#define SM_LT_NUM_OFFSET 13
+#define SM_LT_ABUF_FLG_OFFSET 12
+#define SM_LT_BC_OFFSET 11
-#define SM_LT_ENTRY_16B 16
-#define SM_LT_ENTRY_32B 32
-#define SM_LT_ENTRY_48B 48
-#define SM_LT_ENTRY_64B 64
+#define SM_LT_ENTRY_16B 16
+#define SM_LT_ENTRY_32B 32
+#define SM_LT_ENTRY_48B 48
+#define SM_LT_ENTRY_64B 64
-#define TBL_LT_OFFSET_DEFAULT 0
+#define TBL_LT_OFFSET_DEFAULT 0
-#define SM_CACHE_LINE_SHFT 4 /* log2(16) */
-#define SM_CACHE_LINE_SIZE 16 /* the size of cache line */
+#define SM_CACHE_LINE_SHFT 4 /* log2(16) */
+#define SM_CACHE_LINE_SIZE 16 /* the size of cache line */
-#define MAX_SM_LT_READ_LINE_NUM 4
-#define MAX_SM_LT_WRITE_LINE_NUM 3
+#define MAX_SM_LT_READ_LINE_NUM 4
+#define MAX_SM_LT_WRITE_LINE_NUM 3
-#define SM_LT_FULL_BYTEENB 0xFFFF
+#define SM_LT_FULL_BYTEENB 0xFFFF
-#define TBL_GET_ENB3_MASK(bitmask) ((u16)(((bitmask) >> 32) & 0xFFFF))
-#define TBL_GET_ENB2_MASK(bitmask) ((u16)(((bitmask) >> 16) & 0xFFFF))
-#define TBL_GET_ENB1_MASK(bitmask) ((u16)((bitmask) & 0xFFFF))
+#define TBL_GET_ENB3_MASK(bitmask) ((u16)(((bitmask) >> 32) & 0xFFFF))
+#define TBL_GET_ENB2_MASK(bitmask) ((u16)(((bitmask) >> 16) & 0xFFFF))
+#define TBL_GET_ENB1_MASK(bitmask) ((u16)((bitmask)&0xFFFF))
enum {
- SM_LT_NUM_0 = 0, /* lt num = 0, load/store 16B */
- SM_LT_NUM_1, /* lt num = 1, load/store 32B */
- SM_LT_NUM_2, /* lt num = 2, load/store 48B */
- SM_LT_NUM_3 /* lt num = 3, load 64B */
+ SM_LT_NUM_0 = 0, /* lt num = 0, load/store 16B */
+ SM_LT_NUM_1, /* lt num = 1, load/store 32B */
+ SM_LT_NUM_2, /* lt num = 2, load/store 48B */
+ SM_LT_NUM_3 /* lt num = 3, load 64B */
};
/* lt load request */
@@ -76,7 +69,7 @@ struct sml_lt_store_req {
union sml_lt_req_head head;
u32 index;
u32 byte_enb[2];
- u8 write_data[48];
+ u8 write_data[48];
};
enum {
@@ -164,4 +157,3 @@ struct hinic_csr_request_api_data {
u32 csr_write_data_l;
};
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sml_lt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sml_lt.c
index f1f5deef4..8b0eb7517 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sml_lt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_sml_lt.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sml_lt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include <linux/types.h>
#include <linux/errno.h>
@@ -30,15 +23,12 @@
#define LT_STORE16_API_SIZE (32 + 4)
#ifndef HTONL
-#define HTONL(x) \
- ((((x) & 0x000000ff) << 24) \
- | (((x) & 0x0000ff00) << 8) \
- | (((x) & 0x00ff0000) >> 8) \
- | (((x) & 0xff000000) >> 24))
+#define HTONL(x) \
+ ((((x)&0x000000ff) << 24) | (((x)&0x0000ff00) << 8) | \
+ (((x)&0x00ff0000) >> 8) | (((x)&0xff000000) >> 24))
#endif
-static inline void sm_lt_build_head(union sml_lt_req_head *head,
- u8 instance_id,
+static inline void sm_lt_build_head(union sml_lt_req_head *head, u8 instance_id,
u8 op_id, u8 ack)
{
head->value = 0;
@@ -53,8 +43,7 @@ static inline void sm_lt_build_head(union sml_lt_req_head *head,
}
static inline void sm_lt_load_build_req(struct sml_lt_load_req *req,
- u8 instance_id,
- u8 op_id, u8 ack,
+ u8 instance_id, u8 op_id, u8 ack,
u32 lt_index)
{
sm_lt_build_head(&req->head, instance_id, op_id, ack);
@@ -68,29 +57,29 @@ static inline void sm_lt_load_build_req(struct sml_lt_load_req *req,
static void sml_lt_store_data(u32 *dst, const u32 *src, u8 num)
{
u32 sm_lt_idx;
-
- if (num > SM_LT_NUM_2)
+ if (num > SM_LT_NUM_2) {
return;
+ }
for (sm_lt_idx = 0; sm_lt_idx <= num; sm_lt_idx++) {
// 16Byte each
u32 offset = sm_lt_idx * SM_LT_OFFSET_4;
- *(dst + SM_LT_OFFSET_3 + offset) = *(src + SM_LT_OFFSET_3 + offset);
- *(dst + SM_LT_OFFSET_2 + offset) = *(src + SM_LT_OFFSET_2 + offset);
- *(dst + SM_LT_OFFSET_1 + offset) = *(src + SM_LT_OFFSET_1 + offset);
+ *(dst + SM_LT_OFFSET_3 + offset) =
+ *(src + SM_LT_OFFSET_3 + offset);
+ *(dst + SM_LT_OFFSET_2 + offset) =
+ *(src + SM_LT_OFFSET_2 + offset);
+ *(dst + SM_LT_OFFSET_1 + offset) =
+ *(src + SM_LT_OFFSET_1 + offset);
*(dst + offset) = *(src + offset);
}
}
static inline void sm_lt_store_build_req(struct sml_lt_store_req *req,
- u8 instance_id,
- u8 op_id, u8 ack,
- u32 lt_index,
- u16 byte_enb1,
- u8 *data)
+ u8 instance_id, u8 op_id, u8 ack,
+ u32 lt_index, u16 byte_enb1, u8 *data)
{
sm_lt_build_head(&req->head, instance_id, op_id, ack);
- req->index = lt_index;
- req->index = HTONL(req->index);
+ req->index = lt_index;
+ req->index = HTONL(req->index);
req->extra = 0;
req->byte_enb[0] = 0;
req->byte_enb[0] = HTONL(req->byte_enb[0]);
@@ -98,8 +87,8 @@ static inline void sm_lt_store_build_req(struct sml_lt_store_req *req,
sml_lt_store_data((u32 *)req->write_data, (u32 *)(void *)data, 0);
}
-int hinic5_dbg_lt_rd_16byte(void *hwdev, u8 dest, u8 instance,
- u32 lt_index, u8 *data)
+int hinic5_dbg_lt_rd_16byte(void *hwdev, u8 dest, u8 instance, u32 lt_index,
+ u8 *data)
{
struct sml_lt_load_req req;
int ret;
@@ -147,4 +136,3 @@ int hinic5_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
return 0;
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_wq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_wq.c
index 66d12f8e2..332d11813 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_wq.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/hwif/hinic5_wq.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_wq.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -23,9 +16,9 @@
#include "hinic5_hwdev.h"
#include "hinic5_wq.h"
-#define WQ_MIN_DEPTH 64
-#define WQ_MAX_DEPTH 65536
-#define WQ_MAX_NUM_PAGES (PAGE_SIZE / sizeof(u64))
+#define WQ_MIN_DEPTH 64
+#define WQ_MAX_DEPTH 65536
+#define WQ_MAX_NUM_PAGES (PAGE_SIZE / sizeof(u64))
static int wq_init_wq_block(struct hinic5_wq *wq)
{
@@ -44,9 +37,8 @@ static int wq_init_wq_block(struct hinic5_wq *wq)
return -EFAULT;
}
- wq->wq_block_vaddr = dma_zalloc_coherent(wq->dev_hdl, PAGE_SIZE,
- &wq->wq_block_paddr,
- GFP_KERNEL);
+ wq->wq_block_vaddr = dma_zalloc_coherent(
+ wq->dev_hdl, PAGE_SIZE, &wq->wq_block_paddr, GFP_KERNEL);
if (!wq->wq_block_vaddr) {
sdk_err(wq->dev_hdl, "Failed to alloc wq block\n");
return -ENOMEM;
@@ -64,17 +56,17 @@ static int wq_alloc_pages(struct hinic5_wq *wq)
int i, page_idx, err;
u32 wqe_page_size_align = ALIGN(wq->wq_page_size, PAGE_SIZE);
- wq->wq_pages = kcalloc(wq->num_wq_pages, sizeof(*wq->wq_pages),
- GFP_KERNEL);
- if (!wq->wq_pages)
+ wq->wq_pages =
+ kcalloc(wq->num_wq_pages, sizeof(*wq->wq_pages), GFP_KERNEL);
+ if (!wq->wq_pages) {
+ sdk_err(wq->dev_hdl, "Failed to alloc wq pages handle\n");
return -ENOMEM;
+ }
for (page_idx = 0; page_idx < wq->num_wq_pages; page_idx++) {
- err = hinic5_dma_zalloc_coherent_align(wq->dev_hdl,
- wqe_page_size_align,
- wqe_page_size_align,
- GFP_KERNEL,
- &wq->wq_pages[page_idx]);
+ err = hinic5_dma_zalloc_coherent_align(
+ wq->dev_hdl, wqe_page_size_align, wqe_page_size_align,
+ GFP_KERNEL, &wq->wq_pages[page_idx]);
if (err != 0) {
sdk_err(wq->dev_hdl, "Failed to alloc wq page\n");
goto free_wq_pages;
@@ -122,17 +114,20 @@ int hinic5_wq_create(void *hwdev, struct hinic5_wq *wq, u32 q_depth,
pr_err("Invalid wq or dev_hdl\n");
return -EINVAL;
}
- wq_page_size = dev->wq_page_size; // make sure HINIC5_HW_WQ_PAGE_SIZE align
+ wq_page_size =
+ dev->wq_page_size; // make sure HINIC5_HW_WQ_PAGE_SIZE align
if (q_depth < WQ_MIN_DEPTH || q_depth > WQ_MAX_DEPTH ||
- ((q_depth & (q_depth - 1)) != 0) || wqebb_size == 0 ||
+ ((q_depth & (q_depth - 1)) != 0) || (wqebb_size == 0) ||
((wqebb_size & (wqebb_size - 1)) != 0)) {
- sdk_err(dev->dev_hdl, "Wq q_depth(%u) or wqebb_size(%u) is invalid\n",
+ sdk_err(dev->dev_hdl,
+ "Wq q_depth(%u) or wqebb_size(%u) is invalid\n",
q_depth, wqebb_size);
return -EINVAL;
}
- memset(wq, 0, sizeof(struct hinic5_wq));
+ (void)memset_s(wq, sizeof(struct hinic5_wq), 0,
+ sizeof(struct hinic5_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
@@ -146,8 +141,9 @@ int hinic5_wq_create(void *hwdev, struct hinic5_wq *wq, u32 q_depth,
wq->wqebbs_per_page = q_depth;
wq->wqebbs_per_page_shift = (u16)ilog2(wq->wqebbs_per_page);
wq->wqebbs_per_page_mask = (u16)(wq->wqebbs_per_page - 1);
- wq->num_wq_pages = (u16)(ALIGN(((u32)q_depth * wqebb_size),
- wq_page_size) / wq_page_size);
+ wq->num_wq_pages =
+ (u16)(ALIGN(((u32)q_depth * wqebb_size), wq_page_size) /
+ wq_page_size);
return wq_alloc_pages(wq);
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_api_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_api_cmd.h
index 4fbf1c9a3..e66da5ab6 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_api_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_api_cmd.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_api_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_API_CMD_H
#define HINIC5_API_CMD_H
@@ -14,161 +7,161 @@
#include <linux/semaphore.h>
#include "hinic5_eqs.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
/* api_cmd_cell.ctrl structure */
-#define HINIC5_API_CMD_CELL_CTRL_CELL_LEN_SHIFT 0
-#define HINIC5_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_SHIFT 16
-#define HINIC5_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_SHIFT 24
-#define HINIC5_API_CMD_CELL_CTRL_XOR_CHKSUM_SHIFT 56
+#define HINIC5_API_CMD_CELL_CTRL_CELL_LEN_SHIFT 0
+#define HINIC5_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_SHIFT 16
+#define HINIC5_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_SHIFT 24
+#define HINIC5_API_CMD_CELL_CTRL_XOR_CHKSUM_SHIFT 56
-#define HINIC5_API_CMD_CELL_CTRL_CELL_LEN_MASK 0x3FU
-#define HINIC5_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_MASK 0x3FU
-#define HINIC5_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_MASK 0x3FU
-#define HINIC5_API_CMD_CELL_CTRL_XOR_CHKSUM_MASK 0xFFU
+#define HINIC5_API_CMD_CELL_CTRL_CELL_LEN_MASK 0x3FU
+#define HINIC5_API_CMD_CELL_CTRL_RD_DMA_ATTR_OFF_MASK 0x3FU
+#define HINIC5_API_CMD_CELL_CTRL_WR_DMA_ATTR_OFF_MASK 0x3FU
+#define HINIC5_API_CMD_CELL_CTRL_XOR_CHKSUM_MASK 0xFFU
-#define HINIC5_API_CMD_CELL_CTRL_SET(val, member) \
- ((((u64)(val)) & HINIC5_API_CMD_CELL_CTRL_##member##_MASK) << \
- HINIC5_API_CMD_CELL_CTRL_##member##_SHIFT)
+#define HINIC5_API_CMD_CELL_CTRL_SET(val, member) \
+ ((((u64)(val)) & HINIC5_API_CMD_CELL_CTRL_##member##_MASK) \
+ << HINIC5_API_CMD_CELL_CTRL_##member##_SHIFT)
/* api_cmd_cell.desc structure */
-#define HINIC5_API_CMD_DESC_API_TYPE_SHIFT 0
-#define HINIC5_API_CMD_DESC_RD_WR_SHIFT 1
-#define HINIC5_API_CMD_DESC_MGMT_BYPASS_SHIFT 2
-#define HINIC5_API_CMD_DESC_RESP_AEQE_EN_SHIFT 3
-#define HINIC5_API_CMD_DESC_APICHN_RSVD_SHIFT 4
-#define HINIC5_API_CMD_DESC_APICHN_CODE_SHIFT 6
-#define HINIC5_API_CMD_DESC_PRIV_DATA_SHIFT 8
-#define HINIC5_API_CMD_DESC_DEST_SHIFT 32
-#define HINIC5_API_CMD_DESC_SIZE_SHIFT 40
-#define HINIC5_API_CMD_DESC_XOR_CHKSUM_SHIFT 56
-
-#define HINIC5_API_CMD_DESC_API_TYPE_MASK 0x1U
-#define HINIC5_API_CMD_DESC_RD_WR_MASK 0x1U
-#define HINIC5_API_CMD_DESC_MGMT_BYPASS_MASK 0x1U
-#define HINIC5_API_CMD_DESC_RESP_AEQE_EN_MASK 0x1U
-#define HINIC5_API_CMD_DESC_APICHN_RSVD_MASK 0x3U
-#define HINIC5_API_CMD_DESC_APICHN_CODE_MASK 0x3U
-#define HINIC5_API_CMD_DESC_PRIV_DATA_MASK 0xFFFFFFU
-#define HINIC5_API_CMD_DESC_DEST_MASK 0x1FU
-#define HINIC5_API_CMD_DESC_SIZE_MASK 0x7FFU
-#define HINIC5_API_CMD_DESC_XOR_CHKSUM_MASK 0xFFU
-
-#define HINIC5_API_CMD_DESC_SET(val, member) \
- ((((u64)(val)) & HINIC5_API_CMD_DESC_##member##_MASK) << \
- HINIC5_API_CMD_DESC_##member##_SHIFT)
+#define HINIC5_API_CMD_DESC_API_TYPE_SHIFT 0
+#define HINIC5_API_CMD_DESC_RD_WR_SHIFT 1
+#define HINIC5_API_CMD_DESC_MGMT_BYPASS_SHIFT 2
+#define HINIC5_API_CMD_DESC_RESP_AEQE_EN_SHIFT 3
+#define HINIC5_API_CMD_DESC_APICHN_RSVD_SHIFT 4
+#define HINIC5_API_CMD_DESC_APICHN_CODE_SHIFT 6
+#define HINIC5_API_CMD_DESC_PRIV_DATA_SHIFT 8
+#define HINIC5_API_CMD_DESC_DEST_SHIFT 32
+#define HINIC5_API_CMD_DESC_SIZE_SHIFT 40
+#define HINIC5_API_CMD_DESC_XOR_CHKSUM_SHIFT 56
+
+#define HINIC5_API_CMD_DESC_API_TYPE_MASK 0x1U
+#define HINIC5_API_CMD_DESC_RD_WR_MASK 0x1U
+#define HINIC5_API_CMD_DESC_MGMT_BYPASS_MASK 0x1U
+#define HINIC5_API_CMD_DESC_RESP_AEQE_EN_MASK 0x1U
+#define HINIC5_API_CMD_DESC_APICHN_RSVD_MASK 0x3U
+#define HINIC5_API_CMD_DESC_APICHN_CODE_MASK 0x3U
+#define HINIC5_API_CMD_DESC_PRIV_DATA_MASK 0xFFFFFFU
+#define HINIC5_API_CMD_DESC_DEST_MASK 0x1FU
+#define HINIC5_API_CMD_DESC_SIZE_MASK 0x7FFU
+#define HINIC5_API_CMD_DESC_XOR_CHKSUM_MASK 0xFFU
+
+#define HINIC5_API_CMD_DESC_SET(val, member) \
+ ((((u64)(val)) & HINIC5_API_CMD_DESC_##member##_MASK) \
+ << HINIC5_API_CMD_DESC_##member##_SHIFT)
/* api_cmd_status header */
-#define HINIC5_API_CMD_STATUS_HEADER_VALID_SHIFT 0
-#define HINIC5_API_CMD_STATUS_HEADER_CHAIN_ID_SHIFT 16
+#define HINIC5_API_CMD_STATUS_HEADER_VALID_SHIFT 0
+#define HINIC5_API_CMD_STATUS_HEADER_CHAIN_ID_SHIFT 16
-#define HINIC5_API_CMD_STATUS_HEADER_VALID_MASK 0xFFU
-#define HINIC5_API_CMD_STATUS_HEADER_CHAIN_ID_MASK 0xFFU
+#define HINIC5_API_CMD_STATUS_HEADER_VALID_MASK 0xFFU
+#define HINIC5_API_CMD_STATUS_HEADER_CHAIN_ID_MASK 0xFFU
-#define HINIC5_API_CMD_STATUS_HEADER_GET(val, member) \
- (((val) >> HINIC5_API_CMD_STATUS_HEADER_##member##_SHIFT) & \
- HINIC5_API_CMD_STATUS_HEADER_##member##_MASK)
+#define HINIC5_API_CMD_STATUS_HEADER_GET(val, member) \
+ (((val) >> HINIC5_API_CMD_STATUS_HEADER_##member##_SHIFT) & \
+ HINIC5_API_CMD_STATUS_HEADER_##member##_MASK)
/* API_CHAIN_REQ CSR: 0x0020+api_idx*0x080 */
-#define HINIC5_API_CMD_CHAIN_REQ_RESTART_SHIFT 1
-#define HINIC5_API_CMD_CHAIN_REQ_WB_TRIGGER_SHIFT 2
+#define HINIC5_API_CMD_CHAIN_REQ_RESTART_SHIFT 1
+#define HINIC5_API_CMD_CHAIN_REQ_WB_TRIGGER_SHIFT 2
-#define HINIC5_API_CMD_CHAIN_REQ_RESTART_MASK 0x1U
-#define HINIC5_API_CMD_CHAIN_REQ_WB_TRIGGER_MASK 0x1U
+#define HINIC5_API_CMD_CHAIN_REQ_RESTART_MASK 0x1U
+#define HINIC5_API_CMD_CHAIN_REQ_WB_TRIGGER_MASK 0x1U
-#define HINIC5_API_CMD_CHAIN_REQ_SET(val, member) \
- (((val) & HINIC5_API_CMD_CHAIN_REQ_##member##_MASK) << \
- HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT)
+#define HINIC5_API_CMD_CHAIN_REQ_SET(val, member) \
+ (((val)&HINIC5_API_CMD_CHAIN_REQ_##member##_MASK) \
+ << HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT)
-#define HINIC5_API_CMD_CHAIN_REQ_GET(val, member) \
- (((val) >> HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT) & \
- HINIC5_API_CMD_CHAIN_REQ_##member##_MASK)
+#define HINIC5_API_CMD_CHAIN_REQ_GET(val, member) \
+ (((val) >> HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT) & \
+ HINIC5_API_CMD_CHAIN_REQ_##member##_MASK)
-#define HINIC5_API_CMD_CHAIN_REQ_CLEAR(val, member) \
- ((val) & (~(HINIC5_API_CMD_CHAIN_REQ_##member##_MASK \
- << HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT)))
+#define HINIC5_API_CMD_CHAIN_REQ_CLEAR(val, member) \
+ ((val) & (~(HINIC5_API_CMD_CHAIN_REQ_##member##_MASK \
+ << HINIC5_API_CMD_CHAIN_REQ_##member##_SHIFT)))
/* API_CHAIN_CTL CSR: 0x0014+api_idx*0x080 */
-#define HINIC5_API_CMD_CHAIN_CTRL_RESTART_EN_SHIFT 1
-#define HINIC5_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT 2
-#define HINIC5_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT 4
-#define HINIC5_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT 8
-#define HINIC5_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT 28
-#define HINIC5_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT 30
-
-#define HINIC5_API_CMD_CHAIN_CTRL_RESTART_EN_MASK 0x1U
-#define HINIC5_API_CMD_CHAIN_CTRL_XOR_ERR_MASK 0x1U
-#define HINIC5_API_CMD_CHAIN_CTRL_AEQE_EN_MASK 0x1U
-#define HINIC5_API_CMD_CHAIN_CTRL_AEQ_ID_MASK 0x3U
-#define HINIC5_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK 0x3U
-#define HINIC5_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK 0x3U
-
-#define HINIC5_API_CMD_CHAIN_CTRL_SET(val, member) \
- (((val) & HINIC5_API_CMD_CHAIN_CTRL_##member##_MASK) << \
- HINIC5_API_CMD_CHAIN_CTRL_##member##_SHIFT)
-
-#define HINIC5_API_CMD_CHAIN_CTRL_CLEAR(val, member) \
- ((val) & (~(HINIC5_API_CMD_CHAIN_CTRL_##member##_MASK \
- << HINIC5_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
+#define HINIC5_API_CMD_CHAIN_CTRL_RESTART_EN_SHIFT 1
+#define HINIC5_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT 2
+#define HINIC5_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT 4
+#define HINIC5_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT 8
+#define HINIC5_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT 28
+#define HINIC5_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT 30
+
+#define HINIC5_API_CMD_CHAIN_CTRL_RESTART_EN_MASK 0x1U
+#define HINIC5_API_CMD_CHAIN_CTRL_XOR_ERR_MASK 0x1U
+#define HINIC5_API_CMD_CHAIN_CTRL_AEQE_EN_MASK 0x1U
+#define HINIC5_API_CMD_CHAIN_CTRL_AEQ_ID_MASK 0x3U
+#define HINIC5_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK 0x3U
+#define HINIC5_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK 0x3U
+
+#define HINIC5_API_CMD_CHAIN_CTRL_SET(val, member) \
+ (((val)&HINIC5_API_CMD_CHAIN_CTRL_##member##_MASK) \
+ << HINIC5_API_CMD_CHAIN_CTRL_##member##_SHIFT)
+
+#define HINIC5_API_CMD_CHAIN_CTRL_CLEAR(val, member) \
+ ((val) & (~(HINIC5_API_CMD_CHAIN_CTRL_##member##_MASK \
+ << HINIC5_API_CMD_CHAIN_CTRL_##member##_SHIFT)))
/* api_cmd rsp header */
-#define HINIC5_API_CMD_RESP_HEAD_VALID_SHIFT 0
-#define HINIC5_API_CMD_RESP_HEAD_STATUS_SHIFT 8
-#define HINIC5_API_CMD_RESP_HEAD_CHAIN_ID_SHIFT 16
-#define HINIC5_API_CMD_RESP_HEAD_RESP_LEN_SHIFT 24
-#define HINIC5_API_CMD_RESP_HEAD_DRIVER_PRIV_SHIFT 40
+#define HINIC5_API_CMD_RESP_HEAD_VALID_SHIFT 0
+#define HINIC5_API_CMD_RESP_HEAD_STATUS_SHIFT 8
+#define HINIC5_API_CMD_RESP_HEAD_CHAIN_ID_SHIFT 16
+#define HINIC5_API_CMD_RESP_HEAD_RESP_LEN_SHIFT 24
+#define HINIC5_API_CMD_RESP_HEAD_DRIVER_PRIV_SHIFT 40
-#define HINIC5_API_CMD_RESP_HEAD_VALID_MASK 0xFF
-#define HINIC5_API_CMD_RESP_HEAD_STATUS_MASK 0xFFU
-#define HINIC5_API_CMD_RESP_HEAD_CHAIN_ID_MASK 0xFFU
-#define HINIC5_API_CMD_RESP_HEAD_RESP_LEN_MASK 0x1FFU
-#define HINIC5_API_CMD_RESP_HEAD_DRIVER_PRIV_MASK 0xFFFFFFU
+#define HINIC5_API_CMD_RESP_HEAD_VALID_MASK 0xFF
+#define HINIC5_API_CMD_RESP_HEAD_STATUS_MASK 0xFFU
+#define HINIC5_API_CMD_RESP_HEAD_CHAIN_ID_MASK 0xFFU
+#define HINIC5_API_CMD_RESP_HEAD_RESP_LEN_MASK 0x1FFU
+#define HINIC5_API_CMD_RESP_HEAD_DRIVER_PRIV_MASK 0xFFFFFFU
-#define HINIC5_API_CMD_RESP_HEAD_VALID_CODE 0xFF
+#define HINIC5_API_CMD_RESP_HEAD_VALID_CODE 0xFF
-#define HINIC5_API_CMD_RESP_HEADER_VALID(val) \
- (((val) & HINIC5_API_CMD_RESP_HEAD_VALID_MASK) == \
- HINIC5_API_CMD_RESP_HEAD_VALID_CODE)
+#define HINIC5_API_CMD_RESP_HEADER_VALID(val) \
+ (((val)&HINIC5_API_CMD_RESP_HEAD_VALID_MASK) == \
+ HINIC5_API_CMD_RESP_HEAD_VALID_CODE)
-#define HINIC5_API_CMD_RESP_HEAD_GET(val, member) \
- (((val) >> HINIC5_API_CMD_RESP_HEAD_##member##_SHIFT) & \
- HINIC5_API_CMD_RESP_HEAD_##member##_MASK)
+#define HINIC5_API_CMD_RESP_HEAD_GET(val, member) \
+ (((val) >> HINIC5_API_CMD_RESP_HEAD_##member##_SHIFT) & \
+ HINIC5_API_CMD_RESP_HEAD_##member##_MASK)
/* API_STATUS_0 CSR: 0x0030+api_idx*0x080 */
-#define HINIC5_API_CMD_STATUS_CONS_IDX_MASK 0xFFFFFFU
-#define HINIC5_API_CMD_STATUS_CONS_IDX_SHIFT 0
+#define HINIC5_API_CMD_STATUS_CONS_IDX_MASK 0xFFFFFFU
+#define HINIC5_API_CMD_STATUS_CONS_IDX_SHIFT 0
-#define HINIC5_API_CMD_STATUS_FSM_MASK 0xFU
-#define HINIC5_API_CMD_STATUS_FSM_SHIFT 24
+#define HINIC5_API_CMD_STATUS_FSM_MASK 0xFU
+#define HINIC5_API_CMD_STATUS_FSM_SHIFT 24
-#define HINIC5_API_CMD_STATUS_CHKSUM_ERR_MASK 0x3U
-#define HINIC5_API_CMD_STATUS_CHKSUM_ERR_SHIFT 28
+#define HINIC5_API_CMD_STATUS_CHKSUM_ERR_MASK 0x3U
+#define HINIC5_API_CMD_STATUS_CHKSUM_ERR_SHIFT 28
-#define HINIC5_API_CMD_STATUS_CPLD_ERR_MASK 0x1U
-#define HINIC5_API_CMD_STATUS_CPLD_ERR_SHIFT 30
+#define HINIC5_API_CMD_STATUS_CPLD_ERR_MASK 0x1U
+#define HINIC5_API_CMD_STATUS_CPLD_ERR_SHIFT 30
#define HINIC5_API_CMD_STATUS_CONS_IDX(val) \
- ((val) & HINIC5_API_CMD_STATUS_CONS_IDX_MASK)
+ ((val)&HINIC5_API_CMD_STATUS_CONS_IDX_MASK)
-#define HINIC5_API_CMD_STATUS_CHKSUM_ERR(val) \
- (((val) >> HINIC5_API_CMD_STATUS_CHKSUM_ERR_SHIFT) & \
- HINIC5_API_CMD_STATUS_CHKSUM_ERR_MASK)
+#define HINIC5_API_CMD_STATUS_CHKSUM_ERR(val) \
+ (((val) >> HINIC5_API_CMD_STATUS_CHKSUM_ERR_SHIFT) & \
+ HINIC5_API_CMD_STATUS_CHKSUM_ERR_MASK)
-#define HINIC5_API_CMD_STATUS_GET(val, member) \
- (((val) >> HINIC5_API_CMD_STATUS_##member##_SHIFT) & \
- HINIC5_API_CMD_STATUS_##member##_MASK)
+#define HINIC5_API_CMD_STATUS_GET(val, member) \
+ (((val) >> HINIC5_API_CMD_STATUS_##member##_SHIFT) & \
+ HINIC5_API_CMD_STATUS_##member##_MASK)
enum hinic5_api_cmd_chain_type {
/* write to mgmt cpu command with completion */
- HINIC5_API_CMD_WRITE_TO_MGMT_CPU = 2,
+ HINIC5_API_CMD_WRITE_TO_MGMT_CPU = 2,
/* multi read command with completion notification - not used */
- HINIC5_API_CMD_MULTI_READ = 3,
+ HINIC5_API_CMD_MULTI_READ = 3,
/* write command without completion notification */
- HINIC5_API_CMD_POLL_WRITE = 4,
+ HINIC5_API_CMD_POLL_WRITE = 4,
/* read command without completion notification */
- HINIC5_API_CMD_POLL_READ = 5,
+ HINIC5_API_CMD_POLL_READ = 5,
/* read from mgmt cpu command with completion */
- HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU = 6,
+ HINIC5_API_CMD_WRITE_ASYNC_TO_MGMT_CPU = 6,
HINIC5_API_CMD_MAX,
};
@@ -204,72 +197,72 @@ struct hinic5_api_cmd_cell {
};
struct hinic5_api_cmd_resp_fmt {
- u64 header;
- u64 resp_data;
+ u64 header;
+ u64 resp_data;
};
struct hinic5_api_cmd_cell_ctxt {
- struct hinic5_api_cmd_cell *cell_vaddr;
+ struct hinic5_api_cmd_cell *cell_vaddr;
- void *api_cmd_vaddr;
+ void *api_cmd_vaddr;
- struct hinic5_api_cmd_resp_fmt *resp;
+ struct hinic5_api_cmd_resp_fmt *resp;
- struct completion done;
- int status;
+ struct completion done;
+ int status;
- u32 saved_prod_idx;
- struct hinic5_hwdev *hwdev;
+ u32 saved_prod_idx;
+ struct hinic5_hwdev *hwdev;
};
struct hinic5_api_cmd_chain_attr {
- struct hinic5_hwdev *hwdev;
- enum hinic5_api_cmd_chain_type chain_type;
+ struct hinic5_hwdev *hwdev;
+ enum hinic5_api_cmd_chain_type chain_type;
- u32 num_cells;
- u16 rsp_size;
- u16 cell_size;
+ u32 num_cells;
+ u16 rsp_size;
+ u16 cell_size;
};
struct hinic5_api_cmd_chain {
- struct hinic5_hwdev *hwdev;
- enum hinic5_api_cmd_chain_type chain_type;
+ struct hinic5_hwdev *hwdev;
+ enum hinic5_api_cmd_chain_type chain_type;
- u32 num_cells;
- u16 cell_size;
- u16 rsp_size;
- u32 rsvd1;
+ u32 num_cells;
+ u16 cell_size;
+ u16 rsp_size;
+ u32 rsvd1;
/* HW members is 24 bit format */
- u32 prod_idx;
- u32 cons_idx;
+ u32 prod_idx;
+ u32 cons_idx;
- struct semaphore sem;
+ struct semaphore sem;
/* Async cmd can not be scheduling */
- spinlock_t async_lock;
+ spinlock_t async_lock;
- dma_addr_t wb_status_paddr;
- struct hinic5_api_cmd_status *wb_status;
+ dma_addr_t wb_status_paddr;
+ struct hinic5_api_cmd_status *wb_status;
- dma_addr_t head_cell_paddr;
- struct hinic5_api_cmd_cell *head_node;
+ dma_addr_t head_cell_paddr;
+ struct hinic5_api_cmd_cell *head_node;
- struct hinic5_api_cmd_cell_ctxt *cell_ctxt;
- struct hinic5_api_cmd_cell *curr_node;
+ struct hinic5_api_cmd_cell_ctxt *cell_ctxt;
+ struct hinic5_api_cmd_cell *curr_node;
- struct hinic5_dma_addr_align cells_addr;
+ struct hinic5_dma_addr_align cells_addr;
- u8 *cell_vaddr_base;
- u64 cell_paddr_base;
- u8 *rsp_vaddr_base;
- u64 rsp_paddr_base;
- u8 *buf_vaddr_base;
- u64 buf_paddr_base;
- u64 cell_size_align;
- u64 rsp_size_align;
- u64 buf_size_align;
+ u8 *cell_vaddr_base;
+ u64 cell_paddr_base;
+ u8 *rsp_vaddr_base;
+ u64 rsp_paddr_base;
+ u8 *buf_vaddr_base;
+ u64 buf_paddr_base;
+ u64 cell_size_align;
+ u64 rsp_size_align;
+ u64 buf_size_align;
- u64 rsvd2;
+ u64 rsvd2;
};
int hinic5_api_cmd_write(struct hinic5_api_cmd_chain *chain, u8 node_id,
@@ -281,6 +274,7 @@ int hinic5_api_cmd_read(struct hinic5_api_cmd_chain *chain, u8 node_id,
int hinic5_api_cmd_init(struct hinic5_hwdev *hwdev,
struct hinic5_api_cmd_chain **chain);
-void hinic5_api_cmd_free(const struct hinic5_hwdev *hwdev, struct hinic5_api_cmd_chain **chain);
+void hinic5_api_cmd_free(const struct hinic5_hwdev *hwdev,
+ struct hinic5_api_cmd_chain **chain);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq.h
index 94a8db28e..51df18e42 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cmdq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_CMDQ_H
#define HINIC5_CMDQ_H
@@ -23,16 +16,16 @@
#include "ossl_knl.h"
#include "hinic5_hwdev.h"
-#define HINIC5_SCMD_DATA_LEN 16
+#define HINIC5_SCMD_DATA_LEN 16
-#define HINIC5_CMDQ_DEPTH 4096
-#define HINIC5_CMDQ_MAX_BUF_SIZE 2048U
-#define HINIC5_CMDQ_MIN_BUF_SIZE 4U
-#define HINIC5_CMDQ_BUF_ALIGN 2048U
+#define HINIC5_CMDQ_DEPTH 4096
+#define HINIC5_CMDQ_MAX_BUF_SIZE 2048U
+#define HINIC5_CMDQ_MIN_BUF_SIZE 4U
+#define HINIC5_CMDQ_BUF_ALIGN 2048U
-#define HINIC5_CMDQ_CQE_DW0_ERR_CODE_SHIFT 29
-#define HINIC5_CMDQ_CQE_DW0_ERR_CODE_MASK 0x3
-#define HINIC5_CMDQ_CQE_DW0_ERR_STATUS_MASK 0x1fffffff /* 29 bits */
+#define HINIC5_CMDQ_CQE_DW0_ERR_CODE_SHIFT 29
+#define HINIC5_CMDQ_CQE_DW0_ERR_CODE_MASK 0x3
+#define HINIC5_CMDQ_CQE_DW0_ERR_STATUS_MASK 0x1fffffff /* 29 bits */
enum hinic5_cmdq_mode {
HINIC5_NORMAL_CMDQ,
@@ -59,85 +52,85 @@ enum hinic5_cmdq_db_type {
enum bufdesc_len {
BUFDESC_LCMD_LEN = 2,
BUFDESC_SCMD_LEN = 3,
- BUFDESC_ENHANCE_CMD_LEN = 3, /* 64B aligned */
+ BUFDESC_ENHANCE_CMD_LEN = 3, /* 64B aligned */
};
/* hardware define: cmdq wqe */
struct hinic5_cmdq_header {
- u32 header_info;
- u32 saved_data;
+ u32 header_info;
+ u32 saved_data;
};
struct hinic5_scmd_bufdesc {
- u32 buf_len;
- u32 rsvd;
- u8 data[HINIC5_SCMD_DATA_LEN];
+ u32 buf_len;
+ u32 rsvd;
+ u8 data[HINIC5_SCMD_DATA_LEN];
};
struct hinic5_lcmd_bufdesc {
- struct hinic5_sge sge;
- u32 rsvd1;
- u64 saved_async_buf;
- u64 rsvd3;
+ struct hinic5_sge sge;
+ u32 rsvd1;
+ u64 saved_async_buf;
+ u64 rsvd3;
};
struct hinic5_cmdq_db {
- u32 db_head;
- u32 db_info;
+ u32 db_head;
+ u32 db_info;
};
struct hinic5_status {
- u32 status_info;
+ u32 status_info;
};
struct hinic5_ctrl {
- u32 ctrl_info;
+ u32 ctrl_info;
};
struct hinic5_sge_resp {
struct hinic5_sge sge;
- u32 rsvd;
+ u32 rsvd;
};
struct hinic5_cmdq_completion {
union {
- struct hinic5_sge_resp sge_resp;
- u64 direct_resp;
+ struct hinic5_sge_resp sge_resp;
+ u64 direct_resp;
};
};
struct hinic5_cmdq_wqe_scmd {
- struct hinic5_cmdq_header header;
- u64 rsvd;
- struct hinic5_status status;
- struct hinic5_ctrl ctrl;
- struct hinic5_cmdq_completion completion;
- struct hinic5_scmd_bufdesc buf_desc;
+ struct hinic5_cmdq_header header;
+ u64 rsvd;
+ struct hinic5_status status;
+ struct hinic5_ctrl ctrl;
+ struct hinic5_cmdq_completion completion;
+ struct hinic5_scmd_bufdesc buf_desc;
};
struct hinic5_cmdq_wqe_lcmd {
- struct hinic5_cmdq_header header;
- struct hinic5_status status;
- struct hinic5_ctrl ctrl;
- struct hinic5_cmdq_completion completion;
- struct hinic5_lcmd_bufdesc buf_desc;
+ struct hinic5_cmdq_header header;
+ struct hinic5_status status;
+ struct hinic5_ctrl ctrl;
+ struct hinic5_cmdq_completion completion;
+ struct hinic5_lcmd_bufdesc buf_desc;
};
struct hinic5_cmdq_inline_wqe {
- struct hinic5_cmdq_wqe_scmd wqe_scmd;
+ struct hinic5_cmdq_wqe_scmd wqe_scmd;
};
struct hinic5_cmdq_wqe {
union {
- struct hinic5_cmdq_inline_wqe inline_wqe;
- struct hinic5_cmdq_wqe_lcmd wqe_lcmd;
- struct hinic5_enhanced_cmdq_wqe enhanced_cmdq_wqe;
+ struct hinic5_cmdq_inline_wqe inline_wqe;
+ struct hinic5_cmdq_wqe_lcmd wqe_lcmd;
+ struct hinic5_enhanced_cmdq_wqe enhanced_cmdq_wqe;
};
};
struct hinic5_cmdq_arm_bit {
- u32 q_type;
- u32 q_id;
+ u32 q_type;
+ u32 q_id;
};
enum hinic5_cmdq_status {
@@ -161,44 +154,44 @@ enum data_format {
DATA_DIRECT,
};
-#define WQ_BLOCK_PFN_SHIFT 9
-#define CMDQ_PFN_SHIFT 12
-#define CMDQ_PFN(addr) ((addr) >> CMDQ_PFN_SHIFT)
-#define WQ_BLOCK_PFN(addr) ((addr) >> WQ_BLOCK_PFN_SHIFT)
+#define WQ_BLOCK_PFN_SHIFT 9
+#define CMDQ_PFN_SHIFT 12
+#define CMDQ_PFN(addr) ((addr) >> CMDQ_PFN_SHIFT)
+#define WQ_BLOCK_PFN(addr) ((addr) >> WQ_BLOCK_PFN_SHIFT)
struct hinic5_cmdq_cmd_info {
- enum hinic5_cmdq_cmd_type cmd_type;
- u16 channel;
- u16 rsvd1;
- u16 wqebb_use_num;
-
- struct completion *done;
- int *errcode;
- int *cmpt_code;
- u64 *direct_resp;
- u64 cmdq_msg_id;
-
- struct hinic5_cmd_buf *buf_in;
- struct hinic5_cmd_buf *buf_out;
+ enum hinic5_cmdq_cmd_type cmd_type;
+ u16 channel;
+ u16 rsvd1;
+ u16 wqebb_use_num;
+
+ struct completion *done;
+ int *errcode;
+ int *cmpt_code;
+ u64 *direct_resp;
+ u64 cmdq_msg_id;
+
+ struct hinic5_cmd_buf *buf_in;
+ struct hinic5_cmd_buf *buf_out;
};
struct hinic5_cmdq {
- struct hinic5_wq wq;
+ struct hinic5_wq wq;
- enum hinic5_cmdq_type cmdq_type;
- int wrapped;
+ enum hinic5_cmdq_type cmdq_type;
+ int wrapped;
/* spinlock for send cmdq commands */
- spinlock_t cmdq_lock;
+ spinlock_t cmdq_lock;
- struct cmdq_ctxt_info cmdq_ctxt;
- struct enhance_cmdq_ctxt_info cmdq_enhance_ctxt;
+ struct cmdq_ctxt_info cmdq_ctxt;
+ struct enhance_cmdq_ctxt_info cmdq_enhance_ctxt;
- struct hinic5_cmdq_cmd_info *cmd_infos;
+ struct hinic5_cmdq_cmd_info *cmd_infos;
- struct hinic5_hwdev *hwdev;
- struct hinic5_cmdqs *cmdqs;
- u64 rsvd1[2];
+ struct hinic5_hwdev *hwdev;
+ struct hinic5_cmdqs *cmdqs;
+ u64 rsvd1[2];
};
struct hinic5_cmdqs {
@@ -248,12 +241,14 @@ void hinic5_cmdq_enable_channel_lock(struct hinic5_hwdev *hwdev, bool enable);
void hinic5_cmdq_flush_sync_cmd(struct hinic5_hwdev *hwdev);
-void hinic5_enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe,
+void enhanced_cmdq_set_wqe(struct hinic5_cmdq_wqe *wqe,
enum hinic5_cmdq_cmd_type cmd_type,
const struct hinic5_cmdq_cmd_param *cmd_buf,
int wrapped);
-void hinic5_enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs, struct hinic5_cmdq *cmdq);
-void hinic5_cmdqs_param_init(struct hinic5_hwdev *hwdev, struct hinic5_cmdqs *cmdqs);
+void enhanced_cmdq_init_queue_ctxt(struct hinic5_cmdqs *cmdqs,
+ struct hinic5_cmdq *cmdq);
+void hinic5_cmdqs_param_init(struct hinic5_hwdev *hwdev,
+ struct hinic5_cmdqs *cmdqs);
int hinic5_send_fast_msg_need_resp(void *hwdev, u8 mod, u8 cmd,
struct hinic5_cmd_buf *buf_in,
u64 *out_param);
@@ -261,4 +256,3 @@ int hinic5_cos_id_direct_resp(void *hwdev, u8 mod, u8 cmd, u16 cos_id,
struct hinic5_cmd_buf *buf_in, u64 *out_param,
u32 timeout, u16 channel);
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq_enhance.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq_enhance.h
index f1dff9895..5b84854e4 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq_enhance.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_cmdq_enhance.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cmdq_enhance.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_ENHANCED_CMDQ_H
#define HINIC5_ENHANCED_CMDQ_H
@@ -21,122 +14,122 @@ enum complete_format {
SGE_RESPONSE = 1,
};
-#define HINIC5_CMDQ_MAX_INLINE_DATA_SIZE 160U
-#define HINIC5_CMDQ_WQE_INLINE_DATA_PI_OFFSET 2
+#define HINIC5_CMDQ_MAX_INLINE_DATA_SIZE 160U
+#define HINIC5_CMDQ_WQE_INLINE_DATA_PI_OFFSET 2
/* first part 16B */
-#define ENHANCED_CMDQ_CTXT0_CI_WQE_ADDR_SHIFT 0
-#define ENHANCED_CMDQ_CTXT0_RSV1_SHIFT 52
-#define ENHANCED_CMDQ_CTXT0_EQ_SHIFT 53
-#define ENHANCED_CMDQ_CTXT0_CEQ_ARM_SHIFT 61
-#define ENHANCED_CMDQ_CTXT0_CEQ_EN_SHIFT 62
-#define ENHANCED_CMDQ_CTXT0_HW_BUSY_BIT_SHIFT 63
-
-#define ENHANCED_CMDQ_CTXT0_CI_WQE_ADDR_MASK 0xFFFFFFFFFFFFFU
-#define ENHANCED_CMDQ_CTXT0_RSV1_MASK 0x1U
-#define ENHANCED_CMDQ_CTXT0_EQ_MASK 0xFFU
-#define ENHANCED_CMDQ_CTXT0_CEQ_ARM_MASK 0x1U
-#define ENHANCED_CMDQ_CTXT0_CEQ_EN_MASK 0x1U
-#define ENHANCED_CMDQ_CTXT0_HW_BUSY_BIT_MASK 0x1U
-
-#define ENHANCED_CMDQ_CTXT1_Q_DIS_SHIFT 0
-#define ENHANCED_CMDQ_CTXT1_ERR_CODE_SHIFT 1
-#define ENHANCED_CMDQ_CTXT1_RSV1_SHIFT 3
-#define ENHANCED_CMDQ_CTXT1_PI_SHIFT 32
-#define ENHANCED_CMDQ_CTXT1_CI_SHIFT 48
-
-#define ENHANCED_CMDQ_CTXT1_Q_DIS_MASK 0x1U
-#define ENHANCED_CMDQ_CTXT1_ERR_CODE_MASK 0x3U
-#define ENHANCED_CMDQ_CTXT1_RSV1_MASK 0x1FFFFFFFU
-#define ENHANCED_CMDQ_CTXT1_PI_MASK 0xFFFFU
-#define ENHANCED_CMDQ_CTXT1_CI_MASK 0xFFFFU
+#define ENHANCED_CMDQ_CTXT0_CI_WQE_ADDR_SHIFT 0
+#define ENHANCED_CMDQ_CTXT0_RSV1_SHIFT 52
+#define ENHANCED_CMDQ_CTXT0_EQ_SHIFT 53
+#define ENHANCED_CMDQ_CTXT0_CEQ_ARM_SHIFT 61
+#define ENHANCED_CMDQ_CTXT0_CEQ_EN_SHIFT 62
+#define ENHANCED_CMDQ_CTXT0_HW_BUSY_BIT_SHIFT 63
+
+#define ENHANCED_CMDQ_CTXT0_CI_WQE_ADDR_MASK 0xFFFFFFFFFFFFFU
+#define ENHANCED_CMDQ_CTXT0_RSV1_MASK 0x1U
+#define ENHANCED_CMDQ_CTXT0_EQ_MASK 0xFFU
+#define ENHANCED_CMDQ_CTXT0_CEQ_ARM_MASK 0x1U
+#define ENHANCED_CMDQ_CTXT0_CEQ_EN_MASK 0x1U
+#define ENHANCED_CMDQ_CTXT0_HW_BUSY_BIT_MASK 0x1U
+
+#define ENHANCED_CMDQ_CTXT1_Q_DIS_SHIFT 0
+#define ENHANCED_CMDQ_CTXT1_ERR_CODE_SHIFT 1
+#define ENHANCED_CMDQ_CTXT1_RSV1_SHIFT 3
+#define ENHANCED_CMDQ_CTXT1_PI_SHIFT 32
+#define ENHANCED_CMDQ_CTXT1_CI_SHIFT 48
+
+#define ENHANCED_CMDQ_CTXT1_Q_DIS_MASK 0x1U
+#define ENHANCED_CMDQ_CTXT1_ERR_CODE_MASK 0x3U
+#define ENHANCED_CMDQ_CTXT1_RSV1_MASK 0x1FFFFFFFU
+#define ENHANCED_CMDQ_CTXT1_PI_MASK 0xFFFFU
+#define ENHANCED_CMDQ_CTXT1_CI_MASK 0xFFFFU
/* second PART 16B */
-#define ENHANCED_CMDQ_CTXT2_PFT_CI_SHIFT 0
-#define ENHANCED_CMDQ_CTXT2_O_BIT_SHIFT 4
-#define ENHANCED_CMDQ_CTXT2_PFT_THD_SHIFT 32
-#define ENHANCED_CMDQ_CTXT2_PFT_MAX_SHIFT 46
-#define ENHANCED_CMDQ_CTXT2_PFT_MIN_SHIFT 57
+#define ENHANCED_CMDQ_CTXT2_PFT_CI_SHIFT 0
+#define ENHANCED_CMDQ_CTXT2_O_BIT_SHIFT 4
+#define ENHANCED_CMDQ_CTXT2_PFT_THD_SHIFT 32
+#define ENHANCED_CMDQ_CTXT2_PFT_MAX_SHIFT 46
+#define ENHANCED_CMDQ_CTXT2_PFT_MIN_SHIFT 57
-#define ENHANCED_CMDQ_CTXT2_PFT_CI_MASK 0xFU
-#define ENHANCED_CMDQ_CTXT2_O_BIT_MASK 0x1U
-#define ENHANCED_CMDQ_CTXT2_PFT_THD_MASK 0x3FFFFU
-#define ENHANCED_CMDQ_CTXT2_PFT_MAX_MASK 0x7FFFU
-#define ENHANCED_CMDQ_CTXT2_PFT_MIN_MASK 0x7FU
+#define ENHANCED_CMDQ_CTXT2_PFT_CI_MASK 0xFU
+#define ENHANCED_CMDQ_CTXT2_O_BIT_MASK 0x1U
+#define ENHANCED_CMDQ_CTXT2_PFT_THD_MASK 0x3FFFFU
+#define ENHANCED_CMDQ_CTXT2_PFT_MAX_MASK 0x7FFFU
+#define ENHANCED_CMDQ_CTXT2_PFT_MIN_MASK 0x7FU
-#define ENHANCED_CMDQ_CTXT3_PFT_CI_ADDR_SHIFT 0
-#define ENHANCED_CMDQ_CTXT3_PFT_CI_SHIFT 52
+#define ENHANCED_CMDQ_CTXT3_PFT_CI_ADDR_SHIFT 0
+#define ENHANCED_CMDQ_CTXT3_PFT_CI_SHIFT 52
-#define ENHANCED_CMDQ_CTXT3_PFT_CI_ADDR_MASK 0xFFFFFFFFFFFFFU
-#define ENHANCED_CMDQ_CTXT3_PFT_CI_MASK 0xFFFFU
+#define ENHANCED_CMDQ_CTXT3_PFT_CI_ADDR_MASK 0xFFFFFFFFFFFFFU
+#define ENHANCED_CMDQ_CTXT3_PFT_CI_MASK 0xFFFFU
/* THIRD PART 16B */
-#define ENHANCED_CMDQ_CTXT4_CI_CLA_ADDR_SHIFT 0
-
-#define ENHANCED_CMDQ_CTXT4_CI_CLA_ADDR_MASK 0x7FFFFFFFFFFFFFU
-
-#define ENHANCED_CMDQ_SET(val, member) \
- (((u64)(val) & ENHANCED_CMDQ_##member##_MASK) << \
- ENHANCED_CMDQ_##member##_SHIFT)
-
-#define WQ_PREFETCH_MAX 4
-#define WQ_PREFETCH_MIN 1
-#define WQ_PREFETCH_THRESHOLD 256
-
-#define CI_IDX_HIGH_SHIFH 12
-#define CI_HIGN_IDX(val) ((val) >> CI_IDX_HIGH_SHIFH)
-
-#define ENHANCE_CMDQ_WQE_HEADER_SEND_SGE_LEN_SHIFT 0
-#define ENHANCE_CMDQ_WQE_HEADER_BDSL_SHIFT 19
-#define ENHANCE_CMDQ_WQE_HEADER_DF_SHIFT 28
-#define ENHANCE_CMDQ_WQE_HEADER_DN_SHIFT 29
-#define ENHANCE_CMDQ_WQE_HEADER_EC_SHIFT 30
-#define ENHANCE_CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31
-
-#define ENHANCE_CMDQ_WQE_HEADER_SEND_SGE_LEN_MASK 0x3FFFFU
-#define ENHANCE_CMDQ_WQE_HEADER_BDSL_MASK 0xFFU
-#define ENHANCE_CMDQ_WQE_HEADER_DF_MASK 0x1U
-#define ENHANCE_CMDQ_WQE_HEADER_DN_MASK 0x1U
-#define ENHANCE_CMDQ_WQE_HEADER_EC_MASK 0x1U
-#define ENHANCE_CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U
-
-#define ENHANCE_CMDQ_WQE_HEADER_SET(val, member) \
- ((((u32)(val)) & ENHANCE_CMDQ_WQE_HEADER_##member##_MASK) << \
- ENHANCE_CMDQ_WQE_HEADER_##member##_SHIFT)
-
-#define ENHANCE_CMDQ_WQE_HEADER_GET(val, member) \
- (((val) >> ENHANCE_CMDQ_WQE_HEADER_##member##_SHIFT) & \
- ENHANCE_CMDQ_WQE_HEADER_##member##_MASK)
-
-#define ENHANCE_CMDQ_WQE_CS_ERR_CODE_SHIFT 0
-#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_SHIFT 21 /* dw0 shift */
-#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_17_0_SHIFT 14 /* dw3 shift */
-#define ENHANCE_CMDQ_WQE_CS_CMD_SHIFT 4
-#define ENHANCE_CMDQ_WQE_CS_ACK_TYPE_SHIFT 12
-#define ENHANCE_CMDQ_WQE_CS_HW_BUSY_SHIFT 14
-#define ENHANCE_CMDQ_WQE_CS_RN_SHIFT 15
-#define ENHANCE_CMDQ_WQE_CS_MOD_SHIFT 16
-#define ENHANCE_CMDQ_WQE_CS_CF_SHIFT 31
-
-#define ENHANCE_CMDQ_WQE_CS_ERR_CODE_MASK 0xFU
-#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_MASK 0xFFFU /* dw0 mask */
-#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_17_0_MASK 0x3FFFFU /* dw3 mask */
-#define ENHANCE_CMDQ_WQE_CS_CMD_MASK 0xFFU
-#define ENHANCE_CMDQ_WQE_CS_ACK_TYPE_MASK 0x3U
-#define ENHANCE_CMDQ_WQE_CS_HW_BUSY_MASK 0x1U
-#define ENHANCE_CMDQ_WQE_CS_RN_MASK 0x1U
-#define ENHANCE_CMDQ_WQE_CS_MOD_MASK 0x1FU
-#define ENHANCE_CMDQ_WQE_CS_CF_MASK 0x1U
-
-#define ENHANCE_CMDQ_WQE_CS_SET(val, member) \
- ((((u32)(val)) & ENHANCE_CMDQ_WQE_CS_##member##_MASK) << \
- ENHANCE_CMDQ_WQE_CS_##member##_SHIFT)
-
-#define ENHANCE_CMDQ_WQE_CS_GET(val, member) \
- (((val) >> ENHANCE_CMDQ_WQE_CS_##member##_SHIFT) & \
- ENHANCE_CMDQ_WQE_CS_##member##_MASK)
-
-#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_OFFSET 18
+#define ENHANCED_CMDQ_CTXT4_CI_CLA_ADDR_SHIFT 0
+
+#define ENHANCED_CMDQ_CTXT4_CI_CLA_ADDR_MASK 0x7FFFFFFFFFFFFFU
+
+#define ENHANCED_CMDQ_SET(val, member) \
+ (((u64)(val)&ENHANCED_CMDQ_##member##_MASK) \
+ << ENHANCED_CMDQ_##member##_SHIFT)
+
+#define WQ_PREFETCH_MAX 4
+#define WQ_PREFETCH_MIN 1
+#define WQ_PREFETCH_THRESHOLD 256
+
+#define CI_IDX_HIGH_SHIFH 12
+#define CI_HIGN_IDX(val) ((val) >> CI_IDX_HIGH_SHIFH)
+
+#define ENHANCE_CMDQ_WQE_HEADER_SEND_SGE_LEN_SHIFT 0
+#define ENHANCE_CMDQ_WQE_HEADER_BDSL_SHIFT 19
+#define ENHANCE_CMDQ_WQE_HEADER_DF_SHIFT 28
+#define ENHANCE_CMDQ_WQE_HEADER_DN_SHIFT 29
+#define ENHANCE_CMDQ_WQE_HEADER_EC_SHIFT 30
+#define ENHANCE_CMDQ_WQE_HEADER_HW_BUSY_BIT_SHIFT 31
+
+#define ENHANCE_CMDQ_WQE_HEADER_SEND_SGE_LEN_MASK 0x3FFFFU
+#define ENHANCE_CMDQ_WQE_HEADER_BDSL_MASK 0xFFU
+#define ENHANCE_CMDQ_WQE_HEADER_DF_MASK 0x1U
+#define ENHANCE_CMDQ_WQE_HEADER_DN_MASK 0x1U
+#define ENHANCE_CMDQ_WQE_HEADER_EC_MASK 0x1U
+#define ENHANCE_CMDQ_WQE_HEADER_HW_BUSY_BIT_MASK 0x1U
+
+#define ENHANCE_CMDQ_WQE_HEADER_SET(val, member) \
+ ((((u32)(val)) & ENHANCE_CMDQ_WQE_HEADER_##member##_MASK) \
+ << ENHANCE_CMDQ_WQE_HEADER_##member##_SHIFT)
+
+#define ENHANCE_CMDQ_WQE_HEADER_GET(val, member) \
+ (((val) >> ENHANCE_CMDQ_WQE_HEADER_##member##_SHIFT) & \
+ ENHANCE_CMDQ_WQE_HEADER_##member##_MASK)
+
+#define ENHANCE_CMDQ_WQE_CS_ERR_CODE_SHIFT 0
+#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_SHIFT 21 /* dw0 shift */
+#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_17_0_SHIFT 14 /* dw3 shift */
+#define ENHANCE_CMDQ_WQE_CS_CMD_SHIFT 4
+#define ENHANCE_CMDQ_WQE_CS_ACK_TYPE_SHIFT 12
+#define ENHANCE_CMDQ_WQE_CS_HW_BUSY_SHIFT 14
+#define ENHANCE_CMDQ_WQE_CS_RN_SHIFT 15
+#define ENHANCE_CMDQ_WQE_CS_MOD_SHIFT 16
+#define ENHANCE_CMDQ_WQE_CS_CF_SHIFT 31
+
+#define ENHANCE_CMDQ_WQE_CS_ERR_CODE_MASK 0xFU
+#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_MASK 0xFFFU /* dw0 mask */
+#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_17_0_MASK 0x3FFFFU /* dw3 mask */
+#define ENHANCE_CMDQ_WQE_CS_CMD_MASK 0xFFU
+#define ENHANCE_CMDQ_WQE_CS_ACK_TYPE_MASK 0x3U
+#define ENHANCE_CMDQ_WQE_CS_HW_BUSY_MASK 0x1U
+#define ENHANCE_CMDQ_WQE_CS_RN_MASK 0x1U
+#define ENHANCE_CMDQ_WQE_CS_MOD_MASK 0x1FU
+#define ENHANCE_CMDQ_WQE_CS_CF_MASK 0x1U
+
+#define ENHANCE_CMDQ_WQE_CS_SET(val, member) \
+ ((((u32)(val)) & ENHANCE_CMDQ_WQE_CS_##member##_MASK) \
+ << ENHANCE_CMDQ_WQE_CS_##member##_SHIFT)
+
+#define ENHANCE_CMDQ_WQE_CS_GET(val, member) \
+ (((val) >> ENHANCE_CMDQ_WQE_CS_##member##_SHIFT) & \
+ ENHANCE_CMDQ_WQE_CS_##member##_MASK)
+
+#define ENHANCE_CMDQ_WQE_CS_ERR_STATUS_28_18_OFFSET 18
union hinic5_cmdq_enhance_completion {
struct {
@@ -162,7 +155,7 @@ struct sge_send_info {
u32 rsvd;
};
-#define NORMAL_WQE_TYPE 0
+#define NORMAL_WQE_TYPE 0
#define COMPACT_WQE_TYPE 1
struct hinic5_ctrl_section {
u32 header;
@@ -179,10 +172,10 @@ struct hinic5_enhanced_cmd_bufdesc {
};
struct hinic5_enhanced_cmdq_wqe {
- struct hinic5_ctrl_section ctrl_sec; /* 16B */
- union hinic5_cmdq_enhance_completion completion; /* 16B */
+ struct hinic5_ctrl_section ctrl_sec; /* 16B */
+ union hinic5_cmdq_enhance_completion completion; /* 16B */
union {
- struct hinic5_enhanced_cmd_bufdesc buf_desc[2]; /* 32B */
+ struct hinic5_enhanced_cmd_bufdesc buf_desc[2]; /* 32B */
u8 inline_data[HINIC5_CMDQ_MAX_INLINE_DATA_SIZE]; /* 160B max */
};
};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_csr_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_csr_inner.h
index d84fc074c..6be9cb2e8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_csr_inner.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_csr_inner.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_csr_inner.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_CSR_INNER_H
#define HINIC5_CSR_INNER_H
@@ -17,191 +10,186 @@
* 10: bar2
* 11: bar3
*/
-#define HINIC5_CFG_REGS_FLAG 0x40000000
+#define HINIC5_CFG_REGS_FLAG 0x40000000
-#define HINIC5_MGMT_REGS_FLAG 0xC0000000
+#define HINIC5_MGMT_REGS_FLAG 0xC0000000
-#define HINIC5_REGS_FLAG_MASK 0x3FFFFFFF
+#define HINIC5_REGS_FLAG_MASK 0x3FFFFFFF
-#define HINIC5_VF_CFG_REG_OFFSET 0x2000
+#define HINIC5_VF_CFG_REG_OFFSET 0x2000
-#define HINIC5_MISC_INTC_BAR 0x18000
+#define HINIC5_MISC_INTC_BAR 0x18000
-#define HINIC5_HOST_CSR_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x6000)
-#define HINIC5_CSR_GLOBAL_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x6400)
+#define HINIC5_HOST_CSR_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x6000)
+#define HINIC5_CSR_GLOBAL_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x6400)
/* HW interface registers */
-#define HINIC5_CSR_FUNC_ATTR0_ADDR (HINIC5_CFG_REGS_FLAG + 0x0)
-#define HINIC5_CSR_FUNC_ATTR1_ADDR (HINIC5_CFG_REGS_FLAG + 0x4)
-#define HINIC5_CSR_FUNC_ATTR2_ADDR (HINIC5_CFG_REGS_FLAG + 0x8)
-#define HINIC5_CSR_FUNC_ATTR3_ADDR (HINIC5_CFG_REGS_FLAG + 0xC)
-#define HINIC5_CSR_FUNC_ATTR4_ADDR (HINIC5_CFG_REGS_FLAG + 0x10)
-#define HINIC5_CSR_FUNC_ATTR5_ADDR (HINIC5_CFG_REGS_FLAG + 0x14)
-#define HINIC5_CSR_FUNC_ATTR6_ADDR (HINIC5_CFG_REGS_FLAG + 0x18)
-#define HINIC5_CSR_FUNC_TASK1_ADDR (HINIC5_CFG_REGS_FLAG + 0x24)
-
-#define HINIC5_CSR_INTC_BAR_SW_HANDSHAKE_0_CSR0_REG (HINIC5_MISC_INTC_BAR + 0x44)
-
-#define HINIC5_FUNC_CSR_MAILBOX_DATA_OFF 0x80
-#define HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF \
- (HINIC5_CFG_REGS_FLAG + 0x0100)
-#define HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF \
- (HINIC5_CFG_REGS_FLAG + 0x0104)
-#define HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF \
- (HINIC5_CFG_REGS_FLAG + 0x0108)
-#define HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF \
- (HINIC5_CFG_REGS_FLAG + 0x010C)
+#define HINIC5_CSR_FUNC_ATTR0_ADDR (HINIC5_CFG_REGS_FLAG + 0x0)
+#define HINIC5_CSR_FUNC_ATTR1_ADDR (HINIC5_CFG_REGS_FLAG + 0x4)
+#define HINIC5_CSR_FUNC_ATTR2_ADDR (HINIC5_CFG_REGS_FLAG + 0x8)
+#define HINIC5_CSR_FUNC_ATTR3_ADDR (HINIC5_CFG_REGS_FLAG + 0xC)
+#define HINIC5_CSR_FUNC_ATTR4_ADDR (HINIC5_CFG_REGS_FLAG + 0x10)
+#define HINIC5_CSR_FUNC_ATTR5_ADDR (HINIC5_CFG_REGS_FLAG + 0x14)
+#define HINIC5_CSR_FUNC_ATTR6_ADDR (HINIC5_CFG_REGS_FLAG + 0x18)
+#define HINIC5_CSR_FUNC_TASK1_ADDR (HINIC5_CFG_REGS_FLAG + 0x24)
+
+#define HINIC5_CSR_INTC_BAR_SW_HANDSHAKE_0_CSR0_REG \
+ (HINIC5_MISC_INTC_BAR + 0x44)
+
+#define HINIC5_FUNC_CSR_MAILBOX_DATA_OFF 0x80
+#define HINIC5_FUNC_CSR_MAILBOX_CONTROL_OFF (HINIC5_CFG_REGS_FLAG + 0x0100)
+#define HINIC5_FUNC_CSR_MAILBOX_INT_OFFSET_OFF (HINIC5_CFG_REGS_FLAG + 0x0104)
+#define HINIC5_FUNC_CSR_MAILBOX_RESULT_H_OFF (HINIC5_CFG_REGS_FLAG + 0x0108)
+#define HINIC5_FUNC_CSR_MAILBOX_RESULT_L_OFF (HINIC5_CFG_REGS_FLAG + 0x010C)
/* CLP registers */
-#define HINIC5_BAR3_CLP_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x0000)
-
-#define HINIC5_UCPU_CLP_SIZE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x40)
-#define HINIC5_UCPU_CLP_REQBASE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x44)
-#define HINIC5_UCPU_CLP_RSPBASE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x48)
-#define HINIC5_UCPU_CLP_REQ_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x4c)
-#define HINIC5_UCPU_CLP_RSP_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x50)
-#define HINIC5_CLP_REG(member) (HINIC5_UCPU_CLP_##member##_REG)
-
-#define HINIC5_CLP_REQ_DATA HINIC5_BAR3_CLP_BASE_ADDR
-#define HINIC5_CLP_RSP_DATA (HINIC5_BAR3_CLP_BASE_ADDR + 0x1000)
-#define HINIC5_CLP_DATA(member) (HINIC5_CLP_##member##_DATA)
-
-#define HINIC5_PTP_TS_UPDT_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3AC)
-#define HINIC5_PTP_TS_INC_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B0)
-#define HINIC5_PTP_TS_CALIBRATION_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B4)
-#define HINIC5_PTP_TS_WR_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B8)
-#define HINIC5_PTP_TS_WR_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3BC)
-#define HINIC5_PTP_TS_WR_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C0)
-#define HINIC5_PTP_TS_RD_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C4)
-#define HINIC5_PTP_TS_RD_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C8)
-#define HINIC5_PTP_TS_RD_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3CC)
-#define HINIC5_PTP_TS_UP_EN_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3D0)
-#define HINIC5_PTP_TS_DSTR_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3D4)
-#define HINIC5_PTP_REG(member) (HINIC5_PTP_TS_##member##_REG)
-
-#define HINIC5_N_PTP_TS_WR_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E0)
-#define HINIC5_N_PTP_TS_WR_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E4)
-#define HINIC5_N_PTP_TS_WR_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E8)
-#define HINIC5_N_PTP_TS_RD_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3EC)
-#define HINIC5_N_PTP_TS_RD_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F0)
-#define HINIC5_N_PTP_TS_RD_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F4)
-#define HINIC5_N_PTP_TS_UP_EN_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F8)
-#define HINIC5_N_PTP_REG(member) (HINIC5_N_PTP_TS_##member##_REG)
-
-#define HINIC5_PPF_ELECTION_OFFSET 0x0
-#define HINIC5_MPF_ELECTION_OFFSET 0x20
-
-#define HINIC5_CSR_PPF_ELECTION_ADDR \
- (HINIC5_HOST_CSR_BASE_ADDR + HINIC5_PPF_ELECTION_OFFSET)
-
-#define HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR \
- (HINIC5_HOST_CSR_BASE_ADDR + HINIC5_MPF_ELECTION_OFFSET)
-
-#define HINIC5_CSR_FUNC_PPF_ELECT_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x60)
-#define HINIC5_CSR_FUNC_PPF_ELECT_PORT_STRIDE 0x4
-
-#define HINIC5_CSR_FUNC_PPF_ELECT(host_idx) \
- (HINIC5_CSR_FUNC_PPF_ELECT_BASE_ADDR + \
- (host_idx) * HINIC5_CSR_FUNC_PPF_ELECT_PORT_STRIDE)
-
-#define HINIC5_CSR_DMA_ATTR_TBL_ADDR (HINIC5_CFG_REGS_FLAG + 0x380)
-#define HINIC5_CSR_DMA_ATTR_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x390)
+#define HINIC5_BAR3_CLP_BASE_ADDR (HINIC5_MGMT_REGS_FLAG + 0x0000)
+
+#define HINIC5_UCPU_CLP_SIZE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x40)
+#define HINIC5_UCPU_CLP_REQBASE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x44)
+#define HINIC5_UCPU_CLP_RSPBASE_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x48)
+#define HINIC5_UCPU_CLP_REQ_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x4c)
+#define HINIC5_UCPU_CLP_RSP_REG (HINIC5_HOST_CSR_BASE_ADDR + 0x50)
+#define HINIC5_CLP_REG(member) (HINIC5_UCPU_CLP_##member##_REG)
+
+#define HINIC5_CLP_REQ_DATA HINIC5_BAR3_CLP_BASE_ADDR
+#define HINIC5_CLP_RSP_DATA (HINIC5_BAR3_CLP_BASE_ADDR + 0x1000)
+#define HINIC5_CLP_DATA(member) (HINIC5_CLP_##member##_DATA)
+
+#define HINIC5_PTP_TS_UPDT_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3AC)
+#define HINIC5_PTP_TS_INC_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B0)
+#define HINIC5_PTP_TS_CALIBRATION_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B4)
+#define HINIC5_PTP_TS_WR_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3B8)
+#define HINIC5_PTP_TS_WR_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3BC)
+#define HINIC5_PTP_TS_WR_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C0)
+#define HINIC5_PTP_TS_RD_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C4)
+#define HINIC5_PTP_TS_RD_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3C8)
+#define HINIC5_PTP_TS_RD_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3CC)
+#define HINIC5_PTP_TS_UP_EN_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3D0)
+#define HINIC5_PTP_TS_DSTR_CFG_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3D4)
+#define HINIC5_PTP_REG(member) (HINIC5_PTP_TS_##member##_REG)
+
+#define HINIC5_N_PTP_TS_WR_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E0)
+#define HINIC5_N_PTP_TS_WR_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E4)
+#define HINIC5_N_PTP_TS_WR_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3E8)
+#define HINIC5_N_PTP_TS_RD_DATA0_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3EC)
+#define HINIC5_N_PTP_TS_RD_DATA1_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F0)
+#define HINIC5_N_PTP_TS_RD_DATA2_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F4)
+#define HINIC5_N_PTP_TS_UP_EN_REG (HINIC5_CSR_GLOBAL_BASE_ADDR + 0x3F8)
+#define HINIC5_N_PTP_REG(member) (HINIC5_N_PTP_TS_##member##_REG)
+
+#define HINIC5_PPF_ELECTION_OFFSET 0x0
+#define HINIC5_MPF_ELECTION_OFFSET 0x20
+
+#define HINIC5_CSR_PPF_ELECTION_ADDR \
+ (HINIC5_HOST_CSR_BASE_ADDR + HINIC5_PPF_ELECTION_OFFSET)
+
+#define HINIC5_CSR_GLOBAL_MPF_ELECTION_ADDR \
+ (HINIC5_HOST_CSR_BASE_ADDR + HINIC5_MPF_ELECTION_OFFSET)
+
+#define HINIC5_CSR_FUNC_PPF_ELECT_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x60)
+#define HINIC5_CSR_FUNC_PPF_ELECT_PORT_STRIDE 0x4
+
+#define HINIC5_CSR_FUNC_PPF_ELECT(host_idx) \
+ (HINIC5_CSR_FUNC_PPF_ELECT_BASE_ADDR + \
+ (host_idx)*HINIC5_CSR_FUNC_PPF_ELECT_PORT_STRIDE)
+
+#define HINIC5_CSR_DMA_ATTR_TBL_ADDR (HINIC5_CFG_REGS_FLAG + 0x380)
+#define HINIC5_CSR_DMA_ATTR_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x390)
/* MSI-X registers */
-#define HINIC5_CSR_MSIX_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x310)
-#define HINIC5_CSR_MSIX_CTRL_ADDR (HINIC5_CFG_REGS_FLAG + 0x300)
-#define HINIC5_CSR_MSIX_CNT_ADDR (HINIC5_CFG_REGS_FLAG + 0x304)
-#define HINIC5_CSR_FUNC_MSI_CLR_WR_ADDR (HINIC5_CFG_REGS_FLAG + 0x58)
-
-#define HINIC5_MSI_CLR_INDIR_RESEND_TIMER_CLR_SHIFT 0
-#define HINIC5_MSI_CLR_INDIR_INT_MSK_SET_SHIFT 1
-#define HINIC5_MSI_CLR_INDIR_INT_MSK_CLR_SHIFT 2
-#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_SET_SHIFT 3
-#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_CLR_SHIFT 4
-#define HINIC5_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_SHIFT 22
-
-#define HINIC5_MSI_CLR_INDIR_RESEND_TIMER_CLR_MASK 0x1U
-#define HINIC5_MSI_CLR_INDIR_INT_MSK_SET_MASK 0x1U
-#define HINIC5_MSI_CLR_INDIR_INT_MSK_CLR_MASK 0x1U
-#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_SET_MASK 0x1U
-#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_CLR_MASK 0x1U
-#define HINIC5_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_MASK 0x3FFU
-
-#define HINIC5_MSI_CLR_INDIR_SET(val, member) \
- (((val) & HINIC5_MSI_CLR_INDIR_##member##_MASK) << \
- HINIC5_MSI_CLR_INDIR_##member##_SHIFT)
+#define HINIC5_CSR_MSIX_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x310)
+#define HINIC5_CSR_MSIX_CTRL_ADDR (HINIC5_CFG_REGS_FLAG + 0x300)
+#define HINIC5_CSR_MSIX_CNT_ADDR (HINIC5_CFG_REGS_FLAG + 0x304)
+#define HINIC5_CSR_FUNC_MSI_CLR_WR_ADDR (HINIC5_CFG_REGS_FLAG + 0x58)
+
+#define HINIC5_MSI_CLR_INDIR_RESEND_TIMER_CLR_SHIFT 0
+#define HINIC5_MSI_CLR_INDIR_INT_MSK_SET_SHIFT 1
+#define HINIC5_MSI_CLR_INDIR_INT_MSK_CLR_SHIFT 2
+#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_SET_SHIFT 3
+#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_CLR_SHIFT 4
+#define HINIC5_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_SHIFT 22
+
+#define HINIC5_MSI_CLR_INDIR_RESEND_TIMER_CLR_MASK 0x1U
+#define HINIC5_MSI_CLR_INDIR_INT_MSK_SET_MASK 0x1U
+#define HINIC5_MSI_CLR_INDIR_INT_MSK_CLR_MASK 0x1U
+#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_SET_MASK 0x1U
+#define HINIC5_MSI_CLR_INDIR_AUTO_MSK_CLR_MASK 0x1U
+#define HINIC5_MSI_CLR_INDIR_SIMPLE_INDIR_IDX_MASK 0x3FFU
+
+#define HINIC5_MSI_CLR_INDIR_SET(val, member) \
+ (((val)&HINIC5_MSI_CLR_INDIR_##member##_MASK) \
+ << HINIC5_MSI_CLR_INDIR_##member##_SHIFT)
/* EQ registers */
-#define HINIC5_AEQ_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x210)
-#define HINIC5_CEQ_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x290)
+#define HINIC5_AEQ_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x210)
+#define HINIC5_CEQ_INDIR_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x290)
-#define HINIC5_EQ_INDIR_IDX_ADDR(type) \
- ((type == HINIC5_AEQ) ? \
- HINIC5_AEQ_INDIR_IDX_ADDR : HINIC5_CEQ_INDIR_IDX_ADDR)
+#define HINIC5_EQ_INDIR_IDX_ADDR(type) \
+ ((type == HINIC5_AEQ) ? HINIC5_AEQ_INDIR_IDX_ADDR : \
+ HINIC5_CEQ_INDIR_IDX_ADDR)
-#define HINIC5_AEQ_MTT_OFF_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x240)
-#define HINIC5_CEQ_MTT_OFF_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x2C0)
+#define HINIC5_AEQ_MTT_OFF_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x240)
+#define HINIC5_CEQ_MTT_OFF_BASE_ADDR (HINIC5_CFG_REGS_FLAG + 0x2C0)
-#define HINIC5_CSR_EQ_PAGE_OFF_STRIDE 8
+#define HINIC5_CSR_EQ_PAGE_OFF_STRIDE 8
-#define HINIC5_AEQ_HI_PHYS_ADDR_REG(pg_num) \
- (HINIC5_AEQ_MTT_OFF_BASE_ADDR + \
- (pg_num) * HINIC5_CSR_EQ_PAGE_OFF_STRIDE)
+#define HINIC5_AEQ_HI_PHYS_ADDR_REG(pg_num) \
+ (HINIC5_AEQ_MTT_OFF_BASE_ADDR + (pg_num)*HINIC5_CSR_EQ_PAGE_OFF_STRIDE)
-#define HINIC5_AEQ_LO_PHYS_ADDR_REG(pg_num) \
- (HINIC5_AEQ_MTT_OFF_BASE_ADDR + \
- (pg_num) * HINIC5_CSR_EQ_PAGE_OFF_STRIDE + 4)
+#define HINIC5_AEQ_LO_PHYS_ADDR_REG(pg_num) \
+ (HINIC5_AEQ_MTT_OFF_BASE_ADDR + \
+ (pg_num)*HINIC5_CSR_EQ_PAGE_OFF_STRIDE + 4)
-#define HINIC5_CEQ_HI_PHYS_ADDR_REG(pg_num) \
- (HINIC5_CEQ_MTT_OFF_BASE_ADDR + \
- (pg_num) * HINIC5_CSR_EQ_PAGE_OFF_STRIDE)
+#define HINIC5_CEQ_HI_PHYS_ADDR_REG(pg_num) \
+ (HINIC5_CEQ_MTT_OFF_BASE_ADDR + (pg_num)*HINIC5_CSR_EQ_PAGE_OFF_STRIDE)
-#define HINIC5_CEQ_LO_PHYS_ADDR_REG(pg_num) \
- (HINIC5_CEQ_MTT_OFF_BASE_ADDR + \
- (pg_num) * HINIC5_CSR_EQ_PAGE_OFF_STRIDE + 4)
+#define HINIC5_CEQ_LO_PHYS_ADDR_REG(pg_num) \
+ (HINIC5_CEQ_MTT_OFF_BASE_ADDR + \
+ (pg_num)*HINIC5_CSR_EQ_PAGE_OFF_STRIDE + 4)
-#define HINIC5_CSR_AEQ_CTRL_0_ADDR (HINIC5_CFG_REGS_FLAG + 0x200)
-#define HINIC5_CSR_AEQ_CTRL_1_ADDR (HINIC5_CFG_REGS_FLAG + 0x204)
-#define HINIC5_CSR_AEQ_CONS_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x208)
-#define HINIC5_CSR_AEQ_PROD_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x20C)
-#define HINIC5_CSR_AEQ_CI_SIMPLE_INDIR_ADDR (HINIC5_CFG_REGS_FLAG + 0x50)
+#define HINIC5_CSR_AEQ_CTRL_0_ADDR (HINIC5_CFG_REGS_FLAG + 0x200)
+#define HINIC5_CSR_AEQ_CTRL_1_ADDR (HINIC5_CFG_REGS_FLAG + 0x204)
+#define HINIC5_CSR_AEQ_CONS_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x208)
+#define HINIC5_CSR_AEQ_PROD_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x20C)
+#define HINIC5_CSR_AEQ_CI_SIMPLE_INDIR_ADDR (HINIC5_CFG_REGS_FLAG + 0x50)
-#define HINIC5_CSR_CEQ_CTRL_0_ADDR (HINIC5_CFG_REGS_FLAG + 0x280)
-#define HINIC5_CSR_CEQ_CTRL_1_ADDR (HINIC5_CFG_REGS_FLAG + 0x284)
-#define HINIC5_CSR_CEQ_CONS_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x288)
-#define HINIC5_CSR_CEQ_PROD_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x28c)
-#define HINIC5_CSR_CEQ_CI_SIMPLE_INDIR_ADDR (HINIC5_CFG_REGS_FLAG + 0x54)
+#define HINIC5_CSR_CEQ_CTRL_0_ADDR (HINIC5_CFG_REGS_FLAG + 0x280)
+#define HINIC5_CSR_CEQ_CTRL_1_ADDR (HINIC5_CFG_REGS_FLAG + 0x284)
+#define HINIC5_CSR_CEQ_CONS_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x288)
+#define HINIC5_CSR_CEQ_PROD_IDX_ADDR (HINIC5_CFG_REGS_FLAG + 0x28c)
+#define HINIC5_CSR_CEQ_CI_SIMPLE_INDIR_ADDR (HINIC5_CFG_REGS_FLAG + 0x54)
/* API CMD registers */
-#define HINIC5_CSR_API_CMD_BASE (HINIC5_MGMT_REGS_FLAG + 0x2000)
+#define HINIC5_CSR_API_CMD_BASE (HINIC5_MGMT_REGS_FLAG + 0x2000)
-#define HINIC5_CSR_API_CMD_STRIDE 0x80
+#define HINIC5_CSR_API_CMD_STRIDE 0x80
-#define HINIC5_CSR_API_CMD_CHAIN_HEAD_HI_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x0 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_HEAD_HI_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x0 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_CHAIN_HEAD_LO_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x4 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_HEAD_LO_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x4 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_STATUS_HI_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x8 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_STATUS_HI_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x8 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_STATUS_LO_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0xC + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_STATUS_LO_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0xC + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x10 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x10 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_CHAIN_CTRL_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x14 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_CTRL_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x14 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_CHAIN_PI_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x1C + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_PI_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x1C + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x20 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_CHAIN_REQ_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x20 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
-#define HINIC5_CSR_API_CMD_STATUS_0_ADDR(idx) \
- (HINIC5_CSR_API_CMD_BASE + 0x30 + (idx) * HINIC5_CSR_API_CMD_STRIDE)
+#define HINIC5_CSR_API_CMD_STATUS_0_ADDR(idx) \
+ (HINIC5_CSR_API_CMD_BASE + 0x30 + (idx)*HINIC5_CSR_API_CMD_STRIDE)
/* self test register */
#define HINIC5_MGMT_HEALTH_STATUS_ADDR (HINIC5_MGMT_REGS_FLAG + 0x983c)
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_eqs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_eqs.h
index be5289c96..dbc7f6986 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_eqs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_eqs.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_eqs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_EQS_H
#define HINIC5_EQS_H
@@ -19,58 +12,51 @@
#include "hinic5_crm.h"
#include "hinic5_hw.h"
#include "hinic5_hwdev.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
-#define HINIC5_MAX_AEQS 4
-#define HINIC5_MAX_CEQS 32
+#define HINIC5_MAX_AEQS 4
+#define HINIC5_MAX_CEQS 32
-#define HINIC5_AEQ_MAX_PAGES 4
-#define HINIC5_CEQ_MAX_PAGES 8
+#define HINIC5_AEQE_SIZE 64
+#define HINIC5_CEQE_SIZE 4
-#define HINIC5_AEQE_SIZE 64
-#define HINIC5_CEQE_SIZE 4
+#define HINIC5_AEQE_DESC_SIZE 4
+#define HINIC5_AEQE_DATA_SIZE (HINIC5_AEQE_SIZE - HINIC5_AEQE_DESC_SIZE)
-#define HINIC5_AEQE_DESC_SIZE 4
-#define HINIC5_AEQE_DATA_SIZE \
- (HINIC5_AEQE_SIZE - HINIC5_AEQE_DESC_SIZE)
-
-#define HINIC5_AEQ_CPU_AFFINITY_MAX 16
+#define HINIC5_AEQ_CPU_AFFINITY_MAX 16
#if defined(__UEFI__)
-#define HINIC5_DEFAULT_AEQ_LEN 64
-#define HINIC5_DEFAULT_CEQ_LEN 1024
+#define HINIC5_DEFAULT_AEQ_LEN 64
+#define HINIC5_DEFAULT_CEQ_LEN 1024
#elif defined(__PANGEA_BINARY__)
-#define HINIC5_DEFAULT_AEQ_LEN 64
-#define HINIC5_DEFAULT_CEQ_LEN 8192
+#define HINIC5_DEFAULT_AEQ_LEN 64
+#define HINIC5_DEFAULT_CEQ_LEN 8192
#elif (!defined(__PANGEA_BINARY__) && defined(__HIFC__))
-#define HINIC5_DEFAULT_AEQ_LEN 4096
-#define HINIC5_DEFAULT_CEQ_LEN 8192
+#define HINIC5_DEFAULT_AEQ_LEN 4096
+#define HINIC5_DEFAULT_CEQ_LEN 8192
#else
-#define HINIC5_DEFAULT_AEQ_LEN 0x10000
-#define HINIC5_DEFAULT_CEQ_LEN 0x10000
+#define HINIC5_DEFAULT_AEQ_LEN 0x10000
+#define HINIC5_DEFAULT_CEQ_LEN 0x10000
#endif
-#define HINIC5_MIN_EQ_PAGE_SIZE 0x1000 /* min eq page size 4K Bytes */
-#define HINIC5_MAX_EQ_PAGE_SIZE 0x400000 /* max eq page size 4M Bytes */
+#define HINIC5_MIN_EQ_PAGE_SIZE 0x1000 /* min eq page size 4K Bytes */
+#define HINIC5_MAX_EQ_PAGE_SIZE 0x400000 /* max eq page size 4M Bytes */
-#define HINIC5_MIN_AEQ_LEN 64
-#define HINIC5_MAX_AEQ_LEN \
+#define HINIC5_MIN_AEQ_LEN 64
+#define HINIC5_MAX_AEQ_LEN \
((HINIC5_MAX_EQ_PAGE_SIZE / HINIC5_AEQE_SIZE) * HINIC5_AEQ_MAX_PAGES)
-#define HINIC5_MIN_CEQ_LEN 64
-#define HINIC5_MAX_CEQ_LEN \
+#define HINIC5_MIN_CEQ_LEN 64
+#define HINIC5_MAX_CEQ_LEN \
((HINIC5_MAX_EQ_PAGE_SIZE / HINIC5_CEQE_SIZE) * HINIC5_CEQ_MAX_PAGES)
-#define HINIC5_CEQ_ID_CMDQ 0
+#define HINIC5_CEQ_ID_CMDQ 0
-#define EQ_IRQ_NAME_LEN 64
+#define EQ_IRQ_NAME_LEN 64
-#define EQ_USLEEP_LOW_BOUND 900
-#define EQ_USLEEP_HIG_BOUND 1000
+#define EQ_USLEEP_LOW_BOUND 900
+#define EQ_USLEEP_HIG_BOUND 1000
-enum hinic5_eq_type {
- HINIC5_AEQ,
- HINIC5_CEQ
-};
+enum hinic5_eq_type { HINIC5_AEQ, HINIC5_CEQ };
enum hinic5_eq_intr_mode {
HINIC5_INTR_MODE_ARMED,
@@ -83,40 +69,40 @@ enum hinic5_eq_ci_arm_state {
};
struct hinic5_eq {
- struct hinic5_hwdev *hwdev;
- u16 q_id;
- u16 rsvd1;
- enum hinic5_eq_type type;
- u32 page_size;
- u32 orig_page_size;
- u32 eq_len;
+ struct hinic5_hwdev *hwdev;
+ u16 q_id;
+ u16 rsvd1;
+ enum hinic5_eq_type type;
+ u32 page_size;
+ u32 orig_page_size;
+ u32 eq_len;
- u32 cons_idx;
- u16 wrapped;
- u16 rsvd2;
+ u32 cons_idx;
+ u16 wrapped;
+ u16 rsvd2;
- u16 elem_size;
- u16 num_pages;
- u32 num_elem_in_pg;
+ u16 elem_size;
+ u16 num_pages;
+ u32 num_elem_in_pg;
- struct irq_info eq_irq;
- char irq_name[EQ_IRQ_NAME_LEN];
+ struct irq_info eq_irq;
+ char irq_name[EQ_IRQ_NAME_LEN];
- struct hinic5_dma_addr_align *eq_pages;
+ struct hinic5_dma_addr_align *eq_pages;
- struct work_struct aeq_work;
- struct tasklet_struct ceq_tasklet;
+ struct work_struct aeq_work;
+ struct tasklet_struct ceq_tasklet;
- u64 hard_intr_jif;
- u64 soft_intr_jif;
+ u64 hard_intr_jif;
+ u64 soft_intr_jif;
- int cpu;
- u64 rsvd3;
+ int cpu;
+ u64 rsvd3;
};
struct hinic5_aeq_elem {
- u8 aeqe_data[HINIC5_AEQE_DATA_SIZE];
- u32 desc;
+ u8 aeqe_data[HINIC5_AEQE_DATA_SIZE];
+ u32 desc;
};
enum hinic5_aeq_cb_state {
@@ -127,28 +113,28 @@ enum hinic5_aeq_cb_state {
};
struct hinic5_stateless_aeqs {
- hinic5_aeq_swe_cb stateless_aeq_swe_cb;
- void *stateless_aeq_swe_cb_data;
- ulong stateless_aeq_sw_cb_state;
+ hinic5_aeq_swe_cb stateless_aeq_swe_cb;
+ void *stateless_aeq_swe_cb_data;
+ ulong stateless_aeq_sw_cb_state;
};
struct hinic5_aeqs {
- struct hinic5_hwdev *hwdev;
+ struct hinic5_hwdev *hwdev;
- hinic5_aeq_hwe_cb aeq_hwe_cb[HINIC5_MAX_AEQ_EVENTS];
- void *aeq_hwe_cb_data[HINIC5_MAX_AEQ_EVENTS];
- hinic5_aeq_swe_cb aeq_swe_cb[HINIC5_MAX_AEQ_SW_EVENTS];
- void *aeq_swe_cb_data[HINIC5_MAX_AEQ_SW_EVENTS];
- ulong aeq_hw_cb_state[HINIC5_MAX_AEQ_EVENTS];
- ulong aeq_sw_cb_state[HINIC5_MAX_AEQ_SW_EVENTS];
+ hinic5_aeq_hwe_cb aeq_hwe_cb[HINIC5_MAX_AEQ_EVENTS];
+ void *aeq_hwe_cb_data[HINIC5_MAX_AEQ_EVENTS];
+ hinic5_aeq_swe_cb aeq_swe_cb[HINIC5_MAX_AEQ_SW_EVENTS];
+ void *aeq_swe_cb_data[HINIC5_MAX_AEQ_SW_EVENTS];
+ ulong aeq_hw_cb_state[HINIC5_MAX_AEQ_EVENTS];
+ ulong aeq_sw_cb_state[HINIC5_MAX_AEQ_SW_EVENTS];
- struct hinic5_eq aeq[HINIC5_MAX_AEQS];
- u16 num_aeqs;
- u16 rsvd1;
- u32 rsvd2;
+ struct hinic5_eq aeq[HINIC5_MAX_AEQS];
+ u16 num_aeqs;
+ u16 rsvd1;
+ u32 rsvd2;
- int aeq_cpu_affinity[HINIC5_AEQ_CPU_AFFINITY_MAX];
- unsigned int aeq_cpu_affinity_nargs;
+ int aeq_cpu_affinity[HINIC5_AEQ_CPU_AFFINITY_MAX];
+ unsigned int aeq_cpu_affinity_nargs;
struct workqueue_struct *workq;
};
@@ -159,17 +145,17 @@ enum hinic5_ceq_cb_state {
};
struct hinic5_ceqs {
- struct hinic5_hwdev *hwdev;
+ struct hinic5_hwdev *hwdev;
- hinic5_ceq_event_cb ceq_cb[HINIC5_MAX_CEQ_EVENTS];
- void *ceq_cb_data[HINIC5_MAX_CEQ_EVENTS];
- void *ceq_data[HINIC5_MAX_CEQ_EVENTS];
- ulong ceq_cb_state[HINIC5_MAX_CEQ_EVENTS];
+ hinic5_ceq_event_cb ceq_cb[HINIC5_MAX_CEQ_EVENTS];
+ void *ceq_cb_data[HINIC5_MAX_CEQ_EVENTS];
+ void *ceq_data[HINIC5_MAX_CEQ_EVENTS];
+ ulong ceq_cb_state[HINIC5_MAX_CEQ_EVENTS];
- struct hinic5_eq ceq[HINIC5_MAX_CEQS];
- u16 num_ceqs;
- u16 rsvd1;
- u32 rsvd2;
+ struct hinic5_eq ceq[HINIC5_MAX_CEQS];
+ u16 num_ceqs;
+ u16 rsvd1;
+ u32 rsvd2;
};
int hinic5_aeqs_init(struct hinic5_hwdev *hwdev, u16 num_aeqs,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hw_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hw_api.h
index 959c73373..defb418f7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hw_api.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hw_api.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_api.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_HW_API_H
#define HINIC5_HW_API_H
@@ -24,11 +17,11 @@
/* request head */
union chipif_sml_ctr_req_head {
struct {
- u32 pad : 15;
- u32 ack : 1;
- u32 op_id : 5;
- u32 instance : 6;
- u32 src : 5;
+ u32 pad : 15;
+ u32 ack : 1;
+ u32 op_id : 5;
+ u32 instance : 6;
+ u32 src : 5;
} bs;
u32 value;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwdev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwdev.h
index 04690ff5d..5c63b5a9e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwdev.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hwdev.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_HWDEV_H
#define HINIC5_HWDEV_H
@@ -17,7 +10,7 @@
#include "hinic5_profile.h"
#include "hinic5_common.h"
#include "hinic5_chip_info.h"
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
#ifndef __UEFI__
#include <linux/mutex.h>
@@ -29,7 +22,8 @@
#define sdk_err(dev, format, ...) dev_err(dev, "[COMM]" format, ##__VA_ARGS__)
#define sdk_warn(dev, format, ...) dev_warn(dev, "[COMM]" format, ##__VA_ARGS__)
-#define sdk_notice(dev, format, ...) dev_notice(dev, "[COMM]" format, ##__VA_ARGS__)
+#define sdk_notice(dev, format, ...) \
+ dev_notice(dev, "[COMM]" format, ##__VA_ARGS__)
#define sdk_info(dev, format, ...) dev_info(dev, "[COMM]" format, ##__VA_ARGS__)
struct cfg_mgmt_info;
@@ -43,20 +37,21 @@ struct hinic5_hwdev;
struct hinic5_wq;
struct sdk_cmdq_wqe_desc;
-#define HINIC5_CHANNEL_DETECT_PERIOD (5 * 1000)
-#define HINIC5_CHANNEL_DETECT_MAX_BUSY (3)
+#define HINIC5_CHANNEL_DETECT_PERIOD (5 * 1000)
+#define HINIC5_CHANNEL_DETECT_MAX_BUSY (3)
-/**< System and chip time sync period unit in milliseconds */
-#define HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD (500)
+#define HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD \
+ (500) /**< 系统和芯片时间同步周期单位毫秒 */
/**
- * @brief Define a function pointer type for handling hinic5 events
- * @param handle Device handle
- * @param event Event information
+ * @brief 定义一个函数指针类型,用于处理hinic5事件
+ * @param handle 设备句柄
+ * @param event 事件信息
*
- * @return None
+ * @return 无
*/
-typedef void (*hinic5_event_handler)(void *handle, struct hinic5_event_info *event);
+typedef void (*hinic5_event_handler)(void *handle,
+ struct hinic5_event_info *event);
struct hinic5_page_addr {
void *virt_addr;
@@ -74,7 +69,7 @@ struct mqm_addr_trans_tbl_info {
struct hinic5_devlink {
struct hinic5_hwdev *hwdev;
u8 activate_fw; /* 0 ~ 7 */
- u8 switch_cfg; /* 0 ~ 7 */
+ u8 switch_cfg; /* 0 ~ 7 */
};
enum hinic5_func_mode {
@@ -90,6 +85,17 @@ enum hinic5_func_mode {
FUNC_MOD_MULTI_VM_SLAVE,
};
+/**
+ * @brief enum hinic5_hwdev_init_state
+ * @details 定义了硬件设备初始化状态的枚举类型
+ */
+enum hinic5_hwdev_init_state {
+ HINIC5_HWDEV_NONE_INITED = 0, /**< 设备未初始化 */
+ HINIC5_HWDEV_MGMT_INITED, /**< 设备管理模块已初始化 */
+ HINIC5_HWDEV_MBOX_INITED, /**< 设备mailbox模块已初始化 */
+ HINIC5_HWDEV_CMDQ_INITED, /**< 设备cmdq模块已初始化 */
+};
+
enum hinic5_pcie_nosnoop {
HINIC5_PCIE_SNOOP = 0,
HINIC5_PCIE_NO_SNOOP = 1,
@@ -105,26 +111,25 @@ enum hinic5_perf_bitmap {
HINIC5_MAILBOX_PERF = 1,
};
-#define IS_BMGW_MASTER_HOST(hwdev) \
- ((hwdev)->func_mode == FUNC_MOD_MULTI_BM_MASTER)
-#define IS_BMGW_SLAVE_HOST(hwdev) \
- ((hwdev)->func_mode == FUNC_MOD_MULTI_BM_SLAVE)
-#define IS_VM_MASTER_HOST(hwdev) \
- ((hwdev)->func_mode == FUNC_MOD_MULTI_VM_MASTER)
-#define IS_VM_SLAVE_HOST(hwdev) \
- ((hwdev)->func_mode == FUNC_MOD_MULTI_VM_SLAVE)
+#define IS_BMGW_MASTER_HOST(hwdev) \
+ ((hwdev)->func_mode == FUNC_MOD_MULTI_BM_MASTER)
+#define IS_BMGW_SLAVE_HOST(hwdev) \
+ ((hwdev)->func_mode == FUNC_MOD_MULTI_BM_SLAVE)
+#define IS_VM_MASTER_HOST(hwdev) \
+ ((hwdev)->func_mode == FUNC_MOD_MULTI_VM_MASTER)
+#define IS_VM_SLAVE_HOST(hwdev) ((hwdev)->func_mode == FUNC_MOD_MULTI_VM_SLAVE)
-#define IS_MASTER_HOST(hwdev) \
- (IS_BMGW_MASTER_HOST(hwdev) || IS_VM_MASTER_HOST(hwdev))
+#define IS_MASTER_HOST(hwdev) \
+ (IS_BMGW_MASTER_HOST(hwdev) || IS_VM_MASTER_HOST(hwdev))
-#define IS_SLAVE_HOST(hwdev) \
- (IS_BMGW_SLAVE_HOST(hwdev) || IS_VM_SLAVE_HOST(hwdev))
+#define IS_SLAVE_HOST(hwdev) \
+ (IS_BMGW_SLAVE_HOST(hwdev) || IS_VM_SLAVE_HOST(hwdev))
-#define IS_MULTI_HOST(hwdev) \
- (IS_BMGW_MASTER_HOST(hwdev) || IS_BMGW_SLAVE_HOST(hwdev) || \
- IS_VM_MASTER_HOST(hwdev) || IS_VM_SLAVE_HOST(hwdev))
+#define IS_MULTI_HOST(hwdev) \
+ (IS_BMGW_MASTER_HOST(hwdev) || IS_BMGW_SLAVE_HOST(hwdev) || \
+ IS_VM_MASTER_HOST(hwdev) || IS_VM_SLAVE_HOST(hwdev))
-#define NEED_MBOX_FORWARD(hwdev) IS_BMGW_SLAVE_HOST(hwdev)
+#define NEED_MBOX_FORWARD(hwdev) IS_BMGW_SLAVE_HOST(hwdev)
enum hinic5_host_mode_e {
HINIC5_MODE_NORMAL = 0,
@@ -133,26 +138,26 @@ enum hinic5_host_mode_e {
HINIC5_SDI_MODE_MAX,
};
-struct mqm_eqm_hinic5_vram_name_s {
- char hinic5_vram_name[HINIC5_VRAM_NAME_MAX_LEN];
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
};
struct hinic5_sdk_timeout_info {
- enum hinic5_hw_type hw_type; /**< Hardware type FPGA etc. */
- const char *hw_type_desc; /**< Hardware type string representation. */
- u32 mbox_poll_timeout; /* < Timeout for waiting cpi to write back mailbox status */
- u32 mbox_timeout; /**< Timeout for waiting mailbox ack response */
- u32 cmdq_timeout; /**< cmdq timeout */
+ enum hinic5_hw_type hw_type; /**< 硬件类型 FPGA etc. */
+ const char *hw_type_desc; /**< 硬件类型字符串表示. */
+ u32 mbox_poll_timeout; /* < 等待cpi回写mailbox status超时时间 */
+ u32 mbox_timeout; /**< 等待mailbox ack response超时时间 */
+ u32 cmdq_timeout; /**< cmdq 超时时间 */
};
struct hinic5_hwdev {
- void *adapter_hdl; /* pointer to hinic5_adev or NDIS_Adapter */
+ void *adapter_hdl; /* pointer to hinic5_adev or NDIS_Adapter */
#ifdef __UEFI__
- void *busdev_hdl; /* pointer to pcidev or ub dev */
+ void *busdev_hdl; /* pointer to pcidev or ub dev */
#endif
void *dev_hdl; /* pointer to pcidev->dev or Handler, for
- * sdk_err() or dma_alloc()
- */
+ * sdk_err() or dma_alloc()
+ */
void *service_adapter[SERVICE_T_MAX];
void *chip_node;
@@ -160,7 +165,7 @@ struct hinic5_hwdev {
u32 wq_page_size;
int chip_present_flag;
- bool poll; /* use polling mode or int mode */
+ bool poll; /* use polling mode or int mode */
u32 rsvd1;
struct hinic5_hwif *hwif; /* include void __iomem *bar */
@@ -179,16 +184,16 @@ struct hinic5_hwdev {
void *fw_update_hdl;
- void *hinic5_cqm_hdl;
+ void *cqm_hdl;
struct mqm_addr_trans_tbl_info mqm_att;
struct hinic5_page_addr page_pa0;
struct hinic5_page_addr page_pa1;
u32 stateful_ref_cnt;
u32 rsvd2;
- struct mqm_eqm_hinic5_vram_name_s *mqm_eqm_hinic5_vram_name;
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
- struct mutex stateful_mutex; /* protect hinic5_cqm init and deinit */
+ struct mutex stateful_mutex; /* protect cqm init and deinit */
struct hinic5_hw_stats hw_stats;
u8 *chip_fault_stats;
@@ -199,13 +204,13 @@ struct hinic5_hwdev {
struct hinic5_board_info board_info;
#if !defined(__UEFI__) && !defined(__VMWARE__) && !defined(__WIN__)
- struct delayed_work sync_time_task;
- struct delayed_work sync_kernel_time_task;
- struct delayed_work channel_detect_task;
- void *non_ptp_cdev; // TODO: Structure definition reference to be resolved
+ struct delayed_work sync_time_task;
+ struct delayed_work sync_kernel_time_task;
+ struct delayed_work channel_detect_task;
+ void *non_ptp_cdev; // TODO: 待解决结构体定义引用
#endif
- struct hinic5_prof_attr *prof_attr;
+ struct hinic5_prof_attr *prof_attr;
const struct hinic5_prof_adapter *prof_adap;
struct workqueue_struct *workq;
@@ -226,7 +231,7 @@ struct hinic5_hwdev {
struct hinic5_devlink *devlink_dev;
- enum hinic5_func_mode func_mode;
+ enum hinic5_func_mode func_mode;
u32 rsvd3;
u64 cur_recv_aeq_cnt;
@@ -240,48 +245,58 @@ struct hinic5_hwdev {
u8 cmdq_mode;
u8 cmdq_cos_offset;
- u8 rsvd5[5]; // Reserved for hotpatch
+ u8 rsvd5[5]; // 热补丁预留
struct hisdk5_fast_msg_to_func *fast_msg_to_func;
const struct hinic5_sdk_timeout_info *timeout_info;
};
-#define HINIC5_DRV_FEATURE_QW0 \
- (COMM_F_API_CHAIN | COMM_F_CLP | COMM_F_MBOX_SEGMENT | \
- COMM_F_CMDQ_NUM | COMM_F_VIRTIO_VQ_SIZE | COMM_F_EXTEND_CAP | \
- COMM_F_SMF_CACHE_INVALID | COMM_F_ONLY_ENHANCE_CMDQ | \
- COMM_F_USE_REAL_RX_BUF_SIZE | COMM_F_CMD_BUF_SIZE | \
- COMM_F_HTN_CMD | COMM_F_MBOX_MSG_HEAD_SUPP_VER1 | COMM_F_FAST_MSG | \
- COMM_F_UFHD | COMM_F_VIRTIO_FC_CACHE_MODE | COMM_F_NON_PTP_SYNC | \
- COMM_F_HT_GPA | COMM_F_UFHD_FLEX_SEG)
-
-#define HINIC5_MAX_HOST_NUM(hwdev) ((hwdev)->glb_attr.max_host_num)
-#define HINIC5_MAX_PF_NUM(hwdev) ((hwdev)->glb_attr.max_pf_num)
-#define HINIC5_MGMT_CPU_NODE_ID(hwdev) ((hwdev)->glb_attr.mgmt_host_node_id)
-
-#define COMM_FEATURE_QW0(hwdev, feature) (((hwdev)->features[0] & COMM_F_##feature) != 0)
-#define COMM_SUPPORT_API_CHAIN(hwdev) COMM_FEATURE_QW0(hwdev, API_CHAIN)
-#define COMM_SUPPORT_CLP(hwdev) COMM_FEATURE_QW0(hwdev, CLP)
-#define COMM_SUPPORT_CHANNEL_DETECT(hwdev) COMM_FEATURE_QW0(hwdev, CHANNEL_DETECT)
-#define COMM_SUPPORT_CMDQ_NUM(hwdev) COMM_FEATURE_QW0(hwdev, CMDQ_NUM)
-#define COMM_SUPPORT_CMD_BUF_SIZE(hwdev) COMM_FEATURE_QW0(hwdev, CMD_BUF_SIZE)
-#define COMM_SUPPORT_VIRTIO_VQ_SIZE(hwdev) COMM_FEATURE_QW0(hwdev, VIRTIO_VQ_SIZE)
-#define COMM_IS_USE_REAL_RX_BUF_SIZE(hwdev) COMM_FEATURE_QW0(hwdev, USE_REAL_RX_BUF_SIZE)
-#define COMM_SUPPORT_EXTEND_CAPBILITY(hwdev) COMM_FEATURE_QW0(hwdev, EXTEND_CAP)
-#define COMM_SUPPORT_SMF_CACHE_INVALID(hwdev) COMM_FEATURE_QW0(hwdev, SMF_CACHE_INVALID)
-#define COMM_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev) COMM_FEATURE_QW0(hwdev, ONLY_ENHANCE_CMDQ)
-#define COMM_SUPPORT_HTN_CMD(hwdev) COMM_FEATURE_QW0(hwdev, HTN_CMD)
-#define COMM_SUPPORT_FAST_MSG(hwdev) COMM_FEATURE_QW0(hwdev, FAST_MSG)
-#define COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) COMM_FEATURE_QW0(hwdev, MBOX_MSG_HEAD_SUPP_VER1)
-#define COMM_SUPPORT_UFHD(hwdev) COMM_FEATURE_QW0(hwdev, UFHD)
-#define COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) COMM_FEATURE_QW0(hwdev, VIRTIO_FC_CACHE_MODE)
-#define COMM_SUPPORT_NON_PTP_SYNC(hwdev) COMM_FEATURE_QW0(hwdev, NON_PTP_SYNC)
-#define COMM_SUPPORT_HT_GPA(hwdev) COMM_FEATURE_QW0(hwdev, HT_GPA)
-#define COMM_SUPPORT_UFHD_FLEX_SEG(hwdev) COMM_FEATURE_QW0(hwdev, UFHD_FLEX_SEG)
+#define HINIC5_DRV_FEATURE_QW0 \
+ (COMM_F_API_CHAIN | COMM_F_CLP | COMM_F_MBOX_SEGMENT | \
+ COMM_F_CMDQ_NUM | COMM_F_VIRTIO_VQ_SIZE | COMM_F_EXTEND_CAP | \
+ COMM_F_SMF_CACHE_INVALID | COMM_F_ONLY_ENHANCE_CMDQ | \
+ COMM_F_USE_REAL_RX_BUF_SIZE | COMM_F_CMD_BUF_SIZE | COMM_F_HTN_CMD | \
+ COMM_F_MBOX_MSG_HEAD_SUPP_VER1 | COMM_F_FAST_MSG | COMM_F_UFHD | \
+ COMM_F_VIRTIO_FC_CACHE_MODE | COMM_F_NON_PTP_SYNC | COMM_F_HT_GPA | \
+ COMM_F_UFHD_FLEX_SEG | COMM_F_VF_BAT_EXPANDED)
+
+#define HINIC5_MAX_HOST_NUM(hwdev) ((hwdev)->glb_attr.max_host_num)
+#define HINIC5_MAX_PF_NUM(hwdev) ((hwdev)->glb_attr.max_pf_num)
+#define HINIC5_MGMT_CPU_NODE_ID(hwdev) ((hwdev)->glb_attr.mgmt_host_node_id)
+
+#define COMM_FEATURE_QW0(hwdev, feature) \
+ (((hwdev)->features[0] & COMM_F_##feature) != 0)
+#define COMM_SUPPORT_API_CHAIN(hwdev) COMM_FEATURE_QW0(hwdev, API_CHAIN)
+#define COMM_SUPPORT_CLP(hwdev) COMM_FEATURE_QW0(hwdev, CLP)
+#define COMM_SUPPORT_CHANNEL_DETECT(hwdev) \
+ COMM_FEATURE_QW0(hwdev, CHANNEL_DETECT)
+#define COMM_SUPPORT_CMDQ_NUM(hwdev) COMM_FEATURE_QW0(hwdev, CMDQ_NUM)
+#define COMM_SUPPORT_CMD_BUF_SIZE(hwdev) COMM_FEATURE_QW0(hwdev, CMD_BUF_SIZE)
+#define COMM_SUPPORT_VIRTIO_VQ_SIZE(hwdev) \
+ COMM_FEATURE_QW0(hwdev, VIRTIO_VQ_SIZE)
+#define COMM_IS_USE_REAL_RX_BUF_SIZE(hwdev) \
+ COMM_FEATURE_QW0(hwdev, USE_REAL_RX_BUF_SIZE)
+#define COMM_SUPPORT_EXTEND_CAPBILITY(hwdev) COMM_FEATURE_QW0(hwdev, EXTEND_CAP)
+#define COMM_SUPPORT_SMF_CACHE_INVALID(hwdev) \
+ COMM_FEATURE_QW0(hwdev, SMF_CACHE_INVALID)
+#define COMM_SUPPORT_ONLY_ENHANCE_CMDQ(hwdev) \
+ COMM_FEATURE_QW0(hwdev, ONLY_ENHANCE_CMDQ)
+#define COMM_SUPPORT_HTN_CMD(hwdev) COMM_FEATURE_QW0(hwdev, HTN_CMD)
+#define COMM_SUPPORT_FAST_MSG(hwdev) COMM_FEATURE_QW0(hwdev, FAST_MSG)
+#define COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) \
+ COMM_FEATURE_QW0(hwdev, MBOX_MSG_HEAD_SUPP_VER1)
+#define COMM_SUPPORT_UFHD(hwdev) COMM_FEATURE_QW0(hwdev, UFHD)
+#define COMM_SUPPORT_VIRTIO_FC_CACHE(hwdev) \
+ COMM_FEATURE_QW0(hwdev, VIRTIO_FC_CACHE_MODE)
+#define COMM_SUPPORT_NON_PTP_SYNC(hwdev) COMM_FEATURE_QW0(hwdev, NON_PTP_SYNC)
+#define COMM_SUPPORT_HT_GPA(hwdev) COMM_FEATURE_QW0(hwdev, HT_GPA)
+#define COMM_SUPPORT_UFHD_FLEX_SEG(hwdev) COMM_FEATURE_QW0(hwdev, UFHD_FLEX_SEG)
+#define COMM_SUPPORT_VF_BAT_EXPANDED(hwdev) \
+ COMM_FEATURE_QW0(hwdev, VF_BAT_EXPANDED)
bool hinic5_get_perf_en(enum hinic5_perf_bitmap perf_bit);
-#define HINIC5_CHIP_PRESENT 1
-#define HINIC5_CHIP_ABSENT 0
+#define HINIC5_CHIP_PRESENT 1
+#define HINIC5_CHIP_ABSENT 0
/**
* The chip will be absent when
@@ -302,15 +317,15 @@ static inline bool hinic5_is_chip_present(const struct hinic5_hwdev *hwdev)
static inline bool hinic5_is_chip_error(const struct hinic5_hwdev *hwdev)
{
struct card_node *chip_info = (struct card_node *)hwdev->chip_node;
-
return chip_info->exception_flag;
}
-static inline bool hinic5_channel_detect_should_stop(const struct hinic5_hwdev *hwdev)
+static inline bool
+hinic5_channel_detect_should_stop(const struct hinic5_hwdev *hwdev)
{
struct card_node *chip_node = (struct card_node *)hwdev->chip_node;
-
- return atomic_read(&chip_node->channel_busy_cnt) >= HINIC5_CHANNEL_DETECT_MAX_BUSY;
+ return atomic_read(&chip_node->channel_busy_cnt) >=
+ HINIC5_CHANNEL_DETECT_MAX_BUSY;
}
/**
@@ -319,9 +334,10 @@ static inline bool hinic5_channel_detect_should_stop(const struct hinic5_hwdev *
* @param pri_handle: private data will be used by the callback
* @param callback: callback function
*
- * @return 0: success, non-zero: error code
+ * @return 0:成功,非0:错误码
*/
-int hinic5_event_register(void *dev, void *pri_handle, hinic5_event_handler callback);
+int hinic5_event_register(void *dev, void *pri_handle,
+ hinic5_event_handler callback);
/**
* @brief hinic5_event_unregister - unregister hardware event
@@ -335,28 +351,29 @@ void *hinic5_get_ppf_dev(void);
bool hinic5_is_function_active(struct hinic5_hwdev *hwdev);
/**
- * @brief Dump CMDQ work queue wqebb
- * @param[in] hwdev Hardware device
- * @param[in] cmdq_id CMDQ id to query
- * @param[in] wqe_idx wqebb idx to query
- * @param[out] wqe_desc Queried wqebb information
+ * @brief Dump CMDQ 工作队列 wqebb
+ * @param[in] hwdev 硬件设备
+ * @param[in] cmdq_id 查询的 CMDQ id
+ * @param[in] wqe_idx 查询的 wqebb idx
+ * @param[out] wqe_desc 查询到的 wqebb 信息
*
- * @return Success or not
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
int hinic5_dump_cmdq_wqebb(struct hinic5_hwdev *hwdev, u16 cmdq_id, u16 wqe_idx,
struct sdk_cmdq_wqe_desc *wqe_desc);
/**
- * @brief Dump CMDQ work queue information
- * @param[in] hwdev Hardware device
- * @param[in] cmdq_id CMDQ id to query
- * @param[out] wq Queried CMDQ work queue information
+ * @brief Dump CMDQ 工作队列信息
+ * @param[in] hwdev 硬件设备
+ * @param[in] cmdq_id 查询的 CMDQ id
+ * @param[out] wq 查询到的 CMDQ 工作队列信息
*
- * @return Success or not
- * @retval zero: success
- * @retval non-zero: failure
+ * @return 是否成功
+ * @retval zero: success
+ * @retval non-zero: failure
*/
-int hinic5_dump_cmdq_wq(struct hinic5_hwdev *hwdev, u16 cmdq_id, struct hinic5_wq *wq);
+int hinic5_dump_cmdq_wq(struct hinic5_hwdev *hwdev, u16 cmdq_id,
+ struct hinic5_wq *wq);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwif_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwif_inner.h
deleted file mode 100644
index bdfa8e7e1..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_hwif_inner.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hwif_inner.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_HWIF_INNER_H
-#define HINIC5_HWIF_INNER_H
-
-#include "hinic5_hwdev.h"
-
-#define HINIC5_BUS_LINK_DOWN 0xFFFFFFFF
-#define MAKE_64BITS(hi, lo) ((((u64)(hi)) << 32) | ((u64)((u32)(lo))))
-
-struct hinic5_free_db_area {
- unsigned long *db_bitmap_array;
- u32 db_max_areas;
- /* spinlock for allocating doorbell area */
- spinlock_t idx_lock;
-};
-
-struct hinic5_func_attr {
- u16 func_global_idx;
- u8 port_to_port_idx;
- u8 pci_intf_idx;
- u8 vf_in_pf;
- u8 rsvd1;
- u16 rsvd2;
- enum func_type func_type;
-
- u8 mpf_idx;
-
- u8 ppf_idx;
-
- u16 num_irqs; /* max: 2 ^ 15 */
- u8 num_aeqs; /* max: 2 ^ 3 */
- u8 num_ceqs; /* max: 2 ^ 7 */
-
- u16 num_sq; /* max: 2 ^ 8 */
- u8 num_dma_attr; /* max: 2 ^ 6 */
- u8 msix_flex_en;
-
- u16 global_vf_id_of_pf;
- u8 hw_type;
-};
-
-struct hinic5_hwif {
- u8 __iomem *fers2_reg_base;
- u8 __iomem *cfg_regs_base;
- u8 __iomem *intr_regs_base;
- u8 __iomem *mgmt_regs_base; /* only for PPF/PF */
- u64 db_base_phy;
- u64 db_dwqe_len;
- u8 __iomem *db_base;
-
- struct hinic5_free_db_area free_db_area;
-
- struct hinic5_func_attr attr;
-
-#ifdef __UEFI__
- void *bus_dev; /* In pcie scenario it represents pdev, in ub scenario it represents ub dev */
-#endif
- void *hwdev;
-
- u64 rsvd;
-};
-
-enum outbound_flush_state {
- OUTBOUND_FLUSH_DISABLED = 0,
- OUTBOUND_FLUSH_ENABLED = 1,
-};
-
-enum doorbell_flush_state {
- DOORBELL_FLUSH_DISABLED = 0,
- DOORBELL_FLUSH_ENABLED = 1,
-};
-
-enum hinic5_wait_return check_outbound_enable_handler(struct hinic5_hwdev *hwdev);
-
-enum hinic5_pf_status {
- HINIC5_PF_STATUS_INIT = 0X0,
- HINIC5_PF_STATUS_ACTIVE_FLAG = 0x11,
- HINIC5_PF_STATUS_FLR_START_FLAG = 0x12,
- HINIC5_PF_STATUS_FLR_FINISH_FLAG = 0x13,
-};
-
-#define HINIC5_HWIF_NUM_AEQS(hwif) ((hwif)->attr.num_aeqs)
-#define HINIC5_HWIF_NUM_CEQS(hwif) ((hwif)->attr.num_ceqs)
-#define HINIC5_HWIF_NUM_IRQS(hwif) ((hwif)->attr.num_irqs)
-#define HINIC5_HWIF_GLOBAL_IDX(hwif) ((hwif)->attr.func_global_idx)
-#define HINIC5_HWIF_GLOBAL_VF_OFFSET(hwif) ((hwif)->attr.global_vf_id_of_pf)
-#define HINIC5_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx)
-#define HINIC5_PCI_INTF_IDX(hwif) ((hwif)->attr.pci_intf_idx)
-
-#define HINIC5_FUNC_TYPE(dev) ((dev)->hwif->attr.func_type)
-#define HINIC5_IS_PF(dev) (HINIC5_FUNC_TYPE(dev) == TYPE_PF)
-#define HINIC5_IS_VF(dev) (HINIC5_FUNC_TYPE(dev) == TYPE_VF)
-#define HINIC5_IS_PPF(dev) (HINIC5_FUNC_TYPE(dev) == TYPE_PPF)
-
-struct hinic5_health_status {
- u32 rsvd : 7;
- u32 fw_img_load_fail : 1;
- u32 smu_lastword : 1;
- u32 npu_lastword : 1;
- u32 mpu_wdog : 1;
- u32 mpu_lastword : 1;
- u32 wr_phy_timeout : 1;
- u32 wr_mem_timeout : 1;
- u32 wr_reg_timeout : 1;
- u32 sfp_high_temperature_port : 4;
- u32 chip_low_temperature : 1;
- u32 chip_high_temperature : 1;
- u32 logic_except : 1;
- u32 host_heart : 5;
- u32 mpu_init_done : 2;
- u32 mpu_boot_cause : 3;
-};
-
-struct hinic5_chip_base {
- u32 chip_type : 2;
- u32 chip_ver : 2;
- u32 spu_en : 1;
- u32 host_num : 3;
- u32 cfg_template_id : 4;
- u32 board_type : 8;
- u32 board_id : 4;
- u32 mpu_ver : 8;
-};
-
-struct hinic5_chip_info {
- union {
- struct hinic5_health_status health_status;
- struct hinic5_chip_base chip_base;
- u32 value;
- };
-};
-
-struct hinic5_logic_except {
- u32 err_type : 16;
- u32 err_level : 8;
- u32 mode_id : 8;
-};
-
-struct hinic5_temperature_alarm {
- u32 cur_temperature : 16;
- u32 limit_temperature : 16;
-};
-
-struct hinic5_mpu_exception {
- u32 abnormal_thread_id : 16;
- u32 abnormal_reason : 16;
-};
-
-struct hinic5_sfp_high_temperature_port {
- u32 front_actual_temperature : 8;
- u32 front_alarm_threshold_temperature : 8;
- u32 after_actual_temperature : 8;
- u32 after_alarm_threshold_temperature : 8;
-};
-
-struct hinic5_eco0_info {
- u32 stfqu_uncrt_err : 1;
- u32 pqm_uncrt_err : 1;
- u32 mqm_uncrt_err : 1;
- u32 stlqu_uncrt_err : 1;
- u32 smf_uncrt_err : 4;
- u32 sml_uncrt_err : 4;
- u32 stftile_uncrt_err : 4;
- u32 stltile_uncrt_err : 4;
- u32 mpu_uncrt_err : 1;
- u32 cpi_uncrt_err : 1;
- u32 lcam_uncrt_err : 1;
- u32 ipsutx_uncrt_err : 1;
- u32 perx_uncrt_err : 1;
- u32 ipsurx_uncrt_err : 1;
- u32 petx_uncrt_err : 1;
- u32 cpb_uncrt_err : 1;
- u32 ckd_err_int : 2;
- u32 pcie_uncrt_err : 1;
- u32 cryptorx_uncrt_err : 1;
-};
-
-struct hinic5_eco1_info {
- u32 cryptotx_uncrt_err : 1;
- u32 ts_uncrt_err : 1;
- u32 mag_uncrt_err : 1;
- u32 fc_uncrt_err : 1;
- u32 hva_uncrt_err : 1;
- u32 reserved : 27;
-};
-
-struct hinic5_eco2_info {
- union {
- struct hinic5_logic_except logic_except;
- struct hinic5_temperature_alarm temperature_alarm;
- struct hinic5_mpu_exception mpu_exception;
- u32 value;
- u16 short_value;
- };
-};
-
-struct hinic5_eco3_info {
- union {
- struct hinic5_sfp_high_temperature_port sfp_high_temperature_port;
- u32 value;
- };
-};
-
-struct hinic5_eco4_info {
- union {
- struct hinic5_sfp_high_temperature_port sfp_high_temperature_port;
- u32 value;
- };
-};
-
-u32 hinic5_hwif_read_reg(struct hinic5_hwif *hwif, u32 reg);
-
-void hinic5_hwif_write_reg(struct hinic5_hwif *hwif, u32 reg, u32 val);
-
-void hinic5_set_pf_status(struct hinic5_hwif *hwif,
- enum hinic5_pf_status status);
-
-enum hinic5_pf_status hinic5_get_pf_status(struct hinic5_hwif *hwif);
-
-void hinic5_disable_doorbell(struct hinic5_hwif *hwif);
-
-void hinic5_enable_doorbell(struct hinic5_hwif *hwif);
-
-int hinic5_init_hwif(struct hinic5_hwdev *hwdev, void *fers2_reg_base, void *cfg_reg_base,
- void *intr_reg_base, void *mgmt_regs_base, u64 db_base_phy,
- void *db_base, u64 db_dwqe_len);
-
-void hinic5_free_hwif(struct hinic5_hwdev *hwdev);
-
-void hinic5_show_chip_err_info(struct hinic5_hwdev *hwdev);
-
-u8 hinic5_host_ppf_idx(struct hinic5_hwdev *hwdev, u8 host_id);
-
-bool hinic5_get_card_present_state(struct hinic5_hwdev *hwdev);
-
-bool get_handshake_state(struct hinic5_hwdev *hwdev);
-
-int hinic5_n_ptp_ts_up_en(struct hinic5_hwdev *hwdev, u32 flags);
-
-int hinic5_read_n_ptp_ts_data(struct hinic5_hwdev *hwdev, u64 *time_ns);
-
-/**
- * @brief enum hinic5_aeq_type - AEQ event types generated by CPI hardware
- * @details aeqe.sw attribute is 0 (aeqe generated by cpi hardware) supported event types
- */
-enum hinic5_aeq_type {
- HINIC5_HW_INTER_INT = 0, /**< Hardware interrupt event */
- HINIC5_MBX_FROM_FUNC = 1, /**< Mailbox from function */
- HINIC5_MSG_FROM_MGMT_CPU = 2, /**< Mailbox from MPU */
- HINIC5_API_RSP = 3, /**< API response data */
- HINIC5_API_CHAIN_STS = 4, /**< API chain status data */
- HINIC5_MBX_SEND_RSLT = 5, /**< mailbox sending result */
- HINIC5_MAX_AEQ_EVENTS /**< Number of supported event types */
-};
-
-/**
- * @brief enum hinic5_aeq_sw_type - AEQ event types generated by microcode (Tile)
- * @details aeqe.sw attribute is 1 (aeqe generated by microcode) supported event types
- */
-enum hinic5_aeq_sw_type {
- HINIC5_STATELESS_EVENT = 0, /**< Stateless event */
- HINIC5_STATEFUL_EVENT = 1, /**< Stateful event */
- HINIC5_MAX_AEQ_SW_EVENTS /**< Number of supported event types */
-};
-
-/**
- * @brief Define a function pointer type for handling AEQ interrupt
- * @param pri_handle Device handle
- * @param data Interrupt data
- * @param size Interrupt data size
- *
- * @return None
- */
-typedef void (*hinic5_aeq_hwe_cb)(void *pri_handle, u8 *data, u8 size);
-
-/**
- * @brief hinic5_aeq_register_hw_cb - register aeq hardware callback
- * @param hwdev: device pointer to hwdev
- * @param event: event type
- * @param hwe_cb: callback function
- *
- * @return
- * @retval zero: success
- * @retval non-zero: failure
- */
-int hinic5_aeq_register_hw_cb(void *hwdev, void *pri_handle,
- enum hinic5_aeq_type event, hinic5_aeq_hwe_cb hwe_cb);
-
-/**
- * @brief hinic5_aeq_unregister_hw_cb - unregister aeq hardware callback
- *
- * @return
- * @param hwdev: device pointer to hwdev
- * @param event: event type
- */
-void hinic5_aeq_unregister_hw_cb(void *hwdev, enum hinic5_aeq_type event);
-
-/**
- * @brief hinic5_aeq_register_swe_cb - register aeq soft event callback
- * @param hwdev: device pointer to hwdev
- * @pri_handle: the pointer to private invoker device
- * @param event: event type
- * @param aeq_swe_cb: callback function
- *
- * @return
- * @retval zero: success
- * @retval non-zero: failure
- */
-int hinic5_aeq_register_swe_cb(void *hwdev, void *pri_handle, enum hinic5_aeq_sw_type event,
- hinic5_aeq_swe_cb aeq_swe_cb);
-
-/**
- * @brief hinic5_aeq_unregister_swe_cb - unregister aeq soft event callback
- * @param hwdev: device pointer to hwdev
- * @param event: event type
- **/
-void hinic5_aeq_unregister_swe_cb(void *hwdev, enum hinic5_aeq_sw_type event);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_lld_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_lld_inner.h
index 31ae7ff0a..a47b1e316 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_lld_inner.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_lld_inner.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_lld_inner.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2025 Huawei Technologies Co., Ltd */
#ifndef __HINIC5_LLD_INNER_H
#define __HINIC5_LLD_INNER_H
@@ -15,9 +8,9 @@
#include "hinic5_lld.h"
/**
- * @brief Get all ULD name array
+ * @brief 获取全部ULD名称数组
*
- * @return Return ULD name array pointer
+ * @return 返回ULD名称数组指针
*/
const char **hinic5_get_uld_names(void);
@@ -27,6 +20,7 @@ const char **hinic5_get_uld_names(void);
*
* @return uld_info
**/
-const struct hinic5_uld_info *hinic5_get_uld_info_by_type(enum hinic5_service_type type);
+const struct hinic5_uld_info *
+hinic5_get_uld_info_by_type(enum hinic5_service_type type);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mbox.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mbox.h
index c5079d566..64abf8be3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mbox.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mbox.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mbox.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_MBOX_H
#define HINIC5_MBOX_H
@@ -19,82 +12,82 @@
#include "mpu_mailbox_msg_header.h"
#include "hinic5_hwdev.h"
-#define HINIC5_MBOX_PF_SEND_ERR 0x1
+#define HINIC5_MBOX_PF_SEND_ERR 0x1
-#define HINIC5_MGMT_SRC_ID 0x1FFF
-#define HINIC5_MAX_FUNCTIONS 4096
+#define HINIC5_MGMT_SRC_ID 0x1FFF
+#define HINIC5_MAX_FUNCTIONS 4096
#define MBOX_SEG_LEN_UNIT 0x4
#define MBOX_MSG_LEN_UNIT 0x4
-#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_SHIFT 0
-#define HINIC5_MSG_HEADER_STATUS_SHIFT 13
-#define HINIC5_MSG_HEADER_VERSION_SHIFT 14
-#define HINIC5_MSG_HEADER_SOURCE_SHIFT 15
-#define HINIC5_MSG_HEADER_AEQ_ID_SHIFT 16
-#define HINIC5_MSG_HEADER_MSG_ID_SHIFT 18
-#define HINIC5_MSG_HEADER_CMD_SHIFT 22
-
-#define HINIC5_MSG_HEADER_V0_MSG_LEN_SHIFT 32
-#define HINIC5_MSG_HEADER_V1_MSG_LEN_SHIFT 32
-#define HINIC5_MSG_HEADER_V0_MODULE_SHIFT 43
-#define HINIC5_MSG_HEADER_V1_MODULE_SHIFT 43
-#define HINIC5_MSG_HEADER_V0_SEG_LEN_SHIFT 48
-#define HINIC5_MSG_HEADER_V1_SEG_LEN_SHIFT 50
-#define HINIC5_MSG_HEADER_NO_ACK_SHIFT 54
-#define HINIC5_MSG_HEADER_DATA_TYPE_SHIFT 55
-#define HINIC5_MSG_HEADER_SEQID_SHIFT 56
-#define HINIC5_MSG_HEADER_LAST_SHIFT 62
-#define HINIC5_MSG_HEADER_DIRECTION_SHIFT 63
-
-#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_MASK 0x1FFF
-#define HINIC5_MSG_HEADER_STATUS_MASK 0x1
-#define HINIC5_MSG_HEADER_VERSION_MASK 0x1
-#define HINIC5_MSG_HEADER_SOURCE_MASK 0x1
-#define HINIC5_MSG_HEADER_AEQ_ID_MASK 0x3
-#define HINIC5_MSG_HEADER_MSG_ID_MASK 0xF
-#define HINIC5_MSG_HEADER_CMD_MASK 0x3FF
-
-#define HINIC5_MSG_HEADER_V0_MSG_LEN_MASK 0x7FF
-#define HINIC5_MSG_HEADER_V1_MSG_LEN_MASK 0x1FF
-#define HINIC5_MSG_HEADER_V0_MODULE_MASK 0x1F
-#define HINIC5_MSG_HEADER_V1_MODULE_MASK 0x3F
-#define HINIC5_MSG_HEADER_V0_SEG_LEN_MASK 0x3F
-#define HINIC5_MSG_HEADER_V1_SEG_LEN_MASK 0xF
-#define HINIC5_MSG_HEADER_NO_ACK_MASK 0x1
-#define HINIC5_MSG_HEADER_DATA_TYPE_MASK 0x1
-#define HINIC5_MSG_HEADER_SEQID_MASK 0x3F
-#define HINIC5_MSG_HEADER_LAST_MASK 0x1
-#define HINIC5_MSG_HEADER_DIRECTION_MASK 0x1
-
-#define HINIC5_MSG_HEADER_GET(val, field) \
- (((val) >> HINIC5_MSG_HEADER_##field##_SHIFT) & \
- HINIC5_MSG_HEADER_##field##_MASK)
-#define HINIC5_MSG_HEADER_SET(val, field) \
- ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_##field##_MASK) << \
- HINIC5_MSG_HEADER_##field##_SHIFT)
-
-#define HINIC5_MSG_HEADER_GET_V0(val, field) \
+#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_SHIFT 0
+#define HINIC5_MSG_HEADER_STATUS_SHIFT 13
+#define HINIC5_MSG_HEADER_VERSION_SHIFT 14
+#define HINIC5_MSG_HEADER_SOURCE_SHIFT 15
+#define HINIC5_MSG_HEADER_AEQ_ID_SHIFT 16
+#define HINIC5_MSG_HEADER_MSG_ID_SHIFT 18
+#define HINIC5_MSG_HEADER_CMD_SHIFT 22
+
+#define HINIC5_MSG_HEADER_V0_MSG_LEN_SHIFT 32
+#define HINIC5_MSG_HEADER_V1_MSG_LEN_SHIFT 32
+#define HINIC5_MSG_HEADER_V0_MODULE_SHIFT 43
+#define HINIC5_MSG_HEADER_V1_MODULE_SHIFT 43
+#define HINIC5_MSG_HEADER_V0_SEG_LEN_SHIFT 48
+#define HINIC5_MSG_HEADER_V1_SEG_LEN_SHIFT 50
+#define HINIC5_MSG_HEADER_NO_ACK_SHIFT 54
+#define HINIC5_MSG_HEADER_DATA_TYPE_SHIFT 55
+#define HINIC5_MSG_HEADER_SEQID_SHIFT 56
+#define HINIC5_MSG_HEADER_LAST_SHIFT 62
+#define HINIC5_MSG_HEADER_DIRECTION_SHIFT 63
+
+#define HINIC5_MSG_HEADER_SRC_GLB_FUNC_IDX_MASK 0x1FFF
+#define HINIC5_MSG_HEADER_STATUS_MASK 0x1
+#define HINIC5_MSG_HEADER_VERSION_MASK 0x1
+#define HINIC5_MSG_HEADER_SOURCE_MASK 0x1
+#define HINIC5_MSG_HEADER_AEQ_ID_MASK 0x3
+#define HINIC5_MSG_HEADER_MSG_ID_MASK 0xF
+#define HINIC5_MSG_HEADER_CMD_MASK 0x3FF
+
+#define HINIC5_MSG_HEADER_V0_MSG_LEN_MASK 0x7FF
+#define HINIC5_MSG_HEADER_V1_MSG_LEN_MASK 0x1FF
+#define HINIC5_MSG_HEADER_V0_MODULE_MASK 0x1F
+#define HINIC5_MSG_HEADER_V1_MODULE_MASK 0x3F
+#define HINIC5_MSG_HEADER_V0_SEG_LEN_MASK 0x3F
+#define HINIC5_MSG_HEADER_V1_SEG_LEN_MASK 0xF
+#define HINIC5_MSG_HEADER_NO_ACK_MASK 0x1
+#define HINIC5_MSG_HEADER_DATA_TYPE_MASK 0x1
+#define HINIC5_MSG_HEADER_SEQID_MASK 0x3F
+#define HINIC5_MSG_HEADER_LAST_MASK 0x1
+#define HINIC5_MSG_HEADER_DIRECTION_MASK 0x1
+
+#define HINIC5_MSG_HEADER_GET(val, field) \
+ (((val) >> HINIC5_MSG_HEADER_##field##_SHIFT) & \
+ HINIC5_MSG_HEADER_##field##_MASK)
+#define HINIC5_MSG_HEADER_SET(val, field) \
+ ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_##field##_MASK) \
+ << HINIC5_MSG_HEADER_##field##_SHIFT)
+
+#define HINIC5_MSG_HEADER_GET_V0(val, field) \
(((val) >> HINIC5_MSG_HEADER_V0_##field##_SHIFT) & \
HINIC5_MSG_HEADER_V0_##field##_MASK)
-#define HINIC5_MSG_HEADER_SET_V0(val, field) \
- ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_V0_##field##_MASK) << \
- HINIC5_MSG_HEADER_V0_##field##_SHIFT)
+#define HINIC5_MSG_HEADER_SET_V0(val, field) \
+ ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_V0_##field##_MASK) \
+ << HINIC5_MSG_HEADER_V0_##field##_SHIFT)
-#define HINIC5_MSG_HEADER_GET_V1(val, field) \
+#define HINIC5_MSG_HEADER_GET_V1(val, field) \
(((val) >> HINIC5_MSG_HEADER_V1_##field##_SHIFT) & \
HINIC5_MSG_HEADER_V1_##field##_MASK)
-#define HINIC5_MSG_HEADER_SET_V1(val, field) \
- ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_V1_##field##_MASK) << \
- HINIC5_MSG_HEADER_V1_##field##_SHIFT)
+#define HINIC5_MSG_HEADER_SET_V1(val, field) \
+ ((u64)(((u64)(val)) & HINIC5_MSG_HEADER_V1_##field##_MASK) \
+ << HINIC5_MSG_HEADER_V1_##field##_SHIFT)
enum hinic5_msg_direction_type {
- HINIC5_MSG_DIRECT_SEND = 0,
- HINIC5_MSG_RESPONSE = 1,
+ HINIC5_MSG_DIRECT_SEND = 0,
+ HINIC5_MSG_RESPONSE = 1,
};
enum hinic5_msg_segment_type {
- NOT_LAST_SEGMENT = 0,
- LAST_SEGMENT = 1,
+ NOT_LAST_SEGMENT = 0,
+ LAST_SEGMENT = 1,
};
enum hinic5_msg_ack_type {
@@ -103,24 +96,24 @@ enum hinic5_msg_ack_type {
};
enum hinic5_data_type {
- HINIC5_DATA_INLINE = 0,
- HINIC5_DATA_DMA = 1,
+ HINIC5_DATA_INLINE = 0,
+ HINIC5_DATA_DMA = 1,
};
enum hinic5_msg_src_type {
- HINIC5_MSG_FROM_MGMT = 0,
- HINIC5_MSG_FROM_MBOX = 1,
+ HINIC5_MSG_FROM_MGMT = 0,
+ HINIC5_MSG_FROM_MBOX = 1,
};
enum hinic5_msg_aeq_type {
- HINIC5_ASYNC_MSG_AEQ = 0,
+ HINIC5_ASYNC_MSG_AEQ = 0,
/* indicate dest func or mgmt cpu which aeq to response mbox message */
- HINIC5_MBOX_RSP_MSG_AEQ = 1,
+ HINIC5_MBOX_RSP_MSG_AEQ = 1,
/* indicate mgmt cpu which aeq to response api cmd message */
- HINIC5_MGMT_RSP_MSG_AEQ = 2,
+ HINIC5_MGMT_RSP_MSG_AEQ = 2,
};
-#define HINIC5_MBOX_WQ_NAME "hinic5_mbox"
+#define HINIC5_MBOX_WQ_NAME "hinic5_mbox"
struct mbox_msg_info {
u64 header;
@@ -129,42 +122,42 @@ struct mbox_msg_info {
};
struct hinic5_msg_desc {
- void *msg;
- u16 msg_len;
- u8 seq_id;
- u8 mod;
- u16 cmd;
- struct mbox_msg_info msg_info;
+ void *msg;
+ u16 msg_len;
+ u8 seq_id;
+ u8 mod;
+ u16 cmd;
+ struct mbox_msg_info msg_info;
};
struct hinic5_msg_channel {
- struct hinic5_msg_desc resp_msg;
- struct hinic5_msg_desc recv_msg;
+ struct hinic5_msg_desc resp_msg;
+ struct hinic5_msg_desc recv_msg;
- atomic_t recv_msg_cnt;
+ atomic_t recv_msg_cnt;
};
/* Receive other functions mbox message */
struct hinic5_recv_mbox {
void *msg;
- u16 msg_len;
- u8 msg_id;
- u8 mod;
- u16 cmd;
- u16 src_func_idx;
+ u16 msg_len;
+ u8 msg_id;
+ u8 mod;
+ u16 cmd;
+ u16 src_func_idx;
enum hinic5_msg_ack_type ack_type;
- u32 rsvd1;
+ u32 rsvd1;
void *resp_buff;
};
struct hinic5_send_mbox {
- u8 *data;
+ u8 *data;
- u64 *wb_status; /* write back status */
- void *wb_vaddr;
- dma_addr_t wb_paddr;
+ u64 *wb_status; /* write back status */
+ void *wb_vaddr;
+ dma_addr_t wb_paddr;
};
enum mbox_event_state {
@@ -187,77 +180,77 @@ enum hinic5_mbox_cb_state {
};
struct mbox_dma_msg {
- u32 xor;
- u32 dma_addr_high;
- u32 dma_addr_low;
- u32 msg_len;
- u64 rsvd;
+ u32 xor ;
+ u32 dma_addr_high;
+ u32 dma_addr_low;
+ u32 msg_len;
+ u64 rsvd;
};
struct mbox_dma_queue {
- void *dma_buff_vaddr;
- dma_addr_t dma_buff_paddr;
+ void *dma_buff_vaddr;
+ dma_addr_t dma_buff_paddr;
- u16 depth;
- u16 prod_idx;
- u16 cons_idx;
+ u16 depth;
+ u16 prod_idx;
+ u16 cons_idx;
};
struct hinic5_mbox {
- struct hinic5_hwdev *hwdev;
+ struct hinic5_hwdev *hwdev;
- bool lock_channel_en;
- ulong channel_stop;
- u16 cur_msg_channel;
- u32 rsvd1;
+ bool lock_channel_en;
+ ulong channel_stop;
+ u16 cur_msg_channel;
+ u32 rsvd1;
/* lock for send mbox message and ack message */
- struct mutex mbox_send_lock;
+ struct mutex mbox_send_lock;
/* lock for send mbox message */
- struct mutex msg_send_lock;
- struct hinic5_send_mbox send_mbox;
+ struct mutex msg_send_lock;
+ struct hinic5_send_mbox send_mbox;
- struct mbox_dma_queue sync_msg_queue;
- struct mbox_dma_queue async_msg_queue;
+ struct mbox_dma_queue sync_msg_queue;
+ struct mbox_dma_queue async_msg_queue;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
struct hinic5_msg_channel mgmt_msg; /* driver and MGMT CPU */
struct hinic5_msg_channel *host_msg; /* PPF message between hosts */
struct hinic5_msg_channel *func_msg; /* PF to VF or VF to PF */
- u16 num_func_msg;
- bool support_h2h_msg; /* host to host */
+ u16 num_func_msg;
+ bool support_h2h_msg; /* host to host */
/* vf receive pf/ppf callback */
- hinic5_vf_mbox_cb vf_mbox_cb[HINIC5_MOD_MAX];
- void *vf_mbox_data[HINIC5_MOD_MAX];
+ hinic5_vf_mbox_cb vf_mbox_cb[HINIC5_MOD_MAX];
+ void *vf_mbox_data[HINIC5_MOD_MAX];
/* pf/ppf receive vf callback */
- hinic5_pf_mbox_cb pf_mbox_cb[HINIC5_MOD_MAX];
- void *pf_mbox_data[HINIC5_MOD_MAX];
+ hinic5_pf_mbox_cb pf_mbox_cb[HINIC5_MOD_MAX];
+ void *pf_mbox_data[HINIC5_MOD_MAX];
/* ppf receive pf/ppf callback */
- hinic5_ppf_mbox_cb ppf_mbox_cb[HINIC5_MOD_MAX];
- void *ppf_mbox_data[HINIC5_MOD_MAX];
+ hinic5_ppf_mbox_cb ppf_mbox_cb[HINIC5_MOD_MAX];
+ void *ppf_mbox_data[HINIC5_MOD_MAX];
/* pf receive ppf callback */
- hinic5_pf_recv_from_ppf_mbox_cb pf_recv_ppf_mbox_cb[HINIC5_MOD_MAX];
- void *pf_recv_ppf_mbox_data[HINIC5_MOD_MAX];
- ulong ppf_to_pf_mbox_cb_state[HINIC5_MOD_MAX];
- ulong ppf_mbox_cb_state[HINIC5_MOD_MAX];
- ulong pf_mbox_cb_state[HINIC5_MOD_MAX];
- ulong vf_mbox_cb_state[HINIC5_MOD_MAX];
-
- u8 send_msg_id;
- u8 rsvd2;
- u16 rsvd3;
- enum mbox_event_state event_flag;
+ hinic5_pf_recv_from_ppf_mbox_cb pf_recv_ppf_mbox_cb[HINIC5_MOD_MAX];
+ void *pf_recv_ppf_mbox_data[HINIC5_MOD_MAX];
+ ulong ppf_to_pf_mbox_cb_state[HINIC5_MOD_MAX];
+ ulong ppf_mbox_cb_state[HINIC5_MOD_MAX];
+ ulong pf_mbox_cb_state[HINIC5_MOD_MAX];
+ ulong vf_mbox_cb_state[HINIC5_MOD_MAX];
+
+ u8 send_msg_id;
+ u8 rsvd2;
+ u16 rsvd3;
+ enum mbox_event_state event_flag;
/* lock for mbox event flag */
- spinlock_t mbox_lock;
- u64 rsvd4;
+ spinlock_t mbox_lock;
+ u64 rsvd4;
};
struct hinic5_mbox_work {
- struct work_struct work;
- struct hinic5_mbox *func_to_func;
- struct hinic5_recv_mbox *recv_mbox;
+ struct work_struct work;
+ struct hinic5_mbox *func_to_func;
+ struct hinic5_recv_mbox *recv_mbox;
struct hinic5_msg_channel *msg_ch;
};
@@ -288,8 +281,8 @@ void hinic5_response_mbox_to_mgmt(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
int hinic5_send_mbox_to_mgmt_no_ack(struct hinic5_hwdev *hwdev, u8 mod, u16 cmd,
void *buf_in, u16 in_size, u16 channel);
int hinic5_mbox_to_func(struct hinic5_mbox *func_to_func, u8 mod, u16 cmd,
- u16 dst_func, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size, u32 timeout, u16 channel);
+ u16 dst_func, void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size, u32 timeout, u16 channel);
int hinic5_mbox_init_host_msg_channel(struct hinic5_hwdev *hwdev);
@@ -298,89 +291,103 @@ int hinic5_mbox_set_channel_status(struct hinic5_hwdev *hwdev, u16 channel,
void hinic5_mbox_enable_channel_lock(struct hinic5_hwdev *hwdev, bool enable);
-void mbox_msg_header_set_last(u64 *header, u16 msg_len, u8 mod,
- u16 seg_len, struct hinic5_hwdev *hwdev);
+void mbox_msg_header_set_last(u64 *header, u16 msg_len, u8 mod, u16 seg_len,
+ struct hinic5_hwdev *hwdev);
#define V0_MOD_ID_MAX 32
static inline u64 hinic5_mbox_set_msg_len(u8 version, u16 msg_len)
{
- if (version != 0)
- return HINIC5_MSG_HEADER_SET_V1(msg_len / MBOX_MSG_LEN_UNIT, MSG_LEN);
- else
+ if (version != 0) {
+ return HINIC5_MSG_HEADER_SET_V1(msg_len / MBOX_MSG_LEN_UNIT,
+ MSG_LEN);
+ } else {
return HINIC5_MSG_HEADER_SET_V0(msg_len, MSG_LEN);
+ }
}
static inline u16 hinic5_mbox_get_msg_len(u8 version, u64 *header)
{
- if (version != 0)
- return (u16)(HINIC5_MSG_HEADER_GET_V1(*header, MSG_LEN) * MBOX_MSG_LEN_UNIT);
- else
+ if (version != 0) {
+ return (u16)(HINIC5_MSG_HEADER_GET_V1(*header, MSG_LEN) *
+ MBOX_MSG_LEN_UNIT);
+ } else {
return HINIC5_MSG_HEADER_GET_V0(*header, MSG_LEN);
+ }
}
static inline u64 hinic5_mbox_set_seg_len(u8 version, u16 seg_len)
{
- if (version != 0)
- return HINIC5_MSG_HEADER_SET_V1(seg_len / MBOX_SEG_LEN_UNIT, SEG_LEN);
- else
+ if (version != 0) {
+ return HINIC5_MSG_HEADER_SET_V1(seg_len / MBOX_SEG_LEN_UNIT,
+ SEG_LEN);
+ } else {
return HINIC5_MSG_HEADER_SET_V0(seg_len, SEG_LEN);
+ }
}
static inline u8 hinic5_mbox_get_seg_len(u8 version, const u64 *header)
{
- if (version != 0)
- return (u8)(HINIC5_MSG_HEADER_GET_V1(*header, SEG_LEN) * MBOX_SEG_LEN_UNIT);
- else
+ if (version != 0) {
+ return (u8)(HINIC5_MSG_HEADER_GET_V1(*header, SEG_LEN) *
+ MBOX_SEG_LEN_UNIT);
+ } else {
return HINIC5_MSG_HEADER_GET_V0(*header, SEG_LEN);
+ }
}
static inline u64 hinic5_mbox_set_mod_id(u8 version, u8 mod)
{
- if (version != 0)
+ if (version != 0) {
return HINIC5_MSG_HEADER_SET_V1(mod, MODULE);
- else
+ } else {
return HINIC5_MSG_HEADER_SET_V0(mod, MODULE);
+ }
}
static inline u8 hinic5_mbox_get_mod_id(u8 version, const u64 *header)
{
- if (version != 0)
+ if (version != 0) {
return HINIC5_MSG_HEADER_GET_V1(*header, MODULE);
- else
+ } else {
return HINIC5_MSG_HEADER_GET_V0(*header, MODULE);
+ }
}
static inline u64 hinic5_mbox_set_version(u8 version)
{
- if (version != 0)
+ if (version != 0) {
return HINIC5_MSG_HEADER_SET(MPU_MAILBOX_HEADER_VER_1, VERSION);
- else
+ } else {
return HINIC5_MSG_HEADER_SET(MPU_MAILBOX_HEADER_VER_0, VERSION);
+ }
}
-static inline u8 hinic5_mbox_get_version(const struct hinic5_hwdev *hwdev, const u64 *header)
+static inline u8 hinic5_mbox_get_version(const struct hinic5_hwdev *hwdev,
+ const u64 *header)
{
return HINIC5_MSG_HEADER_GET(*header, VERSION);
}
-#define MBOX_SEGLEN_MASK_V0 \
+#define MBOX_SEGLEN_MASK_V0 \
HINIC5_MSG_HEADER_SET_V0(HINIC5_MSG_HEADER_V0_SEG_LEN_MASK, SEG_LEN)
-#define MBOX_SEGLEN_MASK_V1 \
+#define MBOX_SEGLEN_MASK_V1 \
HINIC5_MSG_HEADER_SET_V1(HINIC5_MSG_HEADER_V1_SEG_LEN_MASK, SEG_LEN)
static inline u64 hinic5_mbox_get_seg_len_mask(u8 version)
{
- if (version != 0)
+ if (version != 0) {
return MBOX_SEGLEN_MASK_V1;
- else
+ } else {
return MBOX_SEGLEN_MASK_V0;
+ }
}
-static inline u8 hinic5_mbox_get_send_version(const struct hinic5_hwdev *hwdev, u8 mod)
+static inline u8 hinic5_mbox_get_send_version(const struct hinic5_hwdev *hwdev,
+ u8 mod)
{
- if (COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) && mod >= V0_MOD_ID_MAX)
+ if (COMM_SUPPORT_MBOX_HEAD_VER1(hwdev) && mod >= V0_MOD_ID_MAX) {
return MPU_MAILBOX_HEADER_VER_1;
+ }
return MPU_MAILBOX_HEADER_VER_0;
}
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mgmt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mgmt.h
index 22b7a0db2..73c1ea7e8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_mgmt.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mgmt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_MGMT_H
#define HINIC5_MGMT_H
@@ -23,16 +16,13 @@
#include "hinic5_api_cmd.h"
#include "hinic5_hwdev.h"
-#define HINIC5_MGMT_WQ_NAME "hinic5_mgmt"
+#define HINIC5_MGMT_WQ_NAME "hinic5_mgmt"
-#define HINIC5_CLP_REG_GAP 0x20
-#define HINIC5_CLP_INPUT_BUF_LEN_HOST 4096UL
-#define HINIC5_CLP_DATA_UNIT_HOST 4UL
+#define HINIC5_CLP_REG_GAP 0x20
+#define HINIC5_CLP_INPUT_BUF_LEN_HOST 4096UL
+#define HINIC5_CLP_DATA_UNIT_HOST 4UL
-enum clp_data_type {
- HINIC5_CLP_REQ_HOST = 0,
- HINIC5_CLP_RSP_HOST = 1
-};
+enum clp_data_type { HINIC5_CLP_REQ_HOST = 0, HINIC5_CLP_RSP_HOST = 1 };
enum clp_reg_type {
HINIC5_CLP_BA_HOST = 0,
@@ -42,51 +32,51 @@ enum clp_reg_type {
HINIC5_CLP_READY_RSP_HOST = 4
};
-#define HINIC5_CLP_REQ_SIZE_OFFSET 0
-#define HINIC5_CLP_RSP_SIZE_OFFSET 16
-#define HINIC5_CLP_BASE_OFFSET 0
-#define HINIC5_CLP_LEN_OFFSET 0
-#define HINIC5_CLP_START_OFFSET 31
-#define HINIC5_CLP_READY_OFFSET 31
-#define HINIC5_CLP_OFFSET(member) (HINIC5_CLP_##member##_OFFSET)
-
-#define HINIC5_CLP_SIZE_MASK 0x7ffUL
-#define HINIC5_CLP_BASE_MASK 0x7ffffffUL
-#define HINIC5_CLP_LEN_MASK 0x7ffUL
-#define HINIC5_CLP_START_MASK 0x1UL
-#define HINIC5_CLP_READY_MASK 0x1UL
-#define HINIC5_CLP_MASK(member) (HINIC5_CLP_##member##_MASK)
-
-#define HINIC5_CLP_DELAY_CNT_MAX 200UL
-#define HINIC5_CLP_SRAM_SIZE_REG_MAX 0x3ff
-#define HINIC5_CLP_SRAM_BASE_REG_MAX 0x7ffffff
-#define HINIC5_CLP_LEN_REG_MAX 0x3ff
-#define HINIC5_CLP_START_OR_READY_REG_MAX 0x1
+#define HINIC5_CLP_REQ_SIZE_OFFSET 0
+#define HINIC5_CLP_RSP_SIZE_OFFSET 16
+#define HINIC5_CLP_BASE_OFFSET 0
+#define HINIC5_CLP_LEN_OFFSET 0
+#define HINIC5_CLP_START_OFFSET 31
+#define HINIC5_CLP_READY_OFFSET 31
+#define HINIC5_CLP_OFFSET(member) (HINIC5_CLP_##member##_OFFSET)
+
+#define HINIC5_CLP_SIZE_MASK 0x7ffUL
+#define HINIC5_CLP_BASE_MASK 0x7ffffffUL
+#define HINIC5_CLP_LEN_MASK 0x7ffUL
+#define HINIC5_CLP_START_MASK 0x1UL
+#define HINIC5_CLP_READY_MASK 0x1UL
+#define HINIC5_CLP_MASK(member) (HINIC5_CLP_##member##_MASK)
+
+#define HINIC5_CLP_DELAY_CNT_MAX 200UL
+#define HINIC5_CLP_SRAM_SIZE_REG_MAX 0x3ff
+#define HINIC5_CLP_SRAM_BASE_REG_MAX 0x7ffffff
+#define HINIC5_CLP_LEN_REG_MAX 0x3ff
+#define HINIC5_CLP_START_OR_READY_REG_MAX 0x1
struct hinic5_recv_msg {
- void *msg;
+ void *msg;
- u16 msg_len;
- u16 rsvd1;
- enum hinic5_mod_type mod;
+ u16 msg_len;
+ u16 rsvd1;
+ enum hinic5_mod_type mod;
- u16 cmd;
- u8 seq_id;
- u8 rsvd2;
- u16 msg_id;
- u16 rsvd3;
+ u16 cmd;
+ u8 seq_id;
+ u8 rsvd2;
+ u16 msg_id;
+ u16 rsvd3;
- int async_mgmt_to_pf;
- u32 rsvd4;
+ int async_mgmt_to_pf;
+ u32 rsvd4;
- struct completion recv_done;
+ struct completion recv_done;
};
struct hinic5_msg_head {
- u8 status;
- u8 version;
- u8 resp_aeq_num;
- u8 rsvd0[5];
+ u8 status;
+ u8 version;
+ u8 resp_aeq_num;
+ u8 rsvd0[5];
};
enum comm_pf_to_mgmt_event_state {
@@ -104,56 +94,56 @@ enum hinic5_mgmt_msg_cb_state {
};
struct hinic5_clp_pf_to_mgmt {
- struct semaphore clp_msg_lock;
- void *clp_msg_buf;
+ struct semaphore clp_msg_lock;
+ void *clp_msg_buf;
};
struct hinic5_msg_pf_to_mgmt {
- struct hinic5_hwdev *hwdev;
+ struct hinic5_hwdev *hwdev;
/* Async cmd can not be scheduling */
- spinlock_t async_msg_lock;
- struct semaphore sync_msg_lock;
+ spinlock_t async_msg_lock;
+ struct semaphore sync_msg_lock;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- void *async_msg_buf;
- void *sync_msg_buf;
- void *mgmt_ack_buf;
+ void *async_msg_buf;
+ void *sync_msg_buf;
+ void *mgmt_ack_buf;
- struct hinic5_recv_msg recv_msg_from_mgmt;
- struct hinic5_recv_msg recv_resp_msg_from_mgmt;
+ struct hinic5_recv_msg recv_msg_from_mgmt;
+ struct hinic5_recv_msg recv_resp_msg_from_mgmt;
- u16 async_msg_id;
- u16 sync_msg_id;
- u32 rsvd1;
- struct hinic5_api_cmd_chain *cmd_chain[HINIC5_API_CMD_MAX];
+ u16 async_msg_id;
+ u16 sync_msg_id;
+ u32 rsvd1;
+ struct hinic5_api_cmd_chain *cmd_chain[HINIC5_API_CMD_MAX];
- hinic5_mgmt_msg_cb recv_mgmt_msg_cb[HINIC5_MOD_HW_MAX];
- void *recv_mgmt_msg_data[HINIC5_MOD_HW_MAX];
- ulong mgmt_msg_cb_state[HINIC5_MOD_HW_MAX];
+ hinic5_mgmt_msg_cb recv_mgmt_msg_cb[HINIC5_MOD_HW_MAX];
+ void *recv_mgmt_msg_data[HINIC5_MOD_HW_MAX];
+ ulong mgmt_msg_cb_state[HINIC5_MOD_HW_MAX];
- void *async_msg_cb_data[HINIC5_MOD_HW_MAX];
+ void *async_msg_cb_data[HINIC5_MOD_HW_MAX];
/* lock when sending msg */
- spinlock_t sync_event_lock;
+ spinlock_t sync_event_lock;
enum comm_pf_to_mgmt_event_state event_flag;
- u64 rsvd2;
+ u64 rsvd2;
};
struct hinic5_mgmt_msg_handle_work {
- struct work_struct work;
+ struct work_struct work;
struct hinic5_msg_pf_to_mgmt *pf_to_mgmt;
- void *msg;
- u16 msg_len;
- u16 rsvd1;
+ void *msg;
+ u16 msg_len;
+ u16 rsvd1;
- enum hinic5_mod_type mod;
- u16 cmd;
- u16 msg_id;
+ enum hinic5_mod_type mod;
+ u16 cmd;
+ u16 msg_id;
- int async_mgmt_to_pf;
+ int async_mgmt_to_pf;
};
void hinic5_mgmt_msg_aeqe_handler(void *hwdev, u8 *header, u8 size);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_typedef_inner.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_typedef_inner.h
deleted file mode 100644
index dfb5295fe..000000000
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/include/hinic5_typedef_inner.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_typedef_inner.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
-#ifndef HINIC5_TYPESDEF_INNER_H
-#define HINIC5_TYPESDEF_INNER_H
-
-/* static methods testable */
-#ifdef EXPORT_STATIC_SYMBOL
-#define STATIC (__weak noinline)
-#define INLINE (__weak noinline)
-#else
-#define STATIC static
-#define INLINE inline
-#endif
-
-#ifndef GIT_COMMIT_ID
-#define GIT_COMMIT_ID "unknown"
-#endif
-
-#endif /* HINIC5_TYPESDEF_INNER_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.c
index d617ca9c3..7bb96ade7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bus.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -62,21 +55,23 @@ struct hinic5_bus_ops *hinic5_get_dev_ops(struct hinic5_adev *adev)
default:
break;
}
- sdk_err(adev->dev, "Failed to get valid struct hinic5_bus_ops object, dev_type=%d\n",
+ sdk_err(adev->dev,
+ "Failed to get valid struct hinic5_bus_ops object, dev_type=%d\n",
adev->lld_dev.dev_type);
return NULL;
}
/*
- * SDK driver needs to support both UB and PCI scenarios, ub and pci drivers need to register
- */
+SDK驱动需要同时支持UB、PCI场景,ub和pci driver都需要注册
+*/
int hinic5_register_driver(void)
{
int err;
err = hinic5_pci_register_driver();
- if (err != 0)
+ if (err != 0) {
return err;
+ }
#ifdef __UBUS_DRIVER__
err = hinic5_ubus_register_driver();
@@ -97,13 +92,13 @@ void hinic5_unregister_driver(void)
}
/**
- * @brief Determine if the current device is a VF type
- * @param adev Device adapter layer structure pointer
+ * @brief 判断当前设备是否为vf类型
+ * @param adev 设备适配层结构体指针
* @details vf is considered as pf in a virtual machine, that is
vf in host -- return 1
- vf in vm -- return 0
+ vf in vm -- return 0
*
- * @return 0 for PF, 1 for VF
+ * @return 0表示为pf,1表示为vf
*/
bool hinic5_adev_is_virtfn(struct hinic5_adev *adev)
{
@@ -120,7 +115,8 @@ int hinic5_set_func_en(struct hinic5_adev *adev, bool en, u16 vf_func_id)
return adev->bus_ops->set_func_en(adev, en, vf_func_id);
}
-struct hinic5_adev *hinic5_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id)
+struct hinic5_adev *hinic5_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id)
{
return adev->bus_ops->get_vf_adev_by_pf(adev, func_id);
}
@@ -141,9 +137,11 @@ u16 hinic5_adev_get_device_id(struct hinic5_adev *adev)
return adev->bus_ops->get_device_id(adev);
}
-int hinic5_adev_irq_vectors_alloc(struct hinic5_adev *adev, void *entry, u32 irqs_min, u32 irqs_num)
+int hinic5_adev_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num)
{
- return adev->bus_ops->irq_vectors_alloc(adev, entry, irqs_min, irqs_num);
+ return adev->bus_ops->irq_vectors_alloc(adev, entry, irqs_min,
+ irqs_num);
}
void hinic5_adev_irq_vectors_free(struct hinic5_adev *adev)
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.h
index 65348508f..87b103074 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_bus.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_bus.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_BUS_H
#define HINIC5_BUS_H
@@ -18,10 +11,13 @@ struct hinic5_adev;
struct hinic5_bus_ops {
bool (*is_virtfn)(struct hinic5_adev *adev);
struct hinic5_adev *(*get_pf_adev)(struct hinic5_adev *adev);
- int (*set_func_en)(struct hinic5_adev *dst_adev, bool en, u16 vf_func_id);
- struct hinic5_adev *(*get_vf_adev_by_pf)(struct hinic5_adev *adev, u16 func_id);
+ int (*set_func_en)(struct hinic5_adev *dst_adev, bool en,
+ u16 vf_func_id);
+ struct hinic5_adev *(*get_vf_adev_by_pf)(struct hinic5_adev *adev,
+ u16 func_id);
u16 (*get_device_id)(struct hinic5_adev *adev);
- int (*irq_vectors_alloc)(struct hinic5_adev *adev, void *entry, u32 irqs_min, u32 irqs_num);
+ int (*irq_vectors_alloc)(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num);
void (*irq_vectors_free)(struct hinic5_adev *adev);
int (*irq_vector)(struct hinic5_adev *adev, u32 idx);
int (*get_vf_num)(struct hinic5_adev *adev);
@@ -33,26 +29,26 @@ struct hinic5_bus_ops {
enum hinic5_sriov_state {
HINIC5_SRIOV_DISABLE,
HINIC5_SRIOV_ENABLE,
- HINIC5_FUNC_PERSENT,
+ HINIC5_FUNC_PRESENT,
};
struct hinic5_sriov_info {
bool sriov_enabled;
unsigned int num_vfs;
ulong state;
- unsigned short first_ue_idx; /* ubus first vf ue_idx under current pf */
};
bool hinic5_adev_is_virtfn(struct hinic5_adev *adev);
struct hinic5_adev *hinic5_adev_get_pf_adev(struct hinic5_adev *adev);
-struct hinic5_adev *hinic5_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id);
+struct hinic5_adev *hinic5_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id);
int hinic5_set_func_en(struct hinic5_adev *adev, bool en, u16 vf_func_id);
int hinic5_adev_get_vf_num(struct hinic5_adev *adev);
u16 hinic5_adev_get_device_id(struct hinic5_adev *adev);
#ifndef __UEFI__
-int hinic5_adev_irq_vectors_alloc(struct hinic5_adev *adev,
- void *entry, u32 irqs_min, u32 irqs_num);
+int hinic5_adev_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num);
void hinic5_adev_irq_vectors_free(struct hinic5_adev *adev);
int hinic5_adev_irq_vector(struct hinic5_adev *adev, u32 idx);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.c
index c88a58578..3353ff77f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dev_mgmt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -22,11 +15,13 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#include "securec.h"
#include "mpu_inband_cmd_defs.h"
#include "bond_pub_cmd.h"
#include "hinic5_mt.h"
#include "hinic5_crm.h"
#include "hinic5_lld.h"
+#include "hinic5_lld_common.h"
#include "hinic5_lld_inner.h"
#include "hinic5_sriov.h"
#include "hinic5_id_tbl.h"
@@ -34,9 +29,9 @@
#include "hinic5_fw_update.h"
#include "hinic5_dev_mgmt.h"
-#define HINIC5_WAIT_TOOL_CNT_TIMEOUT 10000
-#define HINIC5_WAIT_TOOL_MIN_USLEEP_TIME 9900
-#define HINIC5_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HINIC5_WAIT_TOOL_CNT_TIMEOUT 10000
+#define HINIC5_WAIT_TOOL_MIN_USLEEP_TIME 9900
+#define HINIC5_WAIT_TOOL_MAX_USLEEP_TIME 10000
static ulong card_bit_map;
@@ -47,30 +42,31 @@ inline struct list_head *get_hinic5_chip_list(void)
return &g_hinic5_chip_list;
}
-void hinic5_uld_dev_hold(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+void uld5_dev_hold(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type)
{
struct hinic5_adev *adev = NULL;
-
if (type >= SERVICE_T_MAX) {
pr_err("array uld_ref_cnt upper bound\n");
return;
}
if (!lld_dev || !to_hinic5_adev(lld_dev)) {
- pr_err("lld_dev is null, srv_type = 0x%x, when uld dev hold\n", type);
+ pr_err("lld_dev is null, srv_type = 0x%x, when uld dev hold\n",
+ type);
return;
}
adev = to_hinic5_adev(lld_dev);
atomic_inc(&adev->uld_ref_cnt[type]);
}
-EXPORT_SYMBOL(hinic5_uld_dev_hold);
+EXPORT_SYMBOL(uld5_dev_hold);
-void hinic5_uld_dev_put(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+void uld5_dev_put(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
{
struct hinic5_adev *adev = NULL;
-
if (!lld_dev || !to_hinic5_adev(lld_dev)) {
- pr_err("lld_dev is null, srv_type = 0x%x, when uld dev put\n", type);
+ pr_err("lld_dev is null, srv_type = 0x%x, when uld dev put\n",
+ type);
return;
}
if (type >= SERVICE_T_MAX) {
@@ -81,30 +77,39 @@ void hinic5_uld_dev_put(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type
atomic_dec(&adev->uld_ref_cnt[type]);
}
-EXPORT_SYMBOL(hinic5_uld_dev_put);
+EXPORT_SYMBOL(uld5_dev_put);
-void hinic5_lld_dev_cnt_init(struct hinic5_adev *adev)
+void lld_dev_cnt_init(struct hinic5_adev *adev)
{
atomic_set(&adev->ref_cnt, 0);
}
void hinic5_lld_dev_hold(struct hinic5_lld_dev *dev)
{
- struct hinic5_adev *adev = to_hinic5_adev(dev);
+ struct hinic5_adev *adev = NULL;
+ if (WARN_ON_ONCE(!dev))
+ return;
+
+ adev = to_hinic5_adev(dev);
atomic_inc(&adev->ref_cnt);
}
EXPORT_SYMBOL(hinic5_lld_dev_hold);
void hinic5_lld_dev_put(struct hinic5_lld_dev *dev)
{
- struct hinic5_adev *adev = to_hinic5_adev(dev);
+ struct hinic5_adev *adev = NULL;
+
+ if (WARN_ON_ONCE(!dev))
+ return;
- atomic_dec(&adev->ref_cnt);
+ adev = to_hinic5_adev(dev);
+ if (atomic_dec_return(&adev->ref_cnt) < 0)
+ sdk_err(dev->dev, "Device refcount is less than 0.\n");
}
EXPORT_SYMBOL(hinic5_lld_dev_put);
-void hinic5_wait_lld_dev_unused(struct hinic5_adev *adev)
+void wait_lld_dev_unused(struct hinic5_adev *adev)
{
ulong end;
@@ -120,42 +125,42 @@ void hinic5_wait_lld_dev_unused(struct hinic5_adev *adev)
}
enum hinic5_lld_status {
- HINIC5_NODE_CHANGE = BIT(0),
+ HINIC5_NODE_CHANGE = BIT(0),
};
struct hinic5_lld_lock {
/* lock for chip list */
- struct mutex lld_mutex;
- ulong status;
- atomic_t dev_ref_cnt;
+ struct mutex lld_mutex;
+ ulong status;
+ atomic_t dev_ref_cnt;
};
-struct hinic5_lld_lock hinic5_g_lld_lock;
+struct hinic5_lld_lock g_lld_lock;
-/* max mbox timeout (200s) + extra (100s) */
-#define WAIT_LLD_DEV_HOLD_TIMEOUT (300 * 1000)
-#define WAIT_LLD_DEV_NODE_CHANGED WAIT_LLD_DEV_HOLD_TIMEOUT
-#define WAIT_LLD_DEV_REF_CNT_EMPTY (2 * 60 * 1000) /* 2minutes */
-#define PRINT_TIMEOUT_INTERVAL 10000
-#define MS_PER_SEC 1000
-#define LLD_LOCK_MIN_USLEEP_TIME 900
-#define LLD_LOCK_MAX_USLEEP_TIME 1000
+#define WAIT_LLD_DEV_HOLD_TIMEOUT \
+ (300 * 1000) /* max mbox timeout (200s) + extra (100s) */
+#define WAIT_LLD_DEV_NODE_CHANGED WAIT_LLD_DEV_HOLD_TIMEOUT
+#define WAIT_LLD_DEV_REF_CNT_EMPTY (2 * 60 * 1000) /* 2minutes */
+#define PRINT_TIMEOUT_INTERVAL 10000
+#define MS_PER_SEC 1000
+#define LLD_LOCK_MIN_USLEEP_TIME 900
+#define LLD_LOCK_MAX_USLEEP_TIME 1000
/* node in chip_node will changed, tools or driver can't get node
* during this situation
*/
-void hinic5_lld_lock_chip_node(void)
+void lld_lock_chip_node(void)
{
ulong end;
bool timeout = true;
u32 loop_cnt;
- mutex_lock(&hinic5_g_lld_lock.lld_mutex);
+ mutex_lock(&g_lld_lock.lld_mutex);
loop_cnt = 0;
end = jiffies + msecs_to_jiffies(WAIT_LLD_DEV_NODE_CHANGED);
do {
- if (!test_and_set_bit(HINIC5_NODE_CHANGE, &hinic5_g_lld_lock.status)) {
+ if (!test_and_set_bit(HINIC5_NODE_CHANGE, &g_lld_lock.status)) {
timeout = false;
break;
}
@@ -170,14 +175,14 @@ void hinic5_lld_lock_chip_node(void)
LLD_LOCK_MAX_USLEEP_TIME);
} while (time_before(jiffies, end));
- if (timeout && test_and_set_bit(HINIC5_NODE_CHANGE, &hinic5_g_lld_lock.status))
+ if (timeout && test_and_set_bit(HINIC5_NODE_CHANGE, &g_lld_lock.status))
pr_warn("Wait for lld node change complete timeout when trying to get lld lock\n");
loop_cnt = 0;
timeout = true;
end = jiffies + msecs_to_jiffies(WAIT_LLD_DEV_NODE_CHANGED);
do {
- if (atomic_read(&hinic5_g_lld_lock.dev_ref_cnt) == 0) {
+ if (atomic_read(&g_lld_lock.dev_ref_cnt) == 0) {
timeout = false;
break;
}
@@ -186,38 +191,38 @@ void hinic5_lld_lock_chip_node(void)
if (loop_cnt % PRINT_TIMEOUT_INTERVAL == 0)
pr_warn("Wait for lld dev unused for %us, reference count: %d\n",
loop_cnt / MS_PER_SEC,
- atomic_read(&hinic5_g_lld_lock.dev_ref_cnt));
+ atomic_read(&g_lld_lock.dev_ref_cnt));
/* if sleep 1ms, use usleep_range to be more precise */
usleep_range(LLD_LOCK_MIN_USLEEP_TIME,
LLD_LOCK_MAX_USLEEP_TIME);
} while (time_before(jiffies, end));
- if (timeout && (atomic_read(&hinic5_g_lld_lock.dev_ref_cnt) != 0))
+ if (timeout && (atomic_read(&g_lld_lock.dev_ref_cnt) != 0))
pr_warn("Wait for lld dev unused timeout\n");
- mutex_unlock(&hinic5_g_lld_lock.lld_mutex);
+ mutex_unlock(&g_lld_lock.lld_mutex);
}
-void hinic5_lld_unlock_chip_node(void)
+void lld_unlock_chip_node(void)
{
- clear_bit(HINIC5_NODE_CHANGE, &hinic5_g_lld_lock.status);
+ clear_bit(HINIC5_NODE_CHANGE, &g_lld_lock.status);
}
/* When tools or other drivers want to get node of chip_node, use this function
* to prevent node be freed
*/
-void hinic5_lld_hold(void)
+void lld_hold(void)
{
ulong end;
u32 loop_cnt = 0;
/* ensure there have not any chip node in changing */
- mutex_lock(&hinic5_g_lld_lock.lld_mutex);
+ mutex_lock(&g_lld_lock.lld_mutex);
end = jiffies + msecs_to_jiffies(WAIT_LLD_DEV_HOLD_TIMEOUT);
do {
- if (!test_bit(HINIC5_NODE_CHANGE, &hinic5_g_lld_lock.status))
+ if (!test_bit(HINIC5_NODE_CHANGE, &g_lld_lock.status))
break;
loop_cnt++;
@@ -230,22 +235,22 @@ void hinic5_lld_hold(void)
LLD_LOCK_MAX_USLEEP_TIME);
} while (time_before(jiffies, end));
- if (test_bit(HINIC5_NODE_CHANGE, &hinic5_g_lld_lock.status))
+ if (test_bit(HINIC5_NODE_CHANGE, &g_lld_lock.status))
pr_warn("Wait lld node change complete timeout when trying to hode lld dev\n");
- atomic_inc(&hinic5_g_lld_lock.dev_ref_cnt);
- mutex_unlock(&hinic5_g_lld_lock.lld_mutex);
+ atomic_inc(&g_lld_lock.dev_ref_cnt);
+ mutex_unlock(&g_lld_lock.lld_mutex);
}
-void hinic5_lld_put(void)
+void lld_put(void)
{
- atomic_dec(&hinic5_g_lld_lock.dev_ref_cnt);
+ atomic_dec(&g_lld_lock.dev_ref_cnt);
}
void hinic5_lld_lock_init(void)
{
- mutex_init(&hinic5_g_lld_lock.lld_mutex);
- atomic_set(&hinic5_g_lld_lock.dev_ref_cnt, 0);
+ mutex_init(&g_lld_lock.lld_mutex);
+ atomic_set(&g_lld_lock.dev_ref_cnt, 0);
}
void hinic5_get_all_chip_id(void *id_info)
@@ -255,22 +260,25 @@ void hinic5_get_all_chip_id(void *id_info)
int i = 0;
int id, err;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
- err = sscanf(chip_node->chip_name, HINIC5_CHIP_NAME "%d", &id);
- if (err != 1) {
+ err = sscanf_s(chip_node->chip_name, HINIC5_CHIP_NAME "%d",
+ &id);
+ if (err < 0) {
pr_err("Failed to get hinic5 id\n");
continue;
}
card_id->id[i] = (u32)id;
i++;
}
- hinic5_lld_put();
+ lld_put();
card_id->num = (u32)i;
}
-static bool is_pcidev_match_chip_name(const char *ifname, struct hinic5_adev *adev,
- struct card_node *chip_node, enum func_type type)
+static bool is_pcidev_match_chip_name(const char *ifname,
+ struct hinic5_adev *adev,
+ struct card_node *chip_node,
+ enum func_type type)
{
if (strncmp(chip_node->chip_name, ifname, IFNAMSIZ) == 0) {
if (hinic5_func_type(adev->hwdev) != type)
@@ -280,33 +288,34 @@ static bool is_pcidev_match_chip_name(const char *ifname, struct hinic5_adev *ad
return false;
}
-
/**
- * @brief get_dst_type_lld_dev_by_chip_name - Get lld device pointer by device name
+ * @brief get_dst_type_lld_dev_by_chip_name - 根据设备名称获取lld 设备指针
*
- * @param[in] ifname Device name hinic0
- * @param[in] type function type
- * @param[in] check_active_flag Whether to check if function status is available
+ * @param[in] ifname 设备名称 hinic0
+ * @param[in] type function类型
+ * @param[in] check_active_flag 是否判断function的状态可用
*
* @details NA
*
* @attention: NA
*
- * @return: Returns the queried device
- * @retval NULL Query no match
- * @retval non-NULL Matched device
+ * @return: 返回查询到的设备
+ * @retval NULL 查询无匹配
+ * @retval 非NULL 匹配设备
*/
-static struct hinic5_lld_dev *get_dst_type_lld_dev_by_chip_name(const char *ifname,
- enum func_type type,
- bool check_active_flag)
+static struct hinic5_lld_dev *
+get_dst_type_lld_dev_by_chip_name(const char *ifname, enum func_type type,
+ bool check_active_flag)
{
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
- if ((!check_active_flag || hinic5_is_function_active(adev->hwdev)) &&
- is_pcidev_match_chip_name(ifname, adev, chip_node, type)) {
+ if ((!check_active_flag ||
+ hinic5_is_function_active(adev->hwdev)) &&
+ is_pcidev_match_chip_name(ifname, adev, chip_node,
+ type)) {
return &adev->lld_dev;
}
}
@@ -319,20 +328,25 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_chip_name(const char *chip_name)
{
struct hinic5_lld_dev *dev = NULL;
int i;
- bool check_active_flag[] = {true, false};
+ bool check_active_flag[] = { true, false };
- hinic5_lld_hold();
+ lld_hold();
- for (i = 0; i < sizeof(check_active_flag) / sizeof(check_active_flag[0]); i++) {
- dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_PPF, check_active_flag[i]);
+ for (i = 0;
+ i < sizeof(check_active_flag) / sizeof(check_active_flag[0]);
+ i++) {
+ dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_PPF,
+ check_active_flag[i]);
if (dev)
goto out;
- dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_PF, check_active_flag[i]);
+ dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_PF,
+ check_active_flag[i]);
if (dev)
goto out;
- dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_VF, check_active_flag[i]);
+ dev = get_dst_type_lld_dev_by_chip_name(chip_name, TYPE_VF,
+ check_active_flag[i]);
if (dev)
goto out;
}
@@ -340,51 +354,56 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_chip_name(const char *chip_name)
out:
if (dev)
hinic5_lld_dev_hold(dev);
- hinic5_lld_put();
+ lld_put();
return dev;
}
EXPORT_SYMBOL(hinic5_get_lld_dev_by_chip_name);
-static int get_dynamic_bond_uld_dev_name(struct hinic5_adev *adev, enum hinic5_service_type type,
+static int get_dynamic_bond_uld_dev_name(struct hinic5_adev *adev,
+ enum hinic5_service_type type,
char *ifname)
{
- const struct hinic5_uld_info *uld_info = hinic5_get_uld_info_by_type(type);
+ const struct hinic5_uld_info *uld_info =
+ hinic5_get_uld_info_by_type(type);
u32 out_size = IFNAMSIZ;
if (!uld_info || !uld_info->ioctl || !adev->uld_dev[type])
return -EFAULT;
- return uld_info->ioctl(adev->uld_dev[type], CMD_CUSTOM_BOND_GET_ULD_DEV_NAME,
- NULL, 0, ifname, &out_size);
+ return uld_info->ioctl(adev->uld_dev[type],
+ CMD_CUSTOM_BOND_GET_ULD_DEV_NAME, NULL, 0,
+ ifname, &out_size);
}
-static int get_dynamic_uld_dev_name(struct hinic5_adev *adev, enum hinic5_service_type type,
- char *ifname)
+static int get_dynamic_uld_dev_name(struct hinic5_adev *adev,
+ enum hinic5_service_type type, char *ifname)
{
- const struct hinic5_uld_info *uld_info = hinic5_get_uld_info_by_type(type);
+ const struct hinic5_uld_info *uld_info =
+ hinic5_get_uld_info_by_type(type);
u32 out_size = IFNAMSIZ;
if (!uld_info || !uld_info->ioctl)
return -EFAULT;
- return uld_info->ioctl(adev->uld_dev[type], GET_ULD_DEV_NAME,
- NULL, 0, ifname, &out_size);
+ return uld_info->ioctl(adev->uld_dev[type], GET_ULD_DEV_NAME, NULL, 0,
+ ifname, &out_size);
}
-static bool is_pcidev_match_dev_name(const char *dev_name, struct hinic5_adev *adev,
+static bool is_pcidev_match_dev_name(const char *dev_name,
+ struct hinic5_adev *adev,
enum hinic5_service_type type)
{
- int i;
- char nic_uld_name[IFNAMSIZ] = {0};
- int err;
+ char nic_uld_name[IFNAMSIZ] = { 0 };
+ int i, err;
if (type > SERVICE_T_MAX)
return false;
if (type == SERVICE_T_MAX) {
for (i = SERVICE_T_OVS; i < SERVICE_T_MAX; i++) {
- if (strncmp(adev->uld_dev_name[i], dev_name, IFNAMSIZ) == 0)
+ if (strncmp(adev->uld_dev_name[i], dev_name,
+ IFNAMSIZ) == 0)
return true;
}
} else {
@@ -393,14 +412,16 @@ static bool is_pcidev_match_dev_name(const char *dev_name, struct hinic5_adev *a
}
if (type == SERVICE_T_CUSTOM) {
- err = get_dynamic_bond_uld_dev_name(adev, SERVICE_T_CUSTOM, (char *)nic_uld_name);
+ err = get_dynamic_bond_uld_dev_name(adev, SERVICE_T_CUSTOM,
+ (char *)nic_uld_name);
if (err == 0) {
if (strncmp(nic_uld_name, dev_name, IFNAMSIZ) == 0)
return true;
}
}
- err = get_dynamic_uld_dev_name(adev, SERVICE_T_NIC, (char *)nic_uld_name);
+ err = get_dynamic_uld_dev_name(adev, SERVICE_T_NIC,
+ (char *)nic_uld_name);
if (err == 0) {
if (strncmp(nic_uld_name, dev_name, IFNAMSIZ) == 0)
return true;
@@ -409,63 +430,67 @@ static bool is_pcidev_match_dev_name(const char *dev_name, struct hinic5_adev *a
return false;
}
-static struct hinic5_lld_dev *get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic5_service_type type, bool hold)
+static struct hinic5_lld_dev *
+get_lld_dev_by_dev_name(const char *dev_name, enum hinic5_service_type type,
+ bool hold)
{
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
if (is_pcidev_match_dev_name(dev_name, adev, type)) {
if (hold)
hinic5_lld_dev_hold(&adev->lld_dev);
- hinic5_lld_put();
+ lld_put();
return &adev->lld_dev;
}
}
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id)
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id)
{
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
if (hinic5_func_type(adev->hwdev) == TYPE_VF)
continue;
if ((hinic5_physical_port_id(adev->hwdev) == port_id) &&
- (strncmp(chip_node->chip_name, chip_name, IFNAMSIZ) == 0) &&
+ (strncmp(chip_node->chip_name, chip_name,
+ IFNAMSIZ) == 0) &&
(hinic5_support_nic(adev->hwdev, NULL) != 0)) {
hinic5_lld_dev_hold(&adev->lld_dev);
- hinic5_lld_put();
+ lld_put();
return &adev->lld_dev;
}
}
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
-struct hinic5_lld_dev *hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name)
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name)
{
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
struct hinic5_hwdev *hwdev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
if (strncmp(chip_node->chip_name, chip_name, IFNAMSIZ) != 0)
continue;
@@ -478,13 +503,13 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_with_l3i_enabled(const char *chip_name
if (hinic5_fw_update_ddr_enabled(hwdev)) {
hinic5_lld_dev_hold(&adev->lld_dev);
- hinic5_lld_put();
+ lld_put();
return &adev->lld_dev;
}
}
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
@@ -495,24 +520,26 @@ void *hinic5_get_ppf_dev(void)
struct hinic5_adev *adev = NULL;
struct list_head *chip_list = NULL;
- hinic5_lld_hold();
+ lld_hold();
chip_list = get_hinic5_chip_list();
list_for_each_entry(chip_node, chip_list, node)
list_for_each_entry(adev, &chip_node->func_list, node)
if (hinic5_func_type(adev->hwdev) == TYPE_PPF) {
- pr_info("Get ppf_func_id:%u", hinic5_global_func_id(adev->hwdev));
- hinic5_lld_put();
+ pr_info("Get ppf_func_id:%u",
+ hinic5_global_func_id(adev->hwdev));
+ lld_put();
return adev->lld_dev.hwdev;
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
EXPORT_SYMBOL(hinic5_get_ppf_dev);
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic5_service_type type)
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_dev_name(const char *dev_name,
+ enum hinic5_service_type type)
{
if (!dev_name) {
pr_err("dev_name is null\n");
@@ -520,9 +547,11 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name(const char *dev_name,
}
return get_lld_dev_by_dev_name(dev_name, type, true);
}
+EXPORT_SYMBOL(hinic5_get_lld_dev_by_dev_name);
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic5_service_type type)
+struct hinic5_lld_dev *
+hinic5_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
+ enum hinic5_service_type type)
{
if (!dev_name) {
pr_err("dev_name is null\n");
@@ -532,8 +561,8 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev_name_unsafe(const char *dev_nam
}
EXPORT_SYMBOL(hinic5_get_lld_dev_by_dev_name_unsafe);
-static void *get_uld_by_lld_dev(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type,
- bool hold)
+static void *get_uld_by_lld_dev(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type, bool hold)
{
struct hinic5_adev *adev = NULL;
void *uld = NULL;
@@ -559,27 +588,32 @@ static void *get_uld_by_lld_dev(struct hinic5_lld_dev *lld_dev, enum hinic5_serv
return uld;
}
-void *hinic5_get_uld_dev(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+void *hinic5_get_uld_dev(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type)
{
if (!lld_dev) {
- pr_err("lld_dev is null, srv_type = 0x%x, when get uld dev\n", type);
+ pr_err("lld_dev is null, srv_type = 0x%x, when get uld dev\n",
+ type);
return NULL;
}
return get_uld_by_lld_dev(lld_dev, type, true);
}
EXPORT_SYMBOL(hinic5_get_uld_dev);
-void *hinic5_get_uld_dev_unsafe(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+void *hinic5_get_uld_dev_unsafe(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type)
{
if (!lld_dev) {
- pr_err("lld_dev is null, srv_type = 0x%x, when get uld dev unsafe\n", type);
+ pr_err("lld_dev is null, srv_type = 0x%x, when get uld dev unsafe\n",
+ type);
return NULL;
}
return get_uld_by_lld_dev(lld_dev, type, false);
}
EXPORT_SYMBOL(hinic5_get_uld_dev_unsafe);
-static struct hinic5_lld_dev *get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev, bool hold)
+static struct hinic5_lld_dev *get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev,
+ bool hold)
{
struct hinic5_adev *adev = NULL;
struct card_node *chip_node = NULL;
@@ -592,19 +626,21 @@ static struct hinic5_lld_dev *get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev, bo
if (!adev)
return NULL;
- hinic5_lld_hold();
+ lld_hold();
chip_node = adev->chip_node;
list_for_each_entry(temp_adev, &chip_node->func_list, node) {
- /* In single card multi-cpihost scenario, multiple ppfs exist in the linked list */
- if (temp_adev->hwdev && hinic5_func_type(temp_adev->hwdev) == TYPE_PPF &&
- hinic5_global_func_id(temp_adev->hwdev) == hinic5_ppf_idx(lld_dev->hwdev)) {
+ /* 单卡多cpihost场景下,链表中存在多个ppf */
+ if (temp_adev->hwdev &&
+ hinic5_func_type(temp_adev->hwdev) == TYPE_PPF &&
+ hinic5_global_func_id(temp_adev->hwdev) ==
+ hinic5_ppf_idx(lld_dev->hwdev)) {
if (hold)
hinic5_lld_dev_hold(&temp_adev->lld_dev);
- hinic5_lld_put();
+ lld_put();
return &temp_adev->lld_dev;
}
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
@@ -615,7 +651,8 @@ struct hinic5_lld_dev *hinic5_get_ppf_lld_dev(struct hinic5_lld_dev *lld_dev)
}
EXPORT_SYMBOL(hinic5_get_ppf_lld_dev);
-struct hinic5_lld_dev *hinic5_get_ppf_lld_dev_unsafe(struct hinic5_lld_dev *lld_dev)
+struct hinic5_lld_dev *
+hinic5_get_ppf_lld_dev_unsafe(struct hinic5_lld_dev *lld_dev)
{
return get_ppf_lld_dev(lld_dev, false);
}
@@ -632,8 +669,10 @@ void *hinic5_get_ppf_hw_dev_unsafe(void *hwdev)
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
- if (adev->hwdev && hinic5_func_type(adev->hwdev) == TYPE_PPF)
+ if (adev->hwdev &&
+ hinic5_func_type(adev->hwdev) == TYPE_PPF) {
return adev->lld_dev.hwdev;
+ }
}
}
@@ -642,22 +681,27 @@ void *hinic5_get_ppf_hw_dev_unsafe(void *hwdev)
}
EXPORT_SYMBOL(hinic5_get_ppf_hw_dev_unsafe);
-int hinic5_get_chip_name(struct hinic5_lld_dev *lld_dev, char *chip_name, u16 max_len)
+int hinic5_get_chip_name(struct hinic5_lld_dev *lld_dev, char *chip_name,
+ u16 max_len)
{
struct hinic5_adev *adev = NULL;
- if (!lld_dev || !chip_name || max_len == 0)
+ if (!lld_dev || !chip_name || (max_len == 0))
return -EINVAL;
adev = to_hinic5_adev(lld_dev);
if (!adev)
return -EFAULT;
- hinic5_lld_hold();
- strscpy(chip_name, adev->chip_node->chip_name, max_len);
+ lld_hold();
+ if (strncpy_s(chip_name, max_len, adev->chip_node->chip_name,
+ max_len - 1) != EOK) {
+ lld_put();
+ return -EFAULT;
+ }
chip_name[max_len - 1] = '\0';
- hinic5_lld_put();
+ lld_put();
return 0;
}
@@ -684,7 +728,7 @@ static struct card_node *hinic5_get_chip_node_by_hwdev(const void *hwdev)
if (!hwdev)
return NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(node_tmp, get_hinic5_chip_list(), node) {
if (!chip_node) {
@@ -697,7 +741,7 @@ static struct card_node *hinic5_get_chip_node_by_hwdev(const void *hwdev)
}
}
- hinic5_lld_put();
+ lld_put();
return chip_node;
}
@@ -726,22 +770,20 @@ void hinic5_get_card_info(const void *hwdev, const void *bufin, void *bufout)
if (!chip_node)
return;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(adev, &chip_node->func_list, node) {
if (!is_func_valid(adev))
continue;
- /* When the number of PFs already obtained exceeds the array size,
- * stop getting info, only count PF numbers
- */
+ // 当已获取的pf数量超过数组的大小时,不再获取info信息,仅统计pf数量
if (j >= PF_MAX_SIZE) {
out_info->pf_num++;
j = out_info->pf_num;
continue;
}
- // Skip PFs already obtained before
+ // 跳过前边已获取的pf
if (i < info->pf_num) {
i++;
continue;
@@ -751,34 +793,40 @@ void hinic5_get_card_info(const void *hwdev, const void *bufin, void *bufout)
if (hinic5_support_nic(fun_hwdev, NULL)) {
if (adev->uld_dev[SERVICE_T_NIC]) {
- out_info->pf[j].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(adev, SERVICE_T_NIC, out_info->pf[j].name);
+ out_info->pf[j].pf_type |=
+ (u32)BIT(SERVICE_T_NIC);
+ get_dynamic_uld_dev_name(adev, SERVICE_T_NIC,
+ out_info->pf[j].name);
}
}
if (hinic5_support_ppa(fun_hwdev, NULL)) {
if (adev->uld_dev[SERVICE_T_PPA]) {
- out_info->pf[j].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(adev, SERVICE_T_PPA, out_info->pf[j].name);
+ out_info->pf[j].pf_type |=
+ (u32)BIT(SERVICE_T_PPA);
+ get_dynamic_uld_dev_name(adev, SERVICE_T_PPA,
+ out_info->pf[j].name);
}
}
- if (hinic5_support_bifur(fun_hwdev))
- if (adev->uld_dev[SERVICE_T_BIFUR])
+ if (hinic5_support_bifur(fun_hwdev)) {
+ if (adev->uld_dev[SERVICE_T_BIFUR]) {
get_dynamic_uld_dev_name(adev, SERVICE_T_BIFUR,
out_info->pf[j].name);
+ }
+ }
if (hinic5_func_for_mgmt(fun_hwdev))
- strscpy(out_info->pf[j].name, "FOR_MGMT", IFNAMSIZ);
+ strlcpy(out_info->pf[j].name, "FOR_MGMT", IFNAMSIZ);
- strscpy(out_info->pf[j].bus_info, dev_name(adev->dev),
+ strlcpy(out_info->pf[j].bus_info, dev_name(adev->dev),
sizeof(out_info->pf[j].bus_info));
out_info->pf_num++;
j = out_info->pf_num;
i++;
}
- hinic5_lld_put();
+ lld_put();
}
bool hinic5_is_in_host(void)
@@ -786,17 +834,17 @@ bool hinic5_is_in_host(void)
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
if (hinic5_func_type(adev->hwdev) != TYPE_VF) {
- hinic5_lld_put();
+ lld_put();
return true;
}
}
}
- hinic5_lld_put();
+ lld_put();
return false;
}
@@ -806,14 +854,12 @@ static bool chip_node_is_exist(struct hinic5_adev *adev)
#if !defined(__VMWARE__)
struct card_node *chip_node = NULL;
- /* SPU connects through HVA, each function occupies a bus number,
- * requires special handling; SPU PCI scenario not adapted for multi-card
- */
+ /* SPU通过HVA连接, 每个function占用一个bus number, 需特殊处理; SPU PCI场景未适配多卡 */
if (adev->lld_dev.dev_type == HINIC5_DEVICE_T_PCI &&
HINIC5_IS_SPU_DEV(hinic5_adev_get_device_id(adev))) {
if (!list_empty(get_hinic5_chip_list())) {
- adev->chip_node =
- list_first_entry(get_hinic5_chip_list(), struct card_node, node);
+ adev->chip_node = list_first_entry(
+ get_hinic5_chip_list(), struct card_node, node);
return true;
}
return false;
@@ -831,7 +877,7 @@ static bool chip_node_is_exist(struct hinic5_adev *adev)
return false;
}
-int hinic5_alloc_chip_node(struct hinic5_adev *adev)
+int alloc_chip_node(struct hinic5_adev *adev)
{
struct card_node *chip_node = NULL;
unsigned char i;
@@ -852,14 +898,14 @@ int hinic5_alloc_chip_node(struct hinic5_adev *adev)
chip_node = kzalloc(sizeof(*chip_node), GFP_KERNEL);
if (!chip_node) {
clear_bit(i, &card_bit_map);
- sdk_err(adev->dev,
- "Failed to alloc chip node\n");
+ sdk_err(adev->dev, "Failed to alloc chip node\n");
return -ENOMEM;
}
chip_node->id = adev->info.id;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC5_CHIP_NAME, i) < 0) {
+ if (snprintf_s(chip_node->chip_name, IFNAMSIZ, IFNAMSIZ - 1, "%s%u",
+ HINIC5_CHIP_NAME, i) < 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -868,8 +914,7 @@ int hinic5_alloc_chip_node(struct hinic5_adev *adev)
spin_lock_init(&chip_node->fw_update_context_lock);
spin_lock_init(&chip_node->dbgtool_info_lock);
- sdk_info(adev->dev,
- "Add new chip %s to global list succeed\n",
+ sdk_info(adev->dev, "Add new chip %s to global list succeed\n",
chip_node->chip_name);
list_add_tail(&chip_node->node, get_hinic5_chip_list());
@@ -880,26 +925,27 @@ int hinic5_alloc_chip_node(struct hinic5_adev *adev)
return 0;
}
-void hinic5_free_chip_node(struct hinic5_adev *adev)
+void free_chip_node(struct hinic5_adev *adev)
{
struct card_node *chip_node = adev->chip_node;
int id, err;
if (list_empty(&chip_node->func_list) != 0) {
list_del(&chip_node->node);
- sdk_info(adev->dev,
- "Delete chip %s from global list succeed\n",
+ sdk_info(adev->dev, "Delete chip %s from global list succeed\n",
chip_node->chip_name);
spin_lock_deinit(&chip_node->dbgtool_info_lock);
spin_lock_deinit(&chip_node->fw_update_context_lock);
- err = sscanf(chip_node->chip_name, HINIC5_CHIP_NAME "%d", &id);
- if (err != 1)
+ err = sscanf_s(chip_node->chip_name, HINIC5_CHIP_NAME "%d",
+ &id);
+ if (err < 0)
sdk_err(adev->dev, "Failed to get hinic5 id\n");
if (chip_node->fw_update_context) {
- hinic5_fw_update_free_context(chip_node->fw_update_context);
+ hinic5_fw_update_free_context(
+ chip_node->fw_update_context);
chip_node->fw_update_context = NULL;
}
@@ -909,11 +955,12 @@ void hinic5_free_chip_node(struct hinic5_adev *adev)
}
}
-int hinic5_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid)
+int hinic5_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id,
+ u32 *isvalid)
{
struct hinic5_adev *adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(adev, &chip_node->func_list, node) {
if (hinic5_func_type(adev->hwdev) == TYPE_VF)
continue;
@@ -924,29 +971,31 @@ int hinic5_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
break;
}
}
- hinic5_lld_put();
+ lld_put();
return 0;
}
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_func_id(const char *chip_name, u32 func_id)
+struct hinic5_lld_dev *hinic5_get_lld_dev_by_func_id(const char *chip_name,
+ u32 func_id)
{
struct hinic5_adev *adev = NULL;
struct card_node *chip_node = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, get_hinic5_chip_list(), node) {
- if (strncmp(chip_node->chip_name, chip_name, IFNAMSIZ) != 0)
+ if (strncmp(chip_node->chip_name, chip_name, IFNAMSIZ) != 0) {
continue;
+ }
list_for_each_entry(adev, &chip_node->func_list, node) {
if (hinic5_global_func_id(adev->hwdev) == func_id) {
hinic5_lld_dev_hold(&adev->lld_dev);
- hinic5_lld_put();
+ lld_put();
return &adev->lld_dev;
}
}
}
- hinic5_lld_put();
+ lld_put();
return NULL;
}
@@ -961,14 +1010,14 @@ void hinic5_get_mbox_cnt(const void *hwdev, void *buf_out)
info->func_num = 0;
chip_node = hinic5_get_chip_node_by_hwdev(hwdev);
- if (!chip_node)
+ if (chip_node == NULL)
return;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(adev, &chip_node->func_list, node) {
func_hwdev = (struct hinic5_hwdev *)adev->hwdev;
- strscpy(info->func_info[i].bus_info, dev_name(adev->dev),
+ strlcpy(info->func_info[i].bus_info, dev_name(adev->dev),
sizeof(info->func_info[i].bus_info));
info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
@@ -976,25 +1025,28 @@ void hinic5_get_mbox_cnt(const void *hwdev, void *buf_out)
info->func_num++;
i = info->func_num;
if (i >= ARRAY_SIZE(info->func_info)) {
- sdk_err(adev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ sdk_err(adev->dev,
+ "chip_node->func_list bigger than pf_max + vf_max\n");
break;
}
}
- hinic5_lld_put();
+ lld_put();
}
-int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev, u32 *dev_cnt, void *array[])
+int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev,
+ uint32_t *dev_cnt, void *array[])
{
struct hinic5_adev *adev = to_hinic5_adev(lld_dev);
struct card_node *chip_node = NULL;
void *uld_temp = NULL;
- u32 cnt;
+ uint32_t cnt;
- if (!lld_dev || !adev || !hinic5_support_nic(adev->hwdev, NULL) || !array)
+ if (!lld_dev || !adev || !hinic5_support_nic(adev->hwdev, NULL) ||
+ !array)
return -EINVAL;
- hinic5_lld_hold();
+ lld_hold();
cnt = 0;
chip_node = adev->chip_node;
@@ -1002,14 +1054,15 @@ int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev, u32 *dev_cnt,
if (hinic5_func_type(adev->hwdev) == TYPE_VF)
continue;
- uld_temp = hinic5_get_uld_dev_unsafe(&adev->lld_dev, SERVICE_T_NIC);
+ uld_temp = hinic5_get_uld_dev_unsafe(&adev->lld_dev,
+ SERVICE_T_NIC);
if (!uld_temp)
continue;
array[cnt] = uld_temp;
cnt++;
}
- hinic5_lld_put();
+ lld_put();
*dev_cnt = cnt;
@@ -1017,17 +1070,20 @@ int hinic5_get_card_nic_uld_array(struct hinic5_lld_dev *lld_dev, u32 *dev_cnt,
}
EXPORT_SYMBOL(hinic5_get_card_nic_uld_array);
-int hinic5_get_device_info(struct hinic5_lld_dev *lld_dev, struct hinic5_device_info *info)
+int hinic5_get_device_info(struct hinic5_lld_dev *lld_dev,
+ struct hinic5_device_info *info)
{
struct hinic5_adev *adev = to_hinic5_adev(lld_dev);
- if (!info)
+ if (info == NULL) {
return -EINVAL;
+ }
switch (lld_dev->dev_type) {
case HINIC5_DEVICE_T_PCI:
case HINIC5_DEVICE_T_UB:
- memcpy((info), &adev->info, sizeof(adev->info));
+ memcpy_s((info), sizeof(*info), &adev->info,
+ sizeof(adev->info));
return 0;
default:
break;
@@ -1035,3 +1091,21 @@ int hinic5_get_device_info(struct hinic5_lld_dev *lld_dev, struct hinic5_device_
return -EINVAL;
}
EXPORT_SYMBOL(hinic5_get_device_info);
+
+struct hinic5_lld_dev *hinic5_get_lld_dev_by_dev(struct device *dev)
+{
+ struct hinic5_adev *adev = NULL;
+
+ if (dev == NULL) {
+ return NULL;
+ }
+
+ adev = (struct hinic5_adev *)dev_get_drvdata(dev);
+ if (adev == NULL) {
+ return NULL;
+ }
+
+ atomic_inc(&adev->ref_cnt);
+ return &(adev->lld_dev);
+}
+EXPORT_SYMBOL(hinic5_get_lld_dev_by_dev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.h
index 692d13c5b..de7bd6dbd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_dev_mgmt.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dev_mgmt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_DEV_MGMT_H
#define HINIC5_DEV_MGMT_H
@@ -22,73 +15,73 @@
#include "hinic5_lld.h"
#endif
-#define HINIC5_VF_PCI_CFG_REG_BAR 0
-#define HINIC5_PF_PCI_CFG_REG_BAR 1
+#define HINIC5_VF_PCI_CFG_REG_BAR 0
+#define HINIC5_PF_PCI_CFG_REG_BAR 1
-#define HINIC5_PCI_INTR_REG_BAR 2
-#define HINIC5_PCI_MGMT_REG_BAR 3 /* Only PF have mgmt bar */
-#define HINIC5_PCI_DB_BAR 4
+#define HINIC5_PCI_INTR_REG_BAR 2
+#define HINIC5_PCI_MGMT_REG_BAR 3 /* Only PF have mgmt bar */
+#define HINIC5_PCI_DB_BAR 4
-#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 5000 /* 5 second */
+#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 5000 /* 5 second */
#define PRINT_ULD_DETACH_TIMES 30
#define PRINT_ULD_DETACH_TIMES_INTERVAL 5
-#define ULD_LOCK_MIN_USLEEP_TIME 900
-#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define ULD_LOCK_MIN_USLEEP_TIME 900
+#define ULD_LOCK_MAX_USLEEP_TIME 1000
-#define HINIC5_UBUS_FERS2 2
-#define HINIC5_UBUS_DB_BAR 1
-#define HINIC5_UBUS_INTR_REG_BAR 0
+#define HINIC5_UBUS_FERS2 2
+#define HINIC5_UBUS_DB_BAR 1
+#define HINIC5_UBUS_INTR_REG_BAR 0
/*
- * 1825 UBUS FERS2 resource space layout
+1825 UBUS FERS2 资源空间排布
------------------------------------------
- * CPI VF BAR0 (CFG) 8 KB
- * CPI PF BAR1 (CFG) 64 KB
- * CPI PF BAR3 (MGMT) 128 KB
- */
+CPI VF BAR0 (CFG) 8 KB
+CPI PF BAR1 (CFG) 64 KB
+CPI PF BAR3 (MGMT) 128 KB
+*/
-#define HINIC5_VF_UBUS_CFG_REG_OFFSET 0
-#define HINIC5_VF_UBUS_CFG_REG_SIZE 0x2000 /* 8 KB */
+#define HINIC5_VF_UBUS_CFG_REG_OFFSET 0
+#define HINIC5_VF_UBUS_CFG_REG_SIZE 0x2000 /* 8 KB */
-#define HINIC5_PF_UBUS_CFG_REG_OFFSET HINIC5_VF_UBUS_CFG_REG_SIZE
-#define HINIC5_PF_UBUS_CFG_REG_SIZE 0x10000 /* 64 KB */
+#define HINIC5_PF_UBUS_CFG_REG_OFFSET HINIC5_VF_UBUS_CFG_REG_SIZE
+#define HINIC5_PF_UBUS_CFG_REG_SIZE 0x10000 /* 64 KB */
-#define HINIC5_PF_UBUS_MGMT_REG_OFFSET (HINIC5_PF_UBUS_CFG_REG_OFFSET + HINIC5_PF_UBUS_CFG_REG_SIZE)
-#define HINIC5_PF_UBUS_MGMT_REG_SIZE 0x20000 /* 128 KB */
+#define HINIC5_PF_UBUS_MGMT_REG_OFFSET \
+ (HINIC5_PF_UBUS_CFG_REG_OFFSET + HINIC5_PF_UBUS_CFG_REG_SIZE)
+#define HINIC5_PF_UBUS_MGMT_REG_SIZE 0x20000 /* 128 KB */
/*
- * 1872 UBUS FERS2 resource space layout
- * Ref Semiconductor/Hi1872 V100/Docs/KIA2/0.1.System/1.4.FS/
- * Programming User Guide/Hi1872 V100 UB initialization.docx
+1872 UBUS FERS2 资源空间排布
+Ref 半导体/Hi1872 V100/Docs/KIA2/0.1.System/1.4.FS/Programming User Guide/Hi1872 V100 UB 初始化.docx
- * PF FERS2
+PF FERS2
------------------------------------------
- * UB vendor space for UBD2H 128 KB
- * UB vendor space for UBG 128 KB
- * UMMU non-secure 32 KB
- * CPI PF BAR3 (MGMT) 96 KB
- * CPI PF BAR1 (CFG) 128 KB
+UB vendor space for UBD2H 128 KB
+UB vendor space for UBG 128 KB
+UMMU non-secure 32 KB
+CPI PF BAR3 (MGMT) 96 KB
+CPI PF BAR1 (CFG) 128 KB
- * VF FERS2
+VF FERS2
------------------------------------------
- * UB vendor space for UBD2H 128 KB
- * UB vendor space for UBG 128 KB
- * CPI VF BAR01 (CFG) 256 KB
- */
+UB vendor space for UBD2H 128 KB
+UB vendor space for UBG 128 KB
+CPI VF BAR01 (CFG) 256 KB
+*/
-#define HINIC5_HTN_VF_UBUS_CFG_REG_OFFSET 0x40000 /* 256 KB */
-#define HINIC5_HTN_VF_UBUS_CFG_REG_SIZE 0x40000 /* 256 KB */
+#define HINIC5_HTN_VF_UBUS_CFG_REG_OFFSET 0x40000 /* 256 KB */
+#define HINIC5_HTN_VF_UBUS_CFG_REG_SIZE 0x40000 /* 256 KB */
-#define HINIC5_HTN_PF_UBUS_CFG_REG_OFFSET 0x60000 /* 384 KB */
-#define HINIC5_HTN_PF_UBUS_CFG_REG_SIZE 0x20000 /* 128 KB */
+#define HINIC5_HTN_PF_UBUS_CFG_REG_OFFSET 0x60000 /* 384 KB */
+#define HINIC5_HTN_PF_UBUS_CFG_REG_SIZE 0x20000 /* 128 KB */
-#define HINIC5_HTN_PF_UBUS_MGMT_REG_OFFSET 0x48000 /* 288 KB */
-#define HINIC5_HTN_PF_UBUS_MGMT_REG_SIZE 0x18000 /* 96 KB */
+#define HINIC5_HTN_PF_UBUS_MGMT_REG_OFFSET 0x48000 /* 288 KB */
+#define HINIC5_HTN_PF_UBUS_MGMT_REG_SIZE 0x18000 /* 96 KB */
-/* Default ubus dma bit mask */
+/* 默认ubus dma bit mask */
#define HINIC5_UBUS_DMA_BIT_MASK_DEFAULT 48
-/* ubus dma bit mask control range */
+/* ubus dma bit mask控制范围 */
#define HINIC5_UBUS_DMA_BIT_MASK_MAX 64
#define HINIC5_UBUS_DMA_BIT_MASK_MIN 32
@@ -100,20 +93,20 @@ enum {
};
#define HINIC5_VPMD_PROC_NAME_LEN 32
-/* Structure for device private data */
+/* Structure dev private */
struct hinic5_adev {
struct hinic5_lld_dev lld_dev;
struct device *dev;
void *hwdev;
- void *bus_dev; /* pdev in pcie scenario, ub dev in ubus scenario */
+ void *bus_dev; /* pcie场景下代表pdev,ubus场景下代表ub dev */
struct card_node *chip_node;
/* Record the service object address,
- * such as hinic5_dev, toe_dev, fc_dev
+ * such as hinic5_dev and toe_dev, fc_dev
*/
void *uld_dev[SERVICE_T_MAX];
/* Record the service object name */
char uld_dev_name[SERVICE_T_MAX][IFNAMSIZ];
- /* It is a global variable for driver to manage
+ /* It is a the global variable for driver to manage
* all function device linked list
*/
struct list_head node;
@@ -129,12 +122,10 @@ struct hinic5_adev {
u64 db_base_phy;
u64 cfg_base_phy;
u64 cfg_base_len;
- u64 mgmt_base_phy; /* PF only */
+ u64 mgmt_base_phy; // 仅支持PF
u64 mgmt_base_len;
- /* Used for tool adaptation, temporarily storing fers2 address and size manually in driver,
- * to be removed after tool adaptation
- */
+ /* 适配工具使用,暂时先在驱动手动存fers2的地址和size,工具适配后删除 */
u64 fers2_base_phy;
u64 fers2_total_len;
void __iomem *db_base;
@@ -154,13 +145,13 @@ struct hinic5_adev {
atomic_t uld_ref_cnt[SERVICE_T_MAX];
ulong uld_state;
- spinlock_t uld_lock; /* Spinlock to protect ULD (Upper Layer Driver) operations */
+ spinlock_t uld_lock;
u16 probe_fault_level;
- u16 rsvd2;
+ u16 rsvd2;
#ifdef __VMWARE__
- #include "vm_pci.h"
+#include "vm_pci.h"
#endif
struct hinic5_bus_ops *bus_ops;
struct hinic5_device_info info;
@@ -170,30 +161,37 @@ struct hinic5_adev {
};
struct hinic_chip_info {
- u8 chip_id; /* chip ID within card */
+ u8 chip_id; /* chip id within card */
u8 card_type; /* hinic_multi_chip_card_type */
- u8 rsvd[10]; /* reserved 10 bytes */
+ u8 rsvd[10]; /* reserved 10 bytes */
};
#define to_hinic5_adev(n) container_of(n, struct hinic5_adev, lld_dev)
struct list_head *get_hinic5_chip_list(void);
-int hinic5_alloc_chip_node(struct hinic5_adev *adev);
+int alloc_chip_node(struct hinic5_adev *adev);
-void hinic5_free_chip_node(struct hinic5_adev *adev);
+void free_chip_node(struct hinic5_adev *adev);
-void hinic5_lld_lock_chip_node(void);
+void lld_lock_chip_node(void);
-void hinic5_lld_unlock_chip_node(void);
+void lld_unlock_chip_node(void);
void hinic5_lld_lock_init(void);
-void hinic5_lld_dev_cnt_init(struct hinic5_adev *adev);
-void hinic5_wait_lld_dev_unused(struct hinic5_adev *adev);
+void lld_dev_cnt_init(struct hinic5_adev *adev);
+void wait_lld_dev_unused(struct hinic5_adev *adev);
struct card_node *hinic5_get_chip_node_by_lld(struct hinic5_lld_dev *lld_dev);
-struct hinic5_lld_dev *hinic5_get_lld_dev_by_func_id(const char *chip_name, u32 func_id);
+struct hinic5_lld_dev *hinic5_get_lld_dev_by_func_id(const char *chip_name,
+ u32 func_id);
+
+static inline enum hinic5_dev_type
+hinic5_adev_get_bus_type(struct hinic5_adev *adev)
+{
+ return adev->lld_dev.dev_type;
+}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld.c
index 12bdf78fd..8d3ddf3fd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_lld.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -35,7 +28,7 @@
#include "hinic5_dev_mgmt.h"
#include "hinic5_nictool.h"
#include "hinic5_hw.h"
-#include "hinic5_hinic5_vram.h"
+#include "hinic5_vram.h"
#include "hinic5_fast_msg_init.h"
#include "hinic5_profile.h"
#include "hinic5_hwdev.h"
@@ -43,16 +36,17 @@
#include "hinic5_fw_update.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic5_bus.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_lld_private.h"
#include "hinic5_hw_comm.h"
#include "hinic5_lld.h"
-static bool use_hinic5_vram;
-module_param(use_hinic5_vram, bool, 0644);
-MODULE_PARM_DESC(use_hinic5_vram, "use HINIC5_VRAM or not (only used in sdi_nanoos) - default is false");
+static bool use_vram = false;
+module_param(use_vram, bool, 0644);
+MODULE_PARM_DESC(use_vram,
+ "use VRAM or not (only used in sdi_nanoos) - default is false");
-static bool disable_attach;
+static bool disable_attach = false;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
@@ -66,7 +60,7 @@ bool hinic5_is_disable_vf_load(void)
return disable_vf_load;
}
-#define HINIC5_WAIT_SRIOV_CFG_TIMEOUT 40000 /* same as default mbox timeout */
+#define HINIC5_WAIT_SRIOV_CFG_TIMEOUT 40000 /* same as default mbox timeout */
#define HINIC5_SYNC_YEAR_OFFSET 1900
#define HINIC5_SYNC_MONTH_OFFSET 1
@@ -77,41 +71,42 @@ MODULE_VERSION(HINIC5_DRV_VERSION);
MODULE_LICENSE("GPL");
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-static DEVICE_ATTR(sriov_numvfs, 0644,
- hinic5_sriov_numvfs_show, hinic5_sriov_numvfs_store);
-static DEVICE_ATTR(sriov_totalvfs, 0444,
- sriov_totalvfs_show, NULL);
+static DEVICE_ATTR(sriov_numvfs, 0664, hinic5_sriov_numvfs_show,
+ hinic5_sriov_numvfs_store);
+static DEVICE_ATTR(sriov_totalvfs, 0444, hinic5_sriov_totalvfs_show, NULL);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
-struct hinic5_uld_info hinic5_g_uld_info[SERVICE_T_MAX];
+STATIC struct hinic5_uld_info g_uld_info[SERVICE_T_MAX] = { { 0 } };
-#define HINIC5_EVENT_PROCESS_TIMEOUT 10000
-struct mutex hinic5_g_uld_mutex; // Global mutex to protect ULD operations
+#define HINIC5_EVENT_PROCESS_TIMEOUT 10000
+STATIC struct mutex g_uld_mutex;
#define HINIC5_PROC_DIR "hisdk5"
-struct proc_dir_entry *g_proc_dir;
+STATIC struct proc_dir_entry *g_proc_dir = NULL;
void hinic5_uld_lock_init(void)
{
- mutex_init(&hinic5_g_uld_mutex);
+ mutex_init(&g_uld_mutex);
}
static const char *s_uld_name[SERVICE_T_MAX] = {
- "nic", "ovs", "roce", "toe", "ioe", "fc", "vbs", "ipsec", "virtio",
- "migrate", "ppa", "custom", "vroce", "ub", "jbof", "macsec", "dmmu",
- "cfm", "bifur", "hihtr"};
+ "nic", "ovs", "roce", "toe", "ioe", "fc", "vbs",
+ "ipsec", "virtio", "migrate", "ppa", "custom", "vroce", "ub",
+ "jbof", "macsec", "dmmu", "cfm", "bifur", "hihtr"
+};
const char **hinic5_get_uld_names(void)
{
return s_uld_name;
}
-const struct hinic5_uld_info *hinic5_get_uld_info_by_type(enum hinic5_service_type type)
+const struct hinic5_uld_info *
+hinic5_get_uld_info_by_type(enum hinic5_service_type type)
{
if (type >= SERVICE_T_MAX)
return NULL;
- return &hinic5_g_uld_info[type];
+ return &g_uld_info[type];
}
static int attach_uld(struct hinic5_adev *adev, enum hinic5_service_type type,
@@ -123,8 +118,7 @@ static int attach_uld(struct hinic5_adev *adev, enum hinic5_service_type type,
mutex_lock(&adev->adev_mutex);
if (adev->uld_dev[type]) {
- sdk_err(adev->dev,
- "%s driver has attached\n",
+ sdk_err(adev->dev, "%s driver has attached\n",
s_uld_name[type]);
err = 0;
goto out_unlock;
@@ -136,10 +130,10 @@ static int attach_uld(struct hinic5_adev *adev, enum hinic5_service_type type,
}
atomic_set(&adev->uld_ref_cnt[type], 0);
- err = uld_info->probe(&adev->lld_dev, &uld_dev, adev->uld_dev_name[type]);
+ err = uld_info->probe(&adev->lld_dev, &uld_dev,
+ adev->uld_dev_name[type]);
if (err != 0) {
- sdk_info(adev->dev,
- "cannot add object for %s driver\n",
+ sdk_info(adev->dev, "cannot add object for %s driver\n",
s_uld_name[type]);
goto probe_failed;
}
@@ -148,8 +142,7 @@ static int attach_uld(struct hinic5_adev *adev, enum hinic5_service_type type,
set_bit(type, &adev->uld_state);
mutex_unlock(&adev->adev_mutex);
- sdk_info(adev->dev,
- "Attach %s driver succeed\n", s_uld_name[type]);
+ sdk_info(adev->dev, "Attach %s driver succeed\n", s_uld_name[type]);
return 0;
probe_failed:
@@ -159,7 +152,8 @@ static int attach_uld(struct hinic5_adev *adev, enum hinic5_service_type type,
return err;
}
-static void wait_uld_unused(struct hinic5_adev *adev, enum hinic5_service_type type)
+static void wait_uld_unused(struct hinic5_adev *adev,
+ enum hinic5_service_type type)
{
u32 loop_cnt = 0;
u32 print_cnt = 0;
@@ -167,22 +161,24 @@ static void wait_uld_unused(struct hinic5_adev *adev, enum hinic5_service_type t
while (atomic_read(&adev->uld_ref_cnt[type]) != 0) {
loop_cnt++;
if ((loop_cnt % PRINT_ULD_DETACH_TIMEOUT_INTERVAL == 0) &&
- print_cnt < PRINT_ULD_DETACH_TIMES) {
- sdk_err(adev->dev, "Wait for uld unused for %lds, reference count: %d\n",
- (PRINT_ULD_DETACH_TIMES_INTERVAL * loop_cnt / MSEC_PER_SEC),
+ (print_cnt < PRINT_ULD_DETACH_TIMES)) {
+ sdk_err(adev->dev,
+ "Wait for uld unused for %lds, reference count: %d\n",
+ (PRINT_ULD_DETACH_TIMES_INTERVAL * loop_cnt /
+ MSEC_PER_SEC),
atomic_read(&adev->uld_ref_cnt[type]));
print_cnt++;
}
- usleep_range(ULD_LOCK_MIN_USLEEP_TIME, ULD_LOCK_MAX_USLEEP_TIME);
+ usleep_range(ULD_LOCK_MIN_USLEEP_TIME,
+ ULD_LOCK_MAX_USLEEP_TIME);
}
}
-static void detach_uld(struct hinic5_adev *adev,
- enum hinic5_service_type type)
+static void detach_uld(struct hinic5_adev *adev, enum hinic5_service_type type)
{
- struct hinic5_uld_info *uld_info = &hinic5_g_uld_info[type];
+ struct hinic5_uld_info *uld_info = &g_uld_info[type];
ulong end;
bool timeout = true;
@@ -216,9 +212,7 @@ static void detach_uld(struct hinic5_adev *adev,
if (!timeout)
clear_bit(type, &adev->state);
- sdk_info(adev->dev,
- "Detach %s driver succeed\n",
- s_uld_name[type]);
+ sdk_info(adev->dev, "Detach %s driver succeed\n", s_uld_name[type]);
mutex_unlock(&adev->adev_mutex);
}
@@ -226,40 +220,43 @@ static void attach_ulds(struct hinic5_adev *adev)
{
int type;
- hinic5_lld_hold();
- mutex_lock(&hinic5_g_uld_mutex);
+ lld_hold();
+ mutex_lock(&g_uld_mutex);
for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
- if (hinic5_g_uld_info[type].probe) {
+ if (g_uld_info[type].probe) {
/* vf in VM can not disable service load */
if ((hinic5_adev_is_virtfn(adev) != 0) &&
(!hinic5_get_vf_service_load(adev, (u16)type))) {
- sdk_info(adev->dev, "VF device disable service_type = %d load in host\n",
- type);
+ sdk_info(
+ adev->dev,
+ "VF device disable service_type = %d load in host\n",
+ type);
continue;
}
- attach_uld(adev, (enum hinic5_service_type)type, &hinic5_g_uld_info[type]);
+ attach_uld(adev, (enum hinic5_service_type)type,
+ &g_uld_info[type]);
}
}
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
}
static void detach_ulds(struct hinic5_adev *adev)
{
int type;
- hinic5_lld_hold();
- mutex_lock(&hinic5_g_uld_mutex);
+ lld_hold();
+ mutex_lock(&g_uld_mutex);
for (type = SERVICE_T_MAX - 1; type > SERVICE_T_NIC; type--) {
- if (hinic5_g_uld_info[type].probe)
+ if (g_uld_info[type].probe)
detach_uld(adev, (enum hinic5_service_type)type);
}
- if (hinic5_g_uld_info[SERVICE_T_NIC].probe)
+ if (g_uld_info[SERVICE_T_NIC].probe)
detach_uld(adev, SERVICE_T_NIC);
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
}
int hinic5_register_uld(enum hinic5_service_type type,
@@ -281,26 +278,26 @@ int hinic5_register_uld(enum hinic5_service_type type,
return -EINVAL;
}
- hinic5_lld_hold();
- mutex_lock(&hinic5_g_uld_mutex);
+ lld_hold();
+ mutex_lock(&g_uld_mutex);
- if (hinic5_g_uld_info[type].probe) {
+ if (g_uld_info[type].probe) {
pr_err("%s driver has registered\n", s_uld_name[type]);
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
return -EINVAL;
}
chip_list = get_hinic5_chip_list();
- memcpy(&hinic5_g_uld_info[type], uld_info, sizeof(struct hinic5_uld_info));
+ (void)memcpy_s(&g_uld_info[type], sizeof(struct hinic5_uld_info),
+ uld_info, sizeof(struct hinic5_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(adev, &chip_node->func_list, node) {
if (attach_uld(adev, type, uld_info) != 0) {
- sdk_info(adev->dev,
- "Cannot attach %s driver\n",
+ sdk_info(adev->dev, "Cannot attach %s driver\n",
s_uld_name[type]);
#ifdef CONFIG_MODULE_PROF
- adev->bus_ops->fault_process(adev, hinic5_func_max_vf(adev->hwdev));
+ adev->bus_ops->fault_process(adev);
break;
#else
continue;
@@ -309,8 +306,8 @@ int hinic5_register_uld(enum hinic5_service_type type,
}
}
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
pr_info("Register %s driver succeed\n", s_uld_name[type]);
return 0;
@@ -330,8 +327,8 @@ void hinic5_unregister_uld(enum hinic5_service_type type)
return;
}
- hinic5_lld_hold();
- mutex_lock(&hinic5_g_uld_mutex);
+ lld_hold();
+ mutex_lock(&g_uld_mutex);
chip_list = get_hinic5_chip_list();
list_for_each_entry(chip_node, chip_list, node) {
/* detach vf first */
@@ -348,10 +345,11 @@ void hinic5_unregister_uld(enum hinic5_service_type type)
detach_uld(adev, type);
}
- uld_info = &hinic5_g_uld_info[type];
- memset(uld_info, 0, sizeof(struct hinic5_uld_info));
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ uld_info = &g_uld_info[type];
+ (void)memset_s(uld_info, sizeof(struct hinic5_uld_info), 0,
+ sizeof(struct hinic5_uld_info));
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
}
EXPORT_SYMBOL(hinic5_unregister_uld);
@@ -363,7 +361,7 @@ int hinic5_attach_nic(struct hinic5_lld_dev *lld_dev)
return -EINVAL;
adev = to_hinic5_adev(lld_dev);
- return attach_uld(adev, SERVICE_T_NIC, &hinic5_g_uld_info[SERVICE_T_NIC]);
+ return attach_uld(adev, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
}
EXPORT_SYMBOL(hinic5_attach_nic);
@@ -379,7 +377,8 @@ void hinic5_detach_nic(const struct hinic5_lld_dev *lld_dev)
}
EXPORT_SYMBOL(hinic5_detach_nic);
-int hinic5_attach_service(const struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+int hinic5_attach_service(const struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type)
{
struct hinic5_adev *adev = NULL;
@@ -390,11 +389,12 @@ int hinic5_attach_service(const struct hinic5_lld_dev *lld_dev, enum hinic5_serv
if (!adev)
return -EINVAL;
- return attach_uld(adev, type, &hinic5_g_uld_info[type]);
+ return attach_uld(adev, type, &g_uld_info[type]);
}
EXPORT_SYMBOL(hinic5_attach_service);
-void hinic5_detach_service(const struct hinic5_lld_dev *lld_dev, enum hinic5_service_type type)
+void hinic5_detach_service(const struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type type)
{
struct hinic5_adev *adev = NULL;
@@ -408,8 +408,8 @@ EXPORT_SYMBOL(hinic5_detach_service);
static void hinic5_sync_time_to_fmw(struct hinic5_adev *adev)
{
- struct timeval tv = {0};
- struct rtc_time rt_time = {0};
+ struct timeval tv = { 0 };
+ struct rtc_time rt_time = { 0 };
u64 tv_msec;
int err;
@@ -418,15 +418,18 @@ static void hinic5_sync_time_to_fmw(struct hinic5_adev *adev)
tv_msec = (u64)(tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC);
err = hinic5_sync_time(adev->hwdev, tv_msec);
if (err != 0) {
- sdk_err(adev->dev, "Synchronize UTC time to firmware failed, errno:%d.\n",
+ sdk_err(adev->dev,
+ "Synchronize UTC time to firmware failed, errno:%d.\n",
err);
} else {
rtc_time_to_tm(tv.tv_sec, &rt_time);
- sdk_info(adev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
- rt_time.tm_year + HINIC5_SYNC_YEAR_OFFSET,
- rt_time.tm_mon + HINIC5_SYNC_MONTH_OFFSET,
- rt_time.tm_mday, rt_time.tm_hour,
- rt_time.tm_min, rt_time.tm_sec);
+ sdk_info(
+ adev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ rt_time.tm_year + HINIC5_SYNC_YEAR_OFFSET,
+ rt_time.tm_mon + HINIC5_SYNC_MONTH_OFFSET,
+ rt_time.tm_mday, rt_time.tm_hour, rt_time.tm_min,
+ rt_time.tm_sec);
}
}
@@ -437,13 +440,15 @@ static void send_uld_dev_event(struct hinic5_adev *adev,
for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
if (test_and_set_bit((u32)type, &adev->state)) {
- sdk_warn(adev->dev, "Svc: 0x%x, event: 0x%x can't handler, %s is in detach\n",
- event->service, event->type, s_uld_name[type]);
+ sdk_warn(
+ adev->dev,
+ "Svc: 0x%x, event: 0x%x can't handler, %s is in detach\n",
+ event->service, event->type, s_uld_name[type]);
continue;
}
- if (hinic5_g_uld_info[type].event && adev->uld_dev[type])
- hinic5_g_uld_info[type].event(&adev->lld_dev,
+ if (g_uld_info[type].event && (adev->uld_dev[type] != NULL))
+ g_uld_info[type].event(&adev->lld_dev,
adev->uld_dev[type], event);
clear_bit((u32)type, &adev->state);
}
@@ -454,9 +459,9 @@ static void send_event_to_dst_pf(struct hinic5_adev *adev, u16 func_id,
{
struct hinic5_adev *des_dev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(des_dev, &adev->chip_node->func_list, node) {
- if (adev->lld_state == HINIC5_IN_REMOVE)
+ if (des_dev->lld_state == HINIC5_IN_REMOVE)
continue;
if (hinic5_func_type(des_dev->hwdev) == TYPE_VF)
@@ -467,7 +472,7 @@ static void send_event_to_dst_pf(struct hinic5_adev *adev, u16 func_id,
break;
}
}
- hinic5_lld_put();
+ lld_put();
}
static void send_event_to_all_pf(struct hinic5_adev *adev,
@@ -475,9 +480,9 @@ static void send_event_to_all_pf(struct hinic5_adev *adev,
{
struct hinic5_adev *des_adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(des_adev, &adev->chip_node->func_list, node) {
- if (adev->lld_state == HINIC5_IN_REMOVE)
+ if (des_adev->lld_state == HINIC5_IN_REMOVE)
continue;
if (hinic5_func_type(des_adev->hwdev) == TYPE_VF)
@@ -485,7 +490,7 @@ static void send_event_to_all_pf(struct hinic5_adev *adev,
send_uld_dev_event(des_adev, event);
}
- hinic5_lld_put();
+ lld_put();
}
static void hinic5_event_process(void *adapter, struct hinic5_event_info *event)
@@ -494,7 +499,8 @@ static void hinic5_event_process(void *adapter, struct hinic5_event_info *event)
struct hinic5_fault_event *fault = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
+ if ((event->service == EVENT_SRV_COMM &&
+ event->type == EVENT_COMM_FAULT) &&
fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
fault->event.chip.func_id < hinic5_max_pf_num(adev->hwdev)) {
func_id = fault->event.chip.func_id;
@@ -502,7 +508,9 @@ static void hinic5_event_process(void *adapter, struct hinic5_event_info *event)
return;
}
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ if (event->type == EVENT_COMM_MGMT_WATCHDOG ||
+ ((event->type == EVENT_COMM_FAULT) &&
+ (fault->type == FAULT_TYPE_HEARTBEAT_LOST)))
send_event_to_all_pf(adapter, event);
else
send_uld_dev_event(adapter, event);
@@ -528,7 +536,7 @@ static void uld_def_init(struct hinic5_adev *adev)
**/
static void cfg_order_reg(struct hinic5_adev *adev)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
+ u8 cpu_model[] = { 0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56 };
struct cpuinfo_x86 *cpuinfo = NULL;
u32 i;
@@ -576,14 +584,15 @@ static void set_vf_load_state(struct hinic5_adev *adev)
#ifndef __HIFC__
if ((hinic5_func_type(adev->hwdev) != TYPE_VF) &&
hinic5_is_multi_bm(adev->hwdev)) {
- adev->bus_ops->virt_configure(adev, hinic5_func_max_vf(adev->hwdev));
+ adev->bus_ops->virt_configure(
+ adev, hinic5_func_max_vf(adev->hwdev));
}
#endif
}
}
#define HINIC5_CSR_BASIC_SIZE 0x1000
-#define HINIC5_CSR_MGMT_SIZE 0x10000
+#define HINIC5_CSR_MGMT_SIZE 0x10000
static int hinic5_vpmd_proc_mmap(struct file *file, struct vm_area_struct *vma)
{
@@ -591,12 +600,14 @@ static int hinic5_vpmd_proc_mmap(struct file *file, struct vm_area_struct *vma)
u64 pfn, vma_size, bar_size, ofst, check_size;
struct hinic5_adev *adev = NULL;
- if (!file || !vma || vma->vm_end < vma->vm_start)
+ if ((file == NULL) || (vma == NULL) || (vma->vm_end < vma->vm_start)) {
return -EINVAL;
+ }
adev = (struct hinic5_adev *)PDE_DATA(file_inode(file));
- if (!adev)
+ if (adev == NULL) {
return -EINVAL;
+ }
ofst = vma->vm_pgoff << PAGE_SHIFT;
if (ofst == 0) {
@@ -655,10 +666,14 @@ static const struct file_operations hinic5_vpmd_proc_fops = {
static int hinic5_init_vpmd_proc(struct hinic5_adev *adev)
{
- strscpy(adev->vpmd_proc_name, dev_name(adev->dev), sizeof(adev->vpmd_proc_name));
- adev->vpmd_proc = proc_create_data(&adev->vpmd_proc_name[0], 0640, g_proc_dir,
- &hinic5_vpmd_proc_fops, adev);
- if (!adev->vpmd_proc) {
+ strlcpy(adev->vpmd_proc_name, dev_name(adev->dev),
+ sizeof(adev->vpmd_proc_name));
+
+ adev->vpmd_proc = proc_create_data(&adev->vpmd_proc_name[0],
+ S_IRUSR | S_IRGRP | S_IWUSR,
+ g_proc_dir, &hinic5_vpmd_proc_fops,
+ adev);
+ if (adev->vpmd_proc == NULL) {
sdk_err(adev->dev, "init vpmd proc failed, vpmd_proc_name:%s.",
adev->vpmd_proc_name);
return -ENOMEM;
@@ -676,8 +691,8 @@ static bool hinic5_need_ht_gpa(struct hinic5_hwdev *hwdev)
int hinic5_func_init(struct hinic5_adev *adev)
{
- struct hinic5_init_para init_para = {0};
- bool hinic5_cqm_init_en = false;
+ struct hinic5_init_para init_para = { 0 };
+ bool cqm5_init_en = false;
int err;
uld_def_init(adev);
@@ -729,8 +744,8 @@ int hinic5_func_init(struct hinic5_adev *adev)
goto fw_update_init_err;
}
- hinic5_cqm_init_en = hinic5_need_init_stateful_default(adev->hwdev);
- if (hinic5_cqm_init_en) {
+ cqm5_init_en = hinic5_need_init_stateful_default(adev->hwdev);
+ if (cqm5_init_en) {
err = hinic5_stateful_init(adev->hwdev);
if (err != 0) {
sdk_err(adev->dev, "Failed to init stateful\n");
@@ -742,11 +757,13 @@ int hinic5_func_init(struct hinic5_adev *adev)
adev->lld_dev.hwdev = adev->hwdev;
if (hinic5_func_type(adev->hwdev) != TYPE_VF)
- set_bit(HINIC5_FUNC_PERSENT, &adev->sriov_info.state);
+ set_bit(HINIC5_FUNC_PRESENT, &adev->sriov_info.state);
err = hinic5_event_register(adev->hwdev, adev, hinic5_event_process);
if (err != 0) {
- sdk_err(adev->dev, "Failed to register callback for event, err = %d\n", err);
+ sdk_err(adev->dev,
+ "Failed to register callback for event, err = %d\n",
+ err);
goto event_register_err;
}
@@ -754,15 +771,15 @@ int hinic5_func_init(struct hinic5_adev *adev)
hinic5_sync_time_to_fmw(adev);
/* dbgtool init */
- hinic5_lld_lock_chip_node();
- err = hinic5_nictool_k_init(adev->hwdev, adev->chip_node);
+ lld_lock_chip_node();
+ err = nictool_k_init(adev->hwdev, adev->chip_node);
if (err != 0) {
- hinic5_lld_unlock_chip_node();
+ lld_unlock_chip_node();
sdk_err(adev->dev, "Failed to initialize dbgtool\n");
goto nictool_init_err;
}
list_add_tail(&adev->node, &adev->chip_node->func_list);
- hinic5_lld_unlock_chip_node();
+ lld_unlock_chip_node();
set_vf_load_state(adev);
@@ -782,13 +799,13 @@ int hinic5_func_init(struct hinic5_adev *adev)
return 0;
init_vpmd_proc_err:
- hinic5_lld_lock_chip_node();
- hinic5_nictool_k_uninit(adev->hwdev, adev->chip_node);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ nictool_k_uninit(adev->hwdev, adev->chip_node);
+ lld_unlock_chip_node();
nictool_init_err:
hinic5_event_unregister(adev->hwdev);
event_register_err:
- if (hinic5_cqm_init_en)
+ if (cqm5_init_en)
hinic5_stateful_deinit(adev->hwdev);
stateful_init_err:
hinic5_fw_update_deinit(adev->hwdev);
@@ -820,19 +837,19 @@ void hinic5_func_deinit(struct hinic5_adev *adev)
hinic5_flush_mgmt_workq(adev->hwdev);
- hinic5_lld_lock_chip_node();
+ lld_lock_chip_node();
list_del(&adev->node);
- hinic5_lld_unlock_chip_node();
+ lld_unlock_chip_node();
detach_ulds(adev);
- hinic5_wait_lld_dev_unused(adev);
+ wait_lld_dev_unused(adev);
hinic5_deinit_vpmd_proc(adev);
- hinic5_lld_lock_chip_node();
- hinic5_nictool_k_uninit(adev->hwdev, adev->chip_node);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ nictool_k_uninit(adev->hwdev, adev->chip_node);
+ lld_unlock_chip_node();
hinic5_event_unregister(adev->hwdev);
@@ -856,7 +873,7 @@ void wait_sriov_cfg_complete(struct hinic5_adev *adev)
ulong end;
sriov_info = &adev->sriov_info;
- clear_bit(HINIC5_FUNC_PERSENT, &sriov_info->state);
+ clear_bit(HINIC5_FUNC_PRESENT, &sriov_info->state);
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
end = jiffies + msecs_to_jiffies(HINIC5_WAIT_SRIOV_CFG_TIMEOUT);
@@ -942,33 +959,35 @@ int probe_func_param_init(struct hinic5_adev *adev)
static int hinic5_sdk_proc_init(void)
{
g_proc_dir = proc_mkdir(HINIC5_PROC_DIR, NULL);
- if (!g_proc_dir)
+ if (g_proc_dir == NULL) {
return -EPERM;
+ }
return 0;
}
static void hinic5_sdk_proc_deinit(void)
{
- if (!g_proc_dir)
+ if (g_proc_dir == NULL) {
return;
+ }
proc_remove(g_proc_dir);
g_proc_dir = NULL;
}
-int hinic5_lld_init(void)
+static __init int hinic5_lld_init(void)
{
int err;
pr_info("%s - version %s\n", HINIC5_DRV_DESC, HINIC5_DRV_VERSION);
- memset(hinic5_g_uld_info, 0, sizeof(hinic5_g_uld_info));
+ (void)memset_s(g_uld_info, sizeof(g_uld_info), 0, sizeof(g_uld_info));
hinic5_lld_lock_init();
hinic5_uld_lock_init();
- set_use_hinic5_vram_flag(use_hinic5_vram);
+ set5_use_vram_flag(use_vram);
- if (use_hinic5_vram) {
- err = hisdk5_hinic5_vram_init();
+ if (use_vram) {
+ err = hisdk5_vram_init();
if (err != 0)
return err;
}
@@ -986,8 +1005,9 @@ int hinic5_lld_init(void)
}
err = hinic5_register_driver();
- if (err != 0)
+ if (err != 0) {
goto register_driver_err;
+ }
return 0;
@@ -998,16 +1018,17 @@ int hinic5_lld_init(void)
hinic5_sdk_proc_deinit();
dir_create_err:
- if (use_hinic5_vram)
- hisdk5_hinic5_vram_deinit();
+ if (use_vram) {
+ hisdk5_vram_deinit();
+ }
return err;
}
-void hinic5_lld_exit(void)
+static __exit void hinic5_lld_exit(void)
{
- if (use_hinic5_vram)
- hisdk5_hinic5_vram_deinit();
+ if (use_vram)
+ hisdk5_vram_deinit();
hinic5_unregister_driver();
hinic5_module_post_exit();
@@ -1019,9 +1040,9 @@ static bool is_uld_with_cleanup(enum hinic5_service_type type)
const enum hinic5_service_type uld_with_cleanup[] = {
SERVICE_T_IPSEC,
};
- u32 uld_with_cleanup_size = sizeof(uld_with_cleanup) / sizeof(enum hinic5_service_type);
+ u32 uld_with_cleanup_size =
+ sizeof(uld_with_cleanup) / sizeof(enum hinic5_service_type);
u32 i;
-
for (i = 0; i < uld_with_cleanup_size; i++) {
if (uld_with_cleanup[i] == type)
return true;
@@ -1029,7 +1050,8 @@ static bool is_uld_with_cleanup(enum hinic5_service_type type)
return false;
}
-void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type, void (*cleanup)(void *))
+void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type,
+ void (*cleanup)(void *))
{
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
@@ -1040,13 +1062,13 @@ void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type, void (*
return;
}
- if (!cleanup) {
+ if (cleanup == NULL) {
pr_info("this service no need to cleanup.\n");
return;
}
- hinic5_lld_hold();
- mutex_lock(&hinic5_g_uld_mutex);
+ lld_hold();
+ mutex_lock(&g_uld_mutex);
chip_list = get_hinic5_chip_list();
list_for_each_entry(chip_node, chip_list, node) {
/* detach vf first */
@@ -1062,15 +1084,14 @@ void hinic5_uld_cleanup_before_unregister(enum hinic5_service_type type, void (*
if (hinic5_func_type(adev->hwdev) == TYPE_PPF)
cleanup(adev->uld_dev[type]);
}
- mutex_unlock(&hinic5_g_uld_mutex);
- hinic5_lld_put();
+ mutex_unlock(&g_uld_mutex);
+ lld_put();
}
EXPORT_SYMBOL(hinic5_uld_cleanup_before_unregister);
int hinic5_get_vf_num(struct hinic5_lld_dev *lld_dev)
{
struct hinic5_adev *adev = NULL;
-
if (!lld_dev) {
pr_err("lld_dev is null.\n");
return -EINVAL;
@@ -1091,8 +1112,17 @@ int hinic5_get_chip_node_id(struct hinic5_lld_dev *lld_dev, u64 *chip_node_id)
}
adev = to_hinic5_adev(lld_dev);
+ if (adev->chip_node == NULL) {
+ pr_err("chip_node is null.\n");
+ return -EINVAL;
+ }
*chip_node_id = adev->chip_node->id;
return 0;
}
EXPORT_SYMBOL(hinic5_get_chip_node_id);
+
+#ifndef _LLT_TEST_
+module_init(hinic5_lld_init);
+module_exit(hinic5_lld_exit);
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld_private.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld_private.h
index 0bd0166c0..730c4548d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld_private.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_lld_private.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_lld_private.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_LLD_PRIVATE_H
#define HINIC5_LLD_PRIVATE_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.c
index ccfc44091..de7102208 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_pcie.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -33,13 +26,13 @@
#include "hinic5_dev_mgmt.h"
#include "hinic5_nictool.h"
#include "hinic5_hw.h"
-#include "hinic5_hinic5_vram.h"
+#include "hinic5_vram.h"
#include "hinic5_fast_msg_init.h"
#include "hinic5_lld.h"
#include "hinic5_lld_private.h"
#include "hinic5_profile.h"
#include "hinic5_hwdev.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_prof_adap.h"
#include "hinic5_fw_update.h"
#include "mpu_inband_cmd_defs.h"
@@ -47,10 +40,10 @@
#include "hinic5_sysfs.h"
#include "hinic5_pcie.h"
-#define HINIC5_VF_TIMER_DISABLE_MAX_TIMEOUT 50 /* 50 mseconds */
-#define HINIC5_VF_TIMER_DISABLE_WAIT_TIME 5 /* 5 mseconds */
-#define HINIC5_VF_NOTIFY_FLR_BIT BIT(17)
-#define HINIC5_PF_HOST_MPU_NOTIFY_BIT BIT(31)
+#define HINIC5_VF_TIMER_DISABLE_MAX_TIMEOUT 50 /* 50 mseconds */
+#define HINIC5_VF_TIMER_DISABLE_WAIT_TIME 5 /* 5 mseconds */
+#define HINIC5_VF_NOTIFY_FLR_BIT (1UL << 17)
+#define HINIC5_PF_HOST_MPU_NOTIFY_BIT (1UL << 31)
#define HINIC5_VF_FUNC_ATTRIBUTE6_OFFSET 0x2018
#define HINIC5_PF_HOST_MPU_NOTIFY_OFFSET 0x60C0
@@ -64,48 +57,46 @@ static DEFINE_MUTEX(g_vf_offset_lock);
static struct attribute *hinic5_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
- &dev_attr_sriov_numvfs.attr,
- &dev_attr_sriov_totalvfs.attr,
+ &dev_attr_sriov_numvfs.attr, &dev_attr_sriov_totalvfs.attr,
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
NULL
};
static const struct attribute_group hinic5_attr_group = {
- .attrs = hinic5_attributes,
+ .attrs = hinic5_attributes,
};
-static int mapping_bar(struct pci_dev *pdev,
- struct hinic5_adev *adev)
+static int mapping_bar(struct pci_dev *pdev, struct hinic5_adev *adev)
{
int cfg_bar;
cfg_bar = HINIC5_IS_VF_DEV(hinic5_adev_get_device_id(adev)) ?
- HINIC5_VF_PCI_CFG_REG_BAR : HINIC5_PF_PCI_CFG_REG_BAR;
+ HINIC5_VF_PCI_CFG_REG_BAR :
+ HINIC5_PF_PCI_CFG_REG_BAR;
adev->cfg_base_phy = pci_resource_start(pdev, cfg_bar);
adev->cfg_base_len = pci_resource_len(pdev, cfg_bar);
adev->cfg_reg_base = pci_ioremap_bar(pdev, cfg_bar);
if (!adev->cfg_reg_base) {
- sdk_err(&pdev->dev,
- "Failed to map configuration regs\n");
+ sdk_err(&pdev->dev, "Failed to map configuration regs\n");
return -ENOMEM;
}
adev->intr_reg_base = pci_ioremap_bar(pdev, HINIC5_PCI_INTR_REG_BAR);
if (!adev->intr_reg_base) {
- sdk_err(&pdev->dev,
- "Failed to map interrupt regs\n");
+ sdk_err(&pdev->dev, "Failed to map interrupt regs\n");
goto map_intr_bar_err;
}
if (!HINIC5_IS_VF_DEV(hinic5_adev_get_device_id(adev))) {
- adev->mgmt_base_phy = pci_resource_start(pdev, HINIC5_PCI_MGMT_REG_BAR);
- adev->mgmt_base_len = pci_resource_len(pdev, HINIC5_PCI_MGMT_REG_BAR);
+ adev->mgmt_base_phy =
+ pci_resource_start(pdev, HINIC5_PCI_MGMT_REG_BAR);
+ adev->mgmt_base_len =
+ pci_resource_len(pdev, HINIC5_PCI_MGMT_REG_BAR);
adev->mgmt_reg_base =
pci_ioremap_bar(pdev, HINIC5_PCI_MGMT_REG_BAR);
if (!adev->mgmt_reg_base) {
- sdk_err(&pdev->dev,
- "Failed to map mgmt regs\n");
+ sdk_err(&pdev->dev, "Failed to map mgmt regs\n");
goto map_mgmt_bar_err;
}
}
@@ -114,8 +105,7 @@ static int mapping_bar(struct pci_dev *pdev,
adev->db_dwqe_len = pci_resource_len(pdev, HINIC5_PCI_DB_BAR);
adev->db_base = pci_ioremap_bar(pdev, HINIC5_PCI_DB_BAR);
if (!adev->db_base) {
- sdk_err(&pdev->dev,
- "Failed to map doorbell regs\n");
+ sdk_err(&pdev->dev, "Failed to map doorbell regs\n");
goto map_db_err;
}
@@ -151,22 +141,22 @@ static int hinic5_pci_init(struct pci_dev *pdev)
int err;
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
- if (!adev)
+ if (!adev) {
+ sdk_err(&pdev->dev, "Failed to alloc pci device adapter\n");
return -ENOMEM;
+ }
adev->dev = &pdev->dev;
adev->bus_dev = pdev;
mutex_init(&adev->adev_mutex);
pci_set_drvdata(pdev, adev);
- err = pci_enable_device(pdev);
- if (err != 0) {
+ if ((err = pci_enable_device(pdev)) != 0) {
sdk_err(&pdev->dev, "Failed to enable PCI device\n");
goto pci_enable_err;
}
- err = pci_request_regions(pdev, HINIC5_DRV_NAME);
- if (err != 0) {
+ if ((err = pci_request_regions(pdev, HINIC5_DRV_NAME)) != 0) {
sdk_err(&pdev->dev, "Failed to request regions\n");
goto pci_regions_err;
}
@@ -178,19 +168,23 @@ static int hinic5_pci_init(struct pci_dev *pdev)
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); /* 64 bit DMA mask */
if (err != 0) {
sdk_warn(&pdev->dev, "Couldn't set 64-bit DMA mask\n");
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); /* 32 bit DMA mask */
+ err = dma_set_mask(&pdev->dev,
+ DMA_BIT_MASK(32)); /* 32 bit DMA mask */
if (err != 0) {
sdk_err(&pdev->dev, "Failed to set DMA mask\n");
goto dma_mask_err;
}
}
- err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); /* 64 bit DMA mask */
+ err = dma_set_coherent_mask(&pdev->dev,
+ DMA_BIT_MASK(64)); /* 64 bit DMA mask */
if (err != 0) {
sdk_warn(&pdev->dev, "Couldn't set 64-bit coherent DMA mask\n");
- err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); /* 32 bit DMA mask */
+ err = dma_set_coherent_mask(
+ &pdev->dev, DMA_BIT_MASK(32)); /* 32 bit DMA mask */
if (err != 0) {
- sdk_err(&pdev->dev, "Failed to set coherent DMA mask\n");
+ sdk_err(&pdev->dev,
+ "Failed to set coherent DMA mask\n");
goto dma_consistnet_mask_err;
}
}
@@ -250,9 +244,9 @@ static int hinic5_remove_func(struct hinic5_adev *adev)
hinic5_func_deinit(adev);
- hinic5_lld_lock_chip_node();
- hinic5_free_chip_node(adev);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ free_chip_node(adev);
+ lld_unlock_chip_node();
unmapping_bar(adev);
@@ -280,17 +274,19 @@ static int hinic5_get_pf_info(struct hinic5_adev *dev, u16 service,
int err;
if (service >= SERVICE_T_MAX) {
- sdk_err(dev->dev, "Current vf do not supports set service_type = %u state in host\n",
+ sdk_err(dev->dev,
+ "Current vf do not supports set service_type = %u state in host\n",
service);
return -EFAULT;
}
- pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
- if (!pf_infos) {
+ *pf_infos = kzalloc(sizeof(struct hinic5_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
sdk_err(dev->dev, "Failed to allocate pf infos\n");
return -ENOMEM;
}
- err = hinic5_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC5_CHANNEL_COMM);
+ err = hinic5_get_hw_pf_infos(dev->hwdev, *pf_infos,
+ HINIC5_CHANNEL_COMM);
if (err != 0) {
kfree(*pf_infos);
sdk_err(dev->dev, "Get chipf pf info failed, ret %d\n", err);
@@ -300,8 +296,9 @@ static int hinic5_get_pf_info(struct hinic5_adev *dev, u16 service,
return 0;
}
-static int get_vf_service_state_param(struct hinic5_lld_dev *lld_dev, struct hinic5_adev *dev_ptr,
- u16 service, struct hinic5_hw_pf_infos **pf_infos)
+static int get_vf_service_state_param(struct hinic5_lld_dev *lld_dev,
+ struct hinic5_adev *dev_ptr, u16 service,
+ struct hinic5_hw_pf_infos **pf_infos)
{
int err;
@@ -315,31 +312,35 @@ static int get_vf_service_state_param(struct hinic5_lld_dev *lld_dev, struct hin
return 0;
}
-static int hinic5_dst_pdev_valid(struct hinic5_adev *dst_dev, struct pci_dev **des_pdev_ptr,
- u16 vf_devfn, bool en)
+static int hinic5_dst_pdev_valid(struct hinic5_adev *dst_dev,
+ struct pci_dev **des_pdev_ptr, u16 vf_devfn,
+ bool en)
{
struct pci_dev *pdev = container_of(dst_dev->dev, struct pci_dev, dev);
u16 bus;
bus = pdev->bus->number + vf_devfn / BUS_MAX_DEV_NUM;
- *des_pdev_ptr = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
- bus, vf_devfn % BUS_MAX_DEV_NUM);
+ *des_pdev_ptr = pci_get_domain_bus_and_slot(
+ pci_domain_nr(pdev->bus), bus, vf_devfn % BUS_MAX_DEV_NUM);
if (!(*des_pdev_ptr)) {
pr_err("des_pdev is NULL\n");
return -EFAULT;
}
/* OVS sriov hw scene, when vf bind to vf_io return error. */
- if (!en && (strcmp((*des_pdev_ptr)->driver->name, HINIC5_DRV_NAME) != 0)) {
- pr_err("vf bind driver:%s\n", (*des_pdev_ptr)->driver->name);
- return -EFAULT;
+ if (!en) {
+ struct pci_driver *drv = (*des_pdev_ptr)->driver;
+ if (!drv || strcmp(drv->name, HINIC5_DRV_NAME) != 0) {
+ pr_err("vf bind driver:%s\n", drv ? drv->name : "none");
+ return -EFAULT;
+ }
}
return 0;
}
-static int paramerter_is_unexpected(struct hinic5_adev *dst_dev, u16 *func_id, u16 *vf_start,
- u16 *vf_end, u16 vf_func_id)
+static int paramerter_is_unexpected(struct hinic5_adev *dst_dev, u16 *func_id,
+ u16 *vf_start, u16 *vf_end, u16 vf_func_id)
{
if (hinic5_func_type(dst_dev->hwdev) == TYPE_VF)
return -EPERM;
@@ -361,8 +362,9 @@ void hinic5_notify_vf_timer_disable(struct pci_dev *pdev)
struct pci_dev *physfn = NULL;
u32 val;
- if (!pdev || pdev->vendor != PCI_VENDOR_ID_HUAWEI ||
- (pdev->device != HINIC5_DEV_ID_VF && pdev->device != HINIC5_DEV_ID_25V1_VF))
+ if (pdev == NULL || pdev->vendor != PCI_VENDOR_ID_HUAWEI ||
+ ((pdev->device != HINIC5_DEV_ID_VF) &&
+ (pdev->device != HINIC5_DEV_ID_25V1_VF)))
return;
sdk_warn(&pdev->dev, "Notify vf disable timer bitmap before flr\n");
@@ -385,15 +387,17 @@ void hinic5_notify_vf_timer_disable(struct pci_dev *pdev)
/* Set VF FUNC ATTR6 17bit to mark vf before flr */
val = ioread32be(bar + HINIC5_VF_FUNC_ATTRIBUTE6_OFFSET);
- iowrite32be(val | HINIC5_VF_NOTIFY_FLR_BIT, bar + HINIC5_VF_FUNC_ATTRIBUTE6_OFFSET);
+ iowrite32be(val | HINIC5_VF_NOTIFY_FLR_BIT,
+ bar + HINIC5_VF_FUNC_ATTRIBUTE6_OFFSET);
- /* Set PF HOST_MPU_NOTIFY to cause mpu interrupt */
+ /* Set PF HOST_MPU_NOTIFY to cause mpu intterrupt */
val = ioread32be(bar_physfn + HINIC5_PF_HOST_MPU_NOTIFY_OFFSET);
iowrite32be(val | HINIC5_PF_HOST_MPU_NOTIFY_BIT,
bar_physfn + HINIC5_PF_HOST_MPU_NOTIFY_OFFSET);
/* Wait for MPU disable vf timer bitmap */
- timeout = jiffies + msecs_to_jiffies(HINIC5_VF_TIMER_DISABLE_MAX_TIMEOUT);
+ timeout =
+ jiffies + msecs_to_jiffies(HINIC5_VF_TIMER_DISABLE_MAX_TIMEOUT);
do {
val = ioread32be(bar + HINIC5_VF_FUNC_ATTRIBUTE6_OFFSET);
if ((val & HINIC5_VF_NOTIFY_FLR_BIT) == 0)
@@ -403,11 +407,12 @@ void hinic5_notify_vf_timer_disable(struct pci_dev *pdev)
iounmap(bar_physfn);
iounmap(bar);
+ return;
}
EXPORT_SYMBOL(hinic5_notify_vf_timer_disable);
-int hinic5_set_vf_service_state(struct hinic5_lld_dev *lld_dev,
- u16 vf_func_id, u16 service, bool en)
+int hinic5_set_vf_service_state(struct hinic5_lld_dev *lld_dev, u16 vf_func_id,
+ u16 service, bool en)
{
struct hinic5_adev *dev = to_hinic5_adev(lld_dev);
struct hinic5_hw_pf_infos *pf_infos = NULL;
@@ -419,32 +424,35 @@ int hinic5_set_vf_service_state(struct hinic5_lld_dev *lld_dev,
bool find_dst_dev = false;
err = get_vf_service_state_param(lld_dev, dev, service, &pf_infos);
- if (err != 0 || !pf_infos)
+ if (err != 0 || pf_infos == NULL)
return err;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start,
&vf_end, vf_func_id) != 0)
continue;
dst_pdev = container_of(dst_dev->dev, struct pci_dev, dev);
- vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
- (u16)dst_pdev->devfn;
+ vf_devfn = pf_infos->infos[func_id].vf_offset +
+ (vf_func_id - vf_start) + (u16)dst_pdev->devfn;
err = hinic5_dst_pdev_valid(dst_dev, &des_pdev, vf_devfn, en);
if (err != 0) {
- sdk_err(dev->dev, "Can not get vf func_id %u from pf %u\n",
+ sdk_err(dev->dev,
+ "Can not get vf func_id %u from pf %u\n",
vf_func_id, func_id);
- hinic5_lld_put();
+ lld_put();
goto free_pf_info;
}
dst_dev = pci_get_drvdata(des_pdev);
/* When enable vf scene, if vf bind to vf-io, return ok */
- if ((strcmp(des_pdev->driver->name, HINIC5_DRV_NAME) != 0) ||
- !dst_dev || (!en && dst_dev->lld_state != HINIC5_PROBE_OK) ||
+ if (!des_pdev->driver ||
+ (strcmp(des_pdev->driver->name, HINIC5_DRV_NAME) != 0) ||
+ !dst_dev ||
+ (!en && dst_dev->lld_state != HINIC5_PROBE_OK) ||
(en && dst_dev->lld_state != HINIC5_NOT_PROBE)) {
- hinic5_lld_put();
+ lld_put();
goto free_pf_info;
}
@@ -453,24 +461,25 @@ int hinic5_set_vf_service_state(struct hinic5_lld_dev *lld_dev,
find_dst_dev = true;
break;
}
- hinic5_lld_put();
+ lld_put();
if (!find_dst_dev) {
err = -EFAULT;
- sdk_err(dev->dev, "Invalid parameter vf_id %u\n", vf_func_id);
+ sdk_err(dev->dev, "Invalid parameter vf_id %u \n", vf_func_id);
goto free_pf_info;
}
err = hinic5_pci_set_func_en(dst_dev, en, vf_func_id);
free_pf_info:
- if (pf_infos)
+ if (pf_infos != NULL)
kfree(pf_infos);
return err;
}
EXPORT_SYMBOL(hinic5_set_vf_service_state);
-int hinic5_pci_irq_vectors_alloc(struct hinic5_adev *adev, void *entry, u32 irqs_min, u32 irqs_num)
+int hinic5_pci_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num)
{
struct pci_dev *pdev = to_pci_dev(adev->dev);
@@ -556,7 +565,8 @@ static void hinic5_pci_remove(struct pci_dev *pdev)
#ifndef __HIFC__
#ifdef CONFIG_PCI_IOV
- if (pdev->is_virtfn != 0 && (hinic5_get_pf_device_id(pdev) == HINIC5_DEV_ID_SDI_6_0_PF) &&
+ if ((pdev->is_virtfn != 0) &&
+ (hinic5_get_pf_device_id(pdev) == HINIC5_DEV_ID_SDI_6_0_PF) &&
hinic5_get_vf_load_state(pdev))
return;
#endif
@@ -585,7 +595,6 @@ static void hinic5_mask_aer_comp_abort(struct pci_dev *pdev)
int pos;
struct pci_dev *rp = pcie_find_root_port(pdev);
-
if (!rp) {
sdk_warn(&pdev->dev, "Cannot find root port.\n");
return;
@@ -593,7 +602,8 @@ static void hinic5_mask_aer_comp_abort(struct pci_dev *pdev)
pos = pci_find_ext_capability(rp, PCI_EXT_CAP_ID_ERR);
if (!pos) {
- sdk_err(&pdev->dev, "AER capability is not found in PCIe config space.\n");
+ sdk_err(&pdev->dev,
+ "AER capability is not found in PCIe config space.\n");
return;
}
@@ -609,10 +619,11 @@ static int hinic5_probe_func(struct hinic5_adev *adev)
int err;
err = probe_func_param_init(adev);
- if (err == -EEXIST)
+ if (err == -EEXIST) {
return 0;
- else if (err != 0)
+ } else if (err != 0) {
return err;
+ }
err = mapping_bar(pdev, adev);
if (err != 0) {
@@ -621,14 +632,15 @@ static int hinic5_probe_func(struct hinic5_adev *adev)
}
/* if chip information of pcie function exist, add the function into chip */
- hinic5_lld_lock_chip_node();
- err = hinic5_alloc_chip_node(adev);
+ lld_lock_chip_node();
+ err = alloc_chip_node(adev);
if (err != 0) {
- hinic5_lld_unlock_chip_node();
- sdk_err(&pdev->dev, "Failed to add new chip node to global list\n");
+ lld_unlock_chip_node();
+ sdk_err(&pdev->dev,
+ "Failed to add new chip node to global list\n");
goto alloc_chip_node_fail;
}
- hinic5_lld_unlock_chip_node();
+ lld_unlock_chip_node();
err = hinic5_func_init(adev);
if (err != 0)
@@ -636,11 +648,9 @@ static int hinic5_probe_func(struct hinic5_adev *adev)
#if (defined CONFIG_ARM) || (defined CONFIG_ARM64)
/* Prevent PF from being in an abnormal state
- * due to illegal memory access by its VF.
- */
+ due to illegal memory access by its VF. */
if (hinic5_func_type(adev->hwdev) == TYPE_PPF) {
- if (!hinic5_in_spu(adev->hwdev))
- hinic5_mask_aer_comp_abort(pdev);
+ hinic5_mask_aer_comp_abort(pdev);
}
#endif /* ARM */
@@ -652,7 +662,8 @@ static int hinic5_probe_func(struct hinic5_adev *adev)
}
err = hinic5_set_bdf_ctxt(adev->hwdev, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn));
if (err != 0) {
sdk_err(&pdev->dev, "Failed to set BDF info to MPU\n");
sysfs_remove_group(&pdev->dev.kobj, &hinic5_attr_group);
@@ -673,9 +684,9 @@ static int hinic5_probe_func(struct hinic5_adev *adev)
hinic5_func_deinit(adev);
func_init_err:
- hinic5_lld_lock_chip_node();
- hinic5_free_chip_node(adev);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ free_chip_node(adev);
+ lld_unlock_chip_node();
alloc_chip_node_fail:
unmapping_bar(adev);
@@ -689,7 +700,6 @@ bool hinic5_pci_is_virtfn(struct hinic5_adev *adev)
{
#ifdef CONFIG_PCI_IOV
struct pci_dev *pdev = to_pci_dev(adev->dev);
-
return (bool)(pdev->is_virtfn);
#else
return false;
@@ -706,10 +716,17 @@ int hinic5_pci_get_vf_num(struct hinic5_adev *adev)
int hinic5_pci_init_device_info(struct hinic5_adev *adev)
{
struct hinic5_adev *pf_adev = hinic5_pdev_get_pf_adev(adev);
- struct pci_dev *pdev = to_pci_dev(pf_adev->dev);
- u64 bus_domain_nr = (u64)pci_domain_nr(pdev->bus);
+ struct pci_dev *pdev = NULL;
+ u64 bus_domain_nr;
+
+ if (!pf_adev)
+ return -EFAULT;
- adev->info.id = (bus_domain_nr << PCI_BUS_NUM_SHIFT) + pdev->bus->number;
+ pdev = to_pci_dev(pf_adev->dev);
+ bus_domain_nr = (u64)pci_domain_nr(pdev->bus);
+
+ adev->info.id =
+ (bus_domain_nr << PCI_BUS_NUM_SHIFT) + pdev->bus->number;
return 0;
}
@@ -721,14 +738,17 @@ u16 hinic5_pci_get_device_id(struct hinic5_adev *adev)
return pdev->device;
}
-int hinic5_pci_set_func_en(struct hinic5_adev *dst_adev, bool en, u16 vf_func_id)
+int hinic5_pci_set_func_en(struct hinic5_adev *dst_adev, bool en,
+ u16 vf_func_id)
{
- struct pci_dev *des_pdev = container_of(dst_adev->dev, struct pci_dev, dev);
+ struct pci_dev *des_pdev =
+ container_of(dst_adev->dev, struct pci_dev, dev);
int err;
mutex_lock(&dst_adev->adev_mutex);
/* unload invalid vf func id */
- if (!en && vf_func_id != hinic5_global_func_id(dst_adev->hwdev) &&
+ if (!en && (vf_func_id != hinic5_global_func_id(dst_adev->hwdev)) &&
+ des_pdev->driver &&
(strcmp(des_pdev->driver->name, HINIC5_DRV_NAME) == 0)) {
pr_err("dst_adev func id:%u, vf_func_id:%u\n",
hinic5_global_func_id(dst_adev->hwdev), vf_func_id);
@@ -756,11 +776,14 @@ struct hinic5_adev *hinic5_pdev_get_pf_adev(struct hinic5_adev *adev)
struct hinic5_adev *pf_adev = NULL;
struct pci_dev *pdev = to_pci_dev(adev->dev);
- pf_adev = (hinic5_pci_is_virtfn(adev) != 0) ? pci_get_drvdata(pdev->physfn) : adev;
+ pf_adev = (hinic5_pci_is_virtfn(adev) != 0) ?
+ pci_get_drvdata(pdev->physfn) :
+ adev;
return pf_adev;
}
-static int hinic5_pf_get_vf_offset_info(struct hinic5_adev *des_adev, u16 *vf_offset)
+static int hinic5_pf_get_vf_offset_info(struct hinic5_adev *des_adev,
+ u16 *vf_offset)
{
int err, i;
struct hinic5_hw_pf_infos *pf_infos = NULL;
@@ -776,20 +799,27 @@ static int hinic5_pf_get_vf_offset_info(struct hinic5_adev *des_adev, u16 *vf_of
if (g_vf_offset.valid == 0) {
pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
if (!pf_infos) {
+ sdk_err(pf_adev->dev, "Malloc pf_infos fail\n");
err = -ENOMEM;
goto err_malloc;
}
- err = hinic5_get_hw_pf_infos(pf_adev->hwdev, pf_infos, HINIC5_CHANNEL_COMM);
+ err = hinic5_get_hw_pf_infos(pf_adev->hwdev, pf_infos,
+ HINIC5_CHANNEL_COMM);
if (err != 0) {
- sdk_warn(pf_adev->dev, "Hinic5_get_hw_pf_infos fail err %d\n", err);
+ sdk_warn(pf_adev->dev,
+ "Hinic5_get_hw_pf_infos fail err %d\n", err);
err = -EFAULT;
goto err_out;
}
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] =
+ pf_infos->infos[i].vf_offset;
+ }
+
+ wmb();
g_vf_offset.valid = 1;
- for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
- g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
kfree(pf_infos);
}
@@ -807,7 +837,8 @@ static int hinic5_pf_get_vf_offset_info(struct hinic5_adev *des_adev, u16 *vf_of
return err;
}
-struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id)
+struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id)
{
int err;
u16 bus_num;
@@ -821,7 +852,8 @@ struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 f
vf_start = hinic5_glb_pf_vf_offset(src_adev->hwdev);
vf_end = vf_start + hinic5_func_max_vf(src_adev->hwdev);
pf_func_id = hinic5_global_func_id(src_adev->hwdev);
- if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ if (func_id <= vf_start || func_id > vf_end ||
+ pf_func_id >= CMD_MAX_MAX_PF_NUM)
return NULL;
err = hinic5_pf_get_vf_offset_info(src_adev, &vf_offset);
@@ -833,20 +865,28 @@ struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 f
des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
bus_num = pdev->bus->number + des_fn / BUS_MAX_DEV_NUM;
- dst_vf_pdev = pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+ dst_vf_pdev = pci_get_domain_bus_and_slot(0, bus_num,
+ (des_fn % BUS_MAX_DEV_NUM));
+ if (!dst_vf_pdev)
+ return NULL;
dst_adev = pci_get_drvdata(dst_vf_pdev);
+ if (!dst_adev) {
+ pci_dev_put(dst_vf_pdev);
+ return NULL;
+ }
put_device(dst_adev->dev);
return dst_adev;
}
-STATIC int hinic5_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+STATIC int hinic5_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev,
+ u16 *global_func_id)
{
struct pci_dev *pf_pdev = NULL;
struct hinic5_adev *adev = NULL;
u16 pf_bus, vf_bus, vf_offset;
int err;
- if (!pdev || !global_func_id || pdev->is_virtfn == 0)
+ if (!pdev || !global_func_id || (pdev->is_virtfn == 0))
return -EINVAL;
pf_pdev = pdev->physfn;
@@ -858,7 +898,8 @@ STATIC int hinic5_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *glob
adev = pci_get_drvdata(pf_pdev);
err = hinic5_pf_get_vf_offset_info(adev, &vf_offset);
if (err != 0) {
- sdk_err(&pdev->dev, "Func hinic5_pf_get_vf_offset_info fail\n");
+ sdk_err(&pdev->dev,
+ "Func hinic5_pf_get_vf_offset_info fail\n");
return -EFAULT;
}
} else {
@@ -866,9 +907,11 @@ STATIC int hinic5_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *glob
sdk_err(&pdev->dev, "Pf offset get fail\n");
return -EFAULT;
}
+ rmb();
}
- *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ *global_func_id =
+ (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
(u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
return 0;
@@ -906,7 +949,7 @@ STATIC bool hinic5_get_vf_nic_en_status(struct pci_dev *pdev)
}
if (hisdk5_get_plug_srv_bitmap(adev->hwdev, COMM_PLUG_SRV_NIC,
- global_func_id, &nic_en) != 0) {
+ global_func_id, &nic_en) != 0) {
sdk_err(&pdev->dev, "Get function nic status failed\n");
return false;
}
@@ -917,7 +960,8 @@ STATIC bool hinic5_get_vf_nic_en_status(struct pci_dev *pdev)
return (nic_en != 0);
}
-static int hinic5_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int hinic5_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
{
struct hinic5_adev *adev = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
@@ -927,7 +971,8 @@ static int hinic5_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
#ifndef __HIFC__
#ifdef CONFIG_PCI_IOV
- if (pdev->is_virtfn != 0 && (hinic5_get_pf_device_id(pdev) == HINIC5_DEV_ID_SDI_6_0_PF) &&
+ if ((pdev->is_virtfn != 0) &&
+ (hinic5_get_pf_device_id(pdev) == HINIC5_DEV_ID_SDI_6_0_PF) &&
hinic5_get_vf_load_state(pdev)) {
sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
return -EINVAL;
@@ -954,11 +999,12 @@ static int hinic5_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
adev->lld_dev.dev_type = HINIC5_DEVICE_T_PCI;
adev->bus_ops = hinic5_get_dev_ops(adev);
err = adev->bus_ops->init_device_info(adev);
- if (err != 0)
+ if (err != 0) {
goto init_device_info_err;
- hinic5_lld_dev_cnt_init(adev);
+ }
+ lld_dev_cnt_init(adev);
- if (pdev->is_virtfn != 0 && (!hinic5_get_vf_load_state(pdev)) &&
+ if ((pdev->is_virtfn != 0) && (!hinic5_get_vf_load_state(pdev)) &&
(!hinic5_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
@@ -1001,17 +1047,11 @@ void hinic5_pci_probe_fault_process(struct hinic5_adev *adev)
}
static const struct pci_device_id hinic5_pci_table[] = {
-#ifdef CONFIG_SP_VID_DID
- {PCI_VDEVICE(SPNIC, HINIC5_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(SPNIC, HINIC5_DEV_ID_SDI_5_1_PF), 0},
- {PCI_VDEVICE(SPNIC, HINIC5_DEV_ID_VF), 0},
-#else
- {PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_72V1_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_72V1_VF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_25V1_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_25V1_VF), 0},
-#endif
- {0,}
+ { PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_72V1_PF), 0 },
+ { PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_72V1_VF), 0 },
+ { PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_25V1_PF), 0 },
+ { PCI_VDEVICE(HUAWEI, HINIC5_DEV_ID_25V1_VF), 0 },
+ { 0, 0 }
};
@@ -1084,24 +1124,24 @@ static struct pci_driver_rh hinic5_driver_rh = {
static struct pci_error_handlers hinic5_err_handler = {
.error_detected = hinic5_io_error_detected,
#ifdef HAVE_PCIE_RESET_DONE
- .reset_done = hinic5_reset_done,
+ .reset_done = hinic5_reset_done,
#endif
};
static struct pci_driver hinic5_driver = {
- .name = HINIC5_DRV_NAME,
- .id_table = hinic5_pci_table,
- .probe = hinic5_pci_probe,
- .remove = hinic5_pci_remove,
- .shutdown = hinic5_pci_shutdown,
+ .name = HINIC5_DRV_NAME,
+ .id_table = hinic5_pci_table,
+ .probe = hinic5_pci_probe,
+ .remove = hinic5_pci_remove,
+ .shutdown = hinic5_pci_shutdown,
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic5_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
.rh_reserved = &hinic5_driver_rh,
#endif
- .err_handler = &hinic5_err_handler,
+ .err_handler = &hinic5_err_handler,
#if (KERNEL_VERSION(3, 10, 0) != LINUX_VERSION_CODE)
- .groups = hisdk5_driver_attr_groups,
+ .groups = hisdk5_driver_attr_groups,
#endif
};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.h
index d95752fac..70541f6b6 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_pcie.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_pcie.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_PCIE_H
#define HINIC5_PCIE_H
@@ -14,18 +7,21 @@
#include <linux/pci.h>
#include "hinic5_dev_mgmt.h"
-#define PCI_BUS_NUM_SHIFT 8
+#define PCI_BUS_NUM_SHIFT 8
#define BUS_MAX_DEV_NUM 256
int hinic5_pci_register_driver(void);
void hinic5_pci_unregister_driver(void);
bool hinic5_pci_is_virtfn(struct hinic5_adev *adev);
struct hinic5_adev *hinic5_pdev_get_pf_adev(struct hinic5_adev *adev);
-int hinic5_pci_set_func_en(struct hinic5_adev *dst_adev, bool en, u16 vf_func_id);
+int hinic5_pci_set_func_en(struct hinic5_adev *dst_adev, bool en,
+ u16 vf_func_id);
int hinic5_pci_get_vf_num(struct hinic5_adev *adev);
u16 hinic5_pci_get_device_id(struct hinic5_adev *adev);
-struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id);
-int hinic5_pci_irq_vectors_alloc(struct hinic5_adev *adev, void *entry, u32 irqs_min, u32 irqs_num);
+struct hinic5_adev *hinic5_pci_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id);
+int hinic5_pci_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num);
void hinic5_pci_irq_vectors_free(struct hinic5_adev *adev);
int hinic5_pci_irq_vector(struct hinic5_adev *adev, u32 idx);
int hinic5_pci_init_device_info(struct hinic5_adev *adev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.c
index 2d8e1f98f..71aea358e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sriov.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -46,7 +39,8 @@ int hinic5_init_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
return 0;
}
-#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE)) && !defined(__WIN__)
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE)) && \
+ !defined(__WIN__)
ssize_t hinic5_sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -82,7 +76,7 @@ ssize_t hinic5_sriov_numvfs_store(struct device *dev,
return -ERANGE;
if (num_vfs == cur_vfs)
- return count; /* no change */
+ return count; /* no change */
if (num_vfs == 0) {
/* disable VFs */
@@ -94,8 +88,10 @@ ssize_t hinic5_sriov_numvfs_store(struct device *dev,
/* enable VFs */
if (cur_vfs) {
- nic_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n",
- cur_vfs, num_vfs);
+ nic_warn(
+ &pdev->dev,
+ "%d VFs already enabled. Disable before enabling %d VFs\n",
+ cur_vfs, num_vfs);
return -EBUSY;
}
@@ -115,7 +111,8 @@ ssize_t hinic5_sriov_numvfs_store(struct device *dev,
static void migration_uninit_vf(struct pci_dev *pdev)
{
#if (defined CONFIG_ARM) || (defined CONFIG_ARM64)
- void (*uninit_vfs)(struct pci_dev *) = __symbol_get("migration_dev_uninit_vfs");
+ void (*uninit_vfs)(struct pci_dev *) =
+ __symbol_get("migration_dev_uninit_vfs");
if (uninit_vfs) {
uninit_vfs(pdev);
@@ -128,13 +125,14 @@ int hinic5_pci_sriov_disable(struct pci_dev *dev)
{
#ifdef CONFIG_PCI_IOV
struct hinic5_sriov_info *sriov_info = NULL;
- struct hinic5_event_info event = {0};
+ struct hinic5_event_info event = { 0 };
void *hwdev = NULL;
sriov_info = hinic5_get_sriov_info_by_pcidev(dev);
hwdev = hinic5_get_hwdev_by_pcidev(dev);
if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV disable is not permitted, please wait...\n");
+ sdk_err(&dev->dev,
+ "SR-IOV disable is not permitted, please wait...\n");
return -EPERM;
}
@@ -153,14 +151,18 @@ int hinic5_pci_sriov_disable(struct pci_dev *dev)
*/
if (pci_vfs_assigned(dev) != 0) {
clear_bit(HINIC5_SRIOV_DISABLE, &sriov_info->state);
- sdk_warn(&dev->dev, "Unloading driver while VFs are assigned - VFs will not be deallocated\n");
+ sdk_warn(
+ &dev->dev,
+ "Unloading driver while VFs are assigned - VFs will not be deallocated\n");
return -EPERM;
}
event.service = EVENT_SRV_COMM;
event.type = EVENT_COMM_SRIOV_STATE_CHANGE;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable = 0;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs = 0;
+ ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable =
+ 0;
+ ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs =
+ 0;
hinic5_event_callback(hwdev, &event);
sriov_info->sriov_enabled = false;
@@ -180,10 +182,11 @@ int hinic5_pci_sriov_disable(struct pci_dev *dev)
#ifdef CONFIG_PCI_IOV
#if (defined CONFIG_ARM) || (defined CONFIG_ARM64)
-static int migration_init_vf(struct pci_dev *dev, int num_vfs, struct hinic5_sriov_info *sriov_info)
+static int migration_init_vf(struct pci_dev *dev, int num_vfs,
+ struct hinic5_sriov_info *sriov_info)
{
int err = 0;
- int (*migration_dev_init_vfs)(struct pci_dev *dev, uint32_t num_vfs);
+ int (*migration_dev_init_vfs)(struct pci_dev *, uint32_t);
migration_dev_init_vfs = __symbol_get("migration_dev_init_vfs");
if (migration_dev_init_vfs) {
@@ -203,15 +206,16 @@ static int migration_init_vf(struct pci_dev *dev, int num_vfs, struct hinic5_sri
static void hinic5_event_callback_dev(struct hinic5_sriov_info *sriov_info,
void *hwdev, int num_vfs)
{
- struct hinic5_event_info event = {0};
+ struct hinic5_event_info event = { 0 };
sriov_info->sriov_enabled = true;
-
sriov_info->num_vfs = (u32)num_vfs;
event.service = EVENT_SRV_COMM;
event.type = EVENT_COMM_SRIOV_STATE_CHANGE;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable = 1;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs = (u16)num_vfs;
+ ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable =
+ 1;
+ ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs =
+ (u16)num_vfs;
hinic5_event_callback(hwdev, &event);
clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
@@ -223,7 +227,8 @@ int hinic5_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
#ifdef CONFIG_PCI_IOV
int err, pre_existing_vfs;
- struct hinic5_sriov_info *sriov_info = hinic5_get_sriov_info_by_pcidev(dev);
+ struct hinic5_sriov_info *sriov_info =
+ hinic5_get_sriov_info_by_pcidev(dev);
void *hwdev = hinic5_get_hwdev_by_pcidev(dev);
if (!hwdev) {
@@ -232,7 +237,9 @@ int hinic5_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
}
if (test_and_set_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n", num_vfs);
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
+ num_vfs);
return -EPERM;
}
@@ -242,9 +249,8 @@ int hinic5_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
- if (pre_existing_vfs != 0 && pre_existing_vfs != num_vfs) {
- err = hinic5_pci_sriov_disable(dev);
- if (err != 0) {
+ if ((pre_existing_vfs != 0) && (pre_existing_vfs != num_vfs)) {
+ if ((err = hinic5_pci_sriov_disable(dev)) != 0) {
clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
return err;
}
@@ -253,16 +259,15 @@ int hinic5_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
- err = hinic5_init_vf_hw(hwdev, 1, (u16)num_vfs);
- if (err != 0) {
+ if ((err = hinic5_init_vf_hw(hwdev, 1, (u16)num_vfs)) != 0) {
sdk_err(&dev->dev,
- "Failed to init vf in hardware before enable sriov, error %d\n", err);
+ "Failed to init vf in hardware before enable sriov, error %d\n",
+ err);
clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
return err;
}
- err = pci_enable_sriov(dev, num_vfs);
- if (err != 0) {
+ if ((err = pci_enable_sriov(dev, num_vfs)) != 0) {
sdk_err(&dev->dev, "Failed to enable SR-IOV, error %d\n", err);
clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
return err;
@@ -270,8 +275,9 @@ int hinic5_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
#if (defined CONFIG_ARM) || (defined CONFIG_ARM64)
err = migration_init_vf(dev, num_vfs, sriov_info);
- if (err < 0)
+ if (err < 0) {
return err;
+ }
#endif
hinic5_event_callback_dev(sriov_info, hwdev, num_vfs);
return num_vfs;
@@ -296,7 +302,7 @@ int hinic5_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
if (!sriov_info)
return -EFAULT;
- if (!test_bit(HINIC5_FUNC_PERSENT, &sriov_info->state))
+ if (!test_bit(HINIC5_FUNC_PRESENT, &sriov_info->state))
return -EFAULT;
if (num_vfs == 0)
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.h
index 4d1050927..40b2443dc 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sriov.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sriov.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_SRIOV_H
#define HINIC5_SRIOV_H
@@ -16,7 +9,7 @@
#include "hinic5_bus.h"
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE) || \
- defined(__WIN__) || defined(__VMWARE__))
+ defined(__WIN__) || defined(__VMWARE__))
ssize_t hinic5_sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
ssize_t hinic5_sriov_numvfs_show(struct device *dev,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.c
index 4faf1e134..b947ee72a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.c
@@ -1,12 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sysfs.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sysfs.h>
@@ -15,14 +6,14 @@
#include "hinic5_dev_mgmt.h"
#include "hinic5_hw.h"
#include "hinic5_hwdev.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_sysfs.h"
/* driver attributes */
static ssize_t metadata_show(struct device_driver *dev, char *buf)
{
return (ssize_t)sysfs_emit(buf, "commit: %s\ncompile time: %s\n",
- GIT_COMMIT_ID, "2026-05-20_00:00:00");
+ GIT_COMMIT_ID, __TIME_STR__);
}
static DRIVER_ATTR_RO(metadata);
@@ -41,20 +32,21 @@ const struct attribute_group *hisdk5_driver_attr_groups[] = {
};
/* device attributes */
-static ssize_t timeout_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct hinic5_adev *adev = dev_get_drvdata(dev);
struct hinic5_hwdev *hwdev = adev->hwdev;
ssize_t len = 0;
- if (!hwdev || !hwdev->timeout_info)
+ if (hwdev == NULL || hwdev->timeout_info == NULL) {
return len;
+ }
len += sysfs_emit(buf,
- "hw_type: %s\n"
- "mbox_timeout: %u ms\nmailbox_poll_timeout: %u ms\n"
- "cmdq_timeout: %u ms\n",
+ "hw_type: %s\n"
+ "mbox_timeout: %u ms\nmailbox_poll_timeout: %u ms\n"
+ "cmdq_timeout: %u ms\n",
hwdev->timeout_info->hw_type_desc,
hwdev->timeout_info->mbox_timeout,
hwdev->timeout_info->mbox_poll_timeout,
@@ -63,10 +55,8 @@ static ssize_t timeout_show(struct device *dev,
}
static DEVICE_ATTR_RO(timeout);
-static struct attribute *hisdk5_device_attrs[] = {
- &dev_attr_timeout.attr,
- NULL
-};
+static struct attribute *hisdk5_device_attrs[] = { &dev_attr_timeout.attr,
+ NULL };
static const struct attribute_group hisdk5_device_attr_group = {
.attrs = hisdk5_device_attrs
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.h
index fbb3cb1ff..4abc6fe9d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_sysfs.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sysfs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef __HINIC5_SYSFS_H_
#define __HINIC5_SYSFS_H_
@@ -20,4 +13,4 @@ extern const struct attribute_group *hisdk5_driver_attr_groups[];
int register_device_attr_groups(struct hinic5_adev *adev);
void unregister_device_attr_groups(struct hinic5_adev *adev);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.c
index df8cea4f8..e04f267df 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ubus.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifdef __UBUS_DRIVER__
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -26,6 +19,7 @@
#include <linux/mod_devicetable.h>
#endif
+#include "securec.h"
#include "ossl_knl.h"
#include "hinic5_mt.h"
#include "hinic5_common.h"
@@ -34,7 +28,7 @@
#include "hinic5_dev_mgmt.h"
#include "hinic5_nictool.h"
#include "hinic5_hw.h"
-#include "hinic5_hinic5_vram.h"
+#include "hinic5_vram.h"
#include "hinic5_fast_msg_init.h"
#include "hinic5_lld.h"
#include "hinic5_lld_private.h"
@@ -57,10 +51,13 @@ static enum ubus_device_type ubus_get_device_type(hinic_ub_dev *ubus_dev)
{
if (HINIC_UB_GET_DEVICE_ID(ubus_dev) == HINIC5_UDEV_DEVICE_ID_1825_PF ||
HINIC_UB_GET_DEVICE_ID(ubus_dev) == HINIC5_UDEV_DEVICE_ID_1825_VF ||
- HINIC_UB_GET_DEVICE_ID(ubus_dev) == HINIC5_UDEV_DEVICE_ID_1825_TEMP) {
+ HINIC_UB_GET_DEVICE_ID(ubus_dev) ==
+ HINIC5_UDEV_DEVICE_ID_1825_TEMP) {
return UBUS_DEVICE_TYPE_1825;
- } else if (HINIC_UB_GET_DEVICE_ID(ubus_dev) == HINIC5_UDEV_DEVICE_ID_1872_PF ||
- HINIC_UB_GET_DEVICE_ID(ubus_dev) == HINIC5_UDEV_DEVICE_ID_1872_VF) {
+ } else if (HINIC_UB_GET_DEVICE_ID(ubus_dev) ==
+ HINIC5_UDEV_DEVICE_ID_1872_PF ||
+ HINIC_UB_GET_DEVICE_ID(ubus_dev) ==
+ HINIC5_UDEV_DEVICE_ID_1872_VF) {
return UBUS_DEVICE_TYPE_1872;
} else {
return UBUS_DEVICE_TYPE_INVALID;
@@ -74,24 +71,22 @@ struct fers2_conf {
u32 mgmt_reg_size;
};
-static const struct fers2_conf PF_RS2_CONF = {
- HINIC5_PF_UBUS_CFG_REG_OFFSET, HINIC5_PF_UBUS_CFG_REG_SIZE,
- HINIC5_PF_UBUS_MGMT_REG_OFFSET, HINIC5_PF_UBUS_MGMT_REG_SIZE
-};
+static const struct fers2_conf PF_RS2_CONF = { HINIC5_PF_UBUS_CFG_REG_OFFSET,
+ HINIC5_PF_UBUS_CFG_REG_SIZE,
+ HINIC5_PF_UBUS_MGMT_REG_OFFSET,
+ HINIC5_PF_UBUS_MGMT_REG_SIZE };
-static const struct fers2_conf VF_RS2_CONF = {
- HINIC5_VF_UBUS_CFG_REG_OFFSET, HINIC5_VF_UBUS_CFG_REG_SIZE,
- 0, 0
-};
+static const struct fers2_conf VF_RS2_CONF = { HINIC5_VF_UBUS_CFG_REG_OFFSET,
+ HINIC5_VF_UBUS_CFG_REG_SIZE, 0,
+ 0 };
static const struct fers2_conf HTN_PF_RS2_CONF = {
- HINIC5_HTN_PF_UBUS_CFG_REG_OFFSET, HINIC5_HTN_PF_UBUS_CFG_REG_SIZE,
+ HINIC5_HTN_PF_UBUS_CFG_REG_OFFSET, HINIC5_HTN_PF_UBUS_CFG_REG_SIZE,
HINIC5_HTN_PF_UBUS_MGMT_REG_OFFSET, HINIC5_HTN_PF_UBUS_MGMT_REG_SIZE
};
static const struct fers2_conf HTN_VF_RS2_CONF = {
- HINIC5_HTN_VF_UBUS_CFG_REG_OFFSET, HINIC5_HTN_VF_UBUS_CFG_REG_SIZE,
- 0, 0
+ HINIC5_HTN_VF_UBUS_CFG_REG_OFFSET, HINIC5_HTN_VF_UBUS_CFG_REG_SIZE, 0, 0
};
static const struct fers2_conf *get_fers2_config(hinic_ub_dev *ubus_dev,
@@ -126,9 +121,9 @@ static int ubus_mapping_bar(hinic_ub_dev *ubus_dev, struct hinic5_adev *adev)
#endif
/* resource 2 */
- adev->fers2_base_phy = ub_resource_start(ubus_dev, HINIC5_UBUS_FERS2);
+ adev->fers2_base_phy = ub_resource_start(ubus_dev, HINIC5_UBUS_FERS2);
adev->fers2_total_len = ub_resource_len(ubus_dev, HINIC5_UBUS_FERS2);
- adev->fers2_reg_base = ub_iomap(ubus_dev, HINIC5_UBUS_FERS2, 0);
+ adev->fers2_reg_base = ub_iomap(ubus_dev, HINIC5_UBUS_FERS2, 0);
if (!adev->fers2_reg_base) {
sdk_err(&ubus_dev->dev, "Failed to map resource 2\n");
return -ENOMEM;
@@ -141,28 +136,27 @@ static int ubus_mapping_bar(hinic_ub_dev *ubus_dev, struct hinic5_adev *adev)
/* mgmt reg */
if (is_pf) {
- adev->mgmt_reg_base = adev->fers2_reg_base + rs2->mgmt_reg_offset;
- adev->mgmt_base_phy = adev->fers2_base_phy + rs2->mgmt_reg_offset;
- adev->mgmt_base_len = rs2->mgmt_reg_offset;
+ adev->mgmt_reg_base =
+ adev->fers2_reg_base + rs2->mgmt_reg_offset;
+ adev->mgmt_base_phy =
+ adev->fers2_base_phy + rs2->mgmt_reg_offset;
+ adev->mgmt_base_len = rs2->mgmt_reg_size;
}
/* interrupt reg */
adev->intr_reg_base = ub_iomap(ubus_dev, HINIC5_UBUS_INTR_REG_BAR, 0);
if (!adev->intr_reg_base) {
- sdk_err(&ubus_dev->dev,
- "Failed to map interrupt regs\n");
+ sdk_err(&ubus_dev->dev, "Failed to map interrupt regs\n");
goto map_intr_bar_err;
}
/* doorbell reg */
adev->db_base_phy = ub_resource_start(ubus_dev, HINIC5_UBUS_DB_BAR);
adev->db_dwqe_len = ub_resource_len(ubus_dev, HINIC5_UBUS_DB_BAR);
- adev->db_base = devm_ioremap_wc(&ubus_dev->dev,
- adev->db_base_phy,
+ adev->db_base = devm_ioremap_wc(&ubus_dev->dev, adev->db_base_phy,
adev->db_dwqe_len);
if (!adev->db_base) {
- sdk_err(&ubus_dev->dev,
- "Failed to map doorbell regs\n");
+ sdk_err(&ubus_dev->dev, "Failed to map doorbell regs\n");
goto map_db_err;
}
@@ -203,11 +197,12 @@ static int hinic5_ubus_init(hinic_ub_dev *ubus_dev)
struct hinic5_adev *adev = NULL;
int err;
- /* Write config space, config comes from ubus driver after loading */
+ /* 写配置空间 配置来源于ubus驱动加载后的配置 */
(void)HINIC_UB_SET_HOST_INFO(ubus_dev);
adev = devm_kzalloc(&ubus_dev->dev, sizeof(*adev), GFP_KERNEL);
if (!adev) {
+ sdk_err(&ubus_dev->dev, "Failed to alloc ub device adapter\n");
return -ENOMEM;
}
adev->dev = &ubus_dev->dev;
@@ -218,7 +213,8 @@ static int hinic5_ubus_init(hinic_ub_dev *ubus_dev)
/* set bus_access_en */
HINIC_UB_UE_ENABLE(ubus_dev, 1);
- sdk_info(&ubus_dev->dev, "Ubus DMA Bit Mask is (%u).\n", ubus_dma_bit_mask);
+ sdk_info(&ubus_dev->dev, "Ubus DMA Bit Mask is (%u).\n",
+ ubus_dma_bit_mask);
if (ubus_dma_bit_mask < HINIC5_UBUS_DMA_BIT_MASK_MIN ||
ubus_dma_bit_mask > HINIC5_UBUS_DMA_BIT_MASK_MAX) {
err = -EPERM;
@@ -254,14 +250,15 @@ static int hinic5_remove_ubus_func(struct hinic5_adev *adev)
hinic5_detect_hw_present(adev->hwdev);
- if (hinic5_func_type(adev->hwdev) != TYPE_VF)
+ if (hinic5_func_type(adev->hwdev) != TYPE_VF) {
wait_sriov_cfg_complete(adev);
+ }
hinic5_func_deinit(adev);
- hinic5_lld_lock_chip_node();
- hinic5_free_chip_node(adev);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ free_chip_node(adev);
+ lld_unlock_chip_node();
ubus_unmapping_bar(adev);
@@ -289,15 +286,17 @@ static void hinic5_ubus_remove(hinic_ub_dev *ubus_dev)
sdk_info(&ubus_dev->dev, "Ubus device removed\n");
}
-static int hinic5_probe_ubus_func(hinic_ub_dev *ubus_dev, struct hinic5_adev *adev)
+static int hinic5_probe_ubus_func(hinic_ub_dev *ubus_dev,
+ struct hinic5_adev *adev)
{
int err;
err = probe_func_param_init(adev);
- if (err == -EEXIST)
+ if (err == -EEXIST) {
return 0;
- else if (err != 0)
+ } else if (err != 0) {
return err;
+ }
err = ubus_mapping_bar(ubus_dev, adev);
if (err != 0) {
@@ -305,14 +304,15 @@ static int hinic5_probe_ubus_func(hinic_ub_dev *ubus_dev, struct hinic5_adev *ad
goto map_bar_failed;
}
- hinic5_lld_lock_chip_node();
- err = hinic5_alloc_chip_node(adev);
+ lld_lock_chip_node();
+ err = alloc_chip_node(adev);
if (err != 0) {
- hinic5_lld_unlock_chip_node();
- sdk_err(&ubus_dev->dev, "Failed to add new chip node to global list\n");
+ lld_unlock_chip_node();
+ sdk_err(&ubus_dev->dev,
+ "Failed to add new chip node to global list\n");
goto alloc_chip_node_fail;
}
- hinic5_lld_unlock_chip_node();
+ lld_unlock_chip_node();
err = hinic5_func_init(adev);
if (err != 0)
@@ -327,9 +327,9 @@ static int hinic5_probe_ubus_func(hinic_ub_dev *ubus_dev, struct hinic5_adev *ad
return 0;
func_init_err:
- hinic5_lld_lock_chip_node();
- hinic5_free_chip_node(adev);
- hinic5_lld_unlock_chip_node();
+ lld_lock_chip_node();
+ free_chip_node(adev);
+ lld_unlock_chip_node();
alloc_chip_node_fail:
ubus_unmapping_bar(adev);
@@ -339,7 +339,8 @@ static int hinic5_probe_ubus_func(hinic_ub_dev *ubus_dev, struct hinic5_adev *ad
return err;
}
-static int hinic5_ubus_probe(hinic_ub_dev *ubus_dev, const struct ub_device_id *utbl_entry)
+static int hinic5_ubus_probe(hinic_ub_dev *ubus_dev,
+ const struct ub_device_id *utbl_entry)
{
struct hinic5_adev *adev = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
@@ -363,10 +364,11 @@ static int hinic5_ubus_probe(hinic_ub_dev *ubus_dev, const struct ub_device_id *
adev->bus_ops = hinic5_get_dev_ops(adev);
adev->bus_dev = ubus_dev;
err = adev->bus_ops->init_device_info(adev);
- if (err != 0)
+ if (err != 0) {
goto init_device_info_err;
+ }
- hinic5_lld_dev_cnt_init(adev);
+ lld_dev_cnt_init(adev);
err = hinic5_probe_ubus_func(ubus_dev, adev);
if (err != 0)
@@ -408,53 +410,62 @@ void hinic5_ubus_probe_fault_process(struct hinic5_adev *adev)
static const struct ub_device_id hinic5_ubus_tbl[] = {
{
HUAWEI_UB_DEVICE_ID(HINIC5_UDEV_DEVICE_ID_1825_PF),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID(HINIC5_UDEV_DEVICE_ID_1825_VF),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID(HINIC5_UDEV_DEVICE_ID_1825_TEMP),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID(HINIC5_UDEV_DEVICE_ID_1872_PF),
- HINIC5_UDEV_CLASS_CODE_1872, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1872,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID(HINIC5_UDEV_DEVICE_ID_1872_VF),
- HINIC5_UDEV_CLASS_CODE_1872, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1872,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
/* Old Vendor ID, to be deleted */
{
HUAWEI_UB_DEVICE_ID_OLD(HINIC5_UDEV_DEVICE_ID_1825_PF),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID_OLD(HINIC5_UDEV_DEVICE_ID_1825_VF),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID_OLD(HINIC5_UDEV_DEVICE_ID_1825_TEMP),
- HINIC5_UDEV_CLASS_CODE_1825, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1825,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID_OLD(HINIC5_UDEV_DEVICE_ID_1872_PF),
- HINIC5_UDEV_CLASS_CODE_1872, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1872,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
{
HUAWEI_UB_DEVICE_ID_OLD(HINIC5_UDEV_DEVICE_ID_1872_VF),
- HINIC5_UDEV_CLASS_CODE_1872, HINIC5_UDEV_CLASS_CODE_MASK,
+ HINIC5_UDEV_CLASS_CODE_1872,
+ HINIC5_UDEV_CLASS_CODE_MASK,
},
/* required last entry */
- {0},
+ { 0 },
};
u16 hinic5_ubus_get_device_id(struct hinic5_adev *adev)
{
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
-
return HINIC_UB_GET_DEVICE_ID(udev);
}
@@ -462,7 +473,6 @@ bool hinic5_ubus_is_virtfn(struct hinic5_adev *adev)
{
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
u16 dev_id = hinic5_ubus_get_device_id(adev);
-
if (dev_id == HINIC5_UDEV_DEVICE_ID_1825_VF)
return true;
if (dev_id == HINIC5_UDEV_DEVICE_ID_1872_VF)
@@ -478,18 +488,24 @@ bool hinic5_ubus_is_virtfn(struct hinic5_adev *adev)
int hinic5_ub_init_device_info(struct hinic5_adev *adev)
{
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
+ int ret;
- adev->info.id = (u64)((udev->guid.bits.seq_num >> HINIC5_CARD_ID_OFFSET) &
- HINIC5_CARD_ID_MASK);
+ adev->info.id =
+ (u64)((udev->guid.bits.seq_num >> HINIC5_CARD_ID_OFFSET) &
+ HINIC5_CARD_ID_MASK);
if (sizeof(udev->guid) != sizeof(adev->info.guid)) {
sdk_err(adev->dev, "guid size is not matched.\n");
return -EINVAL;
}
- memcpy(&adev->info.guid, &udev->guid, sizeof(udev->guid));
+ ret = memcpy_s(&adev->info.guid, sizeof(adev->info.guid), &(udev->guid),
+ sizeof(udev->guid));
+ if (ret != 0) {
+ return -ENOMEM;
+ }
- sdk_info(adev->dev, "card_id: %lld, seq_num: %lld\n",
- adev->info.id, (u64)(udev->guid.bits.seq_num));
+ sdk_info(adev->dev, "card_id: %lld, seq_num: 0x%lld\n", adev->info.id,
+ (u64)(udev->guid.bits.seq_num));
return 0;
}
@@ -499,21 +515,26 @@ struct hinic5_adev *hinic5_ubus_get_pf_adev(struct hinic5_adev *adev)
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
#ifdef UB_SUPPORT_ENTITY
- pf_adev = (hinic5_ubus_is_virtfn(adev) != 0) ? dev_get_drvdata(&udev->pue->dev) : adev;
+ pf_adev = (hinic5_ubus_is_virtfn(adev) != 0) ?
+ dev_get_drvdata(&udev->pue->dev) :
+ adev;
#else
- pf_adev = (hinic5_ubus_is_virtfn(adev) != 0) ? dev_get_drvdata(&udev->pdev->dev) : adev;
+ pf_adev = (hinic5_ubus_is_virtfn(adev) != 0) ?
+ dev_get_drvdata(&udev->pdev->dev) :
+ adev;
#endif
return pf_adev;
}
-struct hinic5_adev *hinic5_ubus_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id)
+struct hinic5_adev *hinic5_ubus_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id)
{
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
hinic_ub_dev *vd_dev = NULL;
#ifdef UB_SUPPORT_ENTITY
list_for_each_entry(vd_dev, &udev->ue_list, node) {
- if (vd_dev->entity_idx == func_id) {
+ if (vd_dev->entity_idx == func_id) {
#else
list_for_each_entry(vd_dev, &udev->vdevice_list, node) {
if (vd_dev->fe_idx == func_id) {
@@ -535,17 +556,18 @@ int hinic5_ubus_get_vf_num(struct hinic5_adev *adev)
#endif
}
-int hinic5_ubus_set_func_en(struct hinic5_adev *dst_dev, bool en, u16 vf_func_id)
+int hinic5_ubus_set_func_en(struct hinic5_adev *dst_dev, bool en,
+ u16 vf_func_id)
{
hinic_ub_dev *des_udev = container_of(dst_dev->dev, hinic_ub_dev, dev);
int err;
mutex_lock(&dst_dev->adev_mutex);
/* unload invalid vf func id */
- if (!en && vf_func_id != hinic5_global_func_id(dst_dev->hwdev) &&
+ if (!en && (vf_func_id != hinic5_global_func_id(dst_dev->hwdev)) &&
(strcmp(des_udev->driver->name, HINIC5_DRV_NAME) == 0)) {
pr_err("dst_dev func id:%u, vf_func_id:%u\n",
- hinic5_global_func_id(dst_dev->hwdev), vf_func_id);
+ hinic5_global_func_id(dst_dev->hwdev), vf_func_id);
mutex_unlock(&dst_dev->adev_mutex);
return -EFAULT;
}
@@ -565,7 +587,8 @@ int hinic5_ubus_set_func_en(struct hinic5_adev *dst_dev, bool en, u16 vf_func_id
return 0;
}
-int hinic5_ubus_irq_vectors_alloc(struct hinic5_adev *adev, void *entry, u32 irqs_min, u32 irqs_num)
+int hinic5_ubus_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num)
{
hinic_ub_dev *udev = HINIC_TO_UB_DEV(adev->dev);
@@ -604,9 +627,9 @@ static ub_ers_result_t hinic5_ubus_error_detected(hinic_ub_dev *ubus_dev,
static const struct ub_error_handlers hinic5_ubus_err_handler = {
#ifdef UB_SUPPORT_B177
- .ub_error_detected = hinic5_ubus_error_detected,
+ .ub_error_detected = hinic5_ubus_error_detected,
#else
- .error_detected = hinic5_ubus_error_detected,
+ .error_detected = hinic5_ubus_error_detected,
#endif
};
@@ -624,7 +647,8 @@ static int hinic5_ubus_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(hinic5_ubus_pm_ops, hinic5_ubus_suspend, hinic5_ubus_resume);
+static SIMPLE_DEV_PM_OPS(hinic5_ubus_pm_ops, hinic5_ubus_suspend,
+ hinic5_ubus_resume);
static struct ub_driver hinic5_ubus_driver = {
.name = HINIC5_DRV_NAME,
@@ -674,7 +698,9 @@ void hinic5_ubus_numvds_store_vds_process(struct hinic5_adev *adev, int nums)
*/
ret = hinic5_ubus_virt_configure(udev, i, 1);
if (ret != 0)
- sdk_warn(adev->dev, "driver virt_configure return %d\n", ret);
+ sdk_warn(adev->dev,
+ "driver virt_configure return %d\n",
+ ret);
if (--cnt == 0)
return;
}
@@ -694,7 +720,9 @@ void hinic5_ubus_numvds_store_vds_process(struct hinic5_adev *adev, int nums)
*/
ret = hinic5_ubus_virt_configure(udev, i, 1);
if (ret != 0)
- sdk_warn(adev->dev, "driver virt_configure return %d\n", ret);
+ sdk_warn(adev->dev,
+ "driver virt_configure return %d\n",
+ ret);
if (--cnt == 0)
return;
}
@@ -706,7 +734,8 @@ void hinic5_ubus_numvds_store_vds_process(struct hinic5_adev *adev, int nums)
for (; i <= vd_end_idx; i++) {
ret = hinic5_ubus_virt_configure(udev, i, 1);
if (ret != 0)
- sdk_warn(adev->dev, "driver virt_configure return %d\n", ret);
+ sdk_warn(adev->dev, "driver virt_configure return %d\n",
+ ret);
if (--cnt == 0)
return;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.h
index 2a12b9cf5..94b7d33f8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ubus.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_UBUS_H
#define HINIC5_UBUS_H
@@ -27,41 +20,44 @@ enum ubus_device_type {
UBUS_DEVICE_TYPE_INVALID
};
-// TODO: UB B173 and later version interface differences, need to define UB_SUPPORT_ENTITY for 173 and later
+// TODO: UB B173之后的版本接口差异, 173及以后需要define UB_SUPPORT_ENTITY
#ifdef UB_SUPPORT_ENTITY
typedef struct ub_entity hinic_ub_dev;
-#define HINIC_UB_UE_ENABLE(ubus_dev, enable) ub_entity_enable(ubus_dev, enable)
-#define HINIC_UB_UNSET_HOST_INFO(ubus_dev) ub_unset_user_info(ubus_dev)
-#define HINIC_UB_SET_HOST_INFO(ubus_dev) ub_set_user_info(ubus_dev)
-#define HINIC_UB_DISABLE_FUNC(ubus_dev) ub_disable_entities(ubus_dev)
-#define HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx) ub_enable_ue(ubus_dev, ue_idx)
+#define HINIC_UB_UE_ENABLE(ubus_dev, enable) ub_entity_enable(ubus_dev, enable)
+#define HINIC_UB_UNSET_HOST_INFO(ubus_dev) ub_unset_user_info(ubus_dev)
+#define HINIC_UB_SET_HOST_INFO(ubus_dev) ub_set_user_info(ubus_dev)
+#define HINIC_UB_DISABLE_FUNC(ubus_dev) ub_disable_entities(ubus_dev)
+#define HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx) ub_enable_ue(ubus_dev, ue_idx)
#define HINIC_UB_DISABLE_VDEV(ubus_dev, ue_idx) ub_disable_ue(ubus_dev, ue_idx)
-#define HINIC_UB_GET_DEVICE_ID(udev) uent_device(udev)
-#define HINIC_UB_GET_CLASS_CODE(udev) uent_class(udev)
-#define HINIC_TO_UB_DEV(dev) to_ub_entity(dev)
+#define HINIC_UB_GET_DEVICE_ID(udev) uent_device(udev)
+#define HINIC_UB_GET_CLASS_CODE(udev) uent_class(udev)
+#define HINIC_TO_UB_DEV(dev) to_ub_entity(dev)
#else
typedef struct ub_dev hinic_ub_dev;
-#define HINIC_UB_UE_ENABLE(ubus_dev, enable) ub_fe_enable(ubus_dev, enable)
-#define HINIC_UB_UNSET_HOST_INFO(ubus_dev) ub_unset_hostinfo(ubus_dev)
-#define HINIC_UB_SET_HOST_INFO(ubus_dev) ub_set_hostinfo(ubus_dev)
-#define HINIC_UB_DISABLE_FUNC(ubus_dev) ub_disable_funcs(ubus_dev)
-#define HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx) ub_enable_vdev(ubus_dev, ue_idx)
-#define HINIC_UB_DISABLE_VDEV(ubus_dev, ue_idx) ub_disable_vdev(ubus_dev, ue_idx)
-#define HINIC_UB_GET_DEVICE_ID(udev) udev_device(udev)
-#define HINIC_UB_GET_CLASS_CODE(udev) udev_class(udev)
-#define HINIC_TO_UB_DEV(dev) to_ub_dev(dev)
+#define HINIC_UB_UE_ENABLE(ubus_dev, enable) ub_fe_enable(ubus_dev, enable)
+#define HINIC_UB_UNSET_HOST_INFO(ubus_dev) ub_unset_hostinfo(ubus_dev)
+#define HINIC_UB_SET_HOST_INFO(ubus_dev) ub_set_hostinfo(ubus_dev)
+#define HINIC_UB_DISABLE_FUNC(ubus_dev) ub_disable_funcs(ubus_dev)
+#define HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx) ub_enable_vdev(ubus_dev, ue_idx)
+#define HINIC_UB_DISABLE_VDEV(ubus_dev, ue_idx) \
+ ub_disable_vdev(ubus_dev, ue_idx)
+#define HINIC_UB_GET_DEVICE_ID(udev) udev_device(udev)
+#define HINIC_UB_GET_CLASS_CODE(udev) udev_class(udev)
+#define HINIC_TO_UB_DEV(dev) to_ub_dev(dev)
#endif
int hinic5_ubus_register_driver(void);
void hinic5_ubus_unregister_driver(void);
bool hinic5_ubus_is_virtfn(struct hinic5_adev *adev);
struct hinic5_adev *hinic5_ubus_get_pf_adev(struct hinic5_adev *adev);
-int hinic5_ubus_set_func_en(struct hinic5_adev *dst_dev, bool en, u16 vf_func_id);
-struct hinic5_adev *hinic5_ubus_get_vf_adev_by_pf(struct hinic5_adev *adev, u16 func_id);
+int hinic5_ubus_set_func_en(struct hinic5_adev *dst_dev, bool en,
+ u16 vf_func_id);
+struct hinic5_adev *hinic5_ubus_get_vf_adev_by_pf(struct hinic5_adev *adev,
+ u16 func_id);
int hinic5_ubus_get_vf_num(struct hinic5_adev *adev);
u16 hinic5_ubus_get_device_id(struct hinic5_adev *adev);
-int hinic5_ubus_irq_vectors_alloc(struct hinic5_adev *adev,
- void *entry, u32 irqs_min, u32 irqs_num);
+int hinic5_ubus_irq_vectors_alloc(struct hinic5_adev *adev, void *entry,
+ u32 irqs_min, u32 irqs_num);
void hinic5_ubus_irq_vectors_free(struct hinic5_adev *adev);
int hinic5_ubus_irq_vector(struct hinic5_adev *adev, u32 idx);
int hinic5_ub_init_device_info(struct hinic5_adev *adev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.c
index 5844bd75e..3c86054ba 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ubus_sriov.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifdef __UBUS_DRIVER__
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -14,16 +7,16 @@
#include <linux/interrupt.h>
#include "ossl_knl.h"
-#include "hinic5_hwdev.h"
#include "hinic5_crm.h"
#include "hinic5_hw.h"
#include "hinic5_hwdev.h"
+#include "hinic5_ubus.h"
+#include "hinic5_ubus_sriov.h"
+
#ifndef __WIN__
#include "hinic5_lld.h"
#include "hinic5_dev_mgmt.h"
#endif
-#include "hinic5_ubus_sriov.h"
-#include "hinic5_ubus.h"
static int ub_get_totalvds(hinic_ub_dev *udev)
{
@@ -55,122 +48,100 @@ static int ub_num_vdevice(hinic_ub_dev *udev)
#endif
}
-static void hinic5_ubus_event_callback_dev(struct hinic5_sriov_info *sriov_info, void *hwdev, int num_vfs)
+static void sriov_event_callback(void *hwdev, bool en, int num_vfs, int vf_id)
{
- struct hinic5_event_info event = {0};
- sriov_info->sriov_enabled = true;
+ struct hinic5_event_info event = {
+ .service = EVENT_SRV_COMM,
+ .type = EVENT_COMM_SRIOV_STATE_CHANGE,
+ };
+ struct hinic5_sriov_state_info *state = (void *)event.event_data;
- sriov_info->num_vfs = (u32)num_vfs;
+ state->enable = en ? 1 : 0;
+ state->num_vfs = (u16)num_vfs;
+ state->vf_id = (u32)vf_id;
- event.service = EVENT_SRV_COMM;
- event.type = EVENT_COMM_SRIOV_STATE_CHANGE;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable = 1;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs = (u16)num_vfs;
hinic5_event_callback(hwdev, &event);
-
- clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
}
-int hinic5_ubus_init_func_mbox_channel(void *hwdev)
+static int init_vf_hw(struct hinic5_hwdev *hwdev, u16 vf_id)
{
- /* mbox msg channel resources will be freed during remove process */
- return hinic5_init_func_mbox_msg_channel(hwdev,
- hinic5_func_max_vf(hwdev));
-}
-
-int hinic5_ubus_init_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
-{
- u16 i, func_idx;
int err;
- /* vf use 256K as default wq page size, and can't change it */
- for (i = start_vf_id; i <= end_vf_id; i++) {
- func_idx = hinic5_glb_pf_vf_offset(hwdev) + i;
- err = hinic5_set_wq_page_size(hwdev, func_idx,
- HINIC5_DEFAULT_WQ_PAGE_SIZE,
- HINIC5_CHANNEL_COMM);
- if (err != 0)
- return err;
+ /*
+ * This function is reentrant.
+ * mbox msg channel resources will be freed during remove process.
+ */
+ err = hinic5_init_func_mbox_msg_channel(hwdev,
+ hinic5_func_max_vf(hwdev));
+ if (err != 0) {
+ dev_err(hwdev->dev_hdl,
+ "Failed to init mbox msg channel, max vf %u\n",
+ hinic5_func_max_vf(hwdev));
+ return err;
}
- return 0;
+ return hinic5_set_wq_page_size(
+ hwdev, vf_id, HINIC5_DEFAULT_WQ_PAGE_SIZE, HINIC5_CHANNEL_COMM);
}
-int hinic5_ubus_sriov_enable(hinic_ub_dev *ubus_dev, int ue_idx)
+static int virt_configure_enable(hinic_ub_dev *ubus_dev, int ue_idx)
{
- int err, pre_existing_vfs;
struct hinic5_adev *adev = dev_get_drvdata(&ubus_dev->dev);
- void *hwdev = adev->hwdev;
+ struct hinic5_hwdev *hwdev = adev->hwdev;
struct hinic5_sriov_info *sriov_info = &adev->sriov_info;
- u32 tmp_vf_id = ue_idx - sriov_info->first_ue_idx;
-
- if (!hwdev) {
- sdk_err(&ubus_dev->dev, "hwdev is null\n");
- return -EPERM;
- }
+ int err = 0, num_vfs_new;
if (test_and_set_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&ubus_dev->dev,
- "SR-IOV enable in process, please wait, ue_idx %d\n", ue_idx);
- return -EPERM;
- }
-
- pre_existing_vfs = ub_num_vdevice(ubus_dev);
- if ((pre_existing_vfs + 1) > ub_get_totalvds(ubus_dev)) {
- clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
- return -ERANGE;
+ sdk_warn(&ubus_dev->dev,
+ "SR-IOV enable in process, please wait, ue_idx %d\n",
+ ue_idx);
+ return -EBUSY;
}
- /* If not first enable, do not reinitialize FUNC MAILBOX channel */
- if (!sriov_info->sriov_enabled) {
- err = hinic5_ubus_init_func_mbox_channel(hwdev);
- sriov_info->first_ue_idx = ue_idx;
- if (err != 0) {
- clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
- return err;
- }
+ num_vfs_new = ub_num_vdevice(ubus_dev) + 1;
+ if (WARN_ON_ONCE(num_vfs_new > ub_get_totalvds(ubus_dev))) {
+ err = -ERANGE;
+ goto out;
}
- err = hinic5_ubus_init_vf_hw(hwdev, tmp_vf_id, tmp_vf_id);
- if (err != 0) {
+ if ((err = init_vf_hw(hwdev, ue_idx)) != 0) {
sdk_err(&ubus_dev->dev,
- "Failed to init vf in hardware before enable sriov, error %d\n", err);
- clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
- return err;
+ "Failed to init vf in hardware before enable sriov, error %d\n",
+ err);
+ goto out;
}
- err = HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx);
- if (err != 0) {
- sdk_err(&ubus_dev->dev, "Failed to enable SR-IOV, error %d\n", err);
- clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
- return err;
+ if ((err = HINIC_UB_ENABLE_VDEV(ubus_dev, ue_idx)) != 0) {
+ sdk_err(&ubus_dev->dev, "Failed to enable SR-IOV, error %d\n",
+ err);
+ goto out;
}
- hinic5_ubus_event_callback_dev(sriov_info, hwdev, (pre_existing_vfs + 1));
- return 0;
+ sriov_info->sriov_enabled = true;
+ sriov_info->num_vfs = num_vfs_new;
+
+ sriov_event_callback(hwdev, true, num_vfs_new, ue_idx);
+
+out:
+ clear_bit(HINIC5_SRIOV_ENABLE, &sriov_info->state);
+ return err;
}
-int hinic5_ubus_sriov_disable(hinic_ub_dev *ubus_dev, int ue_idx)
+static int virt_configure_disable(hinic_ub_dev *ubus_dev, int ue_idx)
{
struct hinic5_adev *adev = dev_get_drvdata(&ubus_dev->dev);
+ struct hinic5_hwdev *hwdev = adev->hwdev;
struct hinic5_sriov_info *sriov_info = &adev->sriov_info;
- struct hinic5_event_info event = {0};
- void *hwdev = adev->hwdev;
- u32 tmp_vf_id = ue_idx - sriov_info->first_ue_idx;
- int err, pre_existing_vfs;
-
- if (!hwdev) {
- sdk_err(&ubus_dev->dev, "SR-IOV disable is not permitted, please wait...\n");
- return -EPERM;
- }
+ int err = 0, num_vfs_new;
/* if SR-IOV is already disabled then there is nothing to do */
- if (!sriov_info->sriov_enabled)
+ if (WARN_ON_ONCE(!sriov_info->sriov_enabled))
return 0;
if (test_and_set_bit(HINIC5_SRIOV_DISABLE, &sriov_info->state)) {
- sdk_err(&ubus_dev->dev, "SR-IOV disable in process, please wait");
- return -EPERM;
+ sdk_err(&ubus_dev->dev,
+ "SR-IOV disable in process, please wait");
+ return -EBUSY;
}
/* If our VFs are assigned we cannot shut down SR-IOV
@@ -179,64 +150,60 @@ int hinic5_ubus_sriov_disable(hinic_ub_dev *ubus_dev, int ue_idx)
*/
// todo, VFs in VM,cannot disable directly
- pre_existing_vfs = ub_num_vdevice(ubus_dev);
- event.service = EVENT_SRV_COMM;
- event.type = EVENT_COMM_SRIOV_STATE_CHANGE;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->enable = 0;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->vf_id = tmp_vf_id;
- ((struct hinic5_sriov_state_info *)(void *)event.event_data)->num_vfs =
- (u16)(pre_existing_vfs - 1);
- hinic5_event_callback(hwdev, &event);
+ num_vfs_new = ub_num_vdevice(ubus_dev) - 1;
+
+ sriov_event_callback(hwdev, false, num_vfs_new, ue_idx);
/* disable iov and allow time for transactions to clear */
- err = HINIC_UB_DISABLE_VDEV(ubus_dev, ue_idx);
- if (err != 0) {
- sdk_err(&ubus_dev->dev, "Failed to disable SR-IOV, error %d\n", err);
- clear_bit(HINIC5_SRIOV_DISABLE, &sriov_info->state);
- return err;
+ if ((err = HINIC_UB_DISABLE_VDEV(ubus_dev, ue_idx)) != 0) {
+ sdk_err(&ubus_dev->dev, "Failed to disable SR-IOV, error %d\n",
+ err);
+ goto out;
}
- sriov_info->num_vfs = pre_existing_vfs - 1;
+ sriov_info->num_vfs = num_vfs_new;
+ if (num_vfs_new == 0)
+ sriov_info->sriov_enabled = false;
- if (sriov_info->num_vfs == 0)
- sriov_info->sriov_enabled = 0;
+out:
clear_bit(HINIC5_SRIOV_DISABLE, &sriov_info->state);
- return 0;
+ return err;
}
-/*
- UBUS sriov implementation differs from PCIE, UBUS supports dynamic vf number modification
- 1) pcie needs echo 2 --> echo 0 --> echo 3, ubus does not,
- ub_dev maintains vdevice list with start_vf_idx and end_vf_idx
- 2) pcie echo only calls driver interface once per echo,
- decides how many vfs to enable based on vf_num parameter;
- ubus echo calls driver interface multiple times based on vf_num
+/**
+ * ubus sriov 实现与 pcie 有区别:
+ * 1) ubus 支持动态修改 VF 个数
+ * pcie 需要 echo 2 --> echo 0 --> echo 3,UBUS 不需要
+ * 2)ubus virt_configure() 可能会多次调用
+ * 使能多个 vf 时,pcie 回调只会调用一次
+ *
+ * @note Ubus ensures that only primary entity can access this
*/
int hinic5_ubus_virt_configure(hinic_ub_dev *ubus_dev, int ue_idx, bool is_en)
{
- struct hinic5_sriov_info *sriov_info = NULL;
struct hinic5_adev *adev = dev_get_drvdata(&ubus_dev->dev);
+ struct hinic5_sriov_info *sriov_info = NULL;
+ int err;
- if (!adev)
- return -EFAULT;
+ if (unlikely(!adev || !adev->hwdev))
+ return -EPERM;
sriov_info = &adev->sriov_info;
+ if (!test_bit(HINIC5_FUNC_PRESENT, &sriov_info->state))
+ return -EAGAIN;
- if (!sriov_info)
- return -EFAULT;
-
- if (!test_bit(HINIC5_FUNC_PERSENT, &sriov_info->state))
- return -EFAULT;
+ dev_info(&ubus_dev->dev, "virt configure, idx %d, en %d.\n", ue_idx,
+ is_en);
- /* The ubus framework have ensure that only primary entity can come
- * here, so we not need to check is this a primary entity again.
- */
- dev_info(&ubus_dev->dev, "ubase virt configure set idx = %d en = %d.\n",
- ue_idx, is_en);
-
- if (!is_en)
- return hinic5_ubus_sriov_disable(ubus_dev, ue_idx);
+ if (is_en)
+ err = virt_configure_enable(ubus_dev, ue_idx);
else
- return hinic5_ubus_sriov_enable(ubus_dev, ue_idx);
+ err = virt_configure_disable(ubus_dev, ue_idx);
+
+ if (err != 0)
+ dev_err(&ubus_dev->dev,
+ "virt configure failed, idx %d, en %d, err %d.\n",
+ ue_idx, is_en, err);
+ return err;
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.h
index fbc4e4bb1..37952632b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/lld/hinic5_ubus_sriov.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ubus_sriov.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_SRIOV_H
#define HINIC5_SRIOV_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.c
index 2e9a4dcc0..c79572273 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_devlink.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -16,6 +9,7 @@
#include "hinic5_devlink.h"
#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#include "mpu_inband_cmd.h"
+#include "hisdk5_typedef.h"
#include "hinic5_common.h"
#include "hinic5_api_cmd.h"
#include "hinic5_mgmt.h"
@@ -24,6 +18,7 @@
#include "fw_typedef.h"
#ifdef HAVE_DEVLINK_FLASH_UPDATE_METHOD
+
static bool check_image_valid(struct hinic5_hwdev *hwdev, const u8 *buf,
u32 size, struct host_image *host_image)
{
@@ -33,37 +28,54 @@ static bool check_image_valid(struct hinic5_hwdev *hwdev, const u8 *buf,
fw_image = (struct firmware_image *)buf;
if (fw_image->fw_magic != FW_MAGIC_NUM) {
- sdk_err(hwdev->dev_hdl, "Wrong fw magic read from file, fw_magic: 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "Wrong fw magic read from file, fw_magic: 0x%x\n",
fw_image->fw_magic);
return false;
}
if (fw_image->fw_info.section_cnt > FW_TYPE_MAX_NUM) {
- sdk_err(hwdev->dev_hdl, "Wrong fw type number read from file, fw_type_num: 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "Wrong fw type number read from file, fw_type_num: 0x%x\n",
fw_image->fw_info.section_cnt);
return false;
}
+ if (size < FW_IMAGE_HEAD_SIZE) {
+ sdk_err(hwdev->dev_hdl,
+ "Wrong fw size read from file, size: 0x%x\n", size);
+ return false;
+ }
+
for (i = 0, n = 0; i < fw_image->fw_info.section_cnt; i++) {
- if (fw_image->section_info[i].section_type == UP_FW_UPDATE_L0FW) {
+ if (fw_image->section_info[i].section_type ==
+ UP_FW_UPDATE_L0FW) {
len += fw_image->section_info[i].section_len;
- memcpy(&host_image->section_info[n++], &fw_image->section_info[i],
- sizeof(struct firmware_section));
+ (void)memcpy_s(&host_image->section_info[n++],
+ sizeof(struct firmware_section),
+ &fw_image->section_info[i],
+ sizeof(struct firmware_section));
break;
}
}
for (i = 0; i < fw_image->fw_info.section_cnt; i++) {
- if (fw_image->section_info[i].section_type == UP_FW_UPDATE_L0FW)
+ if (fw_image->section_info[i].section_type ==
+ UP_FW_UPDATE_L0FW) {
continue;
+ }
len += fw_image->section_info[i].section_len;
- memcpy(&host_image->section_info[n++], &fw_image->section_info[i],
- sizeof(struct firmware_section));
+ (void)memcpy_s(&host_image->section_info[n++],
+ sizeof(struct firmware_section),
+ &fw_image->section_info[i],
+ sizeof(struct firmware_section));
}
if (len != fw_image->fw_len ||
(u32)(fw_image->fw_len + FW_IMAGE_HEAD_SIZE) != size) {
- sdk_err(hwdev->dev_hdl, "Wrong data size read from file\n");
+ sdk_err(hwdev->dev_hdl,
+ "Wrong data size read from file, len: 0x%x, fw_len: 0x%x\n",
+ len, fw_image->fw_len);
return false;
}
@@ -79,12 +91,13 @@ static bool check_image_device_type(struct hinic5_hwdev *hwdev, u32 device_type)
{
struct comm_cmd_board_info board_info;
- /* Cold upgrade takes firmware type as default value 0 */
+ /* 冷升级取固件type为默认值0 */
if (device_type == FW_DEFAULT_TYPE_COLD_UPDATE)
return true;
- memset(&board_info, 0, sizeof(board_info));
- if (hinic5_get_board_info(hwdev, &board_info.info, HINIC5_CHANNEL_COMM) != 0) {
+ (void)memset_s(&board_info, sizeof(board_info), 0, sizeof(board_info));
+ if (hinic5_get_board_info(hwdev, &board_info.info,
+ HINIC5_CHANNEL_COMM) != 0) {
sdk_err(hwdev->dev_hdl, "Failed to get board info\n");
return false;
}
@@ -92,7 +105,8 @@ static bool check_image_device_type(struct hinic5_hwdev *hwdev, u32 device_type)
if (device_type == board_info.info.board_type)
return true;
- sdk_err(hwdev->dev_hdl, "The image device type: 0x%x doesn't match the firmware device type: 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "The image device type: 0x%x doesn't match the firmware device type: 0x%x\n",
device_type, board_info.info.board_type);
return false;
@@ -100,10 +114,12 @@ static bool check_image_device_type(struct hinic5_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic5_cmd_update_firmware *msg,
struct firmware_section *section_info,
- const int *remain_len, u32 *send_len, const u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ const u32 *send_pos)
{
- memset(msg->data, 0, sizeof(msg->data));
- msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
+ (void)memset_s(msg->data, sizeof(msg->data), 0, sizeof(msg->data));
+ msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true :
+ false;
msg->section_info.section_crc = section_info->section_crc;
msg->section_info.section_type = section_info->section_type;
msg->section_version = section_info->section_version;
@@ -132,10 +148,12 @@ static int hinic5_flash_firmware(struct hinic5_hwdev *hwdev, const u8 *data,
int remain_len, err;
update_msg = kzalloc(sizeof(*update_msg), GFP_KERNEL);
- if (!update_msg)
+ if (!update_msg) {
+ sdk_err(hwdev->dev_hdl, "Failed to alloc update message\n");
return -ENOMEM;
+ }
- for (i = 0; i < image->type_num; i++) {
+ for (i = 0; i < image->type_num; i++) {
section_offset = image->section_info[i].section_offset;
remain_len = (int)(image->section_info[i].section_len);
send_len = 0;
@@ -143,36 +161,48 @@ static int hinic5_flash_firmware(struct hinic5_hwdev *hwdev, const u8 *data,
while (remain_len > 0) {
if (!total_flag) {
- update_msg->total_len = image->image_info.total_len;
+ update_msg->total_len =
+ image->image_info.total_len;
total_flag = true;
} else {
update_msg->total_len = 0;
}
- encapsulate_update_cmd(update_msg, &image->section_info[i],
- &remain_len, &send_len, &send_pos);
-
- memcpy(update_msg->data,
- ((data + FW_IMAGE_HEAD_SIZE) + section_offset) + send_pos,
- update_msg->ctl_info.fragment_len);
-
- err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
- COMM_MGMT_CMD_UPDATE_FW,
- update_msg, sizeof(*update_msg),
- update_msg, &out_size,
- FW_UPDATE_MGMT_TIMEOUT, 0);
- if (err != 0 || out_size == 0 || update_msg->msg_head.status != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to update firmware, err: %d, \
- status: 0x%x, out size: 0x%x\n",
- err, update_msg->msg_head.status, out_size);
+ encapsulate_update_cmd(update_msg,
+ &image->section_info[i],
+ &remain_len, &send_len,
+ &send_pos);
+
+ err = memcpy_s(
+ update_msg->data, sizeof(update_msg->data),
+ ((data + FW_IMAGE_HEAD_SIZE) + section_offset) +
+ send_pos,
+ update_msg->ctl_info.fragment_len);
+ if (err != 0) {
+ kfree(update_msg);
+ return -ENOMEM;
+ }
+
+ err = hinic5_msg_to_mgmt_sync(
+ hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_UPDATE_FW,
+ update_msg, sizeof(*update_msg), update_msg,
+ &out_size, FW_UPDATE_MGMT_TIMEOUT, 0);
+ if ((err != 0) || (out_size == 0) ||
+ (update_msg->msg_head.status != 0)) {
+ sdk_err(hwdev->dev_hdl,
+ "Failed to update firmware, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, update_msg->msg_head.status,
+ out_size);
err = (update_msg->msg_head.status != 0) ?
- update_msg->msg_head.status : -EIO;
+ update_msg->msg_head.status :
+ -EIO;
kfree(update_msg);
return err;
}
send_pos = send_len;
- remain_len = (int)(image->section_info[i].section_len - send_len);
+ remain_len = (int)(image->section_info[i].section_len -
+ send_len);
}
}
@@ -181,8 +211,10 @@ static int hinic5_flash_firmware(struct hinic5_hwdev *hwdev, const u8 *data,
return 0;
}
-static int hinic5_flash_update_notify(struct devlink *devlink, const struct firmware *fw,
- struct host_image *image, struct netlink_ext_ack *extack)
+static int hinic5_flash_update_notify(struct devlink *devlink,
+ const struct firmware *fw,
+ struct host_image *image,
+ struct netlink_ext_ack *extack)
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
struct hinic5_hwdev *hwdev = devlink_dev->hwdev;
@@ -191,23 +223,28 @@ static int hinic5_flash_update_notify(struct devlink *devlink, const struct firm
#ifdef HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY
devlink_flash_update_begin_notify(devlink);
#endif
- devlink_flash_update_status_notify(devlink, "Flash firmware begin", NULL, 0, 0);
+ devlink_flash_update_status_notify(devlink, "Flash firmware begin",
+ NULL, 0, 0);
sdk_info(hwdev->dev_hdl, "Flash firmware begin\n");
err = hinic5_flash_firmware(hwdev, fw->data, image);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to flash firmware, err: %d\n", err);
+ sdk_err(hwdev->dev_hdl, "Failed to flash firmware, err: %d\n",
+ err);
NL_SET_ERR_MSG_MOD(extack, "Flash firmware failed");
- devlink_flash_update_status_notify(devlink, "Flash firmware failed", NULL, 0, 0);
+ devlink_flash_update_status_notify(
+ devlink, "Flash firmware failed", NULL, 0, 0);
} else {
err = hinic5_activate_firmware(hwdev, 0);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, " Failed to activate firmware, err: %d\n", err);
- devlink_flash_update_status_notify(devlink,
- "Activate firmware failed", NULL, 0, 0);
+ sdk_err(hwdev->dev_hdl,
+ " Faild to activate firmware, err: %d\n", err);
+ devlink_flash_update_status_notify(
+ devlink, "Activate firmware failed", NULL, 0,
+ 0);
} else {
sdk_info(hwdev->dev_hdl, "Flash firmware end\n");
- devlink_flash_update_status_notify(devlink,
- "Flash firmware end", NULL, 0, 0);
+ devlink_flash_update_status_notify(
+ devlink, "Flash firmware end", NULL, 0, 0);
}
}
#ifdef HAVE_DEVLINK_FLASH_UPDATE_BEGIN_END_NOTIFY
@@ -218,24 +255,26 @@ static int hinic5_flash_update_notify(struct devlink *devlink, const struct firm
}
#ifdef HAVE_DEVLINK_OPS_FLASH_UPDATE_HAVE_PARAMS
+static int
+hinic5_devlink_flash_update(struct devlink *devlink,
+ struct devlink_flash_update_params *params,
+ struct netlink_ext_ack *extack)
+#else
static int hinic5_devlink_flash_update(struct devlink *devlink,
- struct devlink_flash_update_params *params,
+ const char *file_name,
+ const char *component,
struct netlink_ext_ack *extack)
-#else
-static int hinic5_devlink_flash_update(struct devlink *devlink, const char *file_name,
- const char *component, struct netlink_ext_ack *extack)
#endif
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
struct hinic5_hwdev *hwdev = devlink_dev->hwdev;
#ifndef HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FW
- const struct firmware *fw = NULL; // fw and file_name are mutually exclusive
+ const struct firmware *fw = NULL; // fw和file_name是互斥的
#else
const struct firmware *fw = params->fw;
#endif
struct host_image *image = NULL;
int err;
-
image = kzalloc(sizeof(*image), GFP_KERNEL);
if (!image) {
sdk_err(hwdev->dev_hdl, "Failed to alloc host image\n");
@@ -248,7 +287,7 @@ static int hinic5_devlink_flash_update(struct devlink *devlink, const char *file
#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS_FILE_NAME
err = request_firmware_direct(&fw, params->file_name, hwdev->dev_hdl);
#else
- // This scenario theoretically does not exist
+ // 理论上不存在该场景
kfree(image);
err = -EINVAL;
goto devlink_param_reset;
@@ -294,7 +333,7 @@ static int hinic5_devlink_info_get(struct devlink *dl,
{
struct hinic5_devlink *devlink_dev = devlink_priv(dl);
struct hinic5_hwdev *hwdev = devlink_dev->hwdev;
- u8 mgmt_ver[HINIC5_MGMT_VERSION_MAX_LEN] = {0};
+ u8 mgmt_ver[HINIC5_MGMT_VERSION_MAX_LEN] = { 0 };
int err;
#ifdef HAVE_DEVLINK_INFO_DRIVER_NAME_PUT
@@ -305,20 +344,23 @@ static int hinic5_devlink_info_get(struct devlink *dl,
};
#endif
- /* Firmware version */
- err = hinic5_get_mgmt_version(hwdev, mgmt_ver, sizeof(mgmt_ver), HINIC5_CHANNEL_COMM);
+ /* 固件版本 */
+ err = hinic5_get_mgmt_version(hwdev, mgmt_ver, sizeof(mgmt_ver),
+ HINIC5_CHANNEL_COMM);
if (err != 0) {
sdk_info(hwdev->dev_hdl, "Failed to get firmware versions\n");
return err;
}
- err = devlink_info_version_stored_put(req, "fw.version", (char *)&mgmt_ver[0]);
+ err = devlink_info_version_stored_put(req, "fw.version",
+ (char *)&mgmt_ver[0]);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to set stored fw version\n");
return err;
}
- err = devlink_info_version_running_put(req, "fw.version", (char *)&mgmt_ver[0]);
+ err = devlink_info_version_running_put(req, "fw.version",
+ (char *)&mgmt_ver[0]);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to set running fw version\n");
return err;
@@ -335,8 +377,9 @@ static const struct devlink_ops hinic5_devlink_ops = {
.info_get = hinic5_devlink_info_get,
};
-static int hinic5_devlink_get_activate_firmware_config(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx)
+STATIC int
+hinic5_devlink_get_activate_firmware_config(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
@@ -346,12 +389,14 @@ static int hinic5_devlink_get_activate_firmware_config(struct devlink *devlink,
}
#ifdef HAVE_DEVLINK_PARAM_SET_EXTACK
-static int hinic5_devlink_set_activate_firmware_config(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx,
- struct netlink_ext_ack *extack)
+STATIC int
+hinic5_devlink_set_activate_firmware_config(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx,
+ struct netlink_ext_ack *extack)
#else
-static int hinic5_devlink_set_activate_firmware_config(struct devlink *devlink, u32 id,
- struct devlink_param_gset_ctx *ctx)
+STATIC int
+hinic5_devlink_set_activate_firmware_config(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
#endif
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
@@ -363,7 +408,8 @@ static int hinic5_devlink_set_activate_firmware_config(struct devlink *devlink,
err = hinic5_activate_firmware(hwdev, devlink_dev->activate_fw);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Failed to activate firmware, err: %d\n", err);
+ sdk_err(hwdev->dev_hdl,
+ "Failed to activate firmware, err: %d\n", err);
return err;
}
@@ -372,7 +418,7 @@ static int hinic5_devlink_set_activate_firmware_config(struct devlink *devlink,
return 0;
}
-static int hinic5_devlink_get_switch_config(struct devlink *devlink, u32 id,
+STATIC int hinic5_devlink_get_switch_config(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
@@ -383,11 +429,11 @@ static int hinic5_devlink_get_switch_config(struct devlink *devlink, u32 id,
}
#ifdef HAVE_DEVLINK_PARAM_SET_EXTACK
-static int hinic5_devlink_set_switch_config(struct devlink *devlink, u32 id,
+STATIC int hinic5_devlink_set_switch_config(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx,
- struct netlink_ext_ack *extack)
+ struct netlink_ext_ack *extack)
#else
-static int hinic5_devlink_set_switch_config(struct devlink *devlink, u32 id,
+STATIC int hinic5_devlink_set_switch_config(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
#endif
{
@@ -409,17 +455,20 @@ static int hinic5_devlink_set_switch_config(struct devlink *devlink, u32 id,
return 0;
}
-static int hinic5_devlink_firmware_config_validate(struct devlink *devlink, u32 id,
- union devlink_param_value val,
- struct netlink_ext_ack *extack)
+STATIC int
+hinic5_devlink_firmware_config_validate(struct devlink *devlink, u32 id,
+ union devlink_param_value val,
+ struct netlink_ext_ack *extack)
{
struct hinic5_devlink *devlink_dev = devlink_priv(devlink);
struct hinic5_hwdev *hwdev = devlink_dev->hwdev;
u8 cfg_index = val.vu8;
if (cfg_index > FW_CFG_MAX_INDEX) {
- sdk_err(hwdev->dev_hdl, "Firmware cfg index out of range [0,7]\n");
- NL_SET_ERR_MSG_MOD(extack, "Firmware cfg index out of range [0,7]");
+ sdk_err(hwdev->dev_hdl,
+ "Firmware cfg index out of range [0,7]\n");
+ NL_SET_ERR_MSG_MOD(extack,
+ "Firmware cfg index out of range [0,7]");
return -ERANGE;
}
@@ -427,14 +476,14 @@ static int hinic5_devlink_firmware_config_validate(struct devlink *devlink, u32
}
static const struct devlink_param hinic5_devlink_params[] = {
- DEVLINK_PARAM_DRIVER(HINIC5_DEVLINK_PARAM_ID_ACTIVATE_FW,
- "activate_fw", DEVLINK_PARAM_TYPE_U8,
+ DEVLINK_PARAM_DRIVER(HINIC5_DEVLINK_PARAM_ID_ACTIVATE_FW, "activate_fw",
+ DEVLINK_PARAM_TYPE_U8,
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
hinic5_devlink_get_activate_firmware_config,
hinic5_devlink_set_activate_firmware_config,
hinic5_devlink_firmware_config_validate),
- DEVLINK_PARAM_DRIVER(HINIC5_DEVLINK_PARAM_ID_SWITCH_CFG,
- "switch_cfg", DEVLINK_PARAM_TYPE_U8,
+ DEVLINK_PARAM_DRIVER(HINIC5_DEVLINK_PARAM_ID_SWITCH_CFG, "switch_cfg",
+ DEVLINK_PARAM_TYPE_U8,
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
hinic5_devlink_get_switch_config,
hinic5_devlink_set_switch_config,
@@ -481,6 +530,7 @@ int hinic5_init_devlink(struct hinic5_hwdev *hwdev)
register_devlink_err:
devlink_free(devlink);
+ hwdev->devlink_dev = NULL;
return -EFAULT;
}
@@ -494,5 +544,6 @@ void hinic5_uninit_devlink(struct hinic5_hwdev *hwdev)
ARRAY_SIZE(hinic5_devlink_params));
devlink_unregister(devlink);
devlink_free(devlink);
+ hwdev->devlink_dev = NULL;
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.h
index 0ffdbd52e..e89ba2360 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_devlink.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_devlink.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_DEVLINK_H
#define HINIC5_DEVLINK_H
@@ -14,12 +7,12 @@
#include "ossl_knl.h"
#include "hinic5_hwdev.h"
-#define FW_MAGIC_NUM 0x5a5a1100
-#define FW_IMAGE_HEAD_SIZE 4096
-#define FW_FRAGMENT_MAX_LEN 1536
-#define FW_CFG_DEFAULT_INDEX 0xFF
-#define FW_TYPE_MAX_NUM 0x40
-#define FW_CFG_MAX_INDEX 7
+#define FW_MAGIC_NUM 0x5a5a1100
+#define FW_IMAGE_HEAD_SIZE 4096
+#define FW_FRAGMENT_MAX_LEN 1536
+#define FW_CFG_DEFAULT_INDEX 0xFF
+#define FW_TYPE_MAX_NUM 0x40
+#define FW_CFG_MAX_INDEX 7
#define FW_DEFAULT_TYPE_COLD_UPDATE 0
#ifdef HAVE_DEVLINK_FLASH_UPDATE_PARAMS
@@ -30,26 +23,22 @@ enum hinic5_devlink_param_id {
};
#endif
-#define IMAGE_MPU_ALL_IN (BIT_ULL(UP_FW_UPDATE_UP_TEXT) | \
- BIT_ULL(UP_FW_UPDATE_UP_DATA) | \
- BIT_ULL(UP_FW_UPDATE_UP_DICT))
-// BIT_ULL(UP_FW_UPDATE_MPU_CNT_DICT)),
-// cnt index file integrity check needs consideration, temporarily not added for compatibility
+#define IMAGE_MPU_ALL_IN \
+ (BIT_ULL(UP_FW_UPDATE_UP_TEXT) | BIT_ULL(UP_FW_UPDATE_UP_DATA) | \
+ BIT_ULL(UP_FW_UPDATE_UP_DICT))
+// BIT_ULL(UP_FW_UPDATE_MPU_CNT_DICT)) ,需要考虑cnt index文件的完整校验,兼容性考虑,暂时不加
-#define IMAGE_NPU_ALL_IN (BIT_ULL(UP_FW_UPDATE_TILE_PCPTR) | \
- BIT_ULL(UP_FW_UPDATE_TILE_TEXT) | \
- BIT_ULL(UP_FW_UPDATE_TILE_DATA) | \
- BIT_ULL(UP_FW_UPDATE_TILE_DICT) | \
- BIT_ULL(UP_FW_UPDATE_PPE_STATE) | \
- BIT_ULL(UP_FW_UPDATE_PPE_BRANCH) | \
- BIT_ULL(UP_FW_UPDATE_PPE_EXTACT))
-// BIT_ULL(UP_FW_UPDATE_NPU_CNT_DICT)),
-// cnt index file integrity check needs consideration, temporarily not added for compatibility
+#define IMAGE_NPU_ALL_IN \
+ (BIT_ULL(UP_FW_UPDATE_TILE_PCPTR) | BIT_ULL(UP_FW_UPDATE_TILE_TEXT) | \
+ BIT_ULL(UP_FW_UPDATE_TILE_DATA) | BIT_ULL(UP_FW_UPDATE_TILE_DICT) | \
+ BIT_ULL(UP_FW_UPDATE_PPE_STATE) | BIT_ULL(UP_FW_UPDATE_PPE_BRANCH) | \
+ BIT_ULL(UP_FW_UPDATE_PPE_EXTACT))
+// BIT_ULL(UP_FW_UPDATE_NPU_CNT_DICT) ,需要考虑cnt index文件的完整校验,兼容性考虑,暂时不加
#define IMAGE_COLD_SUB_MODULES_MUST_IN (IMAGE_MPU_ALL_IN | IMAGE_NPU_ALL_IN)
-#define IMAGE_CFG_SUB_MODULES_MUST_IN (BIT_ULL(UP_FW_UPDATE_CFG0) | \
- BIT_ULL(UP_FW_UPDATE_CFG1))
+#define IMAGE_CFG_SUB_MODULES_MUST_IN \
+ (BIT_ULL(UP_FW_UPDATE_CFG0) | BIT_ULL(UP_FW_UPDATE_CFG1))
struct firmware_section {
u32 section_len;
@@ -69,10 +58,10 @@ struct firmware_image {
u32 rsvd : 16;
} fw_info;
struct firmware_section section_info[FW_TYPE_MAX_NUM];
- u32 device_id; /* cfg fw board_type value */
- u32 rsvd0[101]; /* device_id and rsvd0[101] is update_head_extend_info */
- u32 rsvd1[534]; /* big bin file total size 4096B */
- u32 bin_data; /* obtain the address for use */
+ u32 device_id; /* cfg fw board_type value */
+ u32 rsvd0[101]; /* device_id and rsvd0[101] is update_head_extend_info */
+ u32 rsvd1[534]; /* big bin file total size 4096B */
+ u32 bin_data; /* obtain the address for use */
};
struct host_image {
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.c
index 0540cda55..effbc76d3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fw_update.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
#include <asm/byteorder.h>
#include "ossl_knl.h"
@@ -19,21 +12,21 @@
#include "mpu_inband_cmd.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic5_hw_mt.h"
-#include "hinic5_typedef_inner.h"
+#include "hisdk5_typedef.h"
#include "hinic5_fw_update.h"
-/* Reference for below defines: hwsdk/hinic5_cqm/hinic5_cqm_bat_cla.h */
-#define SM_BAT_NO_BYPASS_CACHE 0
-#define SM_BAT_ENTRY_SIZE_256 0
-#define SM_CLA_LVL_0 0
-#define SM_CHIP_GPA_HIMASK 0x1ffffff
-#define SM_CHIP_GPA_LOMASK 0xffffffff
-#define SM_MAX_INDEX_BIT 19
+/* Reference for below defines: hwsdk/cqm/cqm_bat_cla.h */
+#define SM_BAT_NO_BYPASS_CACHE 0
+#define SM_BAT_ENTRY_SIZE_256 0
+#define SM_CLA_LVL_0 0
+#define SM_CHIP_GPA_HIMASK 0x1ffffff
+#define SM_CHIP_GPA_LOMASK 0xffffffff
+#define SM_MAX_INDEX_BIT 19
-#define SM_CHIP_GPA_HI(gpa) ((u32)(((u64)((gpa)) >> 32) & SM_CHIP_GPA_HIMASK))
-#define SM_CHIP_GPA_LW(gpa) ((u32)((u64)(gpa) & SM_CHIP_GPA_LOMASK))
+#define SM_CHIP_GPA_HI(gpa) ((u32)(((u64)((gpa)) >> 32) & SM_CHIP_GPA_HIMASK))
+#define SM_CHIP_GPA_LW(gpa) ((u32)((u64)(gpa)&SM_CHIP_GPA_LOMASK))
-/* Reference: hwsdk/hinic5_cqm/hinic5_cqm_bat_cla.h#tag_hinic5_cqm_bat_entry_standerd */
+/* Reference: hwsdk/cqm/cqm_bat_cla.h#tag_cqm_bat_entry_standerd */
struct sm_bat_entry_standerd {
u32 entry_size : 2;
u32 rsv1 : 6;
@@ -55,14 +48,15 @@ struct sm_bat_entry_standerd {
};
/* Reference: pfm_load_api.h */
-#define FW_SEC_TYPE_TILE_TEXT 0x4
-#define FW_SEC_TYPE_PHY 0x18
+#define FW_SEC_TYPE_TILE_TEXT 0x4
+#define FW_SEC_TYPE_PHY 0x18
-#define BAT_L3I_MEM_SIZE (2U * 1024 * 1024)
+#define BAT_L3I_MEM_SIZE (2U * 1024 * 1024)
-#define FW_SEC_HDR_SIZE 0x2100
-#define FW_SEC_SIZE_TILE_TEXT (1U * 1024 * 1024) /* FW .text section max size: 1MB */
-#define FW_SEC_SIZE_PHY (512U * 1024) /* FW .phy section max size: 512KB */
+#define FW_SEC_HDR_SIZE 0x2100
+#define FW_SEC_SIZE_TILE_TEXT \
+ (1U * 1024 * 1024) /* FW .text section max size: 1MB */
+#define FW_SEC_SIZE_PHY (512U * 1024) /* FW .phy section max size: 512KB */
static int bat_l3i_get_entry_offset(struct tag_fw_update_handle *handle,
u32 *l3i_entry_offset)
@@ -73,14 +67,17 @@ static int bat_l3i_get_entry_offset(struct tag_fw_update_handle *handle,
ret = hinic5_bat_get_l3i_entry_config(hwdev, &l3i_config);
if (unlikely(ret != 0)) {
- sdk_err(hwdev->dev_hdl, "hinic5_bat_get_l3i_entry_config fail.\n");
+ sdk_err(hwdev->dev_hdl,
+ "hinic5_bat_get_l3i_entry_config fail.\n");
return ret;
}
if (unlikely(!l3i_config.mapping)) {
- sdk_err(hwdev->dev_hdl, "l3i should not mapping in current function.\n");
+ sdk_err(hwdev->dev_hdl,
+ "l3i should not mapping in current function.\n");
return -EINVAL;
}
- if (unlikely(l3i_config.bat_entry_size != sizeof(struct sm_bat_entry_standerd))) {
+ if (unlikely(l3i_config.bat_entry_size !=
+ sizeof(struct sm_bat_entry_standerd))) {
sdk_err(hwdev->dev_hdl, "l3i entry size mismatch.\n");
return -EINVAL;
}
@@ -89,16 +86,18 @@ static int bat_l3i_get_entry_offset(struct tag_fw_update_handle *handle,
return 0;
}
-static void bat_l3i_fill_bat_entry_data(struct sm_bat_entry_standerd *data,
- const struct tag_fw_update_bat_l3i_entry *entry,
- const struct tag_fw_update_handle *handle)
+static void
+bat_l3i_fill_bat_entry_data(struct sm_bat_entry_standerd *data,
+ const struct tag_fw_update_bat_l3i_entry *entry,
+ const struct tag_fw_update_handle *handle)
{
u8 z = SM_MAX_INDEX_BIT;
data->entry_size = SM_BAT_ENTRY_SIZE_256;
data->max_number = entry->buf_size / FW_UPDATE_CHIP_CACHELINE;
data->cla_gpa_h = SM_CHIP_GPA_HI(entry->buf_pa);
- data->cla_gpa_l = SM_CHIP_GPA_LW(entry->buf_pa) | handle->gpa_check_enable;
+ data->cla_gpa_l = SM_CHIP_GPA_LW(entry->buf_pa) |
+ handle->gpa_check_enable;
data->z = z;
data->y = 0;
data->x = 0;
@@ -107,11 +106,12 @@ static void bat_l3i_fill_bat_entry_data(struct sm_bat_entry_standerd *data,
}
#ifdef __FW_UPDATE_DEBUG__
-#define FUD_PR_BYTE_MAX 16
-#define FUD_PR_BYTE_MUL 3
-#define FUD_PR_BYTE_BUF_MAX (FUD_PR_BYTE_MAX * FUD_PR_BYTE_MUL + 1)
-static void mpu_set_bat_l3i_entry_print_data(struct tag_fw_update_handle *handle,
- struct comm_cmd_set_bat_info *cmd)
+#define FUD_PR_BYTE_MAX 16
+#define FUD_PR_BYTE_MUL 3
+#define FUD_PR_BYTE_BUF_MAX (FUD_PR_BYTE_MAX * FUD_PR_BYTE_MUL + 1)
+static void
+mpu_set_bat_l3i_entry_print_data(struct tag_fw_update_handle *handle,
+ struct comm_cmd_set_bat_info *cmd)
{
struct hinic5_hwdev *hwdev = handle->hwdev;
u8 buf[FUD_PR_BYTE_BUF_MAX];
@@ -124,7 +124,7 @@ static void mpu_set_bat_l3i_entry_print_data(struct tag_fw_update_handle *handle
p = buf;
pe = p + FUD_PR_BYTE_BUF_MAX;
- memset(buf, 0, FUD_PR_BYTE_BUF_MAX);
+ (void)memset_s(buf, FUD_PR_BYTE_BUF_MAX, 0, FUD_PR_BYTE_BUF_MAX);
for (i = 0; i < size; i++) {
(void)sprintf_s(p, pe - p, "%02X ", cmd->data[i]);
@@ -140,7 +140,7 @@ static int mgmt_set_bat_l3i_entry(struct tag_fw_update_handle *handle,
struct tag_fw_update_bat_l3i_entry *entry)
{
struct hinic5_hwdev *hwdev = handle->hwdev;
- struct sm_bat_entry_standerd bat_data = {0};
+ struct sm_bat_entry_standerd bat_data = { 0 };
struct comm_cmd_set_bat_info buf;
u16 out_size = sizeof(buf);
u32 l3i_entry_offset = HINIC5_BAT_MAX;
@@ -152,46 +152,48 @@ static int mgmt_set_bat_l3i_entry(struct tag_fw_update_handle *handle,
bat_l3i_fill_bat_entry_data(&bat_data, entry, handle);
- memset(&buf, 0, sizeof(buf));
+ (void)memset_s(&buf, sizeof(buf), 0, sizeof(buf));
buf.func_id = func_id;
buf.smf_id = smf_id;
buf.bat_offset = l3i_entry_offset;
buf.data_size = sizeof(bat_data);
- memcpy(buf.data, (void *)&bat_data, sizeof(bat_data));
+ (void)memcpy_s(buf.data, sizeof(buf.data), (void *)&bat_data,
+ sizeof(bat_data));
#ifdef __FW_UPDATE_DEBUG__
- sdk_info(hwdev->dev_hdl,
- "fw_update: BAT L3I update: smf_id %u, func_id %u, bat_off %u\n",
- smf_id, func_id, l3i_entry_offset);
+ sdk_info(
+ hwdev->dev_hdl,
+ "fw_update: BAT L3I update: smf_id %u, func_id %u, bat_off %u\n",
+ smf_id, func_id, l3i_entry_offset);
mpu_set_bat_l3i_entry_print_data(handle, &buf);
#endif
ret = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
- COMM_MGMT_CMD_SET_BAT_INFO,
- &buf, sizeof(buf), &buf, &out_size,
- 0, HINIC5_CHANNEL_COMM);
+ COMM_MGMT_CMD_SET_BAT_INFO, &buf,
+ sizeof(buf), &buf, &out_size, 0,
+ HINIC5_CHANNEL_COMM);
if (ret != 0 || out_size == 0 || buf.head.status != 0) {
sdk_err(hwdev->dev_hdl,
- "Failed to set bat info, err: %d, \
- status: 0x%x, out size: 0x%x, channel: 0x%x\n",
+ "Failed to set bat info, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
ret, buf.head.status, out_size, HINIC5_CHANNEL_COMM);
- return ret;
+ return (ret != 0) ? ret : -EIO;
}
return 0;
}
-static int fw_update_init_bat_l3i_entry(struct tag_fw_update_handle *handle,
- struct tag_fw_update_bat_l3i_entry *entry,
- u32 page_order)
+static int
+fw_update_init_bat_l3i_entry(struct tag_fw_update_handle *handle,
+ struct tag_fw_update_bat_l3i_entry *entry,
+ u32 page_order)
{
struct hinic5_hwdev *hwdev = handle->hwdev;
struct device *dev = handle->dev;
u32 buf_size;
dma_addr_t pa;
int ret;
- void *va = (void *)(uintptr_t)__get_free_pages(GFP_KERNEL | __GFP_ZERO, page_order);
-
+ void *va = (void *)(uintptr_t)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+ page_order);
if (!va) {
sdk_err(hwdev->dev_hdl,
"BAT L3I buffer alloc failed, page_order %u\n",
@@ -220,8 +222,9 @@ static int fw_update_init_bat_l3i_entry(struct tag_fw_update_handle *handle,
return ret;
}
-static void fw_update_deinit_bat_l3i_entry(struct tag_fw_update_handle *handle,
- struct tag_fw_update_bat_l3i_entry *entry)
+static void
+fw_update_deinit_bat_l3i_entry(struct tag_fw_update_handle *handle,
+ struct tag_fw_update_bat_l3i_entry *entry)
{
struct device *dev = handle->dev;
@@ -236,7 +239,7 @@ static void fw_update_deinit_bat_l3i_entry(struct tag_fw_update_handle *handle,
entry->buf_va = 0;
}
- memset(entry, 0, sizeof(*entry));
+ memset_s(entry, sizeof(*entry), 0, sizeof(*entry));
}
static int fw_update_init_bat_l3i(struct tag_fw_update_handle *handle)
@@ -265,24 +268,28 @@ static int fw_update_init_bat_l3i(struct tag_fw_update_handle *handle)
smf_num = (int)handle->smf_enabled_num;
- sdk_info(hwdev->dev_hdl, "fw_update: smf num %d, per size 0x%X, page order %d\n",
+ sdk_info(hwdev->dev_hdl,
+ "fw_update: smf num %d, per size 0x%X, page order %d\n",
smf_num, per_smf_size, page_order);
for (smf_idx = 0; smf_idx < smf_num; smf_idx++) {
smf_id = handle->smf_enabled[smf_idx];
smf_entry = &handle->bat_l3i_entries[smf_id];
- ret = fw_update_init_bat_l3i_entry(handle, smf_entry, (u32)page_order);
+ ret = fw_update_init_bat_l3i_entry(handle, smf_entry,
+ (u32)page_order);
if (ret != 0)
goto entry_init_error;
#ifdef __FW_UPDATE_DEBUG__
- sdk_info(hwdev->dev_hdl,
- "fw_update: BAT L3I init: smf_id %u, va 0x%lx, pa 0x%lx, size 0x%x\n",
- smf_id, (uintptr_t)smf_entry->buf_va,
- (uintptr_t)smf_entry->buf_pa, smf_entry->buf_size);
+ sdk_info(
+ hwdev->dev_hdl,
+ "fw_update: BAT L3I init: smf_id %u, va 0x%lx, pa 0x%lx, size 0x%x\n",
+ smf_id, (uintptr_t)smf_entry->buf_va,
+ (uintptr_t)smf_entry->buf_pa, smf_entry->buf_size);
#endif
- ret = mgmt_set_bat_l3i_entry(handle, smf_id, func_id, smf_entry);
+ ret = mgmt_set_bat_l3i_entry(handle, smf_id, func_id,
+ smf_entry);
if (ret != 0)
goto entry_init_error;
}
@@ -338,8 +345,9 @@ static void fw_update_capability_init(struct tag_fw_update_handle *handle)
fw_update_capability_init_smf(handle);
handle->gpa_check_enable = true;
- if (svc_cap->test_mode != 0)
+ if (svc_cap->test_mode != 0) {
handle->gpa_check_enable = svc_cap->test_gpa_check_enable;
+ }
}
static int fw_update_alloc(struct hinic5_hwdev *hwdev)
@@ -347,7 +355,7 @@ static int fw_update_alloc(struct hinic5_hwdev *hwdev)
struct tag_fw_update_handle *handle = NULL;
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
- if (unlikely(!handle)) {
+ if (unlikely(handle == NULL)) {
sdk_err(hwdev->dev_hdl, "fw_update_hdl alloc fail.\n");
return -ENOMEM;
}
@@ -365,7 +373,7 @@ int hinic5_fw_update_init(void *hwdev_hdl)
struct tag_fw_update_handle *handle = NULL;
int ret;
- if (unlikely(!hwdev_hdl)) {
+ if (unlikely(hwdev_hdl == NULL)) {
pr_err("hwdev_hdl is null.\n");
return -EINVAL;
}
@@ -399,7 +407,7 @@ void hinic5_fw_update_deinit(void *hwdev_hdl)
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)hwdev_hdl;
struct tag_fw_update_handle *handle = NULL;
- if (likely(!hwdev || !hwdev->fw_update_hdl))
+ if (likely(hwdev == NULL || hwdev->fw_update_hdl == NULL))
return;
handle = (struct tag_fw_update_handle *)hwdev->fw_update_hdl;
@@ -420,27 +428,27 @@ bool hinic5_fw_update_ddr_enabled(void *hwdev_hdl)
return COMM_SUPPORT_UFHD_FLEX_SEG(hwdev) || COMM_SUPPORT_UFHD(hwdev);
}
-static struct fw_update_context *hinic5_fw_update_create_context(struct hinic5_hwdev *hwdev)
+static struct fw_update_context *
+hinic5_fw_update_create_context(struct hinic5_hwdev *hwdev)
{
- struct fw_update_context *context;
-
- context = vzalloc(sizeof(*context));
-
- if (!context)
+ struct fw_update_context *context =
+ vzalloc(sizeof(struct fw_update_context));
+ if (context == NULL)
return NULL;
- context->sec_text.data_cap = get_device_capablity(hwdev)->fw_update_cap.fw_tile_text_size;
+ context->sec_text.data_cap =
+ get_device_capablity(hwdev)->fw_update_cap.fw_tile_text_size;
if (context->sec_text.data_cap == 0) {
/* for compatibility */
context->sec_text.data_cap = FW_SEC_SIZE_TILE_TEXT;
}
context->sec_text.data = vzalloc(context->sec_text.data_cap);
- if (!context->sec_text.data)
+ if (context->sec_text.data == NULL)
goto alloc_sec_text_data_failed;
context->sec_phy.data_cap = FW_SEC_SIZE_PHY;
context->sec_phy.data = vzalloc(FW_SEC_SIZE_PHY);
- if (!context->sec_phy.data)
+ if (context->sec_phy.data == NULL)
goto alloc_sec_phy_data_failed;
return context;
@@ -454,9 +462,10 @@ static struct fw_update_context *hinic5_fw_update_create_context(struct hinic5_h
void hinic5_fw_update_free_context(void *update_context_hdl)
{
- struct fw_update_context *context = (struct fw_update_context *)update_context_hdl;
+ struct fw_update_context *context =
+ (struct fw_update_context *)update_context_hdl;
- if (!context)
+ if (context == NULL)
return;
if (context->sec_phy.data) {
@@ -479,8 +488,9 @@ static int fw_update_context_get(struct hinic5_hwdev *hwdev,
spinlock_t *lock = NULL;
int ret;
- if (unlikely(!chip_node)) {
- sdk_warn(hwdev->dev_hdl, "fw_update: chip_node not init, try later.\n");
+ if (unlikely(chip_node == NULL)) {
+ sdk_warn(hwdev->dev_hdl,
+ "fw_update: chip_node not init, try later.\n");
return -EAGAIN;
}
@@ -488,14 +498,17 @@ static int fw_update_context_get(struct hinic5_hwdev *hwdev,
ret = spin_trylock(lock);
if (unlikely(ret == 0)) {
- sdk_warn(hwdev->dev_hdl, "fw_update: not allowed to concurrent update, ret %d, abort!",
- ret);
+ sdk_warn(
+ hwdev->dev_hdl,
+ "fw_update: not allowed to concurrent update, ret %d, abort!",
+ ret);
return -EBUSY;
}
- if (unlikely(!chip_node->fw_update_context)) {
- chip_node->fw_update_context = hinic5_fw_update_create_context(hwdev);
- if (!chip_node->fw_update_context) {
+ if (unlikely(chip_node->fw_update_context == NULL)) {
+ chip_node->fw_update_context =
+ hinic5_fw_update_create_context(hwdev);
+ if (chip_node->fw_update_context == NULL) {
pr_err("fw_update: create context failed.\n");
spin_unlock(lock);
return -ENOMEM;
@@ -545,7 +558,8 @@ static int check_fw_section_update(struct fw_section_data *section,
return -EFBIG;
}
- memset(section->data, 0, section->data_cap);
+ (void)memset_s(section->data, section->data_cap, 0,
+ section->data_cap);
section->data_size = update->setion_total_len;
section->verified = 0;
}
@@ -569,18 +583,22 @@ static int check_fw_section_update(struct fw_section_data *section,
return 0;
}
-static inline int mgmt_cmd_update_fw_op(void *hwdev, struct hinic5_mt_cmd_info *cmd_info)
+static inline int mgmt_cmd_update_fw_op(void *hwdev,
+ struct hinic5_mt_cmd_info *cmd_info)
{
return hinic5_msg_to_mgmt_sync(hwdev, cmd_info->mod, cmd_info->cmd,
- cmd_info->buf_in, cmd_info->in_size, cmd_info->buf_out,
- cmd_info->out_size, cmd_info->timeout,
+ cmd_info->buf_in, cmd_info->in_size,
+ cmd_info->buf_out, cmd_info->out_size,
+ cmd_info->timeout,
HINIC5_CHANNEL_DEFAULT);
}
-static int handle_fw_section_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_info,
+static int handle_fw_section_update(void *hwdev,
+ struct hinic5_mt_cmd_info *cmd_info,
struct fw_section_data *section)
{
- struct fw_update_msg_st *update = (struct fw_update_msg_st *)(cmd_info->buf_in);
+ struct fw_update_msg_st *update =
+ (struct fw_update_msg_st *)(cmd_info->buf_in);
struct mgmt_msg_head *result_head = NULL;
u32 data_len;
int ret = 0;
@@ -595,15 +613,15 @@ static int handle_fw_section_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_
return ret;
}
- if (*cmd_info->out_size < sizeof(struct mgmt_msg_head)) {
- pr_err("fw_update: incompatible protocol, out_size %u\n", *cmd_info->out_size);
+ if (*(cmd_info->out_size) < sizeof(struct mgmt_msg_head)) {
+ pr_err("fw_update: incompatible protocol, out_size %u\n",
+ *(cmd_info->out_size));
return -EINVAL;
}
result_head = (struct mgmt_msg_head *)(cmd_info->buf_out);
/* MPU will not return verify result if Repeat-Msg requested
- * so we skip updating section data
- */
+ * so we skip updating section data */
if (result_head->status == MPU_FW_UPDATE_FLUSH_FLASH_REPEAT)
return 0;
@@ -618,12 +636,19 @@ static int handle_fw_section_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_
data_len = (u32)update->ctl_info.Fragment_Len;
- memcpy(section->data + section->data_off, update->data, data_len);
+ ret = memcpy_s(section->data + section->data_off,
+ section->data_cap - section->data_off, update->data,
+ data_len);
+ if (ret != 0) {
+ pr_err("fw_update: memcpy ctx buf err\n");
+ return ret;
+ }
section->data_off += data_len;
if (update->ctl_info.SL == 1) {
pr_info("fw_update: tile text section upload success. section type 0x%x, size 0x%x\n",
- update->section_info.FW_section_type, section->data_size);
+ update->section_info.FW_section_type,
+ section->data_size);
}
return 0;
@@ -632,7 +657,8 @@ static int handle_fw_section_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_
static int handle_cmd_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_info,
struct fw_update_context *context)
{
- struct fw_update_msg_st *update = (struct fw_update_msg_st *)(cmd_info->buf_in);
+ struct fw_update_msg_st *update =
+ (struct fw_update_msg_st *)(cmd_info->buf_in);
struct fw_section_data *section = NULL;
int ret = 0;
@@ -644,19 +670,21 @@ static int handle_cmd_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_info,
#ifdef __FW_UPDATE_DEBUG__
pr_info("fw_update: sec_type %u, off 0x%x, len %u\n",
- update->section_info.FW_section_type,
- update->section_offset,
+ update->section_info.FW_section_type, update->section_offset,
(u32)update->ctl_info.Fragment_Len);
#endif
/* handle new update session */
if (update->total_len != 0) {
if (context->update_started != 0 &&
- (context->sec_text.data_off != context->sec_text.data_size ||
- context->sec_phy.data_off != context->sec_phy.data_size))
+ ((context->sec_text.data_off !=
+ context->sec_text.data_size) ||
+ (context->sec_phy.data_off != context->sec_phy.data_size)))
pr_warn("fw_update: previous update may not completed, .text off 0x%x size 0x%x, .phy off 0x%x size 0x%x\n",
- context->sec_text.data_off, context->sec_text.data_size,
- context->sec_phy.data_off, context->sec_phy.data_size);
+ context->sec_text.data_off,
+ context->sec_text.data_size,
+ context->sec_phy.data_off,
+ context->sec_phy.data_size);
fw_update_context_reset(context);
context->update_started = 1;
}
@@ -684,16 +712,17 @@ static int handle_cmd_update(void *hwdev, struct hinic5_mt_cmd_info *cmd_info,
return ret;
}
-int hinic5_fw_update_cmd_update(void *hwdev_hdl, struct hinic5_mt_cmd_info *cmd_info)
+int hinic5_fw_update_cmd_update(void *hwdev_hdl,
+ struct hinic5_mt_cmd_info *cmd_info)
{
struct fw_update_context *context = NULL;
int ret = 0;
/* use extended upload procedure if FW hot update via L3I
- * is enabled, otherwise use normal way
- */
- if (!hinic5_fw_update_ddr_enabled(hwdev_hdl))
+ * is enabled, otherwise use normal way */
+ if (!hinic5_fw_update_ddr_enabled(hwdev_hdl)) {
return mgmt_cmd_update_fw_op(hwdev_hdl, cmd_info);
+ }
ret = fw_update_context_get((struct hinic5_hwdev *)hwdev_hdl, &context);
if (ret != 0)
@@ -718,9 +747,11 @@ int hinic5_fw_update_cmd_update(void *hwdev_hdl, struct hinic5_mt_cmd_info *cmd_
* @retval zero: success
* @retval non-zero: failure
*/
-STATIC int hinic5_bat_l3i_store(const struct hinic5_hwdev *hwdev, const u8 *data, u32 data_size)
+STATIC int hinic5_bat_l3i_store(const struct hinic5_hwdev *hwdev,
+ const u8 *data, u32 data_size)
{
- struct tag_fw_update_handle *handle = (struct tag_fw_update_handle *)hwdev->fw_update_hdl;
+ struct tag_fw_update_handle *handle =
+ (struct tag_fw_update_handle *)hwdev->fw_update_hdl;
struct service_cap *svc_cap = &hwdev->cfg_mgmt->svc_cap;
struct tag_fw_update_bat_l3i_entry *smf_entry = NULL;
const u32 cache_line = FW_UPDATE_CHIP_CACHELINE;
@@ -731,9 +762,9 @@ STATIC int hinic5_bat_l3i_store(const struct hinic5_hwdev *hwdev, const u8 *data
u8 *buf = NULL, *buf_end = NULL;
u8 *va = NULL, *va_end = NULL;
- if (unlikely(!data || data_size == 0 ||
+ if (unlikely((data == NULL) || (data_size == 0) ||
(data_size % cache_line != 0) ||
- data_size > FW_UPDATE_DDR_MAX))
+ (data_size > FW_UPDATE_DDR_MAX)))
return -EINVAL;
smf_enabled_num = handle->smf_enabled_num;
@@ -769,27 +800,31 @@ STATIC int hinic5_bat_l3i_store(const struct hinic5_hwdev *hwdev, const u8 *data
*/
STATIC void hinic5_bat_l3i_clean(const struct hinic5_hwdev *hwdev)
{
- struct tag_fw_update_handle *handle = (struct tag_fw_update_handle *)hwdev->fw_update_hdl;
+ struct tag_fw_update_handle *handle =
+ (struct tag_fw_update_handle *)hwdev->fw_update_hdl;
struct tag_fw_update_bat_l3i_entry *smf_entry = NULL;
u32 i, smf_id;
- if (!handle)
+ if (handle == NULL)
return;
for (i = 0; i < handle->smf_enabled_num; i++) {
smf_id = handle->smf_enabled[i];
smf_entry = &handle->bat_l3i_entries[smf_id];
- memset(smf_entry->buf_va, 0, smf_entry->buf_size);
+ (void)memset_s(smf_entry->buf_va, smf_entry->buf_size, 0,
+ smf_entry->buf_size);
}
}
static inline bool fw_section_data_valid(struct hinic5_hwdev *hwdev,
const struct fw_section_data *section)
{
- u32 fw_img_hdr_size = get_device_capablity(hwdev)->fw_update_cap.fw_img_hdr_size;
+ u32 fw_img_hdr_size =
+ get_device_capablity(hwdev)->fw_update_cap.fw_img_hdr_size;
/* for compatibility */
- if (fw_img_hdr_size == 0)
+ if (fw_img_hdr_size == 0) {
fw_img_hdr_size = FW_SEC_HDR_SIZE;
+ }
return section->verified == 1 &&
section->data_off == section->data_size &&
@@ -805,13 +840,15 @@ static int hot_active_fw_check(struct hinic5_hwdev *hwdev,
if (!fw_section_data_valid(hwdev, sec_text)) {
pr_err("fw_update: invalid tile text section, off %u, size %u, verify %u\n",
- sec_text->data_off, sec_text->data_size, sec_text->verified);
+ sec_text->data_off, sec_text->data_size,
+ sec_text->verified);
return -EINVAL;
}
if (has_phy_section && !fw_section_data_valid(hwdev, sec_phy)) {
pr_err("fw_update: invalid phy section, off %u, size %u, verify %u\n",
- sec_phy->data_off, sec_phy->data_size, sec_phy->verified);
+ sec_phy->data_off, sec_phy->data_size,
+ sec_phy->verified);
return -EINVAL;
}
@@ -829,7 +866,8 @@ static int hot_active_fw_prepare(struct hinic5_hwdev *hwdev,
u8 *data = NULL;
int ret = 0;
- fw_img_hdr_size = get_device_capablity(hwdev)->fw_update_cap.fw_img_hdr_size;
+ fw_img_hdr_size =
+ get_device_capablity(hwdev)->fw_update_cap.fw_img_hdr_size;
if (fw_img_hdr_size == 0) {
/* for compatibility */
fw_img_hdr_size = FW_SEC_HDR_SIZE;
@@ -840,9 +878,11 @@ static int hot_active_fw_prepare(struct hinic5_hwdev *hwdev,
data_len += sec_phy->data_size - fw_img_hdr_size;
if (data_len % cache_line != 0) {
- data_len_aligned = (data_len + cache_line - 1) / cache_line * cache_line;
+ data_len_aligned =
+ (data_len + cache_line - 1) / cache_line * cache_line;
if (data_len_aligned > FW_UPDATE_DDR_MAX) {
- sdk_err(hwdev->dev_hdl, "fw_update: update data too large, size 0x%x, aligned size 0x%x\n",
+ sdk_err(hwdev->dev_hdl,
+ "fw_update: update data too large, size 0x%x, aligned size 0x%x\n",
data_len, data_len_aligned);
return -EINVAL;
}
@@ -850,54 +890,68 @@ static int hot_active_fw_prepare(struct hinic5_hwdev *hwdev,
data_len_aligned = data_len;
}
- sdk_info(hwdev->dev_hdl, "fw_update: update data size 0x%x, aligned size 0x%x\n",
+ sdk_info(hwdev->dev_hdl,
+ "fw_update: udpate data size 0x%x, aligned size 0x%x\n",
data_len, data_len_aligned);
data = vzalloc(data_len_aligned);
- if (!data) {
+ if (data == NULL) {
+ sdk_err(hwdev->dev_hdl, "fw_update: no mem.\n");
return -ENOMEM;
}
- memcpy(data,
- sec_text->data + fw_img_hdr_size,
- sec_text->data_size - fw_img_hdr_size);
+ ret = memcpy_s(data, data_len_aligned, sec_text->data + fw_img_hdr_size,
+ sec_text->data_size - fw_img_hdr_size);
+ if (ret != 0)
+ goto out;
- if (has_phy_section && sec_phy->data_size > fw_img_hdr_size) {
+ if (has_phy_section && (sec_phy->data_size > fw_img_hdr_size)) {
data_off = sec_text->data_size - fw_img_hdr_size;
- memcpy(data + data_off,
- sec_phy->data + fw_img_hdr_size,
- sec_phy->data_size - fw_img_hdr_size);
+ ret = memcpy_s(data + data_off, data_len_aligned - data_off,
+ sec_phy->data + fw_img_hdr_size,
+ sec_phy->data_size - fw_img_hdr_size);
+ if (ret != 0)
+ goto out;
}
ret = hinic5_bat_l3i_store(hwdev, data, data_len_aligned);
if (ret != 0)
- sdk_err(hwdev->dev_hdl, "fw_update: hinic5_bat_l3i_store fail, data len %u\n",
+ sdk_err(hwdev->dev_hdl,
+ "fw_update: hinic5_bat_l3i_store fail, data len %u\n",
data_len_aligned);
+out:
+ vfree(data);
return ret;
}
-int hinic5_fw_update_cmd_hot_active(void *hwdev_hdl, struct hinic5_mt_cmd_info *cmd_info)
+int hinic5_fw_update_cmd_hot_active(void *hwdev_hdl,
+ struct hinic5_mt_cmd_info *cmd_info)
{
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)hwdev_hdl;
- struct cmd_hot_active_fw *hot_active = (struct cmd_hot_active_fw *)(cmd_info->buf_in);
+ struct cmd_hot_active_fw *hot_active =
+ (struct cmd_hot_active_fw *)(cmd_info->buf_in);
struct fw_update_context *context = NULL;
int ret = 0;
if (cmd_info->in_size < sizeof(struct cmd_hot_active_fw)) {
- pr_err("fw_update: invalid argument size %u\n", cmd_info->in_size);
+ pr_err("fw_update: invalid argument size %u\n",
+ cmd_info->in_size);
return -EINVAL;
}
- if (hot_active->type != FW_HOW_ACTIVE_TYPE_NPU)
+ if (hot_active->type != FW_HOW_ACTIVE_TYPE_NPU) {
return mgmt_cmd_update_fw_op(hwdev, cmd_info);
+ }
if (!hinic5_fw_update_ddr_enabled(hwdev_hdl)) {
- sdk_info(hwdev->dev_hdl, "fw_update: this function does not support hot update via DDR.\n");
+ sdk_info(
+ hwdev->dev_hdl,
+ "fw_update: this function does not support hot update via DDR.\n");
return mgmt_cmd_update_fw_op(hwdev, cmd_info);
}
- if (unlikely(!hwdev->fw_update_hdl)) {
+ if (unlikely(hwdev->fw_update_hdl == NULL)) {
sdk_err(hwdev->dev_hdl, "fw_update: DDR not ready.\n");
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.h
index 5c575327d..79cbab0db 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_fw_update.h
@@ -1,31 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_fw_update.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
#ifndef HINIC5_FW_UPDATE_H
#define HINIC5_FW_UPDATE_H
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_hw_cfg.h"
#include "hinic5_hw_mt.h"
-#define FW_UPDATE_DDR_MAX (1536 * 1024) /* 1.5 MB */
+#define FW_UPDATE_DDR_MAX (1536 * 1024) /* 1.5 MB */
-#define FW_UPDATE_CHIP_CACHELINE 256
+#define FW_UPDATE_CHIP_CACHELINE 256
/* Reference: updatefw.h */
-#define FW_HOW_ACTIVE_TYPE_NPU 2
+#define FW_HOW_ACTIVE_TYPE_NPU 2
struct tag_fw_update_bat_l3i_entry {
- u32 page_order;
- u32 buf_size;
- void *buf_va;
+ u32 page_order;
+ u32 buf_size;
+ void *buf_va;
dma_addr_t buf_pa;
};
@@ -33,9 +26,9 @@ struct tag_fw_update_handle {
struct hinic5_hwdev *hwdev;
struct device *dev;
- u8 gpa_check_enable;
+ u8 gpa_check_enable;
- u8 smf_enabled[CHIP_SMF_NUM_MAX];
+ u8 smf_enabled[CHIP_SMF_NUM_MAX];
u32 smf_enabled_num;
struct tag_fw_update_bat_l3i_entry bat_l3i_entries[CHIP_SMF_NUM_MAX];
@@ -91,13 +84,15 @@ bool hinic5_fw_update_ddr_enabled(void *hwdev_hdl);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_fw_update_cmd_update(void *hwdev_hdl, struct hinic5_mt_cmd_info *cmd_info);
+int hinic5_fw_update_cmd_update(void *hwdev_hdl,
+ struct hinic5_mt_cmd_info *cmd_info);
/**
* @brief hinic5_fw_update_cmd_update - handle cmd HOT_ACTIVE_FW
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_fw_update_cmd_hot_active(void *hwdev_hdl, struct hinic5_mt_cmd_info *cmd_info);
+int hinic5_fw_update_cmd_hot_active(void *hwdev_hdl,
+ struct hinic5_mt_cmd_info *cmd_info);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.c
index fd355afb4..8a13ffbfe 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_mt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include <asm/byteorder.h>
#include "ossl_knl.h"
@@ -18,18 +11,18 @@
#include "hinic5_fw_update.h"
#include "hinic5_hw_mt.h"
-#define HINIC5_CMDQ_BUF_MAX_SIZE 2048U
+#define HINIC5_CMDQ_BUF_MAX_SIZE 2048U
#define DW_WIDTH 4
-#define MSG_MAX_IN_SIZE (2048 * 1024)
-#define MSG_MAX_OUT_SIZE (2048 * 1024)
+#define MSG_MAX_IN_SIZE (2048 * 1024)
+#define MSG_MAX_OUT_SIZE (2048 * 1024)
#define API_CSR_MAX_RD_LEN (4 * 1024 * 1024)
/* completion timeout interval, unit is millisecond */
-#define MGMT_MSG_UPDATE_TIMEOUT 200000
-#define EMU_TIMEOUT_MULTIPLE 2 // emu scenario timeout multiplier
+#define MGMT_MSG_UPDATE_TIMEOUT 200000
+#define EMU_TIMEOUT_MULTIPLE 2 // emu场景下超时时间倍数
-void hinic5_free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf_in)
+void free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf_in)
{
if (!buf_in)
return;
@@ -40,21 +33,19 @@ void hinic5_free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf
kfree(buf_in);
}
-void hinic5_free_buff_out(void *hwdev, const struct msg_module *nt_msg,
- void *buf_out)
+void free_buff_out(void *hwdev, const struct msg_module *nt_msg, void *buf_out)
{
if (!buf_out)
return;
- if (nt_msg->module == SEND_TO_NPU &&
- nt_msg->npu_cmd.direct_resp == 0)
+ if (nt_msg->module == SEND_TO_NPU && (nt_msg->npu_cmd.direct_resp == 0))
hinic5_free_cmd_buf(hwdev, buf_out);
else
kfree(buf_out);
}
-int hinic5_alloc_buff_in(void *hwdev, const struct msg_module *nt_msg,
- u32 in_size, void **buf_in)
+int alloc_buff_in(void *hwdev, const struct msg_module *nt_msg, u32 in_size,
+ void **buf_in)
{
void *msg_buf = NULL;
@@ -92,23 +83,22 @@ int hinic5_alloc_buff_in(void *hwdev, const struct msg_module *nt_msg,
}
if (copy_from_user(msg_buf, nt_msg->in_buf, in_size) != 0) {
- pr_err("%s:%d: Copy from user failed\n",
- __func__, __LINE__);
- hinic5_free_buff_in(hwdev, nt_msg, *buf_in);
+ pr_err("%s:%d: Copy from user failed\n", __func__, __LINE__);
+ free_buff_in(hwdev, nt_msg, *buf_in);
return -EFAULT;
}
return 0;
}
-int hinic5_alloc_buff_out(void *hwdev, const struct msg_module *nt_msg,
- u32 out_size, void **buf_out)
+int alloc_buff_out(void *hwdev, const struct msg_module *nt_msg, u32 out_size,
+ void **buf_out)
{
if (out_size == 0)
return 0;
if (nt_msg->module == SEND_TO_NPU &&
- nt_msg->npu_cmd.direct_resp == 0) {
+ (nt_msg->npu_cmd.direct_resp == 0)) {
struct hinic5_cmd_buf *cmd_buf = NULL;
if (out_size > HINIC5_CMDQ_BUF_MAX_SIZE) {
@@ -133,14 +123,18 @@ int hinic5_alloc_buff_out(void *hwdev, const struct msg_module *nt_msg,
return 0;
}
-int hinic5_copy_buf_out_to_user(const struct msg_module *nt_msg,
- u32 out_size, void *buf_out)
+int copy_buf_out_to_user(const struct msg_module *nt_msg, u32 out_size,
+ void *buf_out)
{
int ret = 0;
void *msg_out = NULL;
- if (nt_msg->module == SEND_TO_NPU &&
- nt_msg->npu_cmd.direct_resp == 0)
+ if (out_size == 0) {
+ return 0;
+ }
+
+ if ((nt_msg->module == SEND_TO_NPU) &&
+ (nt_msg->npu_cmd.direct_resp == 0))
msg_out = ((struct hinic5_cmd_buf *)buf_out)->buf;
else
msg_out = buf_out;
@@ -151,8 +145,8 @@ int hinic5_copy_buf_out_to_user(const struct msg_module *nt_msg,
return ret;
}
-int hinic5_get_func_type(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+int get_func_type(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
u16 func_type;
@@ -168,7 +162,7 @@ int hinic5_get_func_type(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-int hinic5_get_func_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
+int get_func_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
void *buf_out, const u32 *out_size)
{
u16 func_id;
@@ -185,15 +179,15 @@ int hinic5_get_func_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 i
return 0;
}
-int hinic5_get_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+int get_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
return hinic5_dbg_get_hw_stats(hinic5_get_sdk_hwdev_by_lld(lld_dev),
- buf_out, out_size);
+ buf_out, out_size);
}
-int hinic5_clear_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+int clear_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
u16 size;
@@ -207,25 +201,26 @@ int hinic5_clear_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf
return 0;
}
-int hinic5_get_self_test_result(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+int get_self_test_result(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
u32 result;
- if (*out_size != sizeof(u32) || !buf_out) {
+ if (*out_size != sizeof(u32) || !buf_out) {
pr_err("Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u32));
return -EFAULT;
}
- result = hinic5_hinic5_get_self_test_result(hinic5_get_sdk_hwdev_by_lld(lld_dev));
+ result = hinic5_get_self_test_result(
+ hinic5_get_sdk_hwdev_by_lld(lld_dev));
*(u32 *)buf_out = result;
return 0;
}
-int hinic5_get_chip_faults_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+int get_chip_faults_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
u32 offset = 0;
struct nic_cmd_chip_fault_stats *fault_info = NULL;
@@ -251,12 +246,11 @@ static u32 get_mgmt_cmd_default_timeout(void *hwdev, u8 mod, u16 cmd)
u8 hw_type = hinic5_get_hw_type(hwdev);
u32 timeout = 0; /* default mbox/apichain timeout time */
- if (mod == HINIC5_MOD_COMM &&
- (cmd == COMM_MGMT_CMD_UPDATE_FW ||
- cmd == COMM_MGMT_CMD_UPDATE_BIOS ||
- cmd == COMM_MGMT_CMD_ACTIVE_FW ||
- cmd == COMM_MGMT_CMD_SWITCH_CFG ||
- cmd == COMM_MGMT_CMD_HOT_ACTIVE_FW))
+ if (mod == HINIC5_MOD_COMM && (cmd == COMM_MGMT_CMD_UPDATE_FW ||
+ cmd == COMM_MGMT_CMD_UPDATE_BIOS ||
+ cmd == COMM_MGMT_CMD_ACTIVE_FW ||
+ cmd == COMM_MGMT_CMD_SWITCH_CFG ||
+ cmd == COMM_MGMT_CMD_HOT_ACTIVE_FW))
timeout = MGMT_MSG_UPDATE_TIMEOUT;
if (unlikely(hw_type == HINIC5_HW_TYPE_EMU))
@@ -265,8 +259,9 @@ static u32 get_mgmt_cmd_default_timeout(void *hwdev, u8 mod, u16 cmd)
return timeout;
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+#ifdef CONFIG_HINIC5_SDK_DEBUG
+static int api_csr_read(void *hwdev, struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
int ret = 0;
@@ -276,7 +271,8 @@ static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
u32 i;
if (!buf_in || !buf_out || in_size < sizeof(*up_log_msg) ||
- *out_size < up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
+ *out_size < up_log_msg->rd_len ||
+ up_log_msg->rd_len % DW_WIDTH != 0)
return -EINVAL;
node_id = (u8)nt_msg->mpu_cmd.mod;
@@ -299,9 +295,8 @@ static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
return ret;
}
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
+static int api_csr_write(void *hwdev, struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
int ret = 0;
@@ -311,8 +306,10 @@ static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
u32 i;
u8 *data = NULL;
- if (!buf_in || in_size < sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
+ if (!buf_in || in_size < sizeof(*csr_write_msg) ||
+ csr_write_msg->rd_len == 0 ||
+ csr_write_msg->rd_len > API_CSR_MAX_RD_LEN ||
+ csr_write_msg->rd_len % DW_WIDTH != 0)
return -EINVAL;
node_id = (u8)nt_msg->mpu_cmd.mod;
@@ -321,9 +318,11 @@ static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
data = kzalloc(csr_write_msg->rd_len, GFP_KERNEL);
if (!data) {
+ pr_err("No more memory\n");
return -ENOMEM;
}
- if (copy_from_user(data, (void *)csr_write_msg->data, csr_write_msg->rd_len) != 0) {
+ if (copy_from_user(data, (void *)csr_write_msg->data,
+ csr_write_msg->rd_len) != 0) {
pr_err("Copy information from user failed\n");
kfree(data);
return -EFAULT;
@@ -346,11 +345,13 @@ static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
kfree(data);
return ret;
}
+#endif
int hinic5_fw_update_cmd(void *hwdev, struct hinic5_mt_cmd_info *cmd_info)
{
- if (cmd_info->cmd == COMM_MGMT_CMD_UPDATE_FW)
+ if (cmd_info->cmd == COMM_MGMT_CMD_UPDATE_FW) {
return hinic5_fw_update_cmd_update(hwdev, cmd_info);
+ }
return hinic5_fw_update_cmd_hot_active(hwdev, cmd_info);
}
@@ -361,7 +362,7 @@ int send_mbox_to_mgmt(void *hwdev, u8 mod, u16 cmd, void *buf_in, u16 in_size,
struct hinic5_mt_cmd_info cmd_info = { 0 };
if (mod == HINIC5_MOD_COMM && (cmd == COMM_MGMT_CMD_UPDATE_FW ||
- cmd == COMM_MGMT_CMD_HOT_ACTIVE_FW)) {
+ cmd == COMM_MGMT_CMD_HOT_ACTIVE_FW)) {
cmd_info.mod = mod;
cmd_info.cmd = cmd;
cmd_info.buf_in = buf_in;
@@ -378,8 +379,8 @@ int send_mbox_to_mgmt(void *hwdev, u8 mod, u16 cmd, void *buf_in, u16 in_size,
HINIC5_CHANNEL_DEFAULT);
}
-int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+int send_to_mpu(void *hwdev, struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
enum mt_api_type api_type;
enum hinic5_mod_type mod;
@@ -397,8 +398,9 @@ int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
mod = (enum hinic5_mod_type)nt_msg->mpu_cmd.mod;
cmd = nt_msg->mpu_cmd.cmd;
timeout = nt_msg->timeout;
- if (timeout == 0)
+ if (timeout == 0) {
timeout = get_mgmt_cmd_default_timeout(hwdev, mod, cmd);
+ }
switch (api_type) {
case API_TYPE_MBOX:
@@ -406,6 +408,7 @@ int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
buf_out, &temp_out_size, timeout);
*out_size = temp_out_size;
break;
+#ifdef CONFIG_HINIC5_SDK_DEBUG
case API_TYPE_CLP:
ret = hinic5_clp_to_mgmt(hwdev, mod, cmd, buf_in, (u16)in_size,
buf_out, &temp_out_size);
@@ -421,11 +424,13 @@ int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
}
break;
case API_TYPE_API_CHAIN_TO_MPU:
- ret = hinic5_msg_to_mgmt_sync(hwdev, mod, cmd, buf_in, (u16)in_size,
- buf_out, &temp_out_size, timeout,
+ ret = hinic5_msg_to_mgmt_sync(hwdev, mod, cmd, buf_in,
+ (u16)in_size, buf_out,
+ &temp_out_size, timeout,
HINIC5_CHANNEL_DEFAULT);
*out_size = temp_out_size;
break;
+#endif
default:
pr_err("Unsupported api_type %u\n", api_type);
return -EINVAL;
@@ -437,8 +442,8 @@ int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
-int hinic5_send_to_npu(void *hwdev, const struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+int send_to_npu(void *hwdev, const struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
int ret = 0;
u8 cmd;
@@ -450,14 +455,14 @@ int hinic5_send_to_npu(void *hwdev, const struct msg_module *nt_msg,
timeout = nt_msg->timeout;
if (nt_msg->npu_cmd.direct_resp != 0) {
- ret = hinic5_cmdq_direct_resp(hwdev, mod, cmd,
- buf_in, buf_out, timeout,
- HINIC5_CHANNEL_DEFAULT);
+ ret = hinic5_cmdq_direct_resp(hwdev, mod, cmd, buf_in, buf_out,
+ timeout, HINIC5_CHANNEL_DEFAULT);
if (ret != 0)
pr_err("Send direct cmdq failed, err: %d\n", ret);
} else {
ret = hinic5_cmdq_detail_resp(hwdev, mod, cmd, buf_in, buf_out,
- NULL, timeout, HINIC5_CHANNEL_DEFAULT);
+ NULL, timeout,
+ HINIC5_CHANNEL_DEFAULT);
if (ret != 0)
pr_err("Send detail cmdq failed, err: %d\n", ret);
}
@@ -465,8 +470,8 @@ int hinic5_send_to_npu(void *hwdev, const struct msg_module *nt_msg,
return ret;
}
-static int sm_rd16(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd16(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u16 val1;
int ret;
@@ -482,8 +487,8 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd32(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd32(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u32 val1;
int ret;
@@ -499,8 +504,8 @@ static int sm_rd32(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd32_clear(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd32_clear(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u32 val1;
int ret;
@@ -516,8 +521,8 @@ static int sm_rd32_clear(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd64_pair(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd64_pair(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u64 val1 = 0, val2 = 0;
int ret;
@@ -535,8 +540,8 @@ static int sm_rd64_pair(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd64_pair_clear(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd64_pair_clear(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u64 val1 = 0;
u64 val2 = 0;
@@ -556,8 +561,8 @@ static int sm_rd64_pair_clear(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd64(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd64(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u64 val1;
int ret;
@@ -572,8 +577,8 @@ static int sm_rd64(void *hwdev, u32 id, u8 instance,
return ret;
}
-static int sm_rd64_clear(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out)
+static int sm_rd64_clear(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out)
{
u64 val1;
int ret;
@@ -588,46 +593,48 @@ static int sm_rd64_clear(void *hwdev, u32 id, u8 instance,
return ret;
}
-typedef int (*sm_module)(void *hwdev, u32 id, u8 instance,
- u8 node, struct sm_out_st *buf_out);
+typedef int (*sm_module)(void *hwdev, u32 id, u8 instance, u8 node,
+ struct sm_out_st *buf_out);
struct sm_module_handle {
- enum sm_cmd_type sm_cmd_name;
- sm_module sm_func;
+ enum sm_cmd_type sm_cmd_name;
+ sm_module sm_func;
};
-const struct sm_module_handle hinic5_sm_module_cmd_handle[] = {
- {SM_CTR_RD16, sm_rd16},
- {SM_CTR_RD32, sm_rd32},
- {SM_CTR_RD64_PAIR, sm_rd64_pair},
- {SM_CTR_RD64, sm_rd64},
- {SM_CTR_RD32_CLEAR, sm_rd32_clear},
- {SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
- {SM_CTR_RD64_CLEAR, sm_rd64_clear}
+const struct sm_module_handle sm_module_cmd_handle[] = {
+ { SM_CTR_RD16, sm_rd16 },
+ { SM_CTR_RD32, sm_rd32 },
+ { SM_CTR_RD64_PAIR, sm_rd64_pair },
+ { SM_CTR_RD64, sm_rd64 },
+ { SM_CTR_RD32_CLEAR, sm_rd32_clear },
+ { SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear },
+ { SM_CTR_RD64_CLEAR, sm_rd64_clear }
};
-int hinic5_send_to_sm(void *hwdev, const struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+int send_to_sm(void *hwdev, const struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct sm_in_st *sm_in = buf_in;
struct sm_out_st *sm_out = buf_out;
u32 msg_formate = nt_msg->msg_formate;
- int index, num_cmds = ARRAY_LEN(hinic5_sm_module_cmd_handle);
+ int index, num_cmds = ARRAY_LEN(sm_module_cmd_handle);
int ret = 0;
- if (!buf_in || !buf_out || in_size != sizeof(*sm_in) || *out_size != sizeof(*sm_out)) {
+ if (!buf_in || !buf_out || in_size != sizeof(*sm_in) ||
+ *out_size != sizeof(*sm_out)) {
pr_err("Unexpect out buf size :%u, in buf size: %u\n",
*out_size, in_size);
return -EINVAL;
}
for (index = 0; index < num_cmds; index++) {
- if (msg_formate != hinic5_sm_module_cmd_handle[index].sm_cmd_name)
+ if (msg_formate != sm_module_cmd_handle[index].sm_cmd_name)
continue;
- ret = hinic5_sm_module_cmd_handle[index].sm_func(hwdev, (u32)sm_in->id,
+ ret = sm_module_cmd_handle[index].sm_func(hwdev, (u32)sm_in->id,
(u8)sm_in->instance,
- (u8)sm_in->node, sm_out);
+ (u8)sm_in->node,
+ sm_out);
break;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.h
index 9825bfa10..d662c2268 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_hw_mt.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_hw_mt.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_HW_MT_H
#define HINIC5_HW_MT_H
@@ -46,23 +39,23 @@ struct hinic5_mt_cmd_info {
u32 timeout;
};
-int hinic5_get_func_type(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size);
+int get_func_type(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size);
-int hinic5_get_func_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
+int get_func_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
void *buf_out, const u32 *out_size);
-int hinic5_get_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size);
+int get_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size);
-int hinic5_clear_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size);
+int clear_hw_driver_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size);
-int hinic5_get_self_test_result(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size);
+int get_self_test_result(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size);
-int hinic5_get_chip_faults_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size);
+int get_chip_faults_stats(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size);
#ifndef __WIN__
/**
@@ -77,7 +70,8 @@ int hinic5_get_chip_faults_stats(struct hinic5_lld_dev *lld_dev, const void *buf
* @retval non-zero: failure
*/
-int hinic5_alloc_buff_in(void *hwdev, const struct msg_module *nt_msg, u32 in_size, void **buf_in);
+int alloc_buff_in(void *hwdev, const struct msg_module *nt_msg, u32 in_size,
+ void **buf_in);
/**
* @brief alloc output buffer
@@ -91,7 +85,8 @@ int hinic5_alloc_buff_in(void *hwdev, const struct msg_module *nt_msg, u32 in_si
* @retval non-zero: failure
*/
-int hinic5_alloc_buff_out(void *hwdev, const struct msg_module *nt_msg, u32 out_size, void **buf_out);
+int alloc_buff_out(void *hwdev, const struct msg_module *nt_msg, u32 out_size,
+ void **buf_out);
/**
* @brief free input buffer
@@ -104,7 +99,7 @@ int hinic5_alloc_buff_out(void *hwdev, const struct msg_module *nt_msg, u32 out_
* @retval non-zero: failure
*/
-void hinic5_free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf_in);
+void free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf_in);
/**
* @brief free output buffer
@@ -117,7 +112,7 @@ void hinic5_free_buff_in(void *hwdev, const struct msg_module *nt_msg, void *buf
* @retval non-zero: failure
*/
-void hinic5_free_buff_out(void *hwdev, const struct msg_module *nt_msg, void *buf_out);
+void free_buff_out(void *hwdev, const struct msg_module *nt_msg, void *buf_out);
/**
* @brief copy from message buffer to user buffer
@@ -130,7 +125,8 @@ void hinic5_free_buff_out(void *hwdev, const struct msg_module *nt_msg, void *bu
* @retval non-zero: failure
*/
-int hinic5_copy_buf_out_to_user(const struct msg_module *nt_msg, u32 out_size, void *buf_out);
+int copy_buf_out_to_user(const struct msg_module *nt_msg, u32 out_size,
+ void *buf_out);
#endif
/**
* @brief send message to mpu
@@ -146,8 +142,8 @@ int hinic5_copy_buf_out_to_user(const struct msg_module *nt_msg, u32 out_size, v
* @retval non-zero: failure
*/
-int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size);
+int send_to_mpu(void *hwdev, struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
/**
* @brief send message to npu
@@ -163,8 +159,8 @@ int hinic5_send_to_mpu(void *hwdev, struct msg_module *nt_msg,
* @retval non-zero: failure
*/
-int hinic5_send_to_npu(void *hwdev, const struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size);
+int send_to_npu(void *hwdev, const struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
/**
* @brief send message to sm
@@ -180,7 +176,7 @@ int hinic5_send_to_npu(void *hwdev, const struct msg_module *nt_msg,
* @retval non-zero: failure
*/
-int hinic5_send_to_sm(void *hwdev, const struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size);
+int send_to_sm(void *hwdev, const struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.c
index 0f764e767..1ea02d9a3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nictool.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [COMM]" fmt
@@ -37,37 +30,38 @@
static int g_nictool_ref_cnt;
-static dev_t g_dev_id = {0};
+static dev_t g_dev_id = { 0 };
static struct class *g_nictool_class;
static struct cdev g_nictool_cdev;
#define HINIC5_MAX_BUF_SIZE (2048 * 1024)
#define HINIC5_S_TO_US_UNIT 1000000
-void *hinic5_g_card_node_array[MAX_CARD_NUM] = {0};
-void *hinic5_g_card_vir_addr[MAX_CARD_NUM] = {0};
-u64 hinic5_g_card_phy_addr[MAX_CARD_NUM] = {0};
-int hinic5_card_id;
+void *g_card_node_array[MAX_CARD_NUM] = { 0 };
+void *g_card_vir_addr[MAX_CARD_NUM] = { 0 };
+u64 g_card_phy_addr[MAX_CARD_NUM] = { 0 };
+int card_id;
#ifdef __HIFC__
-#define HIADM3_DEV_PATH "/dev/hifc_dev"
-#define HIADM3_DEV_CLASS "hifc_class"
-#define HIADM3_DEV_NAME "hifc_dev"
+#define HIADM3_DEV_PATH "/dev/hifc_dev"
+#define HIADM3_DEV_CLASS "hifc_class"
+#define HIADM3_DEV_NAME "hifc_dev"
#else
-#define HIADM3_DEV_PATH "/dev/hinic5_nictool_dev"
-#define HIADM3_DEV_CLASS "hinic5_nictool_class"
-#define HIADM3_DEV_NAME "hinic5_nictool_dev"
+#define HIADM3_DEV_PATH "/dev/hinic5_nictool_dev"
+#define HIADM3_DEV_CLASS "hinic5_nictool_class"
+#define HIADM3_DEV_NAME "hinic5_nictool_dev"
#endif
typedef int (*hw_driv_module)(struct hinic5_lld_dev *lld_dev,
- const void *buf_in, u32 in_size, void *buf_out, u32 *out_size);
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size);
struct hw_drv_module_handle {
- u32 driv_cmd_name;
- hw_driv_module driv_func;
+ uint32_t driv_cmd_name;
+ hw_driv_module driv_func;
};
-static bool check_cmd_compatible(u32 in_size, u32 expect_in_size,
- u32 out_size, u32 expect_out_size)
+static bool check_cmd_compatible(u32 in_size, u32 expect_in_size, u32 out_size,
+ u32 expect_out_size)
{
if (unlikely(in_size != expect_in_size)) {
pr_err("Incompatible hw driver cmd, in size %u, expect %u\n",
@@ -84,8 +78,9 @@ static bool check_cmd_compatible(u32 in_size, u32 expect_in_size,
return true;
}
-static int get_single_card_info(struct hinic5_lld_dev *lld_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_single_card_info(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
if (!buf_in || in_size != sizeof(struct card_info)) {
pr_err("buf_in is NULL, or in_size(%u) != expect_in_size(%lu)\n",
@@ -99,13 +94,14 @@ static int get_single_card_info(struct hinic5_lld_dev *lld_dev, const void *buf_
return -EINVAL;
}
- hinic5_get_card_info(hinic5_get_sdk_hwdev_by_lld(lld_dev), buf_in, buf_out);
+ hinic5_get_card_info(hinic5_get_sdk_hwdev_by_lld(lld_dev), buf_in,
+ buf_out);
return 0;
}
-static int is_driver_in_vm(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int is_driver_in_vm(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
bool in_host = false;
@@ -123,8 +119,9 @@ static int is_driver_in_vm(struct hinic5_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static int get_all_chip_id_cmd(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_all_chip_id_cmd(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
if (*out_size != sizeof(struct nic_card_id) || !buf_out) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
@@ -140,32 +137,42 @@ static int get_all_chip_id_cmd(struct hinic5_lld_dev *lld_dev, const void *buf_i
static int get_card_usr_api_chain_mem(int card_idx)
{
void *tmp = NULL;
- int i;
-
- hinic5_card_id = card_idx;
- if (!hinic5_g_card_vir_addr[card_idx]) {
- hinic5_g_card_vir_addr[card_idx] =
- (void *)(uintptr_t)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
- if (!hinic5_g_card_vir_addr[card_idx]) {
- pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
+ int i, ret;
+
+ card_id = card_idx;
+ if (!g_card_vir_addr[card_idx]) {
+ g_card_vir_addr[card_idx] = (void *)(uintptr_t)__get_free_pages(
+ GFP_KERNEL, DBGTOOL_PAGE_ORDER);
+ if (!g_card_vir_addr[card_idx]) {
+ pr_err("Alloc api chain memory fail for card %d!\n",
+ card_idx);
return -EFAULT;
}
- memset(hinic5_g_card_vir_addr[card_idx], 0,
- PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER));
+ ret = memset_s(g_card_vir_addr[card_idx],
+ PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER), 0,
+ PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER));
+ if (ret != 0) {
+ pr_err("memset_s for vir_addr failed, ret:%d!\n", ret);
+ free_pages((unsigned long)(uintptr_t)
+ g_card_vir_addr[card_idx],
+ DBGTOOL_PAGE_ORDER);
+ g_card_vir_addr[card_idx] = NULL;
+ return ret;
+ }
- hinic5_g_card_phy_addr[card_idx] =
- virt_to_phys(hinic5_g_card_vir_addr[card_idx]);
- if (hinic5_g_card_phy_addr[card_idx] == 0) {
+ g_card_phy_addr[card_idx] =
+ virt_to_phys(g_card_vir_addr[card_idx]);
+ if (g_card_phy_addr[card_idx] == 0) {
pr_err("phy addr for card %d is 0\n", card_idx);
- free_pages((unsigned long)(uintptr_t)hinic5_g_card_vir_addr[card_idx],
+ free_pages((unsigned long)(uintptr_t)
+ g_card_vir_addr[card_idx],
DBGTOOL_PAGE_ORDER);
- hinic5_g_card_vir_addr[card_idx] = NULL;
+ g_card_vir_addr[card_idx] = NULL;
return -EFAULT;
}
- tmp = hinic5_g_card_vir_addr[card_idx];
+ tmp = g_card_vir_addr[card_idx];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
SetPageReserved(virt_to_page(tmp));
tmp += PAGE_SIZE;
@@ -180,18 +187,19 @@ static void dbgtool_knl_free_mem(u32 id)
void *tmp = NULL;
int i;
- if (!hinic5_g_card_vir_addr[id])
+ if (!g_card_vir_addr[id])
return;
- tmp = hinic5_g_card_vir_addr[id];
+ tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
ClearPageReserved(virt_to_page(tmp));
tmp += PAGE_SIZE;
}
- free_pages((unsigned long)(uintptr_t)hinic5_g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
- hinic5_g_card_vir_addr[id] = NULL;
- hinic5_g_card_phy_addr[id] = 0;
+ free_pages((unsigned long)(uintptr_t)g_card_vir_addr[id],
+ DBGTOOL_PAGE_ORDER);
+ g_card_vir_addr[id] = NULL;
+ g_card_phy_addr[id] = 0;
}
static int card_info_param_valid(const char *dev_name, const void *buf_out,
@@ -211,23 +219,24 @@ static int card_info_param_valid(const char *dev_name, const void *buf_out,
return err;
}
- err = sscanf(dev_name, HINIC5_CHIP_NAME "%d", id);
- if (err != 1) {
+ err = sscanf_s(dev_name, HINIC5_CHIP_NAME "%d", id);
+ if (err <= 0) {
pr_err("Failed to get card id\n");
return err;
}
if (*id >= MAX_CARD_NUM || *id < 0) {
- pr_err("chip id %d exceed limit[0-%d]\n",
- *id, MAX_CARD_NUM - 1);
+ pr_err("chip id %d exceed limit[0-%d]\n", *id,
+ MAX_CARD_NUM - 1);
return -EINVAL;
}
return 0;
}
-static void hinic5_get_card_func_info_by_card_name(const char *chip_name,
- struct hinic5_card_func_info *card_func)
+static void
+hinic5_get_card_func_info_by_card_name(const char *chip_name,
+ struct hinic5_card_func_info *card_func)
{
struct list_head *chip_list = get_hinic5_chip_list();
struct card_node *chip_node = NULL;
@@ -236,7 +245,7 @@ static void hinic5_get_card_func_info_by_card_name(const char *chip_name,
card_func->num_pf = 0;
- hinic5_lld_hold();
+ lld_hold();
list_for_each_entry(chip_node, chip_list, node) {
if (strncmp(chip_node->chip_name, chip_name, IFNAMSIZ) != 0)
@@ -255,27 +264,30 @@ static void hinic5_get_card_func_info_by_card_name(const char *chip_name,
card_func->num_pf++;
if (card_func->num_pf >= CARD_MAX_SIZE) {
- hinic5_lld_put();
+ lld_put();
return;
}
}
}
- hinic5_lld_put();
+ lld_put();
}
-static int get_card_func_info(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_card_func_info(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
struct hinic5_card_func_info *card_func_info = buf_out;
struct card_node *card_info = hinic5_get_chip_node_by_lld(lld_dev);
int err, id = 0;
- err = card_info_param_valid(card_info->chip_name, buf_out, *out_size, &id);
+ err = card_info_param_valid(card_info->chip_name, buf_out, *out_size,
+ &id);
if (err != 0)
return err;
- hinic5_get_card_func_info_by_card_name(card_info->chip_name, card_func_info);
+ hinic5_get_card_func_info_by_card_name(card_info->chip_name,
+ card_func_info);
if (card_func_info->num_pf == 0) {
pr_err("None function found for %s\n", card_info->chip_name);
@@ -289,22 +301,23 @@ static int get_card_func_info(struct hinic5_lld_dev *lld_dev, const void *buf_in
return -EFAULT;
}
- card_func_info->usr_api_phy_addr = hinic5_g_card_phy_addr[id];
+ card_func_info->usr_api_phy_addr = g_card_phy_addr[id];
return 0;
}
-static int get_pf_cap_info(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_pf_cap_info(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct service_cap *func_cap = NULL;
struct hinic5_hwdev *hwdev = NULL;
struct card_node *card_info = hinic5_get_chip_node_by_lld(lld_dev);
struct svc_cap_info *svc_cap_info_in = (struct svc_cap_info *)buf_in;
struct svc_cap_info *svc_cap_info_out = (struct svc_cap_info *)buf_out;
+ int ret;
- if (*out_size != sizeof(struct svc_cap_info) || in_size != sizeof(struct svc_cap_info) ||
- !buf_in || !buf_out) {
+ if (*out_size != sizeof(struct svc_cap_info) ||
+ in_size != sizeof(struct svc_cap_info) || !buf_in || !buf_out) {
pr_err("Invalid parameter: out_buf_size %u, in_size: %u, expect %lu\n",
*out_size, in_size, sizeof(struct svc_cap_info));
return -EINVAL;
@@ -316,22 +329,29 @@ static int get_pf_cap_info(struct hinic5_lld_dev *lld_dev, const void *buf_in, u
return -EINVAL;
}
- hinic5_lld_hold();
- hwdev = (struct hinic5_hwdev *)(card_info->func_handle_array)[svc_cap_info_in->func_idx];
+ lld_hold();
+ hwdev = (struct hinic5_hwdev *)(card_info->func_handle_array)
+ [svc_cap_info_in->func_idx];
if (!hwdev) {
- hinic5_lld_put();
+ lld_put();
return -EINVAL;
}
func_cap = &hwdev->cfg_mgmt->svc_cap;
- memcpy(&svc_cap_info_out->cap, func_cap, sizeof(struct service_cap));
- hinic5_lld_put();
+ ret = memcpy_s(&svc_cap_info_out->cap, sizeof(struct service_cap),
+ func_cap, sizeof(struct service_cap));
+ if (ret != 0) {
+ lld_put();
+ return ret;
+ }
+ lld_put();
return 0;
}
-static int get_hw_drv_version(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_hw_drv_version(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
int err;
@@ -347,16 +367,17 @@ static int get_hw_drv_version(struct hinic5_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC5_DRV_VERSION, "2026-05-20_00:00:00");
+ err = snprintf_s(ver_info->ver, sizeof(ver_info->ver),
+ sizeof(ver_info->ver) - 1, "%s %s",
+ HINIC5_DRV_VERSION, __TIME_STR__);
if (err < 0)
return -EINVAL;
return 0;
}
-static int get_pf_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_pf_id(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic5_pf_info *pf_info = NULL;
struct card_node *chip_node = hinic5_get_chip_node_by_lld(lld_dev);
@@ -366,7 +387,8 @@ static int get_pf_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_
if (!chip_node)
return -ENODEV;
- if (!buf_out || (*out_size != sizeof(*pf_info)) || !buf_in || in_size != sizeof(u32)) {
+ if (!buf_out || (*out_size != sizeof(*pf_info)) || !buf_in ||
+ in_size != sizeof(u32)) {
pr_err("Unexpect out buf size from user :%u, expect: %lu, in size:%u\n",
*out_size, sizeof(*pf_info), in_size);
return -EINVAL;
@@ -374,7 +396,8 @@ static int get_pf_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_
port_id = *((u32 *)buf_in);
pf_info = (struct hinic5_pf_info *)buf_out;
- err = hinic5_get_pf_id(chip_node, port_id, &pf_info->pf_id, &pf_info->isvalid);
+ err = hinic5_get_pf_id(chip_node, port_id, &pf_info->pf_id,
+ &pf_info->isvalid);
if (err != 0)
return err;
@@ -384,8 +407,9 @@ static int get_pf_id(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_
}
#ifdef CONFIG_HINIC5_SDK_DEBUG
-static int set_frequency_reduction_ratio(struct hinic5_lld_dev *lld_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_frequency_reduction_ratio(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
u32 ratio;
int err;
@@ -405,8 +429,9 @@ static int set_frequency_reduction_ratio(struct hinic5_lld_dev *lld_dev, const v
return 0;
}
-static int set_time_diff_enable(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int set_time_diff_enable(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
u32 enable;
int err;
@@ -426,8 +451,8 @@ static int set_time_diff_enable(struct hinic5_lld_dev *lld_dev, const void *buf_
return 0;
}
-static int get_time_diff(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_time_diff(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
int err;
@@ -444,13 +469,13 @@ static int get_time_diff(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32
}
#endif
-static int get_cmdq_info(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_cmdq_info(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
u16 cmdq_id;
- if (!check_cmd_compatible(in_size, sizeof(u32),
- *out_size, sizeof(struct hinic5_wq)))
+ if (!check_cmd_compatible(in_size, sizeof(u32), *out_size,
+ sizeof(struct hinic5_wq)))
return -EINVAL;
cmdq_id = (u16)(*((u32 *)buf_in));
@@ -476,19 +501,21 @@ static int detect_cmdq_channel(struct hinic5_lld_dev *lld_dev,
u64 out_param;
cmdq_npu_dft_s *cmdq_info = NULL;
- if (!buf_in || !buf_out || !out_size) {
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL)) {
sdk_err(adev->dev, "Buf_in or buf_out or out_size is NULL.\n");
return -EINVAL;
}
if (in_size != sizeof(u32)) {
- sdk_err(adev->dev, "Unexpect in buf size from user :%u, expect: %lu\n",
+ sdk_err(adev->dev,
+ "Unexpect in buf size from user :%u, expect: %lu\n",
in_size, sizeof(u32));
return -EINVAL;
}
if (*out_size != sizeof(u32)) {
- sdk_err(adev->dev, "Unexpect out buf size from user :%u, expect: %lu\n",
+ sdk_err(adev->dev,
+ "Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic5_wq));
return -EINVAL;
}
@@ -498,24 +525,24 @@ static int detect_cmdq_channel(struct hinic5_lld_dev *lld_dev,
sdk_info(adev->dev, "debug: cmdq detect q_id=%d\n", cmdq_id);
cmd_buf = hinic5_alloc_cmd_buf(adev->hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
sdk_err(adev->hwdev, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
- /* Use dft_npu test command type = DFT_CMDQ_TYPE_NPU_CHANNEL_TEST,
- * value = DFT_CMDQ_VALUE_CHANNEL_TEST_LOG for connectivity test
- */
+ /* 使用dft_npu测试命令 type = DFT_CMDQ_TYPE_NPU_CHANNEL_TEST,
+ * value = DFT_CMDQ_VALUE_CHANNEL_TEST_LOG 做连通性测试 */
cmd_buf->size = sizeof(cmdq_npu_dft_s);
cmdq_info = (cmdq_npu_dft_s *)cmd_buf->buf;
cmdq_info->type = 0;
cmdq_info->value = 0;
hinic5_cpu_to_be32(cmd_buf->buf, cmd_buf->size);
- err = hinic5_cos_id_direct_resp
- (adev->hwdev, HINIC5_MOD_COMM, COMM_CMD_SEND_NPU_DFT_CMD, cmdq_id, cmd_buf,
- &out_param, 0, HINIC5_CHANNEL_COMM);
- if (err != 0 || out_param != 0) {
+ err = hinic5_cos_id_direct_resp(adev->hwdev, HINIC5_MOD_COMM,
+ COMM_CMD_SEND_NPU_DFT_CMD, cmdq_id,
+ cmd_buf, &out_param, 0,
+ HINIC5_CHANNEL_COMM);
+ if ((err != 0) || (out_param != 0)) {
sdk_err(adev->dev, "Failed to send cmdq channel detect\n");
err = -EFAULT;
}
@@ -529,8 +556,8 @@ static int detect_cmdq_channel(struct hinic5_lld_dev *lld_dev,
}
#endif
-static int get_cmdq_wqe_desc(struct hinic5_lld_dev *lld_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_cmdq_wqe_desc(struct hinic5_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
const struct cmdq_wqe_info *info = buf_in;
@@ -538,15 +565,15 @@ static int get_cmdq_wqe_desc(struct hinic5_lld_dev *lld_dev, const void *buf_in,
*out_size, sizeof(struct sdk_cmdq_wqe_desc)))
return -EINVAL;
- return hinic5_dump_cmdq_wqebb(lld_dev->hwdev,
- (u16)info->q_id, (u16)info->wqebb_id, buf_out);
+ return hinic5_dump_cmdq_wqebb(lld_dev->hwdev, (u16)info->q_id,
+ (u16)info->wqebb_id, buf_out);
}
/* not support fc yet */
static int get_mbox_cnt(struct hinic5_lld_dev *lld_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out) {
+ if (buf_out == NULL) {
pr_err("buf_out is NULL");
return -EINVAL;
}
@@ -561,29 +588,29 @@ static int get_mbox_cnt(struct hinic5_lld_dev *lld_dev, const void *buf_in,
return 0;
}
-struct hw_drv_module_handle hinic5_hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, (hw_driv_module)hinic5_get_func_type},
- {GET_FUNC_IDX, (hw_driv_module)hinic5_get_func_id},
- {GET_HW_STATS, (hw_driv_module)hinic5_get_hw_driver_stats},
- {CLEAR_HW_STATS, (hw_driv_module)hinic5_clear_hw_driver_stats},
- {GET_SELF_TEST_RES, (hw_driv_module)hinic5_get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)hinic5_get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
- {SDK_CMD_GET_CMDQ_INFO, get_cmdq_info},
- {SDK_CMD_GET_CMDQ_WQE_DESC, get_cmdq_wqe_desc},
- {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
+ { FUNC_TYPE, (hw_driv_module)get_func_type },
+ { GET_FUNC_IDX, (hw_driv_module)get_func_id },
+ { GET_HW_STATS, (hw_driv_module)get_hw_driver_stats },
+ { CLEAR_HW_STATS, (hw_driv_module)clear_hw_driver_stats },
+ { GET_SELF_TEST_RES, (hw_driv_module)get_self_test_result },
+ { GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats },
+ { GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info },
+ { IS_DRV_IN_VM, is_driver_in_vm },
+ { GET_CHIP_ID, get_all_chip_id_cmd },
+ { GET_CHIP_INFO, get_card_func_info },
+ { GET_FUNC_CAP, get_pf_cap_info },
+ { GET_DRV_VERSION, get_hw_drv_version },
+ { GET_PF_ID, get_pf_id },
+ { SDK_CMD_GET_CMDQ_INFO, get_cmdq_info },
+ { SDK_CMD_GET_CMDQ_WQE_DESC, get_cmdq_wqe_desc },
+ { GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt },
#ifdef CONFIG_HINIC5_SDK_DEBUG
- {SDK_CMD_CMDQ_CHANNEL_DETECT, detect_cmdq_channel},
- {SDK_CMD_SET_FREQ_REDUCE_RATIO, set_frequency_reduction_ratio},
- {SDK_CMD_SET_TIME_DIFF_ENABLE, set_time_diff_enable},
- {SDK_CMD_GET_TIME_DIFF, get_time_diff},
- {SDK_CMD_ATTACK_TEST, hinic5_sdk_attack_handler},
+ { SDK_CMD_CMDQ_CHANNEL_DETECT, detect_cmdq_channel },
+ { SDK_CMD_SET_FREQ_REDUCE_RATIO, set_frequency_reduction_ratio },
+ { SDK_CMD_SET_TIME_DIFF_ENABLE, set_time_diff_enable },
+ { SDK_CMD_GET_TIME_DIFF, get_time_diff },
+ { SDK_CMD_ATTACK_TEST, hinic5_sdk_attack_handler },
#endif
};
@@ -592,13 +619,13 @@ static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
{
int ret;
- ret = hinic5_alloc_buff_in(hwdev, nt_msg, in_size, buf_in);
+ ret = alloc_buff_in(hwdev, nt_msg, in_size, buf_in);
if (ret != 0) {
pr_err("Alloc tool cmd buff in failed\n");
return ret;
}
- ret = hinic5_alloc_buff_out(hwdev, nt_msg, out_size, buf_out);
+ ret = alloc_buff_out(hwdev, nt_msg, out_size, buf_out);
if (ret != 0) {
pr_err("Alloc tool cmd buff out failed\n");
goto out_free_buf_in;
@@ -607,44 +634,50 @@ static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
return 0;
out_free_buf_in:
- hinic5_free_buff_in(hwdev, nt_msg, *buf_in);
+ free_buff_in(hwdev, nt_msg, *buf_in);
return ret;
}
-static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, void *buf_out)
+static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg, void *buf_in,
+ void *buf_out)
{
- hinic5_free_buff_out(hwdev, nt_msg, buf_out);
- hinic5_free_buff_in(hwdev, nt_msg, buf_in);
+ free_buff_out(hwdev, nt_msg, buf_out);
+ free_buff_in(hwdev, nt_msg, buf_in);
}
-__weak int hinic5_nictool_cmd_extend_handle(void *lld_dev, u32 cmd,
- struct hinic5_mt_msg *mt_msg, bool *support)
+__attribute__((weak)) int
+hinic5_nictool_cmd_extend_handle(void *lld_dev, u32 cmd,
+ struct hinic5_mt_msg *mt_msg, bool *support)
{
*support = false;
return 0;
}
-static int send_to_hw_driver(struct hinic5_lld_dev *lld_dev, struct msg_module *nt_msg,
- const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+static int send_to_hw_driver(struct hinic5_lld_dev *lld_dev,
+ struct msg_module *nt_msg, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = (int)(sizeof(hinic5_hw_driv_module_cmd_handle) /
- sizeof(hinic5_hw_driv_module_cmd_handle[0]));
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
- (enum driver_cmd_type)(nt_msg->msg_formate);
+ (enum driver_cmd_type)(nt_msg->msg_formate);
struct hinic5_mt_msg mt_msg;
bool support = false;
int err = 0;
for (index = 0; index < num_cmds; index++) {
- if (cmd_type != hinic5_hw_driv_module_cmd_handle[index].driv_cmd_name)
+ if (cmd_type !=
+ hw_driv_module_cmd_handle[index].driv_cmd_name) {
continue;
- err = hinic5_hw_driv_module_cmd_handle[index].driv_func
- (lld_dev, buf_in, in_size, buf_out, out_size);
- if (err != 0)
- pr_err("Hw driver cmd %u process failed, err %d\n", cmd_type, err);
+ }
+ err = hw_driv_module_cmd_handle[index].driv_func(
+ lld_dev, buf_in, in_size, buf_out, out_size);
+ if (err != 0) {
+ pr_err("Hw driver cmd %u process failed, err %d\n",
+ cmd_type, err);
+ }
return err;
}
@@ -652,21 +685,24 @@ static int send_to_hw_driver(struct hinic5_lld_dev *lld_dev, struct msg_module *
mt_msg.buf_out = buf_out;
mt_msg.in_size = in_size;
mt_msg.out_size = *out_size;
- err = hinic5_nictool_cmd_extend_handle((void *)lld_dev, (u32)cmd_type, &mt_msg, &support);
+ err = hinic5_nictool_cmd_extend_handle((void *)lld_dev, (u32)cmd_type,
+ &mt_msg, &support);
if (!support) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
}
- if (err != 0)
+ if (err != 0) {
pr_err("extend cmd %d process failed, err:%d\n", cmd_type, err);
+ }
*out_size = mt_msg.out_size;
return err;
}
-static int send_to_service_driver(struct hinic5_lld_dev *lld_dev, struct msg_module *nt_msg,
- const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+static int send_to_service_driver(struct hinic5_lld_dev *lld_dev,
+ struct msg_module *nt_msg, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
const struct hinic5_uld_info *uld_info = NULL;
const char **service_name = NULL;
@@ -677,54 +713,59 @@ static int send_to_service_driver(struct hinic5_lld_dev *lld_dev, struct msg_mod
service_name = hinic5_get_uld_names();
type = nt_msg->module - SEND_TO_SRV_DRV_BASE;
if (type >= SERVICE_T_MAX) {
- pr_err("Ioctl input module id: %u is incorrectly\n", nt_msg->module);
+ pr_err("Ioctl input module id: %u is incorrectly\n",
+ nt_msg->module);
return -EINVAL;
}
uld_dev = hinic5_get_uld_dev(lld_dev, type);
- if (!uld_dev) {
- if (nt_msg->msg_formate == GET_DRV_VERSION)
- return 0;
-
+ if (!uld_dev && nt_msg->msg_formate != GET_DRV_VERSION) {
pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
service_name[type]);
return -EINVAL;
}
uld_info = hinic5_get_uld_info_by_type(type);
- if (!uld_info || !uld_info->ioctl)
+ if (!uld_info || !uld_info->ioctl) {
+ if (nt_msg->msg_formate == GET_DRV_VERSION) {
+ return 0;
+ }
return -EFAULT;
+ }
- ret = uld_info->ioctl(uld_dev, nt_msg->msg_formate,
- buf_in, in_size, buf_out, out_size);
- hinic5_uld_dev_put(lld_dev, type);
+ ret = uld_info->ioctl(uld_dev, nt_msg->msg_formate, buf_in, in_size,
+ buf_out, out_size);
+ uld5_dev_put(lld_dev, type);
return ret;
}
-static int nictool_exec_cmd(struct hinic5_lld_dev *lld_dev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
+static int nictool_exec_cmd(struct hinic5_lld_dev *lld_dev,
+ struct msg_module *nt_msg, void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
int ret = 0;
switch (nt_msg->module) {
case SEND_TO_HW_DRIVER:
- ret = send_to_hw_driver(lld_dev, nt_msg, buf_in, in_size, buf_out, out_size);
+ ret = send_to_hw_driver(lld_dev, nt_msg, buf_in, in_size,
+ buf_out, out_size);
break;
case SEND_TO_MPU:
- ret = hinic5_send_to_mpu(hinic5_get_sdk_hwdev_by_lld(lld_dev),
- nt_msg, buf_in, in_size, buf_out, out_size);
+ ret = send_to_mpu(hinic5_get_sdk_hwdev_by_lld(lld_dev), nt_msg,
+ buf_in, in_size, buf_out, out_size);
break;
case SEND_TO_SM:
- ret = hinic5_send_to_sm(hinic5_get_sdk_hwdev_by_lld(lld_dev),
- nt_msg, buf_in, in_size, buf_out, out_size);
+ ret = send_to_sm(hinic5_get_sdk_hwdev_by_lld(lld_dev), nt_msg,
+ buf_in, in_size, buf_out, out_size);
break;
case SEND_TO_NPU:
- ret = hinic5_send_to_npu(hinic5_get_sdk_hwdev_by_lld(lld_dev),
- nt_msg, buf_in, in_size, buf_out, out_size);
+ ret = send_to_npu(hinic5_get_sdk_hwdev_by_lld(lld_dev), nt_msg,
+ buf_in, in_size, buf_out, out_size);
break;
default:
- ret = send_to_service_driver(lld_dev, nt_msg, buf_in, in_size, buf_out, out_size);
+ ret = send_to_service_driver(lld_dev, nt_msg, buf_in, in_size,
+ buf_out, out_size);
break;
}
@@ -734,7 +775,8 @@ static int nictool_exec_cmd(struct hinic5_lld_dev *lld_dev, struct msg_module *n
static int cmd_parameter_valid(struct msg_module *nt_msg, ulong arg,
u32 *out_size_expect, u32 *in_size)
{
- if (copy_from_user(nt_msg, (void *)(uintptr_t)arg, sizeof(*nt_msg)) != 0) {
+ if (copy_from_user(nt_msg, (void *)(uintptr_t)arg, sizeof(*nt_msg)) !=
+ 0) {
pr_err("Copy information from user failed\n");
return -EFAULT;
}
@@ -743,8 +785,8 @@ static int cmd_parameter_valid(struct msg_module *nt_msg, ulong arg,
*in_size = nt_msg->buf_in_size;
if (*out_size_expect > HINIC5_MAX_BUF_SIZE ||
*in_size > HINIC5_MAX_BUF_SIZE) {
- pr_err("Invalid in size: %u or out size: %u\n",
- *in_size, *out_size_expect);
+ pr_err("Invalid in size: %u or out size: %u\n", *in_size,
+ *out_size_expect);
return -EFAULT;
}
@@ -755,7 +797,8 @@ static int cmd_parameter_valid(struct msg_module *nt_msg, ulong arg,
static inline bool is_send_to_srv_drv(uint32_t module)
{
- return ((module >= SEND_TO_SRV_DRV_BASE) && (module < SEND_TO_DRIVER_MAX));
+ return ((module >= SEND_TO_SRV_DRV_BASE) &&
+ (module < SEND_TO_DRIVER_MAX));
}
#define ROCE_DRV_SCC_CMD_MIN (SERVICE_DRV_BASE_CMD + 1)
@@ -774,64 +817,76 @@ struct hinic5_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
cmd = nt_msg->mpu_cmd.cmd;
if (api_type == API_TYPE_MBOX && mod == HINIC5_MOD_COMM &&
- (cmd == COMM_MGMT_CMD_UPDATE_FW || cmd == COMM_MGMT_CMD_ACTIVE_FW ||
+ (cmd == COMM_MGMT_CMD_UPDATE_FW ||
+ cmd == COMM_MGMT_CMD_ACTIVE_FW ||
cmd == COMM_MGMT_CMD_HOT_ACTIVE_FW)) {
- lld_dev = hinic5_get_lld_dev_with_l3i_enabled(nt_msg->device_name);
- if (lld_dev)
+ lld_dev = hinic5_get_lld_dev_with_l3i_enabled(
+ nt_msg->device_name);
+ if (lld_dev != NULL)
return lld_dev;
}
}
if (nt_msg->module == SEND_TO_NIC_DRIVER &&
- (nt_msg->msg_formate == GET_XSFP_INFO || nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
- return hinic5_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ return hinic5_get_lld_dev_by_chip_and_port(nt_msg->device_name,
+ nt_msg->port_id);
}
if (nt_msg->module == SEND_TO_HIHTR_DRIVER &&
(nt_msg->msg_formate == ROCE_CMD_SET_BYPASS ||
- nt_msg->msg_formate == ROCE_CMD_QUERY_BYPASS)) {
+ nt_msg->msg_formate == ROCE_CMD_QUERY_BYPASS)) {
return hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
}
if (nt_msg->module == SEND_TO_HIHTR_DRIVER &&
(nt_msg->msg_formate >= ROCE_DRV_SCC_CMD_MIN &&
- nt_msg->msg_formate <= ROCE_DRV_SCC_CMD_MAX)) {
+ nt_msg->msg_formate <= ROCE_DRV_SCC_CMD_MAX)) {
return hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
}
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER)
+ if (nt_msg->module == SEND_TO_CUSTOM_DRIVER) {
return hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
+ }
if (nt_msg->module == SEND_TO_BIFUR_DRIVER) {
lld_dev = hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev =
- hinic5_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_NIC);
+ lld_dev = hinic5_get_lld_dev_by_dev_name(
+ nt_msg->device_name, SERVICE_T_NIC);
return lld_dev;
}
if (nt_msg->module == SEND_TO_IPSEC_DRIVER &&
(nt_msg->msg_formate == HISEC_DRIVER_CMD_GET_TRNG ||
- nt_msg->msg_formate == HISEC_DRIVER_CMD_GET_IPSEC_INFO)) {
+ nt_msg->msg_formate == HISEC_DRIVER_CMD_GET_IPSEC_INFO)) {
return hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
}
- if (is_send_to_srv_drv(nt_msg->module) && nt_msg->msg_formate != GET_DRV_VERSION) {
- lld_dev = hinic5_get_lld_dev_by_dev_name(nt_msg->device_name,
- nt_msg->module - SEND_TO_SRV_DRV_BASE);
+ if (is_send_to_srv_drv(nt_msg->module) &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
+ lld_dev = hinic5_get_lld_dev_by_dev_name(
+ nt_msg->device_name,
+ nt_msg->module - SEND_TO_SRV_DRV_BASE);
if (!lld_dev)
- lld_dev = hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
+ lld_dev = hinic5_get_lld_dev_by_chip_name(
+ nt_msg->device_name);
return lld_dev;
}
- /* Support sdk sending dfx commands by specifying function id */
- if (nt_msg->module == SEND_TO_HW_DRIVER && nt_msg->use_func_idx == 1)
- return hinic5_get_lld_dev_by_func_id(nt_msg->device_name, nt_msg->func_idx);
+ /* 支持sdk 以指定function id的方式下发dfx 命令 */
+ if ((nt_msg->module == SEND_TO_HW_DRIVER) &&
+ (nt_msg->use_func_idx == 1)) {
+ return hinic5_get_lld_dev_by_func_id(nt_msg->device_name,
+ nt_msg->func_idx);
+ }
lld_dev = hinic5_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic5_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
+ lld_dev = hinic5_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
return lld_dev;
}
@@ -847,7 +902,7 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, ulong arg)
u32 in_size = 0;
int ret = 0;
- memset(&nt_msg, 0, sizeof(nt_msg));
+ (void)memset_s(&nt_msg, sizeof(nt_msg), 0, sizeof(nt_msg));
if (cmd_parameter_valid(&nt_msg, arg, &out_size_expect, &in_size) != 0)
return -EFAULT;
@@ -874,9 +929,11 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, ulong arg)
out_size = out_size_expect;
- ret = nictool_exec_cmd(lld_dev, &nt_msg, buf_in, in_size, buf_out, &out_size);
+ ret = nictool_exec_cmd(lld_dev, &nt_msg, buf_in, in_size, buf_out,
+ &out_size);
if (ret != 0) {
- pr_err("nictool_exec_cmd failed, module: %u, ret: %d.\n", nt_msg.module, ret);
+ pr_err("nictool_exec_cmd failed, module: %u, ret: %d.\n",
+ nt_msg.module, ret);
goto out_free_buf;
}
@@ -887,12 +944,13 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, ulong arg)
goto out_free_buf;
}
- ret = hinic5_copy_buf_out_to_user(&nt_msg, out_size, buf_out);
+ ret = copy_buf_out_to_user(&nt_msg, out_size, buf_out);
if (ret != 0)
pr_err("Copy information to user failed\n");
out_free_buf:
- free_tmp_buf(hinic5_get_sdk_hwdev_by_lld(lld_dev), &nt_msg, buf_in, buf_out);
+ free_tmp_buf(hinic5_get_sdk_hwdev_by_lld(lld_dev), &nt_msg, buf_in,
+ buf_out);
out_free_lock:
hinic5_lld_dev_put(lld_dev);
@@ -920,8 +978,8 @@ static int dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
return 0;
}
-static long dbgtool_k_unlocked_ioctl(struct file *pfile,
- unsigned int real_cmd, ulong arg)
+static long dbgtool_k_unlocked_ioctl(struct file *pfile, unsigned int real_cmd,
+ ulong arg)
{
int ret;
struct dbgtool_param param;
@@ -929,16 +987,17 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
struct card_node *card_info = NULL;
int i;
- memset(¶m, 0, sizeof(param));
+ (void)memset_s(¶m, sizeof(param), 0, sizeof(param));
- if (copy_from_user(¶m, (void *)(uintptr_t)arg, sizeof(param)) != 0) {
+ if (copy_from_user(¶m, (void *)(uintptr_t)arg, sizeof(param)) !=
+ 0) {
pr_err("Copy param from user fail\n");
return -EFAULT;
}
- hinic5_lld_hold();
+ lld_hold();
for (i = 0; i < MAX_CARD_NUM; i++) {
- card_info = (struct card_node *)hinic5_g_card_node_array[i];
+ card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
if (memcmp(param.chip_name, card_info->chip_name,
@@ -947,12 +1006,12 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
}
if (i == MAX_CARD_NUM || !card_info) {
- hinic5_lld_put();
+ lld_put();
pr_err("Can't find this card %s\n", param.chip_name);
return -EFAULT;
}
- hinic5_card_id = i;
+ card_id = i;
dbgtool_info = (struct dbgtool_k_glb_info *)card_info->dbgtool_info;
down(&dbgtool_info->dbgtool_sem);
@@ -965,6 +1024,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
+
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
@@ -972,7 +1032,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
up(&dbgtool_info->dbgtool_sem);
- hinic5_lld_put();
+ lld_put();
return (long)ret;
}
@@ -999,16 +1059,16 @@ static ssize_t nictool_k_write(struct file *pfile, const char __user *ubuf,
return 0;
}
-static long nictool_k_unlocked_ioctl(struct file *pfile,
- unsigned int cmd, unsigned long arg)
+static long nictool_k_unlocked_ioctl(struct file *pfile, unsigned int cmd,
+ unsigned long arg)
{
unsigned int real_cmd;
real_cmd = _IOC_NR(cmd);
return (real_cmd == NICTOOL_CMD_TYPE) ?
- hinicadm_k_unlocked_ioctl(pfile, arg) :
- dbgtool_k_unlocked_ioctl(pfile, real_cmd, arg);
+ hinicadm_k_unlocked_ioctl(pfile, arg) :
+ dbgtool_k_unlocked_ioctl(pfile, real_cmd, arg);
}
static int hinic5_bar_mmap_param_valid(phys_addr_t phy_addr, u64 vmsize)
@@ -1017,7 +1077,7 @@ static int hinic5_bar_mmap_param_valid(phys_addr_t phy_addr, u64 vmsize)
struct card_node *chip_node = NULL;
struct hinic5_adev *adev = NULL;
- hinic5_lld_hold();
+ lld_hold();
/* get PF bar1 or bar3 physical address to verify */
list_for_each_entry(chip_node, chip_list, node) {
@@ -1026,16 +1086,18 @@ static int hinic5_bar_mmap_param_valid(phys_addr_t phy_addr, u64 vmsize)
continue;
if (((phy_addr >= adev->cfg_base_phy) &&
- (phy_addr + vmsize <= (adev->cfg_base_phy + adev->cfg_base_len))) ||
+ (phy_addr + vmsize <=
+ (adev->cfg_base_phy + adev->cfg_base_len))) ||
((phy_addr >= adev->mgmt_base_phy) &&
- (phy_addr + vmsize <= (adev->mgmt_base_phy + adev->mgmt_base_len)))) {
- hinic5_lld_put();
+ (phy_addr + vmsize <=
+ (adev->mgmt_base_phy + adev->mgmt_base_len)))) {
+ lld_put();
return 0;
}
}
}
- hinic5_lld_put();
+ lld_put();
return -EINVAL;
}
@@ -1052,10 +1114,10 @@ static int hinic5_mem_mmap(struct file *filp, struct vm_area_struct *vma)
}
/* old version of tool set vma->vm_pgoff to 0 */
- phy_addr = (offset != 0) ? offset : hinic5_g_card_phy_addr[hinic5_card_id];
+ phy_addr = (offset != 0) ? offset : g_card_phy_addr[card_id];
/* check phy_addr valid */
- if (phy_addr != hinic5_g_card_phy_addr[hinic5_card_id]) {
+ if (phy_addr != g_card_phy_addr[card_id]) {
err = hinic5_bar_mmap_param_valid(phy_addr, vmsize);
if (err != 0) {
pr_err("mmap param invalid, err: %d\n", err);
@@ -1091,7 +1153,8 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
u32 id;
if (hinic5_func_type(hwdev) != TYPE_VF)
- chip_info->func_handle_array[hinic5_global_func_id(hwdev)] = NULL;
+ chip_info->func_handle_array[hinic5_global_func_id(hwdev)] =
+ NULL;
if (chip_info->func_num == 0) {
pr_err("dbgtool already free.\n");
@@ -1102,12 +1165,12 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (chip_info->func_num > 0)
return;
- err = sscanf(chip_info->chip_name, HINIC5_CHIP_NAME "%u", &id);
- if (err != 1)
+ err = sscanf_s(chip_info->chip_name, HINIC5_CHIP_NAME "%u", &id);
+ if (err <= 0)
pr_err("Failed to get card id\n");
if (id < MAX_CARD_NUM)
- hinic5_g_card_node_array[id] = NULL;
+ g_card_node_array[id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
@@ -1127,18 +1190,18 @@ static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
int err, id = 0;
if (hinic5_func_type(hwdev) != TYPE_VF)
- chip_info->func_handle_array[hinic5_global_func_id(hwdev)] = hwdev;
+ chip_info->func_handle_array[hinic5_global_func_id(hwdev)] =
+ hwdev;
- // Only the first function applies for dbgtool_info,
- // subsequent functions only need to increment reference count, no memory allocation needed
+ // 仅首个function申请dbgtool_info,后续function主需要引用计数++,无需申请内存
if (chip_info->func_num != 0) {
chip_info->func_num++;
return 0;
}
chip_info->func_num++;
- dbgtool_info = (struct dbgtool_k_glb_info *)
- kzalloc(sizeof(struct dbgtool_k_glb_info), GFP_KERNEL);
+ dbgtool_info = (struct dbgtool_k_glb_info *)kzalloc(
+ sizeof(struct dbgtool_k_glb_info), GFP_KERNEL);
if (!dbgtool_info) {
pr_err("Failed to allocate dbgtool_info\n");
goto dbgtool_info_fail;
@@ -1147,8 +1210,8 @@ static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
chip_info->dbgtool_info = dbgtool_info;
/* FFM init */
- dbgtool_info->ffm = (struct ffm_record_info *)
- kzalloc(sizeof(struct ffm_record_info), GFP_KERNEL);
+ dbgtool_info->ffm = (struct ffm_record_info *)kzalloc(
+ sizeof(struct ffm_record_info), GFP_KERNEL);
if (!dbgtool_info->ffm) {
pr_err("Failed to allocate cell contexts for a chain\n");
goto dbgtool_info_ffm_fail;
@@ -1162,7 +1225,12 @@ static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
goto sscanf_chdev_fail;
}
- hinic5_g_card_node_array[id] = chip_info;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id %d, max %d\n", id, MAX_CARD_NUM);
+ goto sscanf_chdev_fail;
+ }
+
+ g_card_node_array[id] = chip_info;
return 0;
@@ -1175,16 +1243,17 @@ static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
dbgtool_info_fail:
if (hinic5_func_type(hwdev) != TYPE_VF)
- chip_info->func_handle_array[hinic5_global_func_id(hwdev)] = NULL;
+ chip_info->func_handle_array[hinic5_global_func_id(hwdev)] =
+ NULL;
chip_info->func_num--;
return -ENOMEM;
}
/**
- * hinic5_nictool_k_init - initialize the hw interface
+ * nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-int hinic5_nictool_k_init(void *hwdev, void *chip_node)
+int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
struct device *pdevice = NULL;
@@ -1194,7 +1263,7 @@ int hinic5_nictool_k_init(void *hwdev, void *chip_node)
if (err != 0)
return err;
- // Only the first function initializes and creates the character device, subsequent functions only need to increment reference count
+ // 仅首个function初始化创建字符设备,后续仅需引用计数+1
if (g_nictool_ref_cnt != 0) {
/* already initialized */
g_nictool_ref_cnt++;
@@ -1229,8 +1298,8 @@ int hinic5_nictool_k_init(void *hwdev, void *chip_node)
/* Export device information to user space
* (/sys/class/class name/device name)
*/
- pdevice = device_create(g_nictool_class, NULL,
- g_dev_id, NULL, HIADM3_DEV_NAME);
+ pdevice = device_create(g_nictool_class, NULL, g_dev_id, NULL,
+ HIADM3_DEV_NAME);
if (IS_ERR(pdevice)) {
pr_err("Export nictool device information to user space fail\n");
err = -EFAULT;
@@ -1258,7 +1327,7 @@ int hinic5_nictool_k_init(void *hwdev, void *chip_node)
return err;
}
-void hinic5_nictool_k_uninit(void *hwdev, void *chip_node)
+void nictool_k_uninit(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -1287,4 +1356,3 @@ void hinic5_nictool_k_uninit(void *hwdev, void *chip_node)
pr_info("Unregister nictool_dev succeed\n");
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.h
index 89d5a0de2..6f772cdbe 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_nictool.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nictool.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NICTOOL_H
#define HINIC5_NICTOOL_H
@@ -28,8 +21,8 @@
#define MAX_CARD_NUM (64)
-int hinic5_nictool_k_init(void *hwdev, void *chip_node);
-void hinic5_nictool_k_uninit(void *hwdev, void *chip_node);
+int nictool_k_init(void *hwdev, void *chip_node);
+void nictool_k_uninit(void *hwdev, void *chip_node);
void hinic5_get_all_chip_id(void *id_info);
@@ -37,10 +30,9 @@ void hinic5_get_card_info(const void *hwdev, const void *bufin, void *bufout);
bool hinic5_is_in_host(void);
-int hinic5_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+int hinic5_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id,
+ u32 *isvalid);
void hinic5_get_mbox_cnt(const void *hwdev, void *buf_out);
-extern struct hinic5_uld_info hinic5_g_uld_info[SERVICE_T_MAX];
-
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.c
index 4f58cf723..6eae97da8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.c
@@ -1,12 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_non_ptp.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
@@ -15,7 +7,7 @@
#include "hinic5_lld.h"
#include "hinic5_dev_mgmt.h"
#include "hinic5_chip_info.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_nictool.h"
#include "hinic5_non_ptp.h"
@@ -27,8 +19,7 @@
#define HINIC5_NON_PTP_CDEV "hinic5_non_ptp_cdev"
#define HINIC5_NON_PTP_CLASS "hinic5_non_ptp_class"
/* for calculate time diff of kernel and chip, influenced by EMU/FPGA/ASIC/EDA,
- * default at ASIC condition is 1, can be modified with dfx tools
- */
+ * default at ASIC condition is 1, can be modified with dfx tools */
unsigned int g_freq_reduce_ratio = 1;
/* for multiple hosts, cdev is created on different hosts */
/* for multiple chips, cdev is reffered by different chips */
@@ -47,28 +38,31 @@ static int hinic5_non_ptp_mmap(struct file *filp, struct vm_area_struct *vma)
if (offset + size > NON_PTP_BUF_SIZE)
return -EINVAL;
- if (!g_non_ptp_info)
+ if (!g_non_ptp_info) {
return -EFAULT;
- /* Map the base address of no_ptp_info, offset 0 corresponds to chip_id 0 */
+ }
+ /* 将no_ptp_info的基址进行映射, offset 0对应chip_id 0 */
pfn = virt_to_phys(g_non_ptp_info) >> PAGE_SHIFT;
- // Force read-only
+ // 强制只读
vm_flags_clear(vma, VM_WRITE);
- // Set nocache
+ // 设置nocache
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- return remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot);
+ return remap_pfn_range(vma, vma->vm_start, pfn, size,
+ vma->vm_page_prot);
}
-static const struct file_operations fops = {
+static struct file_operations fops = {
.mmap = hinic5_non_ptp_mmap,
};
static int hinic5_non_ptp_mem_alloc(struct hinic5_hwdev *hwdev)
{
- /* On first load, initialize cdev memory and ptp info memory */
- if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0)
+ /* 第一次加载时, 初始cdev内存和ptp info内存 */
+ if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0) {
return 0;
+ }
g_non_ptp_cdev =
kzalloc(sizeof(struct hinic5_non_ptp_cdev), GFP_KERNEL);
@@ -78,8 +72,8 @@ static int hinic5_non_ptp_mem_alloc(struct hinic5_hwdev *hwdev)
}
g_non_ptp_info =
- (struct hinic5_non_ptp_info *)
- (uintptr_t)__get_free_pages(GFP_KERNEL, NON_PTP_BUF_PAGE_ORDER);
+ (struct hinic5_non_ptp_info *)(uintptr_t)__get_free_pages(
+ GFP_KERNEL, NON_PTP_BUF_PAGE_ORDER);
if (!g_non_ptp_info) {
sdk_err(hwdev->dev_hdl, "non_ptp_info mem alloc fail.\n");
kfree(g_non_ptp_cdev);
@@ -91,30 +85,40 @@ static int hinic5_non_ptp_mem_alloc(struct hinic5_hwdev *hwdev)
static void hinic5_non_ptp_mem_free(void)
{
- if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0)
+ if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0) {
return;
+ }
- /* When no references, free non ptp info page and cdev memory */
- if (g_non_ptp_info) {
- free_pages((ulong)(uintptr_t)g_non_ptp_info, NON_PTP_BUF_PAGE_ORDER);
+ /* 无引用时, 释放non ptp info page和cdev内存 */
+ if (g_non_ptp_info != NULL) {
+ free_pages((ulong)(uintptr_t)g_non_ptp_info,
+ NON_PTP_BUF_PAGE_ORDER);
g_non_ptp_info = NULL;
}
- if (g_non_ptp_cdev) {
+ if (g_non_ptp_cdev != NULL) {
kfree(g_non_ptp_cdev);
g_non_ptp_cdev = NULL;
}
+ return;
}
static int hinic5_non_ptp_info_init(struct hinic5_hwdev *hwdev, u32 chip_id)
{
+ int err;
struct card_node *chip_node = (struct card_node *)hwdev->chip_node;
- /* Initialize non_ptp_info for current chip */
- if (!chip_node->non_ptp_info) {
+ /* 初始化当前chip对应的 non_ptp_info */
+ if (chip_node->non_ptp_info == NULL) {
chip_node->non_ptp_info = g_non_ptp_info + chip_id;
- memcpy(chip_node->non_ptp_info->name,
- chip_node->chip_name, IFNAMSIZ);
+ err = memcpy_s(chip_node->non_ptp_info->name, IFNAMSIZ,
+ chip_node->chip_name, IFNAMSIZ);
+ if (err != 0) {
+ chip_node->non_ptp_info = NULL;
+ sdk_err(hwdev->dev_hdl,
+ "Current chip non ptp info init fail.\n");
+ return err;
+ }
atomic_set(&chip_node->non_ptp_info->ref_cnt, 0);
}
@@ -125,18 +129,23 @@ static int hinic5_non_ptp_info_init(struct hinic5_hwdev *hwdev, u32 chip_id)
static void hinic5_non_ptp_info_deinit(struct card_node *chip_node)
{
- /* Initialize non_ptp_info for current chip */
- if (!chip_node->non_ptp_info)
+ /* 初始化当前chip对应的 non_ptp_info */
+ if (chip_node->non_ptp_info == NULL) {
return;
+ }
- if (atomic_read(&chip_node->non_ptp_info->ref_cnt) == 0)
+ if (atomic_read(&chip_node->non_ptp_info->ref_cnt) == 0) {
return;
+ }
- /* After ref_cnt decrements by 1, if not 0, interface returns false, early return */
- if (!atomic_sub_and_test(1, &chip_node->non_ptp_info->ref_cnt))
+ /* ref_cnt 减1后不为0, 接口返回false, 提前return */
+ if (!atomic_sub_and_test(1, &chip_node->non_ptp_info->ref_cnt)) {
return;
+ }
- memset(chip_node->non_ptp_info, 0, sizeof(struct hinic5_non_ptp_info));
+ (void)memset_s(chip_node->non_ptp_info,
+ sizeof(struct hinic5_non_ptp_info), 0,
+ sizeof(struct hinic5_non_ptp_info));
chip_node->non_ptp_info = NULL;
}
@@ -144,16 +153,18 @@ static int hinic5_non_ptp_para_check(struct hinic5_hwdev *hwdev, u32 *chip_id)
{
struct card_node *chip_node = NULL;
int err;
- if ((!hwdev) || (!HINIC5_IS_PPF(hwdev)))
+ if ((!hwdev) || (!HINIC5_IS_PPF(hwdev))) {
return -EINVAL;
+ }
chip_node = (struct card_node *)hwdev->chip_node;
- if (!chip_node)
+ if (!chip_node) {
return -EINVAL;
+ }
- /* Get chip number for indexing non ptp information */
- err = sscanf(chip_node->chip_name, HINIC5_CHIP_NAME "%u", chip_id);
- if (err != 1) {
+ /* 获取芯片号,用于索引non ptp信息 */
+ err = sscanf_s(chip_node->chip_name, HINIC5_CHIP_NAME "%u", chip_id);
+ if (err <= 0) {
sdk_err(hwdev->dev_hdl, "Failed to get card id err %d.\n", err);
return -EINVAL;
}
@@ -175,13 +186,14 @@ static int hinic5_non_ptp_ctrl_init(struct hinic5_hwdev *hwdev)
HINIC5_NON_PTP_CDEV_MAX_DEVICES,
HINIC5_NON_PTP_CDEV);
if (err != 0) {
- sdk_err(hwdev->dev_hdl, "Alloc non ptp cdev region failed %d.\n",
- err);
+ sdk_err(hwdev->dev_hdl,
+ "Alloc non ptp cdev region failed %d.\n", err);
return err;
}
/* Create equipment */
- g_non_ptp_cdev->cdev_class = class_create(THIS_MODULE, HINIC5_NON_PTP_CLASS);
+ g_non_ptp_cdev->cdev_class =
+ class_create(THIS_MODULE, HINIC5_NON_PTP_CLASS);
if (IS_ERR(g_non_ptp_cdev->cdev_class)) {
sdk_err(hwdev->dev_hdl, "Create non ptp class fail %ld.\n",
PTR_ERR(g_non_ptp_cdev->cdev_class));
@@ -189,11 +201,11 @@ static int hinic5_non_ptp_ctrl_init(struct hinic5_hwdev *hwdev)
goto class_create_err;
}
- // Initialize cdev structure
+ // 初始化cdev结构
cdev_init(&g_non_ptp_cdev->dev, &fops);
g_non_ptp_cdev->dev.owner = THIS_MODULE;
- // Add cdev to system
+ // 添加cdev到系统
err = cdev_add(&g_non_ptp_cdev->dev, g_non_ptp_cdev->devid,
HINIC5_NON_PTP_CDEV_MAX_DEVICES);
if (err < 0) {
@@ -202,9 +214,9 @@ static int hinic5_non_ptp_ctrl_init(struct hinic5_hwdev *hwdev)
goto cdev_add_err;
}
- g_non_ptp_cdev->cdev_device = device_create(g_non_ptp_cdev->cdev_class, NULL,
- g_non_ptp_cdev->devid, NULL,
- HINIC5_NON_PTP_CDEV);
+ g_non_ptp_cdev->cdev_device = device_create(g_non_ptp_cdev->cdev_class,
+ NULL, g_non_ptp_cdev->devid,
+ NULL, HINIC5_NON_PTP_CDEV);
if (IS_ERR(g_non_ptp_cdev->cdev_device)) {
sdk_err(hwdev->dev_hdl,
"Export non ptp cdev information to user space fail\n");
@@ -226,11 +238,13 @@ static int hinic5_non_ptp_ctrl_init(struct hinic5_hwdev *hwdev)
static void hinic5_non_ptp_ctrl_deinit(void)
{
- if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0)
+ if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0) {
return;
+ }
- if (!g_non_ptp_cdev)
+ if (!g_non_ptp_cdev) {
return;
+ }
device_destroy(g_non_ptp_cdev->cdev_class, g_non_ptp_cdev->devid);
cdev_del(&g_non_ptp_cdev->dev);
class_destroy(g_non_ptp_cdev->cdev_class);
@@ -238,40 +252,45 @@ static void hinic5_non_ptp_ctrl_deinit(void)
HINIC5_NON_PTP_CDEV_MAX_DEVICES);
}
-/* non ptp function initialization main function */
+/* non ptp 功能初始化主函数 */
int hinic5_non_ptp_cdev_init(struct hinic5_hwdev *hwdev)
{
int err;
u32 chip_id;
struct card_node *chip_node = (struct card_node *)hwdev->chip_node;
- sdk_info(hwdev->dev_hdl, "init non ptp start %d.\n", atomic_read(&g_non_ptp_cdev_ref_cnt));
+ sdk_info(hwdev->dev_hdl, "init non ptp start %d.\n",
+ atomic_read(&g_non_ptp_cdev_ref_cnt));
err = hinic5_non_ptp_para_check(hwdev, &chip_id);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
err = hinic5_non_ptp_mem_alloc(hwdev);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
err = hinic5_non_ptp_info_init(hwdev, chip_id);
- if (err != 0)
+ if (err != 0) {
goto info_init_err;
+ }
if (atomic_read(&g_non_ptp_cdev_ref_cnt) > 0) {
atomic_inc(&g_non_ptp_cdev_ref_cnt);
- sdk_info(hwdev->dev_hdl,
- "non ptp cdev exist, cdev refcnt %d, chip refcnt %d.\n",
- atomic_read(&g_non_ptp_cdev_ref_cnt),
- atomic_read(&chip_node->non_ptp_info->ref_cnt));
+ sdk_info(
+ hwdev->dev_hdl,
+ "non ptp cdev exist, cdev refcnt %d, chip refcnt %d.\n",
+ atomic_read(&g_non_ptp_cdev_ref_cnt),
+ atomic_read(&chip_node->non_ptp_info->ref_cnt));
return 0;
}
- /* The following process only involves first initialization */
+ /* 以下流程仅首次初始化涉及 */
atomic_inc(&g_non_ptp_cdev_ref_cnt);
- /* Initialize non ptp cdev class region and device */
+ /* 初始化non ptp cdev的class region 和device */
err = hinic5_non_ptp_ctrl_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Create non ptp sys device fail.\n");
@@ -293,35 +312,37 @@ int hinic5_non_ptp_cdev_init(struct hinic5_hwdev *hwdev)
return err;
}
-/* non ptp function deinitialization main function */
+/* non ptp 功能销毁主函数 */
void hinic5_non_ptp_cdev_deinit(struct hinic5_hwdev *hwdev)
{
struct card_node *chip_node = NULL;
- if (!hwdev || !HINIC5_IS_PPF(hwdev))
+ if ((!hwdev) || (!HINIC5_IS_PPF(hwdev))) {
return;
+ }
chip_node = (struct card_node *)hwdev->chip_node;
- if (!chip_node || !chip_node->non_ptp_info) {
- sdk_info(hwdev->dev_hdl,
- "Exit non ptp deinit, refcnt %d.\n", atomic_read(&g_non_ptp_cdev_ref_cnt));
+ if ((!chip_node) || (!chip_node->non_ptp_info)) {
+ sdk_info(hwdev->dev_hdl, "Exit non ptp deinit, refcnt %d.\n",
+ atomic_read(&g_non_ptp_cdev_ref_cnt));
return;
}
- /* Destroy non ptp info managed by current function's chip */
+ /* 销毁当前function 对应的chip 管理的non ptp info */
hinic5_non_ptp_info_deinit(chip_node);
- /* After ref_cnt decrements by 1, if not 0, interface returns false, early return */
+ /* ref_cnt 减1后不为0, 接口返回false, 提前return */
if (!atomic_sub_and_test(1, &g_non_ptp_cdev_ref_cnt)) {
- sdk_info(hwdev->dev_hdl,
- "Quick deinit non ptp end %d.\n", atomic_read(&g_non_ptp_cdev_ref_cnt));
+ sdk_info(hwdev->dev_hdl, "Quick deinit non ptp end %d.\n",
+ atomic_read(&g_non_ptp_cdev_ref_cnt));
return;
}
- /* Try to destroy non ptp system device, class, region, etc */
+ /* 尝试销毁non ptp系统设备, 类, region等 */
hinic5_non_ptp_ctrl_deinit();
hinic5_non_ptp_mem_free();
- sdk_info(hwdev->dev_hdl, "Deinit non ptp end %d.\n", atomic_read(&g_non_ptp_cdev_ref_cnt));
+ sdk_info(hwdev->dev_hdl, "Deinit non ptp end %d.\n",
+ atomic_read(&g_non_ptp_cdev_ref_cnt));
}
int hinic5_get_non_ptp_chip_time(void *dev, u64 *chip_time)
@@ -329,18 +350,21 @@ int hinic5_get_non_ptp_chip_time(void *dev, u64 *chip_time)
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
int err;
- if (!hwdev || !chip_time)
+ if ((!hwdev) || (!chip_time)) {
return -EINVAL;
+ }
err = hinic5_n_ptp_ts_up_en(hwdev, BIT(1));
if (err != 0) {
- sdk_warn(hwdev->dev_hdl, "Failed to get n_ptp time, err: %d\n", err);
+ sdk_warn(hwdev->dev_hdl, "Failed to get n_ptp time, err: %d\n",
+ err);
return err;
}
err = hinic5_read_n_ptp_ts_data(hwdev, chip_time);
if (err != 0) {
- sdk_warn(hwdev->dev_hdl, "Failed to read n_ptp time, err: %d\n", err);
+ sdk_warn(hwdev->dev_hdl, "Failed to read n_ptp time, err: %d\n",
+ err);
return err;
}
@@ -354,23 +378,28 @@ int hinic5_sync_kernel_time(struct hinic5_hwdev *hwdev)
u64 kernel_time, chip_time;
struct card_node *chip_node = (struct card_node *)(hwdev->chip_node);
- if (!chip_node || !chip_node->non_ptp_info)
+ if ((!chip_node) || (!chip_node->non_ptp_info)) {
return 0;
+ }
if (g_freq_reduce_ratio == 0) {
- sdk_warn(hwdev->dev_hdl, "The frequency scaling ratio must be greater than zero.\n");
+ sdk_warn(
+ hwdev->dev_hdl,
+ "The frequency scaling ratio must be greater than zero.\n");
return -EPERM;
}
err = hinic5_get_non_ptp_chip_time(hwdev, &chip_time);
if (err != 0) {
- sdk_warn(hwdev->dev_hdl, "Failed to read n_ptp time, err: %d\n", err);
+ sdk_warn(hwdev->dev_hdl, "Failed to read n_ptp time, err: %d\n",
+ err);
return err;
}
kernel_time = ktime_get_ns() / g_freq_reduce_ratio;
- chip_node->non_ptp_info->non_ptp_time_diff = (kernel_time > chip_time ?
- (kernel_time - chip_time) : -(chip_time - kernel_time));
+ chip_node->non_ptp_info->non_ptp_time_diff =
+ (kernel_time > chip_time ? (kernel_time - chip_time) :
+ -(chip_time - kernel_time));
return err;
}
@@ -380,11 +409,12 @@ int hinic5_get_non_ptp_time_diff(void *dev, s64 *time_diff)
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
struct card_node *chip_node = NULL;
- if (!hwdev || !time_diff)
+ if ((!hwdev) || (!time_diff)) {
return -EINVAL;
+ }
chip_node = (struct card_node *)(hwdev->chip_node);
- if (!chip_node || !chip_node->non_ptp_info) {
+ if ((!chip_node) || (!chip_node->non_ptp_info)) {
sdk_warn(hwdev->dev_hdl, "chip_node is NULL\n");
return -EINVAL;
}
@@ -403,14 +433,17 @@ int hinic5_set_freq_reduce_ratio(void *dev, u32 ratio)
{
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
- if (!hwdev)
+ if (!hwdev) {
return -EINVAL;
+ }
- if (hinic5_func_type(hwdev) != TYPE_PPF)
+ if (hinic5_func_type(hwdev) != TYPE_PPF) {
return -EPERM;
+ }
- if (ratio == 0)
+ if (ratio == 0) {
return -EINVAL;
+ }
g_freq_reduce_ratio = ratio;
sdk_info(hwdev->dev_hdl, "set freq reduce ratio %d\n", ratio);
@@ -424,24 +457,29 @@ int hinic5_set_non_ptp_time_diff_en(void *dev, bool enable)
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)dev;
struct card_node *chip_node = NULL;
- if (!hwdev)
+ if (!hwdev) {
return -EINVAL;
+ }
- if (hinic5_func_type(hwdev) != TYPE_PPF)
+ if (hinic5_func_type(hwdev) != TYPE_PPF) {
return -EPERM;
+ }
chip_node = (struct card_node *)(hwdev->chip_node);
- if (!chip_node || !chip_node->non_ptp_info)
+ if ((!chip_node) || (!chip_node->non_ptp_info)) {
return -EINVAL;
+ }
- if (enable == chip_node->non_ptp_info->non_ptp_time_diff_enable)
+ if (enable == chip_node->non_ptp_info->non_ptp_time_diff_enable) {
return 0;
+ }
chip_node->non_ptp_info->non_ptp_time_diff_enable = enable;
if (enable) {
- /* When switching from disable to enable, need to queue work */
- queue_delayed_work(hwdev->workq, &hwdev->sync_kernel_time_task,
- msecs_to_jiffies(HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD));
+ /* 从disable切换为enable时, 需要queue work */
+ queue_delayed_work(
+ hwdev->workq, &hwdev->sync_kernel_time_task,
+ msecs_to_jiffies(HINIC5_NON_PTP_SYNC_FW_TIME_PERIOD));
sdk_info(hwdev->dev_hdl, "enable non ptp time diff\n");
} else {
chip_node->non_ptp_info->non_ptp_time_diff = 0;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.h
index ffc43a4a2..fb56b8f5b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_non_ptp.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_non_ptp.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NON_PTP_H
#define HINIC5_NON_PTP_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.c
index 40f96fbef..c3c54ca20 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.c
@@ -1,21 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sdk_attack.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include "ossl_knl.h"
-#include "hinic5_lld.h"
#include "hinic5_dev_mgmt.h"
#include "hinic5_chip_info.h"
-#include "hinic5_hwif_inner.h"
+#include "hisdk5_hwif.h"
#include "hinic5_nictool.h"
#include "hinic5_fast_msg.h"
#include "hinic5_comm_cmd.h"
@@ -23,14 +14,15 @@
#include "fast_msg_common_define.h"
#include "hinic5_sdk_attack.h"
-/* Current macro & structure & enum definition needs to be consistent with tools, see sdk_attack.h */
+/* 当前宏&结构体&枚举类型定义需要与 工具保持一致 见sdk_attack.h */
#define SDK_ATTACK_DW_CNT 512
typedef struct sdk_attack_info {
u32 type;
u32 dw_cnt;
union {
- u32 data[SDK_ATTACK_DW_CNT]; // Default max support attack 2K Bytes
- hisdk5_fast_msg_header attack_fastmsg_header; // fast_msg header type 16Bytes
+ u32 data[SDK_ATTACK_DW_CNT]; // 默认最大支持攻击2K Bytes
+ hisdk5_fast_msg_header
+ attack_fastmsg_header; // fast_msg header 类型 16Bytes
};
} sdk_attack_info_t;
@@ -39,8 +31,9 @@ typedef enum sdk_attack_opcode {
SDK_ATTACK_INVALID_OPCODE = 0xFF
} sdk_attack_opcode_e;
-/* Attack interface, fastmsg en interception removed */
-int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out_param)
+/* 攻击接口, 删除了 fastmsg en的拦截 */
+int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf,
+ u64 *out_param)
{
struct hinic5_hwdev *dev = hwdev;
int err;
@@ -56,13 +49,13 @@ int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out
goto fail;
}
- /* When cmdq number equals 2, fast_msg uses async queue */
+ /* cmdq数量等于2时, fast_msg混用async queue */
if (dev->glb_attr.cmdq_num == fast_msg_qid) {
fast_msg_qid = HINIC5_CMDQ_ASYNC;
}
- err = hinic5_cos_id_detail_resp(hwdev,
- HINIC5_MOD_COMM, COMM_CMD_UCODE_FAST_MSG_CMD,
+ err = hinic5_cos_id_detail_resp(hwdev, HINIC5_MOD_COMM,
+ COMM_CMD_UCODE_FAST_MSG_CMD,
HINIC5_CMDQ_FAST_MSG, cmd_buf, cmd_buf,
out_param, 0, HINIC5_CHANNEL_COMM);
if (!hinic5_is_chip_present(dev)) {
@@ -81,8 +74,9 @@ int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out
return err;
}
-int hinic5_sdk_attack_handler(struct hinic5_lld_dev *lld_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+int hinic5_sdk_attack_handler(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)lld_dev->hwdev;
struct hinic5_cmd_buf *cmd_buf = NULL;
@@ -98,23 +92,26 @@ int hinic5_sdk_attack_handler(struct hinic5_lld_dev *lld_dev, const void *buf_in
sdk_err(hwdev->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
- memset(cmd_buf->buf, 0, cmd_buf->size);
- memcpy(cmd_buf->buf, &attack_info->attack_fastmsg_header,
- attack_len);
- sdk_info(hwdev->dev_hdl, "attack dw cnt %d\n", attack_info->dw_cnt);
- for (; i < attack_info->dw_cnt; i++)
- sdk_info(hwdev->dev_hdl,
- "fastmsg[dw%d]:0x%08x\n", i, ((u32 *)cmd_buf->buf)[i]);
+ memset_s(cmd_buf->buf, cmd_buf->size, 0, cmd_buf->size);
+ memcpy_s(cmd_buf->buf, attack_len,
+ &attack_info->attack_fastmsg_header, attack_len);
+ sdk_info(hwdev->dev_hdl, "attack dw cnt %d\n",
+ attack_info->dw_cnt);
+ for (; i < attack_info->dw_cnt; i++) {
+ sdk_info(hwdev->dev_hdl, "fastmsg[dw%d]:0x%08x\n", i,
+ ((u32 *)cmd_buf->buf)[i]);
+ }
cmd_buf->size = sizeof(hisdk5_fast_msg_header) +
- attack_info->attack_fastmsg_header.data_len;
+ attack_info->attack_fastmsg_header.data_len;
hinic5_cpu_to_be32(cmd_buf->buf, cmd_buf->size);
ret = hinic5_attack_fast_msg(lld_dev->hwdev, cmd_buf, buf_out);
- if (ret != 0)
+ if (ret != 0) {
sdk_info(hwdev->dev_hdl, "fastmsg err ret %d\n", ret);
+ }
hinic5_free_cmd_buf(lld_dev->hwdev, cmd_buf);
break;
default:
break;
}
return ret;
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.h
index d7ef9e277..8ceba3190 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/knldk/mt/hinic5_sdk_attack.h
@@ -1,20 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_sdk_attack.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_SDK_ATTACK_H
#define HINIC5_SDK_ATTACK_H
#include <linux/types.h>
+#include "hinic5_lld.h"
#include "hinic5_hw.h"
-int hinic5_sdk_attack_handler(struct hinic5_lld_dev *lld_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size);
-int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf, u64 *out_param);
+int hinic5_sdk_attack_handler(struct hinic5_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size);
+int hinic5_attack_fast_msg(void *hwdev, struct hinic5_cmd_buf *cmd_buf,
+ u64 *out_param);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/ossl/linux/kernel/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/ossl/linux/kernel/ossl_knl_linux.c
index caef0ac3b..65d1d42c5 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/ossl/linux/kernel/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/sdk/ossl/linux/kernel/ossl_knl_linux.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : ossl_knl_linux.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include <linux/vmalloc.h>
#include "ossl_knl_linux.h"
@@ -26,8 +19,8 @@ unsigned int _work_busy(struct work_struct *work)
#endif
#if (KERNEL_VERSION(3, 4, 0) > LINUX_VERSION_CODE)
-void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
- int off, int size, unsigned int truesize)
+void _kc_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
+ int size, unsigned int truesize)
{
skb_fill_page_desc(skb, i, page, off, size);
skb->len += size;
@@ -144,7 +137,7 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
#endif
#if (KERNEL_VERSION(3, 19, 0) > LINUX_VERSION_CODE)
-#endif /* < 3.19.0 */
+#endif /* < 3.19.0 */
#ifdef NEED_CPUMASK_LOCAL_SPREAD
unsigned int cpumask_local_spread(unsigned int i, int node)
@@ -182,22 +175,22 @@ unsigned int cpumask_local_spread(unsigned int i, int node)
}
#endif
-struct file *hinic5_file_creat(const char *file_name)
+struct file *file_creat(const char *file_name)
{
return filp_open(file_name, O_CREAT | O_RDWR | O_APPEND, 0);
}
-struct file *hinic5_file_open(const char *file_name)
+struct file *file_open(const char *file_name)
{
return filp_open(file_name, O_RDONLY, 0);
}
-void hinic5_file_close(struct file *file_handle)
+void file_close(struct file *file_handle)
{
(void)filp_close(file_handle, NULL);
}
-u32 hinic5_get_file_size(struct file *file_handle)
+u32 get_file_size(struct file *file_handle)
{
struct inode *file_inode = NULL;
@@ -210,12 +203,12 @@ u32 hinic5_get_file_size(struct file *file_handle)
return (u32)(file_inode->i_size);
}
-void hinic5_set_file_position(struct file *file_handle, u32 position)
+void set_file_position(struct file *file_handle, u32 position)
{
file_handle->f_pos = position;
}
-int hinic5_file_read(struct file *file_handle, char *log_buffer, u32 rd_length,
+int file_read(struct file *file_handle, char *log_buffer, u32 rd_length,
u32 *file_pos)
{
if (!file_handle || !log_buffer || rd_length == 0)
@@ -234,14 +227,14 @@ int hinic5_file_read(struct file *file_handle, char *log_buffer, u32 rd_length,
#endif
}
-u32 hinic5_file_write(struct file *file_handle, const char *log_buffer, u32 wr_length)
+u32 file_write(struct file *file_handle, const char *log_buffer, u32 wr_length)
{
if (!file_handle || !log_buffer || wr_length == 0)
return -EINVAL;
#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
- return (u32)file_handle->f_op->write(file_handle, log_buffer,
- wr_length, &file_handle->f_pos);
+ return (u32)file_handle->f_op->write(file_handle, log_buffer, wr_length,
+ &file_handle->f_pos);
#elif (KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE)
return (u32)vfs_write(file_handle,
(__force const char __user *)log_buffer,
@@ -263,23 +256,29 @@ static int _linux_thread_func(void *thread)
return 0;
}
-int hinic5_creat_thread(struct sdk_thread_info *thread_info)
+int creat_thread(struct sdk_thread_info *thread_info)
{
- thread_info->thread_obj = kthread_run(_linux_thread_func, thread_info,
- thread_info->name);
- if (!thread_info->thread_obj)
- return -EFAULT;
+ thread_info->thread_obj =
+ kthread_run(_linux_thread_func, thread_info, thread_info->name);
+ if (IS_ERR(thread_info->thread_obj)) {
+ int err = PTR_ERR(thread_info->thread_obj);
+
+ thread_info->thread_obj = NULL;
+ return err;
+ }
return 0;
}
-void hinic5_stop_thread(struct sdk_thread_info *thread_info)
+void stop_thread(struct sdk_thread_info *thread_info)
{
- if (thread_info->thread_obj)
+ if (thread_info->thread_obj) {
(void)kthread_stop(thread_info->thread_obj);
+ thread_info->thread_obj = NULL;
+ }
}
-void hinic5_utctime_to_localtime(u64 utctime, u64 *localtime)
+void utctime_to_localtime(u64 utctime, u64 *localtime)
{
*localtime = utctime - (u64)(sys_tz.tz_minuteswest * OSSL_MINUTE_BASE);
}
@@ -294,7 +293,7 @@ void initialize_timer(const void *adapter_hdl, struct timer_list *timer)
}
#endif
-void hinic5_add_to_timer(struct timer_list *timer, u64 period)
+void add_to_timer(struct timer_list *timer, u64 period)
{
if (!timer)
return;
@@ -302,9 +301,11 @@ void hinic5_add_to_timer(struct timer_list *timer, u64 period)
add_timer(timer);
}
-void hinic5_stop_timer(struct timer_list *timer) {}
+void stop_timer(struct timer_list *timer)
+{
+}
-void hinic5_delete_timer(struct timer_list *timer)
+void delete_timer(struct timer_list *timer)
{
if (!timer)
return;
@@ -312,19 +313,20 @@ void hinic5_delete_timer(struct timer_list *timer)
del_timer_sync(timer);
}
-u64 hinic5_ossl_get_real_time(void)
+u64 ossl_get_real_time(void)
{
- struct timeval tv = {0};
+ struct timeval tv = { 0 };
u64 tv_msec;
do_gettimeofday(&tv);
- tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
+ tv_msec =
+ (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
#ifdef NEED_MATH64_MUL_U64_U64_DIV_U64
-u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c)
+u64 mul5_u64_u64_div_u64(u64 a, u64 b, u64 c)
{
u64 res = 0, div, rem;
int shift;
@@ -363,17 +365,17 @@ u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c)
return res + div64_u64(a * b, c);
}
-EXPORT_SYMBOL(mul_u64_u64_div_u64);
+EXPORT_SYMBOL(mul5_u64_u64_div_u64);
#endif
-#ifdef NEED_SYSFS_EMIT
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
int sysfs_emit(char *buf, const char *fmt, ...)
{
va_list args;
int len;
- if (WARN(!buf || offset_in_page(buf),
- "invalid %s: buf:%p\n", __func__, buf))
+ if (WARN(!buf || offset_in_page(buf), "invalid sysfs_emit: buf:%p\n",
+ buf))
return 0;
va_start(args, fmt);
@@ -382,4 +384,4 @@ int sysfs_emit(char *buf, const char *fmt, ...)
return len;
}
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_srv_nic.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_srv_nic.h
index 236e2bf03..dad38203c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/include/hinic5_srv_nic.h
@@ -1,12 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_srv_nic.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2022. All rights reserved.
+ ******************************************************************************
+ * @file hinic5_srv_nic.h
+ * @details nic service interface
+ History :
+ 1.Date : 2018/3/8
+ Modification: Created file
+***************************************************************************** */
#ifndef HINIC5_SRV_NIC_H
#define HINIC5_SRV_NIC_H
@@ -19,163 +19,162 @@
#endif
/**
- * @brief struct hinic5_event_link_info Port link event information
- * @details Port link information obtained after link event reporting
+ * @brief struct hinic5_event_link_info 端口link事件信息
+ * @details link事件上报后获取的端口link信息
*/
struct hinic5_event_link_info {
- u8 valid; /**< Whether structure data is valid */
- u8 port_type; /**< Port type */
- u8 autoneg_cap; /**< Auto-negotiation capability */
- u8 autoneg_state; /**< Auto-negotiation state */
- u8 duplex; /**< Duplex mode */
- u8 speed; /**< Port speed */
+ u8 valid; /**< 结构体数据是否有效 */
+ u8 port_type; /**< 端口类型 */
+ u8 autoneg_cap; /**< 自动协商能力 */
+ u8 autoneg_state; /**< 自动协商状态 */
+ u8 duplex; /**< 双工模式 */
+ u8 speed; /**< 端口速率 */
};
enum link_err_type {
- LINK_ERR_MODULE_UNRECOGENIZED, /**< Unrecognized module error type */
+ LINK_ERR_MODULE_UNRECOGENIZED, /**< 未识别的模块错误类型 */
LINK_ERR_NUM,
};
enum port_module_event_type {
- HINIC5_PORT_MODULE_CABLE_PLUGGED, /**< Port cable plugged event */
- HINIC5_PORT_MODULE_CABLE_UNPLUGGED, /**< Port cable unplugged event */
- HINIC5_PORT_MODULE_LINK_ERR, /**< Port link error event */
+ HINIC5_PORT_MODULE_CABLE_PLUGGED, /**< 端口电缆已插入的事件 */
+ HINIC5_PORT_MODULE_CABLE_UNPLUGGED, /**< 端口电缆已拔出的事件 */
+ HINIC5_PORT_MODULE_LINK_ERR, /**< 端口链路出现错误的事件 */
HINIC5_PORT_MODULE_MAX_EVENT,
};
/**
- * @brief struct hinic5_port_module_event Port event information
- * @details DCB event reported DCB information
+ * @brief struct hinic5_port_module_event 端口事件信息
+ * @details DCB事件上报的DCB信息
*/
struct hinic5_port_module_event {
- enum port_module_event_type type; /**< Port cable event type */
- enum link_err_type err_type; /**< Link error event type */
+ enum port_module_event_type type; /**< 端口电缆事件类型 */
+ enum link_err_type err_type; /**< Link错误事件类型 */
};
/**
- * @brief struct hinic5_dcb_info DCB information
- * @details DCB event reported DCB information
+ * @brief struct hinic5_dcb_info DCB信息
+ * @details DCB事件上报的DCB信息
*/
struct hinic5_dcb_info {
- u8 dcb_on; /**< DCB enable status */
- u8 default_cos; /**< Default cos */
- u8 up_cos[NIC_DCB_COS_MAX]; /**< Priority to cos mapping */
+ u8 dcb_on; /**< DCB使能状态 */
+ u8 default_cos; /**< 默认cos */
+ u8 up_cos[NIC_DCB_COS_MAX]; /**< 优先级到cos映射 */
};
enum hinic5_nic_event_type {
- EVENT_NIC_LINK_DOWN, /**< Link down event */
- EVENT_NIC_LINK_UP, /**< Link up event */
- EVENT_NIC_PORT_MODULE_EVENT, /**< Cable plug/unplug event */
- EVENT_NIC_DCB_STATE_CHANGE, /**< DCB state change event */
+ EVENT_NIC_LINK_DOWN, /**< Link down事件 */
+ EVENT_NIC_LINK_UP, /**< Link up事件 */
+ EVENT_NIC_PORT_MODULE_EVENT, /**< 线缆插拔事件 */
+ EVENT_NIC_DCB_STATE_CHANGE, /**< DCB状态变化事件 */
+ EVENT_NIC_LINK_DOWN_DFX, /**< Link down DFX 上报事件 */
};
#if !defined(__UEFI__) && !defined(__VMWARE__)
/**
- * @brief Get lld_dev structure pointer according to netdev
+ * @brief 根据netdev获取lld_dev结构体指针
*
- * @param netdev netdev structure pointer
+ * @param netdev netdev结构体指针
*
- * @details Find lld_dev by netdev matching
+ * @details 根据netdev匹配查找查找lld_dev
*
- * @attention: This interface return will not increment lld_dev reference count++,
- * If lld_dev is released during use, may lead to wild pointer access
+ * @attention: 该接口返回不会对lld_dev引用计数++,使用过程中如果lld_dev被释放可能导致访问野指针
*
- * @return: Returns lld_dev structure pointer when successfully matched to netdev, otherwise returns NULL
+ * @return: 成功匹配到netdev的lld_dev时返回lld_dev结构体指针,否则返回NULL
*/
struct hinic5_lld_dev *hinic5_get_lld_dev_by_netdev(struct net_device *netdev);
#endif
/**
- * @brief Delete device mac interface
+ * @brief 删除设备mac接口
*
* @param hwdev device pointer to hwdev
- * @param mac_addr mac address
- * @param vlan_id vlan id range[0~4095]
+ * @param mac_addr mac地址
+ * @param vlan_id vlan id 范围[0~4095]
* @param func_id global function index
- * @param channel mailbox send used channel id
+ * @param channel channel id,mailbox发送使用的channel id
*
- * @details Delete corresponding function mac address
+ * @details 删除对应function的mac地址
*
- * @attention: Function internal involves sending mailbox messages which will sleep,
- * Prohibited in interrupt context and other processes that do not allow sleeping
+ * @attention: 函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
*
- * @return: Delete MAC returns success or failure.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: 删除MAC返回成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
-int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id, u16 channel);
+int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
+ u16 channel);
/**
- * @brief Get device DCB state
+ * @brief 获取设备DCB状态
*
* @param hwdev device pointer to hwdev
- * @param dcb_state: DCB state information
+ * @param dcb_state:DCB状态信息
*
- * @details Get device DCB state
+ * @details 获取设备DCB状态
*
* @attention: NA
- * @return: DCB state get returns success or failure
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: DCB状态获取返回成功或者失败
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_get_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state);
/**
- * @brief Get PF DCB state
+ * @brief 获取PF DCB状态
*
* @param hwdev device pointer to hwdev
- * @param dcb_state: DCB state information
+ * @param dcb_state:DCB状态信息
*
- * @details VF sends to PF through mailbox info, get PF DCB state information
+ * @details VF通过mailbox信息发送给PF,获取PF DCB状态信息
*
- * @attention: Only VF supported, PF call returns failure; Function internal involves sending mailbox messages which will sleep,
- * Prohibited in interrupt context and other processes that do not allow sleeping
+ * @attention: 仅VF支持,PF调用返回失败;函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
*
- * @return: VF get PF DCB state returns success or failure
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: VF获取PF DCB状态返回成功或者失败
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_get_pf_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state);
/**
- * @brief Get corresponding cos value by priority
+ * @brief 根据优先级获取对应cos值
*
* @param hwdev device pointer to hwdev
- * @param pri Priority PCP mode[0~7] DSCP mode[0~63]
- * @param cos Output cos value [0~7]
+ * @param pri 优先级 PCP模式[0~7] DSCP模式[0~63]
+ * @param cos 输出cos值 [0~7]
*
- * @details Query corresponding cos value through user input pri, in PCP mode pri valid value is 0~7,
- * In DSCP mode, pri valid value is 0~63
+ * @details 通过用户输入的pri查询对应的cos值,PCP模式下,pri合法值为0~7, DSCP模式下,pri合法值0~63
*
* @attention: NA
*
- * @return: pri map cos query success or failure.
- * @retval 0 Success
- * @retval non-0 Failure
+ * @return: pri映射cos查询成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos);
-/* TO DO The following interfaces to be deleted */
+/* TO DO 以下接口待删除 */
#if !defined(__UEFI__) && !defined(__VMWARE__)
typedef u8 (*hinic5_cqe_cb)(void *lld_dev, void *data);
-int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type event,
+int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type event,
hinic5_cqe_cb cqe_cb);
-void hinic5_unregister_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type event);
+void hinic5_unregister_cqe_cb(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type event);
#endif
enum hinic5_bonding_en {
- HINIC5_BONDING_OFFLOAD_DISABLE = 0,
- HINIC5_BONDING_OFFLOAD_ENABLE
+ HINIC5_BONDING_OFFLOAD_DISABLE = 0,
+ HINIC5_BONDING_OFFLOAD_ENABLE
};
enum hinic5_bonding_event_e {
- BOND_EVENT_LINK_DOWN = 0,
- BOND_EVENT_LINK_UP = 1,
- BOND_EVENT_OPEN = 2,
- BOND_EVENT_CLOSE = 3
+ BOND_EVENT_LINK_DOWN = 0,
+ BOND_EVENT_LINK_UP = 1,
+ BOND_EVENT_OPEN = 2,
+ BOND_EVENT_CLOSE = 3
};
-
/* *
* @brief hinic5_bonding_register_service_func - bonding event register
* @param type: hinic5 service type
@@ -183,9 +182,10 @@ enum hinic5_bonding_event_e {
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_bonding_register_service_func(enum hinic5_service_type type, void (*func)(void *netdev,
- u32 bond_id, u8 new_slaves,
- enum hinic5_bonding_event_e event));
+int hinic5_bonding_register_service_func(
+ enum hinic5_service_type type,
+ void (*func)(void *netdev, u32 bond_id, u8 new_slaves,
+ enum hinic5_bonding_event_e event));
/* *
* @brief hinic5_bonding_unregister_service_func - bonding event unregister
@@ -220,7 +220,8 @@ int hinic5_bond_offload_get_uplink_id(u16 bond_id, u32 *uplink_id);
int hinic5_bond_offload_get_slaves(u16 bond_id, void *drv_msg, u8 *slaves);
#if !defined(__UEFI__) && !defined(__WIN__) && !defined(__VMWARE__)
-int hinic5_get_phy_port_id_by_netdev(struct net_device *netdev, uint8_t *phy_port_id);
+int hinic5_get_phy_port_id_by_netdev(struct net_device *netdev,
+ uint8_t *phy_port_id);
#endif
/* *
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.c
index 1ee4e53d2..827d2680f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.c
@@ -1,36 +1,30 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : 182x_cmdq_ops.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include "nic_npu_cmd.h"
#include "hinic5_nic_cmdq.h"
#include "182x_cmdq_ops.h"
-#define HINIC5_DEAULT_DROP_THD_OFF 0
+#define HINIC5_DEAULT_DROP_THD_OFF 0
-#define WQ_PREFETCH_MAX 4
-#define WQ_PREFETCH_MIN 1
-#define WQ_PREFETCH_THRESHOLD 256
+#define WQ_PREFETCH_MAX 4
+#define WQ_PREFETCH_MIN 1
+#define WQ_PREFETCH_THRESHOLD 256
-#define RQ_CTXT_CEQ_ATTR_CI_WR_SHIFT 0
-#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT 21
-#define RQ_CTXT_CEQ_ATTR_CEQ_ARM_SHIFT 30
-#define RQ_CTXT_CEQ_ATTR_EN_SHIFT 31
+#define RQ_CTXT_CEQ_ATTR_CI_WR_SHIFT 0
+#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT 21
+#define RQ_CTXT_CEQ_ATTR_CEQ_ARM_SHIFT 30
+#define RQ_CTXT_CEQ_ATTR_EN_SHIFT 31
-#define RQ_CTXT_CEQ_ATTR_CI_WR_MASK 0x1U
-#define RQ_CTXT_CEQ_ATTR_INTR_MASK 0x3FFU
-#define RQ_CTXT_CEQ_ATTR_CEQ_ARM_MASK 0x1U
-#define RQ_CTXT_CEQ_ATTR_EN_MASK 0x1U
+#define RQ_CTXT_CEQ_ATTR_CI_WR_MASK 0x1U
+#define RQ_CTXT_CEQ_ATTR_INTR_MASK 0x3FFU
+#define RQ_CTXT_CEQ_ATTR_CEQ_ARM_MASK 0x1U
+#define RQ_CTXT_CEQ_ATTR_EN_MASK 0x1U
-static void hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_hdr,
- enum hinic5_qp_ctxt_type ctxt_type, u16 num_queues,
- u16 q_id)
+static void
+hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_hdr,
+ enum hinic5_qp_ctxt_type ctxt_type,
+ u16 num_queues, u16 q_id)
{
qp_ctxt_hdr->queue_type = ctxt_type;
qp_ctxt_hdr->num_queues = num_queues;
@@ -40,10 +34,9 @@ static void hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_
hinic5_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));
}
-static u8 prepare_cmd_buf_qp_context_multi_store(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type,
- u16 start_qid, u16 max_ctxts)
+static u8 prepare_cmd_buf_qp_context_multi_store(
+ struct hinic5_nic_io *nic_io, struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type, u16 start_qid, u16 max_ctxts)
{
struct hinic5_qp_ctxt_block *qp_ctxt_block = NULL;
u16 i;
@@ -55,19 +48,23 @@ static u8 prepare_cmd_buf_qp_context_multi_store(struct hinic5_nic_io *nic_io,
for (i = 0; i < max_ctxts; i++) {
if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
- hinic5_rq_prepare_ctxt(nic_io, &nic_io->rq[start_qid + i],
+ hinic5_rq_prepare_ctxt(nic_io,
+ &nic_io->rq[start_qid + i],
&qp_ctxt_block->rq_ctxt[i]);
else
- hinic5_sq_prepare_ctxt(nic_io, &nic_io->sq[start_qid + i],
- start_qid + i, &qp_ctxt_block->sq_ctxt[i]);
+ hinic5_sq_prepare_ctxt(nic_io,
+ &nic_io->sq[start_qid + i],
+ start_qid + i,
+ &qp_ctxt_block->sq_ctxt[i]);
}
return (u8)HINIC5_UCODE_CMD_MODIFY_QUEUE_CTX;
}
-static u8 prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type)
+static u8
+prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
+ struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type)
{
struct hinic5_clean_queue_ctxt *ctxt_block = NULL;
@@ -82,9 +79,10 @@ static u8 prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
return (u8)HINIC5_UCODE_CMD_CLEAN_QUEUE_CONTEXT;
}
-static u8 prepare_cmd_buf_set_rss_indir_table(const struct hinic5_nic_io *nic_io,
- const u32 *indir_table,
- struct hinic5_cmd_buf *cmd_buf)
+static u8
+prepare_cmd_buf_set_rss_indir_table(const struct hinic5_nic_io *nic_io,
+ const u32 *indir_table,
+ struct hinic5_cmd_buf *cmd_buf)
{
u32 i, size;
u32 *temp = NULL;
@@ -92,39 +90,45 @@ static u8 prepare_cmd_buf_set_rss_indir_table(const struct hinic5_nic_io *nic_io
indir_tbl = (struct nic_rss_indirect_tbl *)cmd_buf->buf;
cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
- memset(indir_tbl, 0, sizeof(*indir_tbl));
+ (void)memset_s(indir_tbl, sizeof(*indir_tbl), 0, sizeof(*indir_tbl));
- for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
+ for (i = 0; i < NIC_RSS_INDIR_SIZE; i++) {
indir_tbl->entry[i] = (u16)(*(indir_table + i));
+ }
size = sizeof(indir_tbl->entry) / sizeof(u32);
temp = (u32 *)indir_tbl->entry;
- for (i = 0; i < size; i++)
+ for (i = 0; i < size; i++) {
temp[i] = cpu_to_be32(temp[i]);
+ }
return (u8)HINIC5_UCODE_CMD_SET_RSS_INDIR_TABLE;
}
-static u8 prepare_cmd_buf_get_rss_indir_table(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf)
+static u8
+prepare_cmd_buf_get_rss_indir_table(const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf)
{
(void)nic_io;
- memset(cmd_buf->buf, 0, cmd_buf->size);
+ (void)memset_s(cmd_buf->buf, cmd_buf->size, 0, cmd_buf->size);
return (u8)HINIC5_UCODE_CMD_GET_RSS_INDIR_TABLE;
}
-static void cmd_buf_to_rss_indir_table(const struct hinic5_cmd_buf *cmd_buf, u32 *indir_table)
+static void cmd_buf_to_rss_indir_table(const struct hinic5_cmd_buf *cmd_buf,
+ u32 *indir_table)
{
u32 i;
u16 *indir_tbl = NULL;
indir_tbl = (u16 *)cmd_buf->buf;
- for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
+ for (i = 0; i < NIC_RSS_INDIR_SIZE; i++) {
indir_table[i] = *(indir_tbl + i);
+ }
}
static u8 prepare_cmd_buf_modify_svlan(struct hinic5_cmd_buf *cmd_buf,
- u16 func_id, u16 vlan_tag, u16 q_id, u8 vlan_mode)
+ u16 func_id, u16 vlan_tag, u16 q_id,
+ u8 vlan_mode)
{
struct nic_vlan_ctx *vlan_ctx = NULL;
@@ -141,17 +145,20 @@ static u8 prepare_cmd_buf_modify_svlan(struct hinic5_cmd_buf *cmd_buf,
return (u8)HINIC5_UCODE_CMD_MODIFY_VLAN_CTX;
}
-static u8 prepare_cmd_buf_clear_vport_stats(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf, u16 func_id)
+static u8
+prepare_cmd_buf_clear_vport_stats(const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf,
+ u16 func_id)
{
return (u8)HINIC5_UCODE_CMD_CLEAR_VPORT_STATS;
}
static u8 prepare_cmd_buf_get_vport_stats(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf, u16 func_id)
+ const struct hinic5_cmd_buf *cmd_buf,
+ u16 func_id)
{
(void)nic_io;
- memset(cmd_buf->buf, 0, cmd_buf->size);
+ (void)memset_s(cmd_buf->buf, cmd_buf->size, 0, cmd_buf->size);
return (u8)HINIC5_UCODE_CMD_GET_VPORT_STATS;
}
@@ -159,10 +166,11 @@ static u8 prepare_cmd_buf_get_vport_stats(const struct hinic5_nic_io *nic_io,
static void cmd_buf_to_vport_stats(const struct hinic5_cmd_buf *cmd_buf,
struct hinic5_vport_stats *stats)
{
- /* Microcode cmdq command word copy,
- Later modification needs to consider hinic5_vport_stats and nic_cmdq_vport_stats differences */
+ /* 微码 cmdq 获取命令字复制,后续修改需要考虑 hinic5_vport_stats 与 nic_cmdq_vport_stats 差异 */
+ (void)memcpy_s(stats, sizeof(struct hinic5_vport_stats), cmd_buf->buf,
+ sizeof(struct hinic5_vport_stats));
- memcpy(stats, cmd_buf->buf, sizeof(struct hinic5_vport_stats));
+ return;
}
static void prepare_sq_ctxt_drop_and_prefetch(struct hinic5_sq_ctxt *sq_ctxt)
@@ -177,13 +185,14 @@ static void prepare_sq_ctxt_drop_and_prefetch(struct hinic5_sq_ctxt *sq_ctxt)
SQ_CTXT_PREF_SET(WQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
}
-static void prepare_rq_ctxt_ceq_and_prefetch
- (struct hinic5_io_queue *rq, struct hinic5_rq_ctxt *rq_ctxt, bool support_rq_sw_compact_wqe)
+static void prepare_rq_ctxt_ceq_and_prefetch(struct hinic5_io_queue *rq,
+ struct hinic5_rq_ctxt *rq_ctxt,
+ bool support_rq_sw_compact_wqe)
{
u16 wqe_type = rq->wqe_type;
rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(0, EN) |
- RQ_CTXT_CEQ_ATTR_SET(rq->msix_entry_idx, INTR);
+ RQ_CTXT_CEQ_ATTR_SET(rq->msix_entry_idx, INTR);
if (wqe_type == HINIC5_COMPACT_RQ_WQE && support_rq_sw_compact_wqe) {
rq_ctxt->ceq_attr |= RQ_CTXT_CEQ_ATTR_SET(1, EN);
@@ -200,17 +209,25 @@ static void prepare_rq_ctxt_ceq_and_prefetch
struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_182x_ops(void)
{
static struct hinic5_nic_cmdq_ops cmdq_182x_ops = {
- .prepare_cmd_buf_clean_tso_lro_space = prepare_cmd_buf_clean_tso_lro_space,
- .prepare_cmd_buf_qp_context_multi_store = prepare_cmd_buf_qp_context_multi_store,
+ .prepare_cmd_buf_clean_tso_lro_space =
+ prepare_cmd_buf_clean_tso_lro_space,
+ .prepare_cmd_buf_qp_context_multi_store =
+ prepare_cmd_buf_qp_context_multi_store,
.prepare_cmd_buf_modify_svlan = prepare_cmd_buf_modify_svlan,
- .prepare_cmd_buf_set_rss_indir_table = prepare_cmd_buf_set_rss_indir_table,
- .prepare_cmd_buf_get_rss_indir_table = prepare_cmd_buf_get_rss_indir_table,
- .prepare_cmd_buf_get_vport_stats = prepare_cmd_buf_get_vport_stats,
- .prepare_cmd_buf_clear_vport_stats = prepare_cmd_buf_clear_vport_stats,
+ .prepare_cmd_buf_set_rss_indir_table =
+ prepare_cmd_buf_set_rss_indir_table,
+ .prepare_cmd_buf_get_rss_indir_table =
+ prepare_cmd_buf_get_rss_indir_table,
+ .prepare_cmd_buf_get_vport_stats =
+ prepare_cmd_buf_get_vport_stats,
+ .prepare_cmd_buf_clear_vport_stats =
+ prepare_cmd_buf_clear_vport_stats,
.cmd_buf_to_vport_stats = cmd_buf_to_vport_stats,
.cmd_buf_to_rss_indir_table = cmd_buf_to_rss_indir_table,
- .prepare_sq_ctxt_drop_and_prefetch = prepare_sq_ctxt_drop_and_prefetch,
- .prepare_rq_ctxt_ceq_and_prefetch = prepare_rq_ctxt_ceq_and_prefetch,
+ .prepare_sq_ctxt_drop_and_prefetch =
+ prepare_sq_ctxt_drop_and_prefetch,
+ .prepare_rq_ctxt_ceq_and_prefetch =
+ prepare_rq_ctxt_ceq_and_prefetch,
};
return &cmdq_182x_ops;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.h
index 1904503f3..1db0cd3bf 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/182x_cmdq_adapt/182x_cmdq_ops.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : 182x_cmdq_ops.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef _182X_CMDQ_PRIVATE_H_
#define _182X_CMDQ_PRIVATE_H_
@@ -15,10 +8,10 @@
#include "hinic5_nic_cmdq.h"
struct hinic5_qp_ctxt_header {
- u16 num_queues;
- u16 queue_type;
- u16 start_qid;
- u16 rsvd;
+ u16 num_queues;
+ u16 queue_type;
+ u16 start_qid;
+ u16 rsvd;
};
struct hinic5_clean_queue_ctxt {
@@ -27,10 +20,10 @@ struct hinic5_clean_queue_ctxt {
};
struct hinic5_qp_ctxt_block {
- struct hinic5_qp_ctxt_header cmdq_hdr;
+ struct hinic5_qp_ctxt_header cmdq_hdr;
union {
- struct hinic5_sq_ctxt sq_ctxt[HINIC5_Q_CTXT_MAX];
- struct hinic5_rq_ctxt rq_ctxt[HINIC5_Q_CTXT_MAX];
+ struct hinic5_sq_ctxt sq_ctxt[HINIC5_Q_CTXT_MAX];
+ struct hinic5_rq_ctxt rq_ctxt[HINIC5_Q_CTXT_MAX];
};
};
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.c
index 2cbe7fceb..7f87a319e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.c
@@ -1,41 +1,35 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : 187x_cmdq_ops.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include "hinic5_nic_cmdq.h"
#include "187x_cmdq_ops.h"
-#define HINIC5_DEAULT_DROP_THD_OFF 0xFFFF
+#define HINIC5_DEAULT_DROP_THD_OFF 0xFFFF
-#define SQ_PREFETCH_MAX 5
-#define SQ_PREFETCH_MIN 4
-#define SQ_PREFETCH_THRESHOLD 48
+#define SQ_PREFETCH_MAX 5
+#define SQ_PREFETCH_MIN 4
+#define SQ_PREFETCH_THRESHOLD 48
-#define RQ_PREFETCH_MAX 4
-#define RQ_PREFETCH_MIN 2
-#define RQ_PREFETCH_THRESHOLD 32
+#define RQ_PREFETCH_MAX 4
+#define RQ_PREFETCH_MIN 2
+#define RQ_PREFETCH_THRESHOLD 32
-#define RQ_PFH_TH 7
+#define RQ_PFH_TH 7
-#define RQ_CTXT_CEQ_ATTR_PFH_TH_SHIFT 0
-#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT 21
-#define RQ_CTXT_CEQ_ATTR_EN_SHIFT 31
+#define RQ_CTXT_CEQ_ATTR_PFH_TH_SHIFT 0
+#define RQ_CTXT_CEQ_ATTR_INTR_SHIFT 21
+#define RQ_CTXT_CEQ_ATTR_EN_SHIFT 31
-#define RQ_CTXT_CEQ_ATTR_PFH_TH_MASK 0x1FU
-#define RQ_CTXT_CEQ_ATTR_EN_MASK 0x1U
-#define RQ_CTXT_CEQ_ATTR_INTR_MASK 0x3FFU
+#define RQ_CTXT_CEQ_ATTR_PFH_TH_MASK 0x1FU
+#define RQ_CTXT_CEQ_ATTR_EN_MASK 0x1U
+#define RQ_CTXT_CEQ_ATTR_INTR_MASK 0x3FFU
#define HI187X_BASE_VF_QUE_ID(nic_io) (4 * (nic_io)->max_qps)
-static void hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_hdr,
- enum hinic5_qp_ctxt_type ctxt_type, u16 num_queues,
- u16 q_id, u16 func_id)
+static void
+hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_hdr,
+ enum hinic5_qp_ctxt_type ctxt_type,
+ u16 num_queues, u16 q_id, u16 func_id)
{
qp_ctxt_hdr->queue_type = ctxt_type;
qp_ctxt_hdr->num_queues = num_queues;
@@ -45,10 +39,9 @@ static void hinic5_qp_prepare_cmdq_header(struct hinic5_qp_ctxt_header *qp_ctxt_
hinic5_cpu_to_be32(qp_ctxt_hdr, sizeof(*qp_ctxt_hdr));
}
-static u8 prepare_cmd_buf_qp_context_multi_store(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type,
- u16 start_qid, u16 max_ctxts)
+static u8 prepare_cmd_buf_qp_context_multi_store(
+ struct hinic5_nic_io *nic_io, struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type, u16 start_qid, u16 max_ctxts)
{
struct hinic5_qp_ctxt_block *qp_ctxt_block = NULL;
u16 func_id;
@@ -61,10 +54,12 @@ static u8 prepare_cmd_buf_qp_context_multi_store(struct hinic5_nic_io *nic_io,
for (i = 0; i < max_ctxts; i++) {
if (ctxt_type == HINIC5_QP_CTXT_TYPE_RQ)
- hinic5_rq_prepare_ctxt(nic_io, &nic_io->rq[start_qid + i],
+ hinic5_rq_prepare_ctxt(nic_io,
+ &nic_io->rq[start_qid + i],
&qp_ctxt_block->rq_ctxt[i]);
else
- hinic5_sq_prepare_ctxt(nic_io, &nic_io->sq[start_qid + i],
+ hinic5_sq_prepare_ctxt(nic_io,
+ &nic_io->sq[start_qid + i],
start_qid + i,
&qp_ctxt_block->sq_ctxt[i]);
}
@@ -72,14 +67,16 @@ static u8 prepare_cmd_buf_qp_context_multi_store(struct hinic5_nic_io *nic_io,
return (u8)HINIC5_HTN_CMD_SQ_RQ_CONTEXT_MULTI_ST;
}
-static u8 prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type)
+static u8
+prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
+ struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type)
{
struct hinic5_clean_queue_ctxt *ctxt_block = NULL;
ctxt_block = cmd_buf->buf;
- ctxt_block->cmdq_hdr.dest_func_id = hinic5_global_func_id(nic_io->hwdev);
+ ctxt_block->cmdq_hdr.dest_func_id =
+ hinic5_global_func_id(nic_io->hwdev);
ctxt_block->cmdq_hdr.num_queues = nic_io->max_qps;
ctxt_block->cmdq_hdr.queue_type = ctxt_type;
ctxt_block->cmdq_hdr.start_qid = 0;
@@ -90,8 +87,9 @@ static u8 prepare_cmd_buf_clean_tso_lro_space(struct hinic5_nic_io *nic_io,
return (u8)HINIC5_HTN_CMD_TSO_LRO_SPACE_CLEAN;
}
-static void prepare_rss_indir_table_cmd_header(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf)
+static void
+prepare_rss_indir_table_cmd_header(const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf)
{
struct hinic5_rss_cmd_header *header = cmd_buf->buf;
@@ -99,48 +97,55 @@ static void prepare_rss_indir_table_cmd_header(const struct hinic5_nic_io *nic_i
hinic5_cpu_to_be32(header, sizeof(*header));
}
-static u8 prepare_cmd_buf_set_rss_indir_table(const struct hinic5_nic_io *nic_io,
- const u32 *indir_table,
- struct hinic5_cmd_buf *cmd_buf)
+static u8
+prepare_cmd_buf_set_rss_indir_table(const struct hinic5_nic_io *nic_io,
+ const u32 *indir_table,
+ struct hinic5_cmd_buf *cmd_buf)
{
u32 i;
u8 *indir_tbl = NULL;
indir_tbl = (u8 *)cmd_buf->buf + sizeof(struct hinic5_rss_cmd_header);
- cmd_buf->size = sizeof(struct hinic5_rss_cmd_header) + NIC_RSS_INDIR_SIZE;
- memset(indir_tbl, 0, NIC_RSS_INDIR_SIZE);
+ cmd_buf->size =
+ sizeof(struct hinic5_rss_cmd_header) + NIC_RSS_INDIR_SIZE;
+ (void)memset_s(indir_tbl, NIC_RSS_INDIR_SIZE, 0, NIC_RSS_INDIR_SIZE);
prepare_rss_indir_table_cmd_header(nic_io, cmd_buf);
- for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
+ for (i = 0; i < NIC_RSS_INDIR_SIZE; i++) {
indir_tbl[i] = (u8)(*(indir_table + i));
+ }
hinic5_cpu_to_be32(indir_tbl, NIC_RSS_INDIR_SIZE);
return (u8)HINIC5_HTN_CMD_SET_RSS_INDIR_TABLE;
}
-static u8 prepare_cmd_buf_get_rss_indir_table(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf)
+static u8
+prepare_cmd_buf_get_rss_indir_table(const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf)
{
- memset(cmd_buf->buf, 0, cmd_buf->size);
+ (void)memset_s(cmd_buf->buf, cmd_buf->size, 0, cmd_buf->size);
prepare_rss_indir_table_cmd_header(nic_io, cmd_buf);
return (u8)HINIC5_HTN_CMD_GET_RSS_INDIR_TABLE;
}
-static void cmd_buf_to_rss_indir_table(const struct hinic5_cmd_buf *cmd_buf, u32 *indir_table)
+static void cmd_buf_to_rss_indir_table(const struct hinic5_cmd_buf *cmd_buf,
+ u32 *indir_table)
{
u32 i;
u8 *indir_tbl = NULL;
indir_tbl = (u8 *)cmd_buf->buf;
hinic5_be32_to_cpu(cmd_buf->buf, NIC_RSS_INDIR_SIZE);
- for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
+ for (i = 0; i < NIC_RSS_INDIR_SIZE; i++) {
indir_table[i] = *(indir_tbl + i);
+ }
}
static u8 prepare_cmd_buf_modify_svlan(struct hinic5_cmd_buf *cmd_buf,
- u16 func_id, u16 vlan_tag, u16 q_id, u8 vlan_mode)
+ u16 func_id, u16 vlan_tag, u16 q_id,
+ u8 vlan_mode)
{
struct hinic5_vlan_ctx *vlan_ctx = NULL;
@@ -169,12 +174,13 @@ static void prepare_sq_ctxt_drop_and_prefetch(struct hinic5_sq_ctxt *sq_ctxt)
SQ_CTXT_PREF_SET(SQ_PREFETCH_THRESHOLD, CACHE_THRESHOLD);
}
-static void prepare_rq_ctxt_ceq_and_prefetch
- (struct hinic5_io_queue *rq, struct hinic5_rq_ctxt *rq_ctxt, bool support_rq_sw_compact_wqe)
+static void prepare_rq_ctxt_ceq_and_prefetch(struct hinic5_io_queue *rq,
+ struct hinic5_rq_ctxt *rq_ctxt,
+ bool support_rq_sw_compact_wqe)
{
rq_ctxt->ceq_attr = RQ_CTXT_CEQ_ATTR_SET(0, EN) |
- RQ_CTXT_CEQ_ATTR_SET(RQ_PFH_TH, PFH_TH) |
- RQ_CTXT_CEQ_ATTR_SET(rq->msix_entry_idx, INTR);
+ RQ_CTXT_CEQ_ATTR_SET(RQ_PFH_TH, PFH_TH) |
+ RQ_CTXT_CEQ_ATTR_SET(rq->msix_entry_idx, INTR);
rq_ctxt->pref_cache =
RQ_CTXT_PREF_SET(RQ_PREFETCH_MIN, CACHE_MIN) |
@@ -185,14 +191,20 @@ static void prepare_rq_ctxt_ceq_and_prefetch
struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_187x_ops(void)
{
static struct hinic5_nic_cmdq_ops cmdq_187x_ops = {
- .prepare_cmd_buf_clean_tso_lro_space = prepare_cmd_buf_clean_tso_lro_space,
- .prepare_cmd_buf_qp_context_multi_store = prepare_cmd_buf_qp_context_multi_store,
+ .prepare_cmd_buf_clean_tso_lro_space =
+ prepare_cmd_buf_clean_tso_lro_space,
+ .prepare_cmd_buf_qp_context_multi_store =
+ prepare_cmd_buf_qp_context_multi_store,
.prepare_cmd_buf_modify_svlan = prepare_cmd_buf_modify_svlan,
- .prepare_cmd_buf_set_rss_indir_table = prepare_cmd_buf_set_rss_indir_table,
- .prepare_cmd_buf_get_rss_indir_table = prepare_cmd_buf_get_rss_indir_table,
+ .prepare_cmd_buf_set_rss_indir_table =
+ prepare_cmd_buf_set_rss_indir_table,
+ .prepare_cmd_buf_get_rss_indir_table =
+ prepare_cmd_buf_get_rss_indir_table,
.cmd_buf_to_rss_indir_table = cmd_buf_to_rss_indir_table,
- .prepare_sq_ctxt_drop_and_prefetch = prepare_sq_ctxt_drop_and_prefetch,
- .prepare_rq_ctxt_ceq_and_prefetch = prepare_rq_ctxt_ceq_and_prefetch,
+ .prepare_sq_ctxt_drop_and_prefetch =
+ prepare_sq_ctxt_drop_and_prefetch,
+ .prepare_rq_ctxt_ceq_and_prefetch =
+ prepare_rq_ctxt_ceq_and_prefetch,
};
return &cmdq_187x_ops;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.h
index 6320e80ba..c380eaf46 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/187x_cmdq_adapt/187x_cmdq_ops.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : 187x_cmdq_ops.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef _187X_CMDQ_PRIVATE_H_
#define _187X_CMDQ_PRIVATE_H_
@@ -27,10 +20,10 @@ struct hinic5_clean_queue_ctxt {
};
struct hinic5_qp_ctxt_block {
- struct hinic5_qp_ctxt_header cmdq_hdr;
+ struct hinic5_qp_ctxt_header cmdq_hdr;
union {
- struct hinic5_sq_ctxt sq_ctxt[HINIC5_Q_CTXT_MAX];
- struct hinic5_rq_ctxt rq_ctxt[HINIC5_Q_CTXT_MAX];
+ struct hinic5_sq_ctxt sq_ctxt[HINIC5_Q_CTXT_MAX];
+ struct hinic5_rq_ctxt rq_ctxt[HINIC5_Q_CTXT_MAX];
};
};
@@ -61,14 +54,14 @@ struct hinic5_vlan_ctx {
struct hinic5_car_cmd_header {
u32 rsv[2];
- u32 op_num; /* Number of configured car_ids, minimum 1, maximum 32 */
+ u32 op_num; /* 配置的car_id个数,一次最少1个,最多32个 */
u16 rsv1;
- u16 index; /* Starting index of configuration, 16B unit, index must be 32B aligned */
+ u16 index; /* 配置的起始index,16B为单位,index必须32B对齐 */
};
struct hinic5_car_cmd_payload {
- u32 context[4]; /* Written by hardware, read by driver */
- u32 profile[4]; /* Written by driver, read by hardware */
+ u32 context[4]; /* 硬件写,驱动读 */
+ u32 profile[4]; /* 驱动写,硬件读 */
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_cmdq_adapt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_cmdq_adapt.c
index 22901854b..0b94238be 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_cmdq_adapt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_cmdq_adapt.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_cmdq_adapt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#include "hinic5_nic_cmdq.h"
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_mag_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_mag_cfg.c
index 9fb5e9e90..d1917bb92 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_mag_cfg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mag_cfg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -31,7 +24,6 @@
#include "cfm_cmd.h"
#include "hinic5_common.h"
#include "mag_mpu_cmd.h"
-#include "nic_mpu_cmd.h"
#include "hinic5_nic_event.h"
#include "mag_mpu_cmd_defs.h"
#include "inband_mpu_cmd_defs.h"
@@ -50,27 +42,28 @@ int hinic5_set_port_enable(void *hwdev, bool enable, u16 channel)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
if (hinic5_func_type(hwdev) == TYPE_VF)
return 0;
- memset(&en_state, 0, sizeof(en_state));
+ (void)memset_s(&en_state, sizeof(en_state), 0, sizeof(en_state));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
en_state.function_id = hinic5_global_func_id(hwdev);
en_state.state = enable ? MAG_CMD_TX_ENABLE | MAG_CMD_RX_ENABLE :
- MAG_CMD_PORT_DISABLE;
+ MAG_CMD_PORT_DISABLE;
err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_SET_PORT_ENABLE, &en_state,
sizeof(en_state), &en_state, &out_size,
channel);
- if (err != 0 || out_size == 0 || en_state.head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (en_state.head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, en_state.head.status, out_size, channel);
return -EIO;
}
@@ -90,22 +83,21 @@ int hinic5_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
+ if (port_stats == NULL)
return -ENOMEM;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
err = -EINVAL;
goto out;
}
- memset(&stats_info, 0, sizeof(stats_info));
+ (void)memset_s(&stats_info, sizeof(stats_info), 0, sizeof(stats_info));
stats_info.port_id = hinic5_physical_port_id(hwdev);
- err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err != 0 || out_size == 0 || port_stats->head.status != 0) {
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, &stats_info,
+ sizeof(stats_info), port_stats, &out_size);
+ if ((err != 0) || (out_size == 0) || (port_stats->head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
err, port_stats->head.status, out_size);
@@ -113,7 +105,11 @@ int hinic5_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
goto out;
}
- memcpy(stats, &port_stats->counter, sizeof(*stats));
+ err = memcpy_s(stats, sizeof(*stats), &port_stats->counter,
+ sizeof(*stats));
+ if (err != 0) {
+ err = -EINVAL;
+ }
out:
kfree(port_stats);
@@ -139,15 +135,15 @@ int hinic5_force_port_relink(void *hwdev)
int hinic5_set_autoneg(void *hwdev, bool enable)
{
- struct hinic5_link_ksettings settings = {0};
+ struct hinic5_link_ksettings settings = { 0 };
struct hinic5_nic_io *nic_io = NULL;
u32 set_settings = 0;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
set_settings |= HILINK_LINK_SET_AUTONEG;
@@ -164,7 +160,7 @@ static int hinic5_cfg_loopback_mode(struct hinic5_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(lp);
int err;
- memset(&lp, 0, sizeof(lp));
+ (void)memset_s(&lp, sizeof(lp), 0, sizeof(lp));
lp.port_id = hinic5_physical_port_id(nic_io->hwdev);
lp.opcode = opcode;
if (opcode == MGMT_MSG_CMD_OP_SET) {
@@ -174,11 +170,11 @@ static int hinic5_cfg_loopback_mode(struct hinic5_nic_io *nic_io, u8 opcode,
err = mag_msg_to_mgmt_sync(nic_io->hwdev, MAG_CMD_CFG_LOOPBACK_MODE,
&lp, sizeof(lp), &lp, &out_size);
- if (err != 0 || out_size == 0 || lp.head.status != 0) {
+ if ((err != 0) || (out_size == 0) || (lp.head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to %s loopback mode, err: %d, status: 0x%x, out size: 0x%x\n",
- opcode == MGMT_MSG_CMD_OP_SET ? "set" : "get",
- err, lp.head.status, out_size);
+ opcode == MGMT_MSG_CMD_OP_SET ? "set" : "get", err,
+ lp.head.status, out_size);
return -EIO;
}
@@ -194,11 +190,11 @@ int hinic5_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !mode || !enable)
+ if ((hwdev == NULL) || (mode == NULL) || (enable == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
return hinic5_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
@@ -209,11 +205,11 @@ int hinic5_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
@@ -234,14 +230,14 @@ int hinic5_set_led_status(void *hwdev, enum mag_led_type type,
u16 out_size = sizeof(led_info);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EFAULT;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io)
return -EINVAL;
- memset(&led_info, 0, sizeof(led_info));
+ (void)memset_s(&led_info, sizeof(led_info), 0, sizeof(led_info));
led_info.function_id = hinic5_global_func_id(hwdev);
led_info.type = type;
@@ -249,8 +245,9 @@ int hinic5_set_led_status(void *hwdev, enum mag_led_type type,
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_LED_CFG, &led_info,
sizeof(led_info), &led_info, &out_size);
- if (err != 0 || led_info.head.status != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (led_info.head.status != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
err, led_info.head.status, out_size);
return -EIO;
}
@@ -266,13 +263,13 @@ int hinic5_set_link_settings(void *hwdev,
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !settings)
+ if ((hwdev == NULL) || (settings == NULL))
return -EINVAL;
- memset(&info, 0, sizeof(info));
+ (void)memset_s(&info, sizeof(info), 0, sizeof(info));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
info.port_id = hinic5_physical_port_id(hwdev);
@@ -283,8 +280,9 @@ int hinic5_set_link_settings(void *hwdev,
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_PORT_CFG, &info,
sizeof(info), &info, &out_size);
- if (err != 0 || out_size == 0 || info.head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (info.head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
err, info.head.status, out_size);
return -EIO;
}
@@ -292,21 +290,23 @@ int hinic5_set_link_settings(void *hwdev,
return info.head.status;
}
-int hinic5_get_bond_link_state(void *hwdev, struct hinic5_nic_io *nic_io, u8 *link_state)
+int hinic5_get_bond_link_state(void *hwdev, struct hinic5_nic_io *nic_io,
+ u8 *link_state)
{
int err;
- struct hinic5_bond_link_info bond_info = {0};
+ struct hinic5_bond_link_info bond_info = { 0 };
u16 out_size = sizeof(bond_info);
bond_info.port_id = hinic5_physical_port_id(hwdev);
err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFM,
- CFM_MPU_CMD_BOND_LINK_INFO_GET, &bond_info,
- sizeof(bond_info), &bond_info, &out_size,
- HINIC5_BOND_MSG_TIMEOUT_MS,
+ CFM_MPU_CMD_BOND_LINK_INFO_GET,
+ &bond_info, sizeof(bond_info), &bond_info,
+ &out_size, HINIC5_BOND_MSG_TIMEOUT_MS,
HINIC5_CHANNEL_NIC);
- if (err != 0 || out_size == 0 || bond_info.head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to get bond link state, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (bond_info.head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bond link state, err: %d, status: 0x%x, out size: 0x%x\n",
err, bond_info.head.status, out_size);
return -EIO;
}
@@ -323,24 +323,25 @@ int hinic5_get_link_state(void *hwdev, u8 *link_state)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !link_state)
+ if ((hwdev == NULL) || (link_state == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- /* If this device has half-offload bond enabled, need to get status from bond */
+ /* 如果此设备开启半卸载bond 那么需要从bond获取状态 */
if ((nic_io->feature_cap & NIC_F_HALF_BOND_OFFLOAD) != 0)
return hinic5_get_bond_link_state(hwdev, nic_io, link_state);
- memset(&get_link, 0, sizeof(get_link));
+ (void)memset_s(&get_link, sizeof(get_link), 0, sizeof(get_link));
get_link.port_id = hinic5_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_LINK_STATUS, &get_link,
sizeof(get_link), &get_link, &out_size);
- if (err != 0 || out_size == 0 || get_link.head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (get_link.head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
err, get_link.head.status, out_size);
return -EIO;
}
@@ -350,56 +351,65 @@ int hinic5_get_link_state(void *hwdev, u8 *link_state)
return 0;
}
-void hinic5_notify_vf_link_status(struct hinic5_nic_io *nic_io,
- u16 vf_id, u8 link_status)
+void hinic5_notify_vf_link_status(struct hinic5_nic_io *nic_io, u16 vf_id,
+ u8 link_status)
{
struct mag_cmd_get_link_status link;
struct vf_data_storage *vf_infos = nic_io->vf_infos;
u16 out_size = sizeof(link);
int err;
- memset(&link, 0, sizeof(link));
+ (void)memset_s(&link, sizeof(link), 0, sizeof(link));
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic5_physical_port_id(nic_io->hwdev);
- err = hinic5_mbox_to_vf_without_ack(nic_io->hwdev, vf_id, HINIC5_MOD_HILINK,
- MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), HINIC5_CHANNEL_NIC);
+ err = hinic5_mbox_to_vf_without_ack(nic_io->hwdev, vf_id,
+ HINIC5_MOD_HILINK,
+ MAG_CMD_GET_LINK_STATUS,
+ &link, sizeof(link),
+ HINIC5_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
- nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ nic_warn(nic_io->dev_hdl,
+ "VF%d not initialized, disconnect it\n",
HW_VF_ID_TO_OS(vf_id));
hinic5_unregister_vf(nic_io, vf_id);
return;
}
- if (err != 0 || out_size == 0 || link.head.status != 0)
+ if ((err != 0) || (out_size == 0) || (link.head.status != 0))
nic_err(nic_io->dev_hdl,
"Send link change event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
- HW_VF_ID_TO_OS(vf_id), err, link.head.status, out_size);
+ HW_VF_ID_TO_OS(vf_id), err, link.head.status,
+ out_size);
}
}
void hinic5_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
{
+ struct vf_data_storage *vf_info = NULL;
struct hinic5_nic_io *nic_io = NULL;
u16 i;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
- if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
+ vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, i);
+ if (vf_info && !vf_info->link_forced)
hinic5_notify_vf_link_status(nic_io, i, link_status);
}
}
-static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {"not set", "rsfec", "basefec",
- "nofec", "llrsfec"};
-static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {"not set", "10MB", "100MB", "1GB", "10GB",
- "25GB", "40GB", "50GB", "100GB", "200GB",
- "400GB", "800GB"};
-static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {"not set", "on", "off"};
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = { "not set", "rsfec",
+ "basefec", "nofec",
+ "llrsfec" };
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10Mbps", "100Mbps", "1Gbps", "10Gbps", "25Gbps",
+ "40Gbps", "50Gbps", "100Gbps", "200Gbps", "400Gbps", "800Gbps"
+};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = { "not set", "on",
+ "off" };
struct port_type_table {
u32 port_type;
@@ -407,15 +417,15 @@ struct port_type_table {
};
static const struct port_type_table port_optical_type_table_s[] = {
- {LINK_PORT_UNKNOWN, "UNKNOWN"},
- {LINK_PORT_OPTICAL_MM, "optical_sr"},
- {LINK_PORT_OPTICAL_SM, "optical_lr"},
- {LINK_PORT_PAS_COPPER, "copper"},
- {LINK_PORT_ACC, "ACC"},
- {LINK_PORT_BASET, "baset"},
- {LINK_PORT_AOC, "AOC"},
- {LINK_PORT_ELECTRIC, "electric"},
- {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+ { LINK_PORT_UNKNOWN, "UNKNOWN" },
+ { LINK_PORT_OPTICAL_MM, "optical_sr" },
+ { LINK_PORT_OPTICAL_SM, "optical_lr" },
+ { LINK_PORT_PAS_COPPER, "copper" },
+ { LINK_PORT_ACC, "ACC" },
+ { LINK_PORT_BASET, "baset" },
+ { LINK_PORT_AOC, "AOC" },
+ { LINK_PORT_ELECTRIC, "electric" },
+ { LINK_PORT_BACKBOARD_INTERFACE, "interface" },
};
static char *get_port_type_name(u32 type)
@@ -430,55 +440,64 @@ static char *get_port_type_name(u32 type)
}
static void get_port_type(struct hinic5_nic_io *nic_io,
- struct mag_cmd_event_port_info *info, char **port_type)
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
{
if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
*port_type = get_port_type_name(info->port_type);
else
- nic_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+ nic_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
}
-static const char *const sfp_type_list[] = { "sfp", "Qsfp", "OSFP", "DSFP"};
-
-static int get_port_temperature_power(const struct mag_cmd_event_port_info *info,
- char *str, u16 str_len)
+static const char *const sfp_type_list[] = { "sfp", "Qsfp", "OSFP", "DSFP" };
+static int
+get_port_temperature_power(const struct mag_cmd_event_port_info *info,
+ char *str, u16 str_len)
{
- char arr[CAP_INFO_MAX_LEN] = {0};
+ char arr[CAP_INFO_MAX_LEN] = { 0 };
int err = 0;
if (info->sfp_type < SFP_TYPE_COUNT) {
- err = snprintf(arr, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u",
- str, sfp_type_list[info->sfp_type], info->cable_temp);
+ err = sprintf_s(arr, CAP_INFO_MAX_LEN,
+ "%s, %s, Temperature: %u", str,
+ sfp_type_list[info->sfp_type],
+ info->cable_temp);
}
switch (info->sfp_type) {
case SFP_TYPE_SFP:
case SFP_TYPE_DSFP:
- err = snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
- arr, info->power[POWER_CHANNEL_INDEX_0],
- info->power[POWER_CHANNEL_INDEX_1]);
- break;
+ err = sprintf_s(str, CAP_INFO_MAX_LEN,
+ "%s, rx power: %uuW, tx power: %uuW", arr,
+ info->power[POWER_CHANNEL_INDEX_0],
+ info->power[POWER_CHANNEL_INDEX_1]);
+ break;
case SFP_TYPE_QSFP:
- err = snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW %uuW %uuW %uuW",
- arr, info->power[POWER_CHANNEL_INDEX_0],
- info->power[POWER_CHANNEL_INDEX_1],
- info->power[POWER_CHANNEL_INDEX_2],
- info->power[POWER_CHANNEL_INDEX_3]);
- break;
+ err = sprintf_s(str, CAP_INFO_MAX_LEN,
+ "%s, rx power: %uuW %uuW %uuW %uuW", arr,
+ info->power[POWER_CHANNEL_INDEX_0],
+ info->power[POWER_CHANNEL_INDEX_1],
+ info->power[POWER_CHANNEL_INDEX_2],
+ info->power[POWER_CHANNEL_INDEX_3]);
+ break;
case SFP_TYPE_OSFP:
- err = snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW %uuW %uuW %uuW",
- arr, info->power[POWER_CHANNEL_INDEX_0],
- info->power[POWER_CHANNEL_INDEX_1],
- info->power[POWER_CHANNEL_INDEX_2],
- info->power[POWER_CHANNEL_INDEX_3]);
- err = snprintf(str, CAP_INFO_MAX_LEN, "%s, %uuW %uuW %uuW %uuW",
- arr, info->osfp_power[POWER_CHANNEL_INDEX_0],
- info->osfp_power[POWER_CHANNEL_INDEX_1],
- info->osfp_power[POWER_CHANNEL_INDEX_2],
- info->osfp_power[POWER_CHANNEL_INDEX_3]);
+ err = sprintf_s(str, CAP_INFO_MAX_LEN,
+ "%s, rx power: %uuW %uuW %uuW %uuW", arr,
+ info->power[POWER_CHANNEL_INDEX_0],
+ info->power[POWER_CHANNEL_INDEX_1],
+ info->power[POWER_CHANNEL_INDEX_2],
+ info->power[POWER_CHANNEL_INDEX_3]);
+ err = sprintf_s(str, CAP_INFO_MAX_LEN,
+ "%s, %uuW %uuW %uuW %uuW", arr,
+ info->osfp_power[POWER_CHANNEL_INDEX_0],
+ info->osfp_power[POWER_CHANNEL_INDEX_1],
+ info->osfp_power[POWER_CHANNEL_INDEX_2],
+ info->osfp_power[POWER_CHANNEL_INDEX_3]);
break;
default:
- err = snprintf(str, CAP_INFO_MAX_LEN, "%s, Invalid SFP TYPE! ", arr);
+ err = sprintf_s(str, CAP_INFO_MAX_LEN, "%s, Invalid SFP TYPE! ",
+ arr);
break;
}
@@ -489,31 +508,33 @@ static int get_port_temperature_power(const struct mag_cmd_event_port_info *info
}
struct speed_mode_map_s speed_mode_map[] = {
- {PORT_SPEED_MODE_400G, PORT_SPEED_400G},
- {PORT_SPEED_MODE_800G, PORT_SPEED_800G},
+ { PORT_SPEED_MODE_400G, PORT_SPEED_400G },
+ { PORT_SPEED_MODE_800G, PORT_SPEED_800G },
};
u32 get_real_port_speed_from_inner_speed(u8 speed)
{
u32 i;
-
- if (speed <= PORT_SPEED_MODE_START) { /* Speed <= 200G is not mapped */
+ if (speed <= PORT_SPEED_MODE_START) { // 小于等于200G速率未映射
return speed;
}
- for (i = 0; i < ARRAY_SIZE(speed_mode_map); i++)
- if (speed_mode_map[i].speed_mode == speed)
+ for (i = 0; i < ARRAY_SIZE(speed_mode_map); i++) {
+ if (speed_mode_map[i].speed_mode == speed) {
return speed_mode_map[i].real_speed;
+ }
+ }
pr_err("unsupported port speed mode: 0x%x\n", speed);
return speed;
}
-static void print_cable_info(struct hinic5_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+static void print_cable_info(struct hinic5_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
{
- char tmp_str[CAP_INFO_MAX_LEN] = {0};
- char tmp_vendor[VENDOR_MAX_LEN] = {0};
- char tmp_vendor_sn[VENDOR_MAX_LEN] = {0};
+ char tmp_str[CAP_INFO_MAX_LEN] = { 0 };
+ char tmp_vendor[VENDOR_MAX_LEN] = { 0 };
+ char tmp_vendor_sn[VENDOR_MAX_LEN] = { 0 };
char *port_type = "Unknown port type";
int i;
int err = 0;
@@ -532,21 +553,26 @@ static void print_cable_info(struct hinic5_nic_io *nic_io, struct mag_cmd_event_
break;
}
- memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
- memcpy(tmp_vendor_sn, info->vendor_sn, sizeof(info->vendor_sn));
+ memcpy_s(tmp_vendor, sizeof(tmp_vendor), info->vendor_name,
+ sizeof(info->vendor_name));
+ memcpy_s(tmp_vendor_sn, sizeof(tmp_vendor_sn), info->vendor_sn,
+ sizeof(info->vendor_sn));
- err = snprintf(tmp_str, CAP_INFO_MAX_LEN,
- "Vendor: %s, %s, %s, length: %um, max_speed: %uGbps",
- tmp_vendor, tmp_vendor_sn, port_type, info->cable_length,
- get_real_port_speed_from_inner_speed(info->max_speed));
+ err = sprintf_s(tmp_str, CAP_INFO_MAX_LEN,
+ "Vendor: %s, %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, tmp_vendor_sn, port_type,
+ info->cable_length,
+ get_real_port_speed_from_inner_speed(info->max_speed));
if (err <= 0) {
nic_info(nic_io->dev_hdl, "Print vendor failed.\n");
return;
}
- if (info->port_type == LINK_PORT_OPTICAL_MM || info->port_type == LINK_PORT_OPTICAL_SM ||
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_OPTICAL_SM ||
info->port_type == LINK_PORT_AOC) {
- err = get_port_temperature_power(info, tmp_str, CAP_INFO_MAX_LEN);
+ err = get_port_temperature_power(info, tmp_str,
+ CAP_INFO_MAX_LEN);
if (err != 0)
return;
}
@@ -568,7 +594,8 @@ static void print_link_info(struct hinic5_nic_io *nic_io,
nic_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
if (info->an_state > PORT_CFG_AN_OFF) {
- nic_info(nic_io->dev_hdl, "an_state %u is invalid", info->an_state);
+ nic_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
return;
}
@@ -584,26 +611,31 @@ static void print_link_info(struct hinic5_nic_io *nic_io,
speed, fec, an_state);
}
-static void print_serdes_txrx_para_1872(struct hinic5_nic_io *nic_io,
- struct mag_cmd_event_port_info *info)
+static void print_serdes_txrx_para(struct hinic5_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
{
- u8 (*sds_txrx_para)[10] = info->sds_txrx_para;
+ u8(*sds_txrx_para)[10U] = info->sds_txrx_para;
u32 ds_mask = info->ds_mask;
u32 ds_id = 0;
- for (ds_id = 0; ds_id < 8U; ds_id++) { /* 1872 has 1 macro with 8 lanes */
+ for (ds_id = 0; ds_id < 8U; ds_id++) {
+ // 1872 只有1个macro,共8条lane; 1825 有2个macro, 共8条lane, 前4条lane来自macro8, 后4条lane来自macro9
if (((ds_mask >> ds_id) & 0x1) == 0x0) {
continue;
}
- nic_info(nic_io->dev_hdl,
- "ds_id: %u, TX pre2: %d, pre1 %d, main %u, post1: %d, post2: %d, RX cur_boost_index: %u, cur_gain_index: %u\n",
- ds_id, (s8)sds_txrx_para[ds_id][0], (s8)sds_txrx_para[ds_id][1],
- sds_txrx_para[ds_id][2], (s8)sds_txrx_para[ds_id][3],
- (s8)sds_txrx_para[ds_id][4], sds_txrx_para[ds_id][5],
- sds_txrx_para[ds_id][6]);
+ nic_info(
+ nic_io->dev_hdl,
+ "ds_id: %u, TX pre3: %d, pre2: %d, pre1 %d, main %u, post1: %d, post2: %d, RX cur_boost_index: %u, cur_gain_index: %u\n",
+ ds_id, (s8)sds_txrx_para[ds_id][7U],
+ (s8)sds_txrx_para[ds_id][0],
+ (s8)sds_txrx_para[ds_id][1], sds_txrx_para[ds_id][2U],
+ (s8)sds_txrx_para[ds_id][3U],
+ (s8)sds_txrx_para[ds_id][4U], sds_txrx_para[ds_id][5U],
+ sds_txrx_para[ds_id][6U]);
}
}
-void hinic5_print_port_info(struct hinic5_nic_io *nic_io, struct mag_cmd_event_port_info *port_info,
+void print_port_info(struct hinic5_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
enum hinic5_nic_event_type type)
{
print_cable_info(nic_io, port_info);
@@ -613,19 +645,27 @@ void hinic5_print_port_info(struct hinic5_nic_io *nic_io, struct mag_cmd_event_p
if (type == EVENT_NIC_LINK_UP)
return;
- nic_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
- port_info->pma_ctrl == 1 ? "off" : "on",
- (port_info->tx_enable != 0) ? "enable" : "disable",
- (port_info->rx_enable != 0) ? "enable" : "disable", port_info->pma_fifo_reg,
- port_info->pma_signal_ok_reg, port_info->rf_lf);
- nic_info(nic_io->dev_hdl, "alos: 0x%x, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
- port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
- port_info->pcs_link, port_info->pcs_mac_link, port_info->pcs_err_cnt);
- nic_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
- port_info->his_link_machine_state, port_info->cur_link_machine_state);
- if (HINIC5_SUPPORT_FEATURE(nic_io->hwdev, HTN_CMDQ)) { /* 1872 */
- print_serdes_txrx_para_1872(nic_io, port_info);
- }
+ nic_info(
+ nic_io->dev_hdl,
+ "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ (port_info->tx_enable != 0) ? "enable" : "disable",
+ (port_info->rx_enable != 0) ? "enable" : "disable",
+ port_info->pma_fifo_reg, port_info->pma_signal_ok_reg,
+ port_info->rf_lf);
+ nic_info(
+ nic_io->dev_hdl,
+ "alos: 0x%x, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ nic_info(
+ nic_io->dev_hdl,
+ "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+
+ print_serdes_txrx_para(nic_io, port_info);
}
static int hinic5_get_vf_link_status_msg_handler(struct hinic5_nic_io *nic_io,
@@ -641,8 +681,7 @@ static int hinic5_get_vf_link_status_msg_handler(struct hinic5_nic_io *nic_io,
link_up = vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up;
if (link_forced)
- get_link->status = link_up ?
- HINIC5_LINK_UP : HINIC5_LINK_DOWN;
+ get_link->status = link_up ? HINIC5_LINK_UP : HINIC5_LINK_DOWN;
else
get_link->status = nic_io->link_status;
@@ -658,7 +697,7 @@ int hinic5_refresh_nic_cfg(void *hwdev, struct mag_port_info *port_info)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return -ENODEV;
}
@@ -666,7 +705,8 @@ int hinic5_refresh_nic_cfg(void *hwdev, struct mag_port_info *port_info)
if (HINIC5_SUPPORT_RATE_LIMIT(hwdev)) {
err = hinic5_set_pf_rate(hwdev, port_info->speed);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to refresh tx pf bandwidth limit\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to refresh tx pf bandwidth limit\n");
return err;
}
}
@@ -678,18 +718,23 @@ static void get_port_info(void *hwdev,
const struct mag_cmd_get_link_status *link_status,
struct hinic5_event_link_info *link_info)
{
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
struct hinic5_nic_io *nic_io = NULL;
int err;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
- if ((hinic5_func_type(hwdev) != TYPE_VF) && link_status->status != 0) {
- err = hinic5_get_port_info(hwdev, &port_info, HINIC5_CHANNEL_NIC);
+ if ((hinic5_func_type(hwdev) != TYPE_VF) &&
+ (link_status->status != 0)) {
+ err = hinic5_get_port_info(hwdev, &port_info,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
+ if (err == -EOPNOTSUPP) {
+ return;
+ }
nic_warn(nic_io->dev_hdl, "Failed to get port info\n");
} else {
link_info->valid = 1;
@@ -703,27 +748,31 @@ static void get_port_info(void *hwdev,
}
}
-static void link_status_event_handler(void *hwdev, void *buf_in,
- u16 in_size, void *buf_out, u16 *out_size)
+static void link_status_event_handler(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
{
struct mag_cmd_get_link_status *link_status = buf_in;
struct mag_cmd_get_link_status *ret_link_status = NULL;
- struct hinic5_event_info event_info = {0};
- struct hinic5_event_link_info *link_info = (void *)event_info.event_data;
+ struct hinic5_event_info event_info = { 0 };
+ struct hinic5_event_link_info *link_info =
+ (void *)event_info.event_data;
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- /* After bond is enabled, bond will notify link status */
- if (!nic_io || ((nic_io->feature_cap & NIC_F_HALF_BOND_OFFLOAD) != 0))
+ /* 开启bond后由bond来通知link状态 */
+ if (nic_io == NULL ||
+ ((nic_io->feature_cap & NIC_F_HALF_BOND_OFFLOAD) != 0))
return;
if (in_size != sizeof(*link_status)) {
- nic_err(nic_io->dev_hdl, "Invalid link status event cmd, length: %u, should be %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Invalid link status event cmd, length: %u, should be %lu\n",
in_size, sizeof(*link_status));
return;
}
- nic_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
+ nic_info(nic_io->dev_hdl,
+ "Link status report received, func_id: %u, status: %u\n",
hinic5_global_func_id(hwdev), link_status->status);
hinic5_link_event_stats(hwdev, link_status->status);
@@ -732,8 +781,8 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
get_port_info(hwdev, link_status, link_info);
event_info.service = EVENT_SRV_NIC;
- event_info.type = (link_status->status != 0) ?
- EVENT_NIC_LINK_UP : EVENT_NIC_LINK_DOWN;
+ event_info.type = (link_status->status != 0) ? EVENT_NIC_LINK_UP :
+ EVENT_NIC_LINK_DOWN;
hinic5_event_callback(hwdev, &event_info);
@@ -750,28 +799,29 @@ static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_event_port_info *port_info = buf_in;
struct hinic5_nic_io *nic_io = NULL;
- struct hinic5_event_info event_info;
enum hinic5_nic_event_type type;
- if (!hwdev) {
+ if (hwdev == NULL) {
pr_err("hwdev is NULL\n");
return;
}
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
if (in_size != sizeof(*port_info)) {
- nic_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ nic_info(nic_io->dev_hdl,
+ "Invalid port info message size %u, should be %lu\n",
in_size, sizeof(*port_info));
return;
}
- /* If bond is enabled, skip processing */
+ /* 如果开启bond则不处理 */
if ((nic_io->feature_cap & NIC_F_HALF_BOND_OFFLOAD) != 0) {
- nic_info(nic_io->dev_hdl, "bond enable ignore port event type: %d\n",
+ nic_info(nic_io->dev_hdl,
+ "bond enable ignore port event type: %d\n",
port_info->event_type);
return;
}
@@ -779,21 +829,8 @@ static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
type = port_info->event_type;
- if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
- nic_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
- type);
- return;
- }
-
- hinic5_print_port_info(nic_io, port_info, type);
-
- memset(&event_info, 0, sizeof(event_info));
- event_info.service = EVENT_SRV_NIC;
- event_info.type = type;
-
- *out_size = sizeof(*port_info);
- hinic5_event_callback(hwdev, &event_info);
+ print_port_info(nic_io, port_info, type);
}
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
@@ -806,18 +843,20 @@ static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_event_info event_info;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
if (in_size != sizeof(*plug_event)) {
- nic_err(nic_io->dev_hdl, "Invalid cable plug cmd, length: %u, should be %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Invalid cable plug cmd, length: %u, should be %lu\n",
in_size, sizeof(*plug_event));
return;
}
- /* If bond is enabled, skip processing */
+ /* 如果开启bond则不处理 */
if ((nic_io->feature_cap & NIC_F_HALF_BOND_OFFLOAD) != 0) {
- nic_info(nic_io->dev_hdl, "bond enable ignore cable plug event\n");
+ nic_info(nic_io->dev_hdl,
+ "bond enable ignore cable plug event\n");
return;
}
@@ -830,12 +869,13 @@ static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- memset(&event_info, 0, sizeof(event_info));
+ (void)memset_s(&event_info, sizeof(event_info), 0, sizeof(event_info));
event_info.service = EVENT_SRV_NIC;
event_info.type = EVENT_NIC_PORT_MODULE_EVENT;
- ((struct hinic5_port_module_event *)(void *)event_info.event_data)->type =
- (plug_event->status != 0) ? HINIC5_PORT_MODULE_CABLE_PLUGGED :
- HINIC5_PORT_MODULE_CABLE_UNPLUGGED;
+ ((struct hinic5_port_module_event *)(void *)event_info.event_data)
+ ->type = (plug_event->status != 0) ?
+ HINIC5_PORT_MODULE_CABLE_PLUGGED :
+ HINIC5_PORT_MODULE_CABLE_UNPLUGGED;
*out_size = sizeof(*plug_event);
plug_event = buf_out;
@@ -853,10 +893,11 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
if (in_size != sizeof(*sfp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
@@ -864,27 +905,30 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
rt_cmd = &nic_io->nic_cfg.rt_cmd;
rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
- memcpy(&rt_cmd->std_sfp_info, sfp_info, sizeof(struct mag_cmd_get_xsfp_info));
+ (void)memcpy_s(&rt_cmd->std_sfp_info,
+ sizeof(struct mag_cmd_get_xsfp_info), sfp_info,
+ sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
-
#define xsfp_tlv_pre_info_len 4
static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, const u16 *out_size)
{
- struct tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
struct hinic5_port_routine_cmd *rt_cmd = NULL;
struct hinic5_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic5_nic_io *nic_io = NULL;
- size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) - xsfp_tlv_pre_info_len;
+ size_t cpy_len =
+ in_size - sizeof(struct mgmt_msg_head) - xsfp_tlv_pre_info_len;
+ u32 ret;
if (in_size <= sizeof(struct mgmt_msg_head) + xsfp_tlv_pre_info_len)
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -892,7 +936,13 @@ static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
- memcpy(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf, xsfp_tlv_info->tlv_buf, cpy_len);
+ ret = (u32)memcpy_s(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf,
+ XSFP_CMIS_INFO_MAX_SIZE, xsfp_tlv_info->tlv_buf,
+ cpy_len);
+ if (ret != 0) {
+ nic_err(nic_io->dev_hdl, "memcpy failed length: %lu, ret %d\n",
+ cpy_len, ret);
+ }
rt_cmd->mpu_send_sfp_info = false;
rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
@@ -907,17 +957,19 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
if (in_size != sizeof(*sfp_abs)) {
- nic_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
- memcpy(&rt_cmd->abs, sfp_abs, sizeof(struct mag_cmd_get_xsfp_present));
+ (void)memcpy_s(&rt_cmd->abs, sizeof(struct mag_cmd_get_xsfp_present),
+ sfp_abs, sizeof(struct mag_cmd_get_xsfp_present));
rt_cmd->mpu_send_sfp_abs = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -933,10 +985,10 @@ bool hinic5_if_sfp_absent(void *hwdev)
bool sfp_abs_status = 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return true;
- memset(&sfp_abs, 0, sizeof(sfp_abs));
+ (void)memset_s(&sfp_abs, sizeof(sfp_abs), 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
@@ -953,10 +1005,9 @@ bool hinic5_if_sfp_absent(void *hwdev)
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
sfp_abs.port_id = port_id;
- err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_PRESENT,
- &sfp_abs, sizeof(sfp_abs), &sfp_abs,
- &out_size);
- if (sfp_abs.head.status != 0 || err != 0 || out_size == 0) {
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_PRESENT, &sfp_abs,
+ sizeof(sfp_abs), &sfp_abs, &out_size);
+ if ((sfp_abs.head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
port_id, err, sfp_abs.head.status, out_size);
@@ -966,39 +1017,51 @@ bool hinic5_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
-int hinic5_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
- const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req)
+int hinic5_get_sfp_tlv_info(
+ void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req)
{
struct hinic5_nic_io *nic_io = NULL;
struct hinic5_port_routine_cmd_extern *rt_cmd_ext = NULL;
u16 out_size = sizeof(*sfp_tlv_info);
int err;
- if (!hwdev || !sfp_tlv_info)
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
- if (rt_cmd_ext->mpu_send_xsfp_tlv_info) {
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info, sizeof(*sfp_tlv_info));
+ (void)memcpy_s(sfp_tlv_info, sizeof(*sfp_tlv_info),
+ &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return 0;
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO, (void *)sfp_tlv_info_req,
- sizeof(*sfp_tlv_info_req), sfp_tlv_info, &out_size);
- if (sfp_tlv_info->head.status != 0 || err != 0 || out_size == 0) {
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req), sfp_tlv_info,
+ &out_size);
+
+ if (sfp_tlv_info->head.status == HINIC5_LOGICAL_OPTICAL_UNSUPPORTED ||
+ sfp_tlv_info->head.status ==
+ HINIC5_MGMT_CMD_UNSUPPORTED) { /* ethtool,返回不支持 */
+ return -EOPNOTSUPP;
+ }
+
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic5_physical_port_id(hwdev), err,
@@ -1014,13 +1077,13 @@ int hinic5_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
struct hinic5_nic_io *nic_io = NULL;
struct hinic5_port_routine_cmd *rt_cmd = NULL;
u16 out_size = sizeof(*sfp_info);
- int err = 0;
+ int err;
- if (!hwdev || !sfp_info)
+ if ((hwdev == NULL) || (sfp_info == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
@@ -1030,7 +1093,8 @@ int hinic5_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EIO;
}
- memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
+ err = memcpy_s(sfp_info, sizeof(*sfp_info),
+ &rt_cmd->std_sfp_info, sizeof(*sfp_info));
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return (err == 0) ? 0 : -ENOMEM;
}
@@ -1040,10 +1104,12 @@ int hinic5_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status == HINIC5_MGMT_CMD_UNSUPPORTED)
+ if (sfp_info->head.status == HINIC5_MGMT_CMD_UNSUPPORTED ||
+ sfp_info->head.status == HINIC5_LOGICAL_OPTICAL_UNSUPPORTED) {
return -EOPNOTSUPP;
+ }
- if (sfp_info->head.status != 0 || err != 0 || out_size == 0) {
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic5_physical_port_id(hwdev), err,
@@ -1057,32 +1123,34 @@ int hinic5_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
int hinic5_get_sfp_eeprom(void *hwdev, u8 *data, u32 len, u32 offset)
{
struct mag_cmd_get_xsfp_info sfp_info;
- int err = 0;
+ int err;
- if (!hwdev || !data || len > PAGE_SIZE)
+ if ((hwdev == NULL) || (data == NULL) || len > PAGE_SIZE)
return -EINVAL;
if (hinic5_if_sfp_absent(hwdev))
return -ENXIO;
- memset(&sfp_info, 0, sizeof(sfp_info));
+ (void)memset_s(&sfp_info, sizeof(sfp_info), 0, sizeof(sfp_info));
err = hinic5_get_sfp_info(hwdev, &sfp_info);
if (err != 0)
return err;
- memcpy(data, sfp_info.sfp_info + offset, len);
+ err = memcpy_s(data, len, sfp_info.sfp_info + offset, len);
return (err == 0) ? 0 : -ENOMEM;
}
-static void hinic5_prase_cmis_tlp_info(u8 *data, u32 len, u8 *sfp_tlv_info, u32 offset)
+static void hinic5_prase_cmis_tlp_info(u8 *data, u32 len, u8 *sfp_tlv_info,
+ u32 offset)
{
struct mgmt_tlv_info *tlv_info = NULL;
u8 *tlv_buf = sfp_tlv_info;
bool need_continue = true;
u8 temp_tlv_info[XSFP_CMIS_INFO_MAX_SIZE];
u32 temp_offset = 0;
+ u32 copy_size = 0;
while (need_continue) {
tlv_info = (struct mgmt_tlv_info *)tlv_buf;
@@ -1094,10 +1162,19 @@ static void hinic5_prase_cmis_tlp_info(u8 *data, u32 len, u8 *sfp_tlv_info, u32
break;
}
- memcpy(temp_tlv_info + temp_offset,
- tlv_buf + MGMT_TLV_U32_SIZE + sizeof(struct mgmt_tlv_info),
- tlv_info->length - MGMT_TLV_U32_SIZE);
- temp_offset += tlv_info->length - MGMT_TLV_U32_SIZE;
+ copy_size = tlv_info->length - MGMT_TLV_U32_SIZE;
+
+ if (temp_offset + copy_size > XSFP_CMIS_INFO_MAX_SIZE) {
+ need_continue = false;
+ break;
+ }
+
+ (void)memcpy_s(temp_tlv_info + temp_offset, copy_size,
+ tlv_buf + MGMT_TLV_U32_SIZE +
+ sizeof(struct mgmt_tlv_info),
+ copy_size);
+ temp_offset += copy_size;
+ break;
case MAG_XSFP_TYPE_WIRE_TYPE:
break;
@@ -1106,10 +1183,15 @@ static void hinic5_prase_cmis_tlp_info(u8 *data, u32 len, u8 *sfp_tlv_info, u32
need_continue = false;
break;
}
-
tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
}
- memcpy(data, temp_tlv_info + offset, len);
+
+ if (offset >= temp_offset || offset + len > temp_offset) {
+ (void)memset_s(data, len, 0, len);
+ return;
+ }
+
+ (void)memcpy_s(data, len, temp_tlv_info + offset, len);
}
int hinic5_get_cmis_eeprom(void *hwdev, u8 *data, u32 len, u32 offset)
@@ -1118,14 +1200,16 @@ int hinic5_get_cmis_eeprom(void *hwdev, u8 *data, u32 len, u32 offset)
struct tag_mag_cmd_get_xsfp_tlv_req sfp_tlv_info_req;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
if (hinic5_if_sfp_absent(hwdev))
return -ENXIO;
- memset(&sfp_tlv_info, 0, sizeof(sfp_tlv_info));
- memset(&sfp_tlv_info_req, 0, sizeof(sfp_tlv_info_req));
+ (void)memset_s(&sfp_tlv_info, sizeof(sfp_tlv_info), 0,
+ sizeof(sfp_tlv_info));
+ (void)memset_s(&sfp_tlv_info_req, sizeof(sfp_tlv_info_req), 0,
+ sizeof(sfp_tlv_info_req));
sfp_tlv_info_req.port_id = hinic5_physical_port_id(hwdev);
sfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
@@ -1139,15 +1223,15 @@ int hinic5_get_cmis_eeprom(void *hwdev, u8 *data, u32 len, u32 offset)
}
u8 support_page[CMIS_MAX_PAGES] = {
- HINIC5_PAGE_L00_H00_OFFSET, HINIC5_PAGE_H01_OFFSET,
- HINIC5_PAGE_H02_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
- HINIC5_PAGE_H10_OFFSET, HINIC5_PAGE_H11_OFFSET
+ HINIC5_PAGE_L00_H00_OFFSET, HINIC5_PAGE_H01_OFFSET,
+ HINIC5_PAGE_H02_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_INVALID_OFFSET, HINIC5_PAGE_INVALID_OFFSET,
+ HINIC5_PAGE_H10_OFFSET, HINIC5_PAGE_H11_OFFSET
};
int hinic5_eeprom_page_check(u8 page_id, u32 offset, u32 len)
@@ -1159,17 +1243,20 @@ int hinic5_eeprom_page_check(u8 page_id, u32 offset, u32 len)
page_offset = support_page[page_id];
- if (page_offset == HINIC5_PAGE_INVALID_OFFSET)
+ if (page_offset == HINIC5_PAGE_INVALID_OFFSET) {
return -EOPNOTSUPP;
+ }
- if (len == 0 ||
- page_offset * QSFP_CMIS_PAGE_SIZE + offset + len >= XSFP_CMIS_INFO_MAX_SIZE)
+ if (len == 0 || page_offset * QSFP_CMIS_PAGE_SIZE + offset + len >=
+ XSFP_CMIS_INFO_MAX_SIZE) {
return -EINVAL;
+ }
return 0;
}
-int hinic5_get_cmis_eeprom_by_page(void *hwdev, u8 page_id, u32 offset, u8 *data, u32 len)
+int hinic5_get_cmis_eeprom_by_page(void *hwdev, u8 page_id, u32 offset,
+ u8 *data, u32 len)
{
u32 data_offset;
@@ -1183,39 +1270,41 @@ static void process_sfp_data(u8 *sfp_data, u8 *sfp_type, u8 *sfp_type_ext)
{
*sfp_type = sfp_data[0x0];
- if (*sfp_type == MODULE_TYPE_SFF8024_ID_QSFP_PLUS_CMIS)
+ if (*sfp_type == MODULE_TYPE_SFF8024_ID_QSFP_PLUS_CMIS) {
*sfp_type_ext = sfp_data[CMIS_UPPER_PAGE_00H_EXT_ID_OFFSET];
- else
+ } else {
*sfp_type_ext = sfp_data[0x1];
+ }
}
int hinic5_get_sfp_cmis_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
{
struct hinic5_nic_io *nic_io = NULL;
struct hinic5_port_routine_cmd_extern *rt_cmd_ext = NULL;
- u8 sfp_data[XSFP_CMIS_INFO_MAX_SIZE] = {0};
+ u8 sfp_data[XSFP_CMIS_INFO_MAX_SIZE] = { 0 };
int err;
- if (!hwdev || !sfp_type || !sfp_type_ext)
+ if ((hwdev == NULL) || (sfp_type == NULL) || (sfp_type_ext == NULL))
return -EINVAL;
if (hinic5_if_sfp_absent(hwdev))
return -ENXIO;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
- if (rt_cmd_ext->mpu_send_xsfp_tlv_info) {
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- hinic5_prase_cmis_tlp_info(sfp_data, XSFP_CMIS_INFO_MAX_SIZE,
- rt_cmd_ext->std_xsfp_tlv_info.tlv_buf, 0);
+ hinic5_prase_cmis_tlp_info(
+ sfp_data, XSFP_CMIS_INFO_MAX_SIZE,
+ rt_cmd_ext->std_xsfp_tlv_info.tlv_buf, 0);
process_sfp_data(sfp_data, sfp_type, sfp_type_ext);
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
@@ -1241,14 +1330,14 @@ int hinic5_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
int err;
- if (!hwdev || !sfp_type || !sfp_type_ext)
+ if ((hwdev == NULL) || (sfp_type == NULL) || (sfp_type_ext == NULL))
return -EINVAL;
if (hinic5_if_sfp_absent(hwdev))
return -ENXIO;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -1277,34 +1366,38 @@ int hinic5_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return 0;
}
-int hinic5_set_link_status_follow(void *hwdev, enum hinic5_link_follow_status status)
+int hinic5_set_link_status_follow(void *hwdev,
+ enum hinic5_link_follow_status status)
{
struct mag_cmd_set_link_follow follow;
struct hinic5_nic_io *nic_io = NULL;
u16 out_size = sizeof(follow);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (status >= HINIC5_LINK_FOLLOW_STATUS_MAX) {
- nic_err(nic_io->dev_hdl, "Invalid link follow status: %d\n", status);
+ nic_err(nic_io->dev_hdl, "Invalid link follow status: %d\n",
+ status);
return -EINVAL;
}
- memset(&follow, 0, sizeof(follow));
+ (void)memset_s(&follow, sizeof(follow), 0, sizeof(follow));
follow.function_id = hinic5_global_func_id(hwdev);
follow.follow = status;
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_LINK_FOLLOW, &follow,
sizeof(follow), &follow, &out_size);
- if ((follow.head.status != HINIC5_MGMT_CMD_UNSUPPORTED && follow.head.status != 0) ||
- err != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Failed to set link status follow port status, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((follow.head.status != HINIC5_MGMT_CMD_UNSUPPORTED &&
+ (follow.head.status != 0)) ||
+ (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set link status follow port status, err: %d, status: 0x%x, out size: 0x%x\n",
err, follow.head.status, out_size);
return -EFAULT;
}
@@ -1314,16 +1407,18 @@ int hinic5_set_link_status_follow(void *hwdev, enum hinic5_link_follow_status st
int hinic5_update_pf_bw(void *hwdev)
{
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
struct hinic5_nic_io *nic_io = NULL;
int err;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- if (hinic5_func_type(hwdev) == TYPE_VF || !HINIC5_SUPPORT_RATE_LIMIT(hwdev)) {
- nic_err(nic_io->dev_hdl, "Current function doesn't support to set rate limit\n");
+ if (hinic5_func_type(hwdev) == TYPE_VF ||
+ !HINIC5_SUPPORT_RATE_LIMIT(hwdev)) {
+ nic_err(nic_io->dev_hdl,
+ "Current function doesn't support to set rate limit\n");
return -EINVAL;
}
@@ -1349,14 +1444,14 @@ int hinic5_set_pf_bw_limit(void *hwdev, u32 bw_limit)
u8 link_state = 0;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
if (hinic5_func_type(hwdev) == TYPE_VF)
return 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (bw_limit > MAX_LIMIT_BW) {
@@ -1371,7 +1466,8 @@ int hinic5_set_pf_bw_limit(void *hwdev, u32 bw_limit)
}
if (link_state == 0) {
- nic_err(nic_io->dev_hdl, "Link status must be up when setting pf tx rate\n");
+ nic_err(nic_io->dev_hdl,
+ "Link status must be up when setting pf tx rate\n");
return -EINVAL;
}
@@ -1391,14 +1487,14 @@ int hinic5_get_pf_bw_limit(void *hwdev, u32 *bw_limit)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !bw_limit)
+ if ((hwdev == NULL) || (bw_limit == NULL))
return -EINVAL;
if (hinic5_func_type(hwdev) == TYPE_VF)
return 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
*bw_limit = nic_io->nic_cfg.pf_bw_limit;
@@ -1414,19 +1510,18 @@ static const struct vf_msg_handler vf_mag_cmd_handler[] = {
};
/* pf/ppf handler mbox msg from vf */
-int hinic5_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
- u16 cmd, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
+int hinic5_pf_mag_mbox_handler(void *hwdev, u16 vf_id, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
{
int index, cmd_size = ARRAY_LEN(vf_mag_cmd_handler);
struct hinic5_nic_io *nic_io = NULL;
const struct vf_msg_handler *handler = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EFAULT;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EFAULT;
for (index = 0; index < cmd_size; index++) {
@@ -1436,8 +1531,9 @@ int hinic5_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
buf_out, out_size);
}
- nic_warn(nic_io->dev_hdl, "NO handler for mag cmd: %u received from vf id: %u\n",
- cmd, vf_id);
+ nic_warn(nic_io->dev_hdl,
+ "NO handler for mag cmd: %u received from vf id: %u\n", cmd,
+ vf_id);
return -EINVAL;
}
@@ -1471,24 +1567,24 @@ static struct nic_event_handler mag_cmd_handler[] = {
{
.cmd = MAG_CMD_GET_XSFP_TLV_INFO,
.handler = (void (*)(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size))port_xsfp_tlv_info_event,
+ void *buf_out,
+ u16 *out_size))port_xsfp_tlv_info_event,
},
};
-static int hinic5_mag_event_handler(void *hwdev, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
+static int hinic5_mag_event_handler(void *hwdev, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
{
struct hinic5_nic_io *nic_io = NULL;
int size = ARRAY_LEN(mag_cmd_handler);
int i;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
*out_size = 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EFAULT;
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
@@ -1506,21 +1602,19 @@ static int hinic5_mag_event_handler(void *hwdev, u16 cmd,
return 0;
}
-int hinic5_vf_mag_event_handler(void *hwdev, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
+int hinic5_vf_mag_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
{
- return hinic5_mag_event_handler(hwdev, cmd, buf_in, in_size,
- buf_out, out_size);
+ return hinic5_mag_event_handler(hwdev, cmd, buf_in, in_size, buf_out,
+ out_size);
}
/* pf/ppf handler mgmt cpu report hilink event */
-void hinic5_pf_mag_event_handler(void *pri_handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size)
+void hinic5_pf_mag_event_handler(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
{
- hinic5_mag_event_handler(pri_handle, cmd, buf_in, in_size,
- buf_out, out_size);
+ hinic5_mag_event_handler(pri_handle, cmd, buf_in, in_size, buf_out,
+ out_size);
}
static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
@@ -1529,11 +1623,13 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
{
int i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
- if (hinic5_func_type(hwdev) == TYPE_VF && (!hinic5_is_slave_host(hwdev)) &&
+ if (hinic5_func_type(hwdev) == TYPE_VF &&
+ (!hinic5_is_slave_host(hwdev)) &&
(!hinic5_is_vf_isolation(hwdev))) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
- return hinic5_mbox_to_pf(hwdev, HINIC5_MOD_HILINK, cmd, buf_in,
+ return hinic5_mbox_to_pf(
+ hwdev, HINIC5_MOD_HILINK, cmd, buf_in,
in_size, buf_out, out_size, 0, channel);
}
}
@@ -1560,7 +1656,7 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
int hinic5_set_fec(void *hwdev, u8 advertised_fec)
{
- struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct mag_cmd_cfg_fec_mode fec_msg = { 0 };
struct hinic5_nic_io *nic_io = NULL;
u16 out_size = sizeof(fec_msg);
int err;
@@ -1572,10 +1668,12 @@ int hinic5_set_fec(void *hwdev, u8 advertised_fec)
fec_msg.opcode = MAG_CMD_OPCODE_SET;
fec_msg.port_id = hinic5_physical_port_id(hwdev);
fec_msg.advertised_fec = advertised_fec;
- err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE, &fec_msg, sizeof(fec_msg),
- &fec_msg, &out_size, HINIC5_CHANNEL_NIC);
- if (err != 0 || fec_msg.head.status != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Set FEC mode failed, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE, &fec_msg,
+ sizeof(fec_msg), &fec_msg, &out_size,
+ HINIC5_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Set FEC mode failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, fec_msg.head.status, out_size);
return -EINVAL;
}
@@ -1584,7 +1682,7 @@ int hinic5_set_fec(void *hwdev, u8 advertised_fec)
int hinic5_get_fec(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
{
- struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct mag_cmd_cfg_fec_mode fec_msg = { 0 };
struct hinic5_nic_io *nic_io = NULL;
u16 out_size = sizeof(fec_msg);
int err;
@@ -1598,16 +1696,18 @@ int hinic5_get_fec(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
fec_msg.opcode = MAG_CMD_OPCODE_GET;
fec_msg.port_id = hinic5_physical_port_id(hwdev);
- err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE, &fec_msg, sizeof(fec_msg),
- &fec_msg, &out_size, HINIC5_CHANNEL_NIC);
- if (err != 0 || fec_msg.head.status != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Get FEC mode failed, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE, &fec_msg,
+ sizeof(fec_msg), &fec_msg, &out_size,
+ HINIC5_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Get FEC mode failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, fec_msg.head.status, out_size);
return -EINVAL;
+ } else {
+ *advertised_fec = fec_msg.advertised_fec;
+ *supported_fec = fec_msg.supported_fec;
}
- *advertised_fec = fec_msg.advertised_fec;
- *supported_fec = fec_msg.supported_fec;
-
return 0;
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic.h
index 74365082e..9cf69e498 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_H
#define HINIC5_NIC_H
@@ -31,12 +24,10 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
-#define SQ_CI_ADDR_SHIFT 2
-#define RQ_CI_ADDR_SHIFT 4
+#define SQ_CI_ADDR_SHIFT 2
+#define RQ_CI_ADDR_SHIFT 4
-#define HW_VF_ID_TO_OS_CO(vf_infos, vf) \
- ((struct vf_data_storage *)((u64)(vf_infos) + \
- (HW_VF_ID_TO_OS(vf) * sizeof(struct vf_data_storage))))
+#define HW_VF_ID_TO_OS_CO(vf_infos, vf) (&(vf_infos)[HW_VF_ID_TO_OS(vf)])
enum hinic5_link_port_type {
LINK_PORT_UNKNOWN,
@@ -119,20 +110,20 @@ struct hinic5_port_routine_cmd_extern {
};
struct hinic5_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct mag_port_info port_info;
+ struct mag_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_limit;
+ u32 rsvd2;
struct hinic5_port_routine_cmd rt_cmd;
@@ -144,9 +135,9 @@ struct hinic5_nic_cfg {
struct hinic5_nic_cmdq_ops;
struct hinic5_nic_aeqs {
- hinic5_aeq_swe_cb nic_aeq_swe_cb[HINIC5_NIC_FATAL_ERROR_MAX];
- void *nic_aeq_swe_data[HINIC5_NIC_FATAL_ERROR_MAX];
- unsigned long nic_aeq_sw_cb_state[HINIC5_NIC_FATAL_ERROR_MAX];
+ hinic5_aeq_swe_cb nic_aeq_swe_cb[HINIC5_NIC_FATAL_ERROR_MAX];
+ void *nic_aeq_swe_data[HINIC5_NIC_FATAL_ERROR_MAX];
+ unsigned long nic_aeq_sw_cb_state[HINIC5_NIC_FATAL_ERROR_MAX];
};
struct hinic5_nic_io {
@@ -164,11 +155,11 @@ struct hinic5_nic_io {
u16 num_qps;
u16 max_qps;
- /* TX direction ci */
+ /* TX方向的ci */
void *sq_ci_vaddr_base;
dma_addr_t sq_ci_dma_base;
- /* RX direction ci */
+ /* RX方向的ci */
void *rq_ci_vaddr_base;
dma_addr_t rq_ci_dma_base;
@@ -196,41 +187,39 @@ struct hinic5_nic_io {
struct vf_msg_handler {
u16 cmd;
- int (*handler)(struct hinic5_nic_io *nic_io, u16 vf,
- void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
+ int (*handler)(struct hinic5_nic_io *nic_io, u16 vf, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
};
struct nic_event_handler {
u16 cmd;
- void (*handler)(void *hwdev, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
+ void (*handler)(void *hwdev, void *buf_in, u16 in_size, void *buf_out,
+ u16 *out_size);
};
-int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_sq_attr *attr);
+int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io,
+ struct hinic5_sq_attr *attr);
-int hinic5_set_rq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_rq_attr *attr);
+int hinic5_set_rq_ci_ctx(struct hinic5_nic_io *nic_io,
+ struct hinic5_rq_attr *attr);
-int hinic5_l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
-int hinic5_l2nic_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+int l2nic_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u16 channel);
-int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid,
- u8 qos, int vf_id);
+int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid, u8 qos,
+ int vf_id);
-int hinic5_vf_event_handler(void *hwdev,
- u16 cmd, void *buf_in, u16 in_size,
+int hinic5_vf_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
-void hinic5_mgmt_event_handler(void *hwdev, u16 cmd,
- void *buf_in, u16 in_size,
+void hinic5_mgmt_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
-int hinic5_pf_mbox_handler(void *hwdev,
- u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
+int hinic5_pf_mbox_handler(void *hwdev, u16 vf_id, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
int hinic5_vf_func_init(struct hinic5_nic_io *nic_io);
@@ -242,20 +231,17 @@ void hinic5_notify_dcb_state_event(struct hinic5_nic_io *nic_io,
int hinic5_save_dcb_state(struct hinic5_nic_io *nic_io,
struct hinic5_dcb_state *dcb_state);
-void hinic5_notify_vf_link_status(struct hinic5_nic_io *nic_io,
- u16 vf_id, u8 link_status);
+void hinic5_notify_vf_link_status(struct hinic5_nic_io *nic_io, u16 vf_id,
+ u8 link_status);
-int hinic5_vf_mag_event_handler(void *hwdev, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size);
+int hinic5_vf_mag_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size);
-void hinic5_pf_mag_event_handler(void *pri_handle, u16 cmd,
- void *buf_in, u16 in_size, void *buf_out,
- u16 *out_size);
+void hinic5_pf_mag_event_handler(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
-int hinic5_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
- u16 cmd, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size);
+int hinic5_pf_mag_mbox_handler(void *hwdev, u16 vf_id, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
u8 hinic5_nic_aeqe_handler(void *hwdev, u8 event, u8 *data);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg.c
index 53c5f1787..0fb142114 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_cfg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -24,7 +17,7 @@
#include "ossl_knl.h"
#include "hinic5_crm.h"
#include "hinic5_hw.h"
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
#include "hinic5_nic_io.h"
#include "hinic5_srv_nic.h"
#include "hinic5_nic.h"
@@ -38,23 +31,25 @@
#include "hinic5_nic_cfg.h"
#ifdef __UEFI__
-#define memcmp CompareMem
+#define memcmp CompareMem
#endif
-int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_sq_attr *attr)
+int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io,
+ struct hinic5_sq_attr *attr)
{
struct hinic5_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
int err;
- if (!nic_io || !attr)
+ if ((nic_io == NULL) || (attr == NULL))
return -EINVAL;
- memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
+ (void)memset_s(&cons_idx_attr, sizeof(cons_idx_attr), 0,
+ sizeof(cons_idx_attr));
cons_idx_attr.func_idx = hinic5_global_func_id(nic_io->hwdev);
- cons_idx_attr.dma_attr_off = attr->dma_attr_off;
+ cons_idx_attr.dma_attr_off = attr->dma_attr_off;
cons_idx_attr.pending_limit = attr->pending_limit;
- cons_idx_attr.coalescing_time = attr->coalescing_time;
+ cons_idx_attr.coalescing_time = attr->coalescing_time;
if (attr->intr_en != 0) {
cons_idx_attr.intr_en = attr->intr_en;
@@ -64,10 +59,12 @@ int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
- if (err != 0 || out_size == 0 || cons_idx_attr.msg_head.status != 0) {
+ if ((err != 0) || (out_size == 0) ||
+ (cons_idx_attr.msg_head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to set ci attribute table, err: %d, status: 0x%x, out_size: 0x%x\n",
err, cons_idx_attr.msg_head.status, out_size);
@@ -77,45 +74,52 @@ int hinic5_set_sq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_sq_attr *at
return 0;
}
-int hinic5_set_rq_ci_ctx(struct hinic5_nic_io *nic_io, struct hinic5_rq_attr *attr)
+int hinic5_set_rq_ci_ctx(struct hinic5_nic_io *nic_io,
+ struct hinic5_rq_attr *attr)
{
struct hinic5_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
int err;
- if (!nic_io || !attr)
+ if ((nic_io == NULL) || (attr == NULL))
return -EINVAL;
- memset(&cons_idx_ctx, 0, sizeof(cons_idx_ctx));
+ (void)memset_s(&cons_idx_ctx, sizeof(cons_idx_ctx), 0,
+ sizeof(cons_idx_ctx));
cons_idx_ctx.cqe_type = attr->cqe_type;
cons_idx_ctx.rq_id = (u8)(attr->l2nic_rqn & 0xff);
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi =
+ upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo =
+ lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
- if (err != 0 || out_size == 0 ||
+ if ((err != 0) || (out_size == 0) ||
(cons_idx_ctx.msg_head.status != 0 &&
- cons_idx_ctx.msg_head.status != HINIC5_MGMT_CMD_UNSUPPORTED)) {
- nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ cons_idx_ctx.msg_head.status != HINIC5_MGMT_CMD_UNSUPPORTED)) {
+ nic_err(nic_io->dev_hdl,
+ "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
+ attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status,
+ out_size);
return -EFAULT;
}
return 0;
}
-#define PF_SET_VF_MAC(hwdev, status) \
- (hinic5_func_type(hwdev) == TYPE_VF && \
- (status) == HINIC5_PF_SET_VF_ALREADY)
+#define PF_SET_VF_MAC(hwdev, status) \
+ (hinic5_func_type(hwdev) == TYPE_VF && \
+ (status) == HINIC5_PF_SET_VF_ALREADY)
static int hinic5_check_mac_info(void *hwdev, u8 status, u16 vlan_id)
{
- if ((status != 0 && status != HINIC5_MGMT_STATUS_EXIST) ||
+ if (((status != 0) && (status != HINIC5_MGMT_STATUS_EXIST)) ||
(((vlan_id & CHECK_IPSU_15BIT) != 0) &&
status == HINIC5_MGMT_STATUS_EXIST)) {
if (PF_SET_VF_MAC(hwdev, status))
@@ -127,7 +131,7 @@ static int hinic5_check_mac_info(void *hwdev, u8 status, u16 vlan_id)
return 0;
}
-#define HINIC_VLAN_ID_MASK 0x7FFF
+#define HINIC_VLAN_ID_MASK 0x7FFF
int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
u16 channel)
@@ -137,13 +141,13 @@ int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !mac_addr)
+ if ((hwdev == NULL) || (mac_addr == NULL))
return -EINVAL;
- memset(&mac_info, 0, sizeof(mac_info));
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
@@ -156,12 +160,12 @@ int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
mac_info.vlan_id = vlan_id;
ether_addr_copy(mac_info.mac, mac_addr);
- err = hinic5_l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_SET_MAC,
- &mac_info, sizeof(mac_info),
- &mac_info, &out_size, channel);
- if (err != 0 || out_size == 0 ||
+ err = l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_SET_MAC,
+ &mac_info, sizeof(mac_info), &mac_info,
+ &out_size, channel);
+ if ((err != 0) || (out_size == 0) ||
(hinic5_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id) != 0)) {
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -169,12 +173,14 @@ int hinic5_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
- nic_warn(nic_io->dev_hdl, "PF has already set VF mac, Ignore set operation\n");
+ nic_warn(nic_io->dev_hdl,
+ "PF has already set VF mac, Ignore set operation\n");
return HINIC5_PF_SET_VF_ALREADY;
}
if (mac_info.msg_head.status == HINIC5_MGMT_STATUS_EXIST) {
- nic_warn(nic_io->dev_hdl, "MAC is repeated. Ignore update operation\n");
+ nic_warn(nic_io->dev_hdl,
+ "MAC is repeated. Ignore update operation\n");
return 0;
}
@@ -190,13 +196,13 @@ int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
struct hinic5_nic_io *nic_io = NULL;
int err = 0;
- if (!hwdev || !mac_addr)
+ if ((hwdev == NULL) || (mac_addr == NULL))
return -EINVAL;
- memset(&mac_info, 0, sizeof(mac_info));
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return -EINVAL;
}
@@ -211,23 +217,27 @@ int hinic5_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
mac_info.vlan_id = vlan_id;
ether_addr_copy(mac_info.mac, mac_addr);
- err = hinic5_l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_DEL_MAC,
+ err = l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_DEL_MAC,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
- if (err != 0 || out_size == 0)
+ if ((err != 0) || (out_size == 0)) {
goto ERR_DEL_MAC;
+ }
switch (mac_info.msg_head.status) {
case 0:
break;
case HINIC5_PF_SET_VF_ALREADY:
if (hinic5_func_type(hwdev) == TYPE_VF) {
- nic_warn(nic_io->dev_hdl, "PF has already set VF mac, Ignore delete operation.\n");
+ nic_warn(
+ nic_io->dev_hdl,
+ "PF has already set VF mac, Ignore delete operation.\n");
return HINIC5_PF_SET_VF_ALREADY;
}
break;
case HINIC5_DEL_MAC_NO_MATCH:
- nic_warn(nic_io->dev_hdl, "Del mac no match, Ignore delete operation.\n");
+ nic_warn(nic_io->dev_hdl,
+ "Del mac no match, Ignore delete operation.\n");
break;
default:
goto ERR_DEL_MAC;
@@ -251,13 +261,13 @@ int hinic5_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !old_mac || !new_mac)
+ if ((hwdev == NULL) || (old_mac == NULL) || (new_mac == NULL))
return -EINVAL;
- memset(&mac_info, 0, sizeof(mac_info));
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -270,12 +280,12 @@ int hinic5_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
ether_addr_copy(mac_info.old_mac, old_mac);
ether_addr_copy(mac_info.new_mac, new_mac);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_UPDATE_MAC,
- &mac_info, sizeof(mac_info),
- &mac_info, &out_size);
- if (err != 0 || out_size == 0 ||
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_UPDATE_MAC,
+ &mac_info, sizeof(mac_info), &mac_info,
+ &out_size);
+ if ((err != 0) || (out_size == 0) ||
(hinic5_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id) != 0)) {
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -283,12 +293,15 @@ int hinic5_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
}
if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
- nic_warn(nic_io->dev_hdl, "PF or Tool has already set VF MAC. Ignore update operation\n");
+ nic_warn(
+ nic_io->dev_hdl,
+ "PF or Tool has already set VF MAC. Ignore update operation\n");
return HINIC5_PF_SET_VF_ALREADY;
}
if (mac_info.msg_head.status == HINIC5_MGMT_STATUS_EXIST) {
- nic_warn(nic_io->dev_hdl, "MAC is repeated. Ignore update operation\n");
+ nic_warn(nic_io->dev_hdl,
+ "MAC is repeated. Ignore update operation\n");
return 0;
}
@@ -302,21 +315,20 @@ int hinic5_get_default_mac(void *hwdev, u8 *mac_addr)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !mac_addr)
+ if ((hwdev == NULL) || (mac_addr == NULL))
return -EINVAL;
- memset(&mac_info, 0, sizeof(mac_info));
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
mac_info.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_MAC,
- &mac_info, sizeof(mac_info),
- &mac_info, &out_size);
- if (err != 0 || out_size == 0 || mac_info.msg_head.status != 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_MAC, &mac_info,
+ sizeof(mac_info), &mac_info, &out_size);
+ if ((err != 0) || (out_size == 0) || (mac_info.msg_head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -335,20 +347,19 @@ static int hinic5_config_vlan(struct hinic5_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(vlan_info);
int err;
- memset(&vlan_info, 0, sizeof(vlan_info));
+ (void)memset_s(&vlan_info, sizeof(vlan_info), 0, sizeof(vlan_info));
vlan_info.opcode = opcode;
vlan_info.func_id = func_id;
vlan_info.vlan_id = vlan_id;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_CFG_FUNC_VLAN,
- &vlan_info, sizeof(vlan_info),
- &vlan_info, &out_size);
- if (err != 0 || out_size == 0 || vlan_info.msg_head.status != 0) {
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_CFG_FUNC_VLAN, &vlan_info,
+ sizeof(vlan_info), &vlan_info, &out_size);
+ if ((err != 0) || (out_size == 0) || (vlan_info.msg_head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to %s vlan, err: %d, status: 0x%x, out size: 0x%x\n",
- opcode == HINIC5_CMD_OP_ADD ? "add" : "delete",
- err, vlan_info.msg_head.status, out_size);
+ opcode == HINIC5_CMD_OP_ADD ? "add" : "delete", err,
+ vlan_info.msg_head.status, out_size);
return -EINVAL;
}
@@ -359,11 +370,11 @@ int hinic5_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
return hinic5_config_vlan(nic_io, HINIC5_CMD_OP_ADD, vlan_id, func_id);
}
@@ -372,11 +383,11 @@ int hinic5_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
return hinic5_config_vlan(nic_io, HINIC5_CMD_OP_DEL, vlan_id, func_id);
}
@@ -388,26 +399,27 @@ int hinic5_set_vport_enable(void *hwdev, u16 func_id, bool enable, u16 channel)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
- memset(&en_state, 0, sizeof(en_state));
+ (void)memset_s(&en_state, sizeof(en_state), 0, sizeof(en_state));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
en_state.func_id = func_id;
en_state.state = enable ? 1 : 0;
en_state.num_qps = (u8)nic_io->num_qps;
- en_state.rx_compact_wqe_en =
- (hinic5_get_rq_wqe_type(nic_io->hwdev) == HINIC5_COMPACT_RQ_WQE);
-
- err = hinic5_l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_SET_VPORT_ENABLE,
- &en_state, sizeof(en_state),
- &en_state, &out_size, channel);
- if (err != 0 || out_size == 0 || en_state.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set vport state, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
+ en_state.rx_compact_wqe_en = (hinic5_get_rq_wqe_type(nic_io->hwdev) ==
+ HINIC5_COMPACT_RQ_WQE);
+
+ err = l2nic_msg_to_mgmt_sync_ch(hwdev, HINIC5_NIC_CMD_SET_VPORT_ENABLE,
+ &en_state, sizeof(en_state), &en_state,
+ &out_size, channel);
+ if ((err != 0) || (out_size == 0) || (en_state.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set vport state, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, en_state.msg_head.status, out_size, channel);
return -EINVAL;
}
@@ -419,14 +431,15 @@ int hinic5_set_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !dcb_state)
+ if ((hwdev == NULL) || (dcb_state == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- if (memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)) == 0)
+ if (memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)) ==
+ 0)
return 0;
/* save in sdk, vf will get dcb state when probing */
@@ -442,14 +455,17 @@ int hinic5_get_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !dcb_state)
+ if ((hwdev == NULL) || (dcb_state == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memcpy(dcb_state, &nic_io->dcb_state, sizeof(*dcb_state));
+ if (memcpy_s(dcb_state, sizeof(*dcb_state), &nic_io->dcb_state,
+ sizeof(*dcb_state)) != 0) {
+ return -EINVAL;
+ }
return 0;
}
@@ -459,17 +475,18 @@ int hinic5_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !cos)
+ if ((hwdev == NULL) || (cos == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC5_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC5_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC5_DCB_DSCP)
return -EINVAL;
if (nic_io->dcb_state.dcb_on != 0) {
@@ -488,7 +505,10 @@ EXPORT_SYMBOL(hinic5_get_cos_by_pri);
int hinic5_save_dcb_state(struct hinic5_nic_io *nic_io,
struct hinic5_dcb_state *dcb_state)
{
- memcpy(&nic_io->dcb_state, dcb_state, sizeof(*dcb_state));
+ if (memcpy_s(&nic_io->dcb_state, sizeof(*dcb_state), dcb_state,
+ sizeof(*dcb_state)) != 0) {
+ return -EINVAL;
+ }
return 0;
}
@@ -500,13 +520,13 @@ int hinic5_get_pf_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state)
u16 out_size = sizeof(vf_dcb);
int err;
- if (!hwdev || !dcb_state)
+ if ((hwdev == NULL) || (dcb_state == NULL))
return -EINVAL;
- memset(&vf_dcb, 0, sizeof(vf_dcb));
+ (void)memset_s(&vf_dcb, sizeof(vf_dcb), 0, sizeof(vf_dcb));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (hinic5_func_type(hwdev) != TYPE_VF) {
@@ -514,15 +534,20 @@ int hinic5_get_pf_dcb_state(void *hwdev, struct hinic5_dcb_state *dcb_state)
return -EINVAL;
}
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_VF_COS, &vf_dcb,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_VF_COS, &vf_dcb,
sizeof(vf_dcb), &vf_dcb, &out_size);
- if (err != 0 || out_size == 0 || vf_dcb.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to get vf default cos, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (vf_dcb.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get vf default cos, err: %d, status: 0x%x, out size: 0x%x\n",
err, vf_dcb.msg_head.status, out_size);
return -EFAULT;
}
- memcpy(dcb_state, &vf_dcb.state, sizeof(*dcb_state));
+ if (memcpy_s(dcb_state, sizeof(*dcb_state), &vf_dcb.state,
+ sizeof(*dcb_state)) != 0) {
+ nic_err(nic_io->dev_hdl, "Get dcb state failed.\n");
+ return -ENOMEM;
+ }
/* Save dcb_state in hw for stateful module */
hinic5_save_dcb_state(nic_io, dcb_state);
@@ -538,7 +563,7 @@ static int hinic5_cfg_hw_pause(struct hinic5_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(pause_info);
int err;
- memset(&pause_info, 0, sizeof(pause_info));
+ (void)memset_s(&pause_info, sizeof(pause_info), 0, sizeof(pause_info));
pause_info.port_id = hinic5_physical_port_id(nic_io->hwdev);
pause_info.opcode = opcode;
@@ -548,17 +573,20 @@ static int hinic5_cfg_hw_pause(struct hinic5_nic_io *nic_io, u8 opcode,
pause_info.tx_pause = nic_pause->tx_pause;
}
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_CFG_PAUSE_INFO,
- &pause_info, sizeof(pause_info),
- &pause_info, &out_size);
- if (err != 0 || out_size == 0 || pause_info.msg_head.status != 0) {
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_CFG_PAUSE_INFO, &pause_info,
+ sizeof(pause_info), &pause_info,
+ &out_size);
+ if ((err != 0) || (out_size == 0) ||
+ (pause_info.msg_head.status != 0)) {
if (pause_info.msg_head.status == UNSUPPORT_SET_PAUSE) {
err = -EOPNOTSUPP;
- nic_err(nic_io->dev_hdl, "Can not set pause when pfc is enable\n");
+ nic_err(nic_io->dev_hdl,
+ "Can not set pause when pfc is enable\n");
} else {
err = -EFAULT;
- nic_err(nic_io->dev_hdl, "Failed to %s pause info, err: %d, status: 0x%x, out size: 0x%x\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s pause info, err: %d, status: 0x%x, out size: 0x%x\n",
opcode == HINIC5_CMD_OP_SET ? "set" : "get",
err, pause_info.msg_head.status, out_size);
}
@@ -580,11 +608,11 @@ int hinic5_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -614,11 +642,11 @@ int hinic5_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
struct hinic5_nic_io *nic_io = NULL;
int err = 0;
- if (!hwdev || !nic_pause)
+ if ((hwdev == NULL) || (nic_pause == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
err = hinic5_cfg_hw_pause(nic_io, HINIC5_CMD_OP_GET, nic_pause);
@@ -635,25 +663,26 @@ int hinic5_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
u16 out_size = sizeof(dcb_state);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
if (hinic5_func_type(hwdev) == TYPE_VF)
return 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&dcb_state, 0, sizeof(dcb_state));
+ (void)memset_s(&dcb_state, sizeof(dcb_state), 0, sizeof(dcb_state));
dcb_state.op_code = op_code;
dcb_state.state = state;
dcb_state.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
- if (err != 0 || dcb_state.head.status != 0 || out_size == 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_QOS_DCB_STATE,
+ &dcb_state, sizeof(dcb_state), &dcb_state,
+ &out_size);
+ if ((err != 0) || (dcb_state.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
err, dcb_state.head.status, out_size);
@@ -676,22 +705,23 @@ int hinic5_flush_qps_res(void *hwdev)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&sq_res, 0, sizeof(sq_res));
+ (void)memset_s(&sq_res, sizeof(sq_res), 0, sizeof(sq_res));
sq_res.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAR_QP_RESOURCE,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAR_QP_RESOURCE,
&sq_res, sizeof(sq_res), &sq_res,
&out_size);
- if (err != 0 || out_size == 0 || sq_res.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to clear sq resources, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (sq_res.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to clear sq resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, sq_res.msg_head.status, out_size);
return -EINVAL;
}
@@ -707,25 +737,27 @@ int hinic5_flush_qps_res_by_nums(void *hwdev, u16 qp_num)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&sq_res, 0, sizeof(sq_res));
+ (void)memset_s(&sq_res, sizeof(sq_res), 0, sizeof(sq_res));
sq_res.func_id = hinic5_global_func_id(hwdev);
sq_res.qp_num = qp_num;
- for (i = 0; i < qp_num; i++)
+ for (i = 0; i < qp_num; i++) {
sq_res.qp[i] = i;
+ }
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAR_ASSIGN_QP_RES,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CLEAR_ASSIGN_QP_RES,
&sq_res, sizeof(sq_res), &sq_res,
&out_size);
- if (err != 0 || out_size == 0 || sq_res.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to clear sq resources by num, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) || (sq_res.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to clear sq resources by num, err: %d, status: 0x%x, out size: 0x%x\n",
err, sq_res.msg_head.status, out_size);
return -EINVAL;
}
@@ -740,21 +772,23 @@ int hinic5_cache_out_qps_res(void *hwdev)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&qp_res, 0, sizeof(qp_res));
+ (void)memset_s(&qp_res, sizeof(qp_res), 0, sizeof(qp_res));
qp_res.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
- if (err != 0 || out_size == 0 || qp_res.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CACHE_OUT_QP_RES,
+ &qp_res, sizeof(qp_res), &qp_res,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (qp_res.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
return -EIO;
}
@@ -770,23 +804,23 @@ static int hinic5_get_vport_stats_by_cmdq(void *hwdev, u16 func_id,
u8 cmd;
int err;
- if (!hwdev || !stats)
+ if ((hwdev == NULL) || (stats == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
return -ENOMEM;
}
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_get_vport_stats(nic_io, cmd_buf, func_id);
- err = hinic5_cmdq_detail_resp(hwdev, HINIC5_MOD_L2NIC,
- cmd, cmd_buf, cmd_buf, NULL, 0,
- HINIC5_CHANNEL_NIC);
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_get_vport_stats(nic_io, cmd_buf,
+ func_id);
+ err = hinic5_cmdq_detail_resp(hwdev, HINIC5_MOD_L2NIC, cmd, cmd_buf,
+ cmd_buf, NULL, 0, HINIC5_CHANNEL_NIC);
if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to get vport stats\n");
goto get_indir_tbl_failed;
@@ -809,58 +843,65 @@ static int hinic5_get_vport_stats_by_mailbox(void *hwdev, u16 func_id,
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !stats)
+ if ((hwdev == NULL) || (stats == NULL))
return -EINVAL;
- memset(&stats_info, 0, sizeof(stats_info));
- memset(&vport_stats, 0, sizeof(vport_stats));
+ (void)memset_s(&stats_info, sizeof(stats_info), 0, sizeof(stats_info));
+ (void)memset_s(&vport_stats, sizeof(vport_stats), 0,
+ sizeof(vport_stats));
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
stats_info.func_id = func_id;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_VPORT_STAT,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_VPORT_STAT,
&stats_info, sizeof(stats_info),
&vport_stats, &out_size);
- if (err != 0 || out_size == 0 || vport_stats.msg_head.status != 0) {
+ if ((err != 0) || (out_size == 0) ||
+ (vport_stats.msg_head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
err, vport_stats.msg_head.status, out_size);
return -EFAULT;
}
- memcpy(stats, &vport_stats.stats, sizeof(*stats));
+ err = memcpy_s(stats, sizeof(*stats), &vport_stats.stats,
+ sizeof(*stats));
return (err == 0) ? 0 : -ENOMEM;
}
-int hinic5_get_vport_stats(void *hwdev, u16 func_id, struct hinic5_vport_stats *stats)
+int hinic5_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic5_vport_stats *stats)
{
- if (HINIC5_SUPPORT_GET_COUNTER_BY_CMDQ(hwdev))
+ if (HINIC5_SUPPORT_GET_COUNTER_BY_CMDQ(hwdev)) {
return hinic5_get_vport_stats_by_cmdq(hwdev, func_id, stats);
- else
+ } else {
return hinic5_get_vport_stats_by_mailbox(hwdev, func_id, stats);
+ }
}
-static int hinic5_set_function_table(struct hinic5_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic5_set_function_table(struct hinic5_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic5_func_tbl_cfg *cfg)
{
struct hinic5_cmd_set_func_tbl cmd_func_tbl;
u16 out_size = sizeof(cmd_func_tbl);
int err;
- memset(&cmd_func_tbl, 0, sizeof(cmd_func_tbl));
+ (void)memset_s(&cmd_func_tbl, sizeof(cmd_func_tbl), 0,
+ sizeof(cmd_func_tbl));
cmd_func_tbl.func_id = hinic5_global_func_id(nic_io->hwdev);
cmd_func_tbl.cfg_bitmap = cfg_bitmap;
cmd_func_tbl.tbl_cfg = *cfg;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_SET_FUNC_TBL,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_SET_FUNC_TBL,
&cmd_func_tbl, sizeof(cmd_func_tbl),
&cmd_func_tbl, &out_size);
- if (err != 0 || cmd_func_tbl.msg_head.status != 0 || out_size == 0) {
+ if ((err != 0) || (cmd_func_tbl.msg_head.status != 0) ||
+ (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to set func table, bitmap: 0x%x, err: %d, status: 0x%x, out size: 0x%x\n",
cfg_bitmap, err, cmd_func_tbl.msg_head.status,
@@ -873,11 +914,11 @@ static int hinic5_set_function_table(struct hinic5_nic_io *nic_io, u32 cfg_bitma
static int hinic5_init_function_table(struct hinic5_nic_io *nic_io)
{
- struct hinic5_func_tbl_cfg func_tbl_cfg = {0};
+ struct hinic5_func_tbl_cfg func_tbl_cfg = { 0 };
u32 cfg_bitmap = BIT(FUNC_CFG_INIT) | BIT(FUNC_CFG_MTU) |
- BIT(FUNC_CFG_RX_BUF_SIZE);
+ BIT(FUNC_CFG_RX_BUF_SIZE);
- if (hinic5_vram_get_kexec_flag() != 0)
+ if (vram5_get_kexec_flag() != 0)
return 0;
func_tbl_cfg.mtu = 0x3FFF; /* default, max mtu */
@@ -888,14 +929,14 @@ static int hinic5_init_function_table(struct hinic5_nic_io *nic_io)
int hinic5_set_port_mtu(void *hwdev, u16 new_mtu)
{
- struct hinic5_func_tbl_cfg func_tbl_cfg = {0};
+ struct hinic5_func_tbl_cfg func_tbl_cfg = { 0 };
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (new_mtu < HINIC5_MIN_MTU_SIZE) {
@@ -906,7 +947,8 @@ int hinic5_set_port_mtu(void *hwdev, u16 new_mtu)
}
if (new_mtu > HINIC5_MAX_JUMBO_FRAME_SIZE) {
- nic_err(nic_io->dev_hdl, "Invalid mtu size: %ubytes, mtu size > %ubytes",
+ nic_err(nic_io->dev_hdl,
+ "Invalid mtu size: %ubytes, mtu size > %ubytes",
new_mtu, HINIC5_MAX_JUMBO_FRAME_SIZE);
return -EINVAL;
}
@@ -923,29 +965,38 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
u16 out_size = sizeof(feature_nego);
int err;
- if (!hwdev || !s_feature || size > NIC_MAX_FEATURE_QWORD)
+ if ((hwdev == NULL) || (s_feature == NULL) ||
+ (size > NIC_MAX_FEATURE_QWORD))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&feature_nego, 0, sizeof(feature_nego));
+ (void)memset_s(&feature_nego, sizeof(feature_nego), 0,
+ sizeof(feature_nego));
feature_nego.func_id = hinic5_global_func_id(hwdev);
feature_nego.opcode = opcode;
if (opcode == HINIC5_CMD_OP_SET)
- memcpy(feature_nego.s_feature, s_feature, size * sizeof(u64));
+ if (memcpy_s(feature_nego.s_feature,
+ sizeof(feature_nego.s_feature), s_feature,
+ size * sizeof(u64)) != 0)
+ return -ENOMEM;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FEATURE_NEGO,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FEATURE_NEGO,
&feature_nego, sizeof(feature_nego),
&feature_nego, &out_size);
- if (err != 0 || out_size == 0 || feature_nego.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to negotiate nic feature, err:%d, status: 0x%x, out_size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) ||
+ (feature_nego.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to negotiate nic feature, err:%d, status: 0x%x, out_size: 0x%x\n",
err, feature_nego.msg_head.status, out_size);
return -EIO;
}
if (opcode == HINIC5_CMD_OP_GET)
- memcpy(s_feature, feature_nego.s_feature, size * sizeof(u64));
+ if (memcpy_s(s_feature, size * sizeof(u64),
+ feature_nego.s_feature, size * sizeof(u64)) != 0)
+ return -ENOMEM;
return 0;
}
@@ -957,22 +1008,23 @@ static int hinic5_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
u16 out_size = sizeof(cfg);
int err;
- if (!hwdev || !pf_bw_limit)
+ if ((hwdev == NULL) || (pf_bw_limit == NULL))
return -EINVAL;
- if (hinic5_func_type(hwdev) == TYPE_VF || !HINIC5_SUPPORT_RATE_LIMIT(hwdev))
+ if (hinic5_func_type(hwdev) == TYPE_VF ||
+ !HINIC5_SUPPORT_RATE_LIMIT(hwdev))
return 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
cfg.bios_cfg.func_id = (u8)hinic5_global_func_id(hwdev);
cfg.bios_cfg.func_valid = 1;
cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
- &cfg, &out_size);
- if (err != 0 || out_size == 0 || cfg.head.status != 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_BIOS_CFG, &cfg,
+ sizeof(cfg), &cfg, &out_size);
+ if ((err != 0) || (out_size == 0) || (cfg.head.status != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
@@ -981,11 +1033,13 @@ static int hinic5_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
/* check data is valid or not */
if (cfg.bios_cfg.signature != BIOS_CFG_SIGNATURE)
- nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
+ nic_warn(nic_io->dev_hdl,
+ "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
- nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n",
cfg.bios_cfg.pf_bw);
return -EINVAL;
}
@@ -1004,15 +1058,17 @@ int hinic5_set_pf_rate(void *hwdev, u8 speed_level)
u32 pf_rate;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
- 0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000, 400000, 800000
+ 0, 10, 100, 1000, 10000, 25000,
+ 40000, 50000, 100000, 200000, 400000, 800000
};
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl, "Invalid speed level: %hhu\n",
+ speed_level);
return -EINVAL;
}
@@ -1020,7 +1076,8 @@ int hinic5_set_pf_rate(void *hwdev, u8 speed_level)
pf_rate = 0;
} else {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / MAX_LIMIT_BW) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / MAX_LIMIT_BW) *
+ nic_io->nic_cfg.pf_bw_limit;
/* bandwidth limit is very small but not unlimit in this case */
if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
pf_rate = 1;
@@ -1031,12 +1088,17 @@ int hinic5_set_pf_rate(void *hwdev, u8 speed_level)
rate_cfg.pir = pf_rate;
rate_cfg.direct = NIC_RATE_DIRECT_TX_BW;
rate_cfg.cfg_mode = NIC_RATE_OP_UNUSE | NIC_RATE_OP_SET;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
- sizeof(rate_cfg), &rate_cfg_ret, &out_size);
- if (err != 0 || out_size == 0 || rate_cfg_ret.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg, sizeof(rate_cfg), &rate_cfg_ret,
+ &out_size);
+ if ((err != 0) || (out_size == 0) ||
+ (rate_cfg_ret.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg_ret.msg_head.status, out_size);
- return (rate_cfg_ret.msg_head.status != 0) ? rate_cfg_ret.msg_head.status : -EIO;
+ return (rate_cfg_ret.msg_head.status != 0) ?
+ rate_cfg_ret.msg_head.status :
+ -EIO;
}
return 0;
@@ -1052,10 +1114,11 @@ int hinic5_set_nic_feature_to_hw(void *hwdev)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- return nic_feature_nego(hwdev, HINIC5_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC5_CMD_OP_SET, &nic_io->feature_cap,
+ 1);
}
u64 hinic5_get_feature_cap(void *hwdev)
@@ -1063,7 +1126,7 @@ u64 hinic5_get_feature_cap(void *hwdev)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return 0;
return nic_io->feature_cap;
@@ -1074,18 +1137,21 @@ void hinic5_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
static int hinic5_init_nic_io(void *hwdev, void *dev_hdl,
- struct hinic5_nic_io **nic_io)
+ struct hinic5_nic_io **nic_io, u16 rx_buff_len)
{
- if (!hwdev || !dev_hdl)
+ int err;
+
+ if (hwdev == NULL || dev_hdl == NULL)
return -EINVAL;
*nic_io = kzalloc(sizeof(**nic_io), GFP_KERNEL);
@@ -1102,9 +1168,28 @@ static int hinic5_init_nic_io(void *hwdev, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
(*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
+ (*nic_io)->rx_buff_len = rx_buff_len;
+
+ err = hinic5_register_service_adapter(hwdev, *nic_io, SERVICE_T_NIC);
+ if (err != 0) {
+ nic_err(dev_hdl, "Failed to register service adapter\n");
+ mutex_deinit(nic_io->nic_cfg.sfp_mutex);
+ sema_deinit(nic_io->nic_cfg.cfg_lock);
+ kfree(*nic_io);
+ return err;
+ }
+
return 0;
}
+static void hinic5_deinit_nic_io(void *hwdev, struct hinic5_nic_io *nic_io)
+{
+ hinic5_unregister_service_adapter(hwdev, SERVICE_T_NIC);
+ mutex_deinit(nic_io->nic_cfg.sfp_mutex);
+ sema_deinit(nic_io->nic_cfg.cfg_lock);
+ kfree(nic_io);
+}
+
/*
* hinic5_init_nic_hwdev - init nic hwdev
* @hwdev: pointer to hwdev
@@ -1116,27 +1201,21 @@ int hinic5_init_nic_hwdev(void *hwdev, void *dev_hdl, u16 rx_buff_len)
struct hinic5_nic_io *nic_io = NULL;
int err;
- err = hinic5_init_nic_io(hwdev, dev_hdl, &nic_io);
+ err = hinic5_init_nic_io(hwdev, dev_hdl, &nic_io, rx_buff_len);
if (err != 0)
return err;
- nic_io->rx_buff_len = rx_buff_len;
-
- err = hinic5_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
- goto register_sa_err;
- }
-
err = hinic5_nic_aeqs_init(nic_io);
if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init nic aeqs\n");
goto nic_aeqs_init_err;
}
- err = hinic5_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC5_CHANNEL_NIC);
+ err = hinic5_set_func_svc_used_state(hwdev, SVC_T_NIC, 1,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to set function svc used state\n");
goto set_used_state_err;
}
@@ -1151,8 +1230,8 @@ int hinic5_init_nic_hwdev(void *hwdev, void *dev_hdl, u16 rx_buff_len)
nic_err(nic_io->dev_hdl, "Failed to get nic features\n");
goto err_out;
}
-
nic_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
+
hinic5_nic_cmdq_adapt_init(nic_io);
err = hinic5_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
@@ -1176,13 +1255,7 @@ int hinic5_init_nic_hwdev(void *hwdev, void *dev_hdl, u16 rx_buff_len)
hinic5_nic_aeqs_free(nic_io);
nic_aeqs_init_err:
- hinic5_unregister_service_adapter(hwdev, SERVICE_T_NIC);
-
-register_sa_err:
- mutex_deinit(&nic_io->nic_cfg.sfp_mutex);
- sema_deinit(&nic_io->nic_cfg.cfg_lock);
-
- kfree(nic_io);
+ hinic5_deinit_nic_io(hwdev, nic_io);
return err;
}
@@ -1191,11 +1264,11 @@ void hinic5_free_nic_hwdev(void *hwdev)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
hinic5_vf_func_free(nic_io);
@@ -1219,20 +1292,21 @@ int hinic5_force_drop_tx_pkt(void *hwdev)
u16 out_size = sizeof(pkt_drop);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&pkt_drop, 0, sizeof(pkt_drop));
+ (void)memset_s(&pkt_drop, sizeof(pkt_drop), 0, sizeof(pkt_drop));
pkt_drop.port = hinic5_physical_port_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FORCE_PKT_DROP,
- &pkt_drop, sizeof(pkt_drop),
- &pkt_drop, &out_size);
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FORCE_PKT_DROP,
+ &pkt_drop, sizeof(pkt_drop), &pkt_drop,
+ &out_size);
if ((pkt_drop.msg_head.status != HINIC5_MGMT_CMD_UNSUPPORTED &&
- pkt_drop.msg_head.status != 0) || err != 0 || out_size == 0) {
+ (pkt_drop.msg_head.status != 0)) ||
+ (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to set force tx packets drop, err: %d, status: 0x%x, out size: 0x%x\n",
err, pkt_drop.msg_head.status, out_size);
@@ -1249,22 +1323,25 @@ int hinic5_set_rx_mode(void *hwdev, u32 enable)
u16 out_size = sizeof(rx_mode_cfg);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
+ (void)memset_s(&rx_mode_cfg, sizeof(rx_mode_cfg), 0,
+ sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic5_global_func_id(hwdev);
rx_mode_cfg.rx_mode = enable;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RX_MODE,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RX_MODE,
&rx_mode_cfg, sizeof(rx_mode_cfg),
&rx_mode_cfg, &out_size);
- if (err != 0 || out_size == 0 || rx_mode_cfg.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set rx mode, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) ||
+ (rx_mode_cfg.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set rx mode, err: %d, status: 0x%x, out size: 0x%x\n",
err, rx_mode_cfg.msg_head.status, out_size);
return -EINVAL;
}
@@ -1279,22 +1356,23 @@ int hinic5_set_rx_vlan_offload(void *hwdev, u8 en)
u16 out_size = sizeof(vlan_cfg);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&vlan_cfg, 0, sizeof(vlan_cfg));
+ (void)memset_s(&vlan_cfg, sizeof(vlan_cfg), 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic5_global_func_id(hwdev);
vlan_cfg.vlan_offload = en;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD,
- &vlan_cfg, sizeof(vlan_cfg),
- &vlan_cfg, &out_size);
- if (err != 0 || out_size == 0 || vlan_cfg.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+ &vlan_cfg, sizeof(vlan_cfg), &vlan_cfg,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (vlan_cfg.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
err, vlan_cfg.msg_head.status, out_size);
return -EINVAL;
}
@@ -1309,33 +1387,36 @@ int hinic5_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
u16 func_id;
int err;
- if (!hwdev || old_vlan >= VLAN_N_VID || new_vlan >= VLAN_N_VID)
+ if ((hwdev == NULL) || old_vlan >= VLAN_N_VID || new_vlan >= VLAN_N_VID)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
- if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
+ if ((nic_io->vf_infos == NULL) ||
+ is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
func_id = hinic5_glb_pf_vf_offset(nic_io->hwdev) + (u16)vf_id;
- err = hinic5_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
- old_vlan, func_id, HINIC5_CHANNEL_NIC);
+ err = hinic5_del_mac(nic_io->hwdev, vf_info->drv_mac_addr, old_vlan,
+ func_id, HINIC5_CHANNEL_NIC);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
}
- err = hinic5_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
- new_vlan, func_id, HINIC5_CHANNEL_NIC);
+ err = hinic5_set_mac(nic_io->hwdev, vf_info->drv_mac_addr, new_vlan,
+ func_id, HINIC5_CHANNEL_NIC);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
- hinic5_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
- old_vlan, func_id, HINIC5_CHANNEL_NIC);
+ hinic5_set_mac(nic_io->hwdev, vf_info->drv_mac_addr, old_vlan,
+ func_id, HINIC5_CHANNEL_NIC);
return err;
}
@@ -1350,25 +1431,25 @@ static int hinic5_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
u16 out_size = sizeof(lro_cfg);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&lro_cfg, 0, sizeof(lro_cfg));
+ (void)memset_s(&lro_cfg, sizeof(lro_cfg), 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic5_global_func_id(hwdev);
lro_cfg.opcode = HINIC5_CMD_OP_SET;
lro_cfg.lro_ipv4_en = ipv4_en;
lro_cfg.lro_ipv6_en = ipv6_en;
lro_cfg.lro_max_pkt_len = lro_max_pkt_len;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_RX_LRO,
- &lro_cfg, sizeof(lro_cfg),
- &lro_cfg, &out_size);
- if (err != 0 || out_size == 0 || lro_cfg.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_RX_LRO, &lro_cfg,
+ sizeof(lro_cfg), &lro_cfg, &out_size);
+ if ((err != 0) || (out_size == 0) || (lro_cfg.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
err, lro_cfg.msg_head.status, out_size);
return -EINVAL;
}
@@ -1383,22 +1464,23 @@ static int hinic5_set_rx_lro_timer(void *hwdev, u32 timer_value)
u16 out_size = sizeof(lro_timer);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&lro_timer, 0, sizeof(lro_timer));
+ (void)memset_s(&lro_timer, sizeof(lro_timer), 0, sizeof(lro_timer));
lro_timer.opcode = HINIC5_CMD_OP_SET;
lro_timer.timer = timer_value;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_LRO_TIMER,
- &lro_timer, sizeof(lro_timer),
- &lro_timer, &out_size);
- if (err != 0 || out_size == 0 || lro_timer.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_LRO_TIMER,
+ &lro_timer, sizeof(lro_timer), &lro_timer,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (lro_timer.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
err, lro_timer.msg_head.status, out_size);
return -EINVAL;
@@ -1414,14 +1496,14 @@ int hinic5_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
u8 ipv4_en = 0, ipv6_en = 0;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
ipv4_en = (lro_en != 0) ? 1 : 0;
ipv6_en = (lro_en != 0) ? 1 : 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
@@ -1447,24 +1529,26 @@ int hinic5_get_veb_offload(void *hwdev, u16 *veb_offload_status)
u16 out_size;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
out_size = sizeof(veb_set_info);
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&veb_set_info, 0, sizeof(veb_set_info));
+ (void)memset_s(&veb_set_info, sizeof(veb_set_info), 0,
+ sizeof(veb_set_info));
veb_set_info.opcode = VEB_OFFLOAD_QUERY;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VEB,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VEB,
&veb_set_info, sizeof(veb_set_info),
&veb_set_info, &out_size);
- if (err != 0 || out_size == 0 ||
+ if ((err != 0) || (out_size == 0) ||
veb_set_info.msg_head.status != 0 ||
veb_set_info.cur_status == VEB_OFFLOAD_STATUS_INVALID) {
- nic_err(nic_io->dev_hdl, "Failed to get veb offload status, err: %d, status: 0x%x, out size: 0x%x\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to get veb offload status, err: %d, status: 0x%x, out size: 0x%x\n",
err, veb_set_info.msg_head.status, out_size);
return -EINVAL;
}
@@ -1481,23 +1565,26 @@ int hinic5_set_veb_offload(void *hwdev, u16 veb_offload_status)
u16 out_size;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
out_size = sizeof(veb_set_info);
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&veb_set_info, 0, sizeof(veb_set_info));
+ (void)memset_s(&veb_set_info, sizeof(veb_set_info), 0,
+ sizeof(veb_set_info));
veb_set_info.opcode = VEB_OFFLOAD_SET;
veb_set_info.set_status = veb_offload_status;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VEB,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VEB,
&veb_set_info, sizeof(veb_set_info),
&veb_set_info, &out_size);
- if (err != 0 || out_size == 0 || veb_set_info.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set veb offload status, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) ||
+ (veb_set_info.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set veb offload status, err: %d, status: 0x%x, out size: 0x%x\n",
err, veb_set_info.msg_head.status, out_size);
return -EINVAL;
}
@@ -1512,22 +1599,25 @@ int hinic5_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
u16 out_size = sizeof(vlan_filter);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&vlan_filter, 0, sizeof(vlan_filter));
+ (void)memset_s(&vlan_filter, sizeof(vlan_filter), 0,
+ sizeof(vlan_filter));
vlan_filter.func_id = hinic5_global_func_id(hwdev);
vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VLAN_FILTER_EN,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_VLAN_FILTER_EN,
&vlan_filter, sizeof(vlan_filter),
&vlan_filter, &out_size);
- if (err != 0 || out_size == 0 || vlan_filter.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set vlan filter, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || (out_size == 0) ||
+ (vlan_filter.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set vlan filter, err: %d, status: 0x%x, out size: 0x%x\n",
err, vlan_filter.msg_head.status, out_size);
return -EINVAL;
}
@@ -1541,16 +1631,16 @@ int hinic5_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
u16 out_size = sizeof(cap_info);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_UCAPTURE_OPT,
- &cap_info, sizeof(cap_info),
- &cap_info, &out_size);
- if (err != 0 || out_size == 0 || cap_info.msg_head.status != 0)
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_UCAPTURE_OPT,
+ &cap_info, sizeof(cap_info), &cap_info,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (cap_info.msg_head.status != 0))
return -EINVAL;
return 0;
@@ -1564,26 +1654,29 @@ int hinic5_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !tcam_rule)
+ if ((hwdev == NULL) || (tcam_rule == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (tcam_rule->index >= HINIC5_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
}
- memset(&tcam_cmd, 0, sizeof(struct nic_cmd_fdir_add_rule));
- memcpy((void *)&tcam_cmd.rule, (void *)tcam_rule, sizeof(struct nic_tcam_cfg_rule));
+ (void)memset_s(&tcam_cmd, sizeof(tcam_cmd), 0,
+ sizeof(struct nic_cmd_fdir_add_rule));
+ if (memcpy_s((void *)&tcam_cmd.rule, sizeof(tcam_cmd.rule),
+ (void *)tcam_rule, sizeof(struct nic_tcam_cfg_rule)) != 0)
+ return -ENOMEM;
tcam_cmd.func_id = hinic5_global_func_id(hwdev);
tcam_cmd.type = TCAM_RULE_FDIR_TYPE;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_ADD_TC_FLOW,
- &tcam_cmd, sizeof(tcam_cmd),
- &tcam_cmd, &out_size);
- if (err != 0 || tcam_cmd.head.status != 0 || out_size == 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_ADD_TC_FLOW,
+ &tcam_cmd, sizeof(tcam_cmd), &tcam_cmd,
+ &out_size);
+ if ((err != 0) || (tcam_cmd.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, tcam_cmd.head.status, out_size);
@@ -1600,11 +1693,11 @@ int hinic5_del_tcam_rule(void *hwdev, u32 index)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (index >= HINIC5_MAX_TCAM_RULES_NUM) {
@@ -1612,16 +1705,17 @@ int hinic5_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
}
- memset(&tcam_cmd, 0, sizeof(struct nic_cmd_fdir_del_rules));
+ (void)memset_s(&tcam_cmd, sizeof(tcam_cmd), 0,
+ sizeof(struct nic_cmd_fdir_del_rules));
tcam_cmd.index_start = index;
tcam_cmd.index_num = 1;
tcam_cmd.func_id = hinic5_global_func_id(hwdev);
tcam_cmd.type = TCAM_RULE_FDIR_TYPE;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_DEL_TC_FLOW,
- &tcam_cmd, sizeof(tcam_cmd),
- &tcam_cmd, &out_size);
- if (err != 0 || tcam_cmd.head.status != 0 || out_size == 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_DEL_TC_FLOW,
+ &tcam_cmd, sizeof(tcam_cmd), &tcam_cmd,
+ &out_size);
+ if ((err != 0) || (tcam_cmd.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Del tcam rule failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, tcam_cmd.head.status, out_size);
@@ -1652,23 +1746,25 @@ static int hinic5_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !index)
+ if ((hwdev == NULL) || (index == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&tcam_block_info, 0, sizeof(struct nic_cmd_ctrl_tcam_block_out));
+ (void)memset_s(&tcam_block_info, sizeof(tcam_block_info), 0,
+ sizeof(struct nic_cmd_ctrl_tcam_block_out));
tcam_block_info.func_id = hinic5_global_func_id(hwdev);
tcam_block_info.alloc_en = alloc_en;
tcam_block_info.tcam_type = NIC_TCAM_BLOCK_TYPE_LARGE;
tcam_block_info.tcam_block_index = *index;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TCAM_BLOCK,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TCAM_BLOCK,
&tcam_block_info, sizeof(tcam_block_info),
&tcam_block_info, &out_size);
- if (err != 0 || tcam_block_info.head.status != 0 || out_size == 0) {
+ if ((err != 0) || (tcam_block_info.head.status != 0) ||
+ (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Set tcam block failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, tcam_block_info.head.status, out_size);
@@ -1698,24 +1794,25 @@ int hinic5_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
+ (void)memset_s(&port_tcam_cmd, sizeof(port_tcam_cmd), 0,
+ sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic5_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_ENABLE_TCAM,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_ENABLE_TCAM,
&port_tcam_cmd, sizeof(port_tcam_cmd),
&port_tcam_cmd, &out_size);
- if (err != 0 || port_tcam_cmd.head.status != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Set fdir tcam filter failed, err: %d, status: 0x%x, out size: 0x%x, enable: 0x%x\n",
- err, port_tcam_cmd.head.status, out_size,
- enable);
+ if ((err != 0) || (port_tcam_cmd.head.status != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Set fdir tcam filter failed, err: %d, status: 0x%x, out size: 0x%x, enable: 0x%x\n",
+ err, port_tcam_cmd.head.status, out_size, enable);
return -EIO;
}
@@ -1729,20 +1826,21 @@ int hinic5_flush_tcam_rule(void *hwdev)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
+ (void)memset_s(&tcam_flush, sizeof(tcam_flush), 0,
+ sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FLUSH_TCAM,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FLUSH_TCAM,
&tcam_flush,
sizeof(struct nic_cmd_flush_tcam_rules),
&tcam_flush, &out_size);
- if (err != 0 || tcam_flush.head.status != 0 || out_size == 0) {
+ if ((err != 0) || (tcam_flush.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Flush tcam fdir rules failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, tcam_flush.head.status, out_size);
@@ -1752,7 +1850,8 @@ int hinic5_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic5_cmd_buf *cmd_buf = NULL;
struct hinic5_nic_io *nic_io = NULL;
@@ -1761,14 +1860,14 @@ int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
int err;
u16 i;
- if (!hwdev || !rxq_info)
+ if ((hwdev == NULL) || (rxq_info == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
return -ENOMEM;
}
@@ -1781,8 +1880,9 @@ int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic5_rxq_hw);
- err = hinic5_cmdq_detail_resp(hwdev, HINIC5_MOD_L2NIC, HINIC5_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC5_CHANNEL_NIC);
+ err = hinic5_cmdq_detail_resp(hwdev, HINIC5_MOD_L2NIC,
+ HINIC5_UCODE_CMD_RXQ_INFO_GET, cmd_buf,
+ cmd_buf, NULL, 0, HINIC5_CHANNEL_NIC);
if (err != 0)
goto get_rxq_info_failed;
@@ -1798,13 +1898,14 @@ int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return err;
}
-int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic5_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
int vf_id;
- if (!hwdev) {
+ if (hwdev == NULL) {
pr_err("hwdev is null.\n");
return -EINVAL;
}
@@ -1815,7 +1916,7 @@ int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
}
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("nic_io is null.\n");
return -EINVAL;
}
@@ -1830,25 +1931,27 @@ int hinic5_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
}
EXPORT_SYMBOL(hinic5_pf_set_vf_link_state);
-int hinic5_add_tc_flow_rule(void *hwdev, struct hinic5_tc_cfg_info *tc_flow_rule, bool default_rule)
+int hinic5_add_tc_flow_rule(void *hwdev,
+ struct hinic5_tc_cfg_info *tc_flow_rule,
+ bool default_rule)
{
u16 out_size = sizeof(struct hinic5_tc_cfg_info);
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !tc_flow_rule)
+ if ((hwdev == NULL) || (tc_flow_rule == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
tc_flow_rule->index = default_rule ? TCAM_INVLD_INDEX : 0;
tc_flow_rule->opcode = HINIC5_TC_CFG_RULE_OPS_ADD;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TC_FLOW_RULE,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TC_FLOW_RULE,
tc_flow_rule, sizeof(*tc_flow_rule),
tc_flow_rule, &out_size);
- if (err != 0 || tc_flow_rule->head.status != 0 || out_size == 0) {
+ if ((err != 0) || (tc_flow_rule->head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Add tc flow rule failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, tc_flow_rule->head.status, out_size);
@@ -1865,20 +1968,22 @@ int hinic5_del_tc_flow_rule(void *hwdev, u16 rule_id)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL) {
return -EINVAL;
+ }
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL) {
return -EINVAL;
+ }
- memset(&cmd, 0, sizeof(struct hinic5_tc_cfg_info));
+ (void)memset_s(&cmd, sizeof(cmd), 0, sizeof(struct hinic5_tc_cfg_info));
cmd.index = rule_id;
cmd.opcode = HINIC5_TC_CFG_RULE_OPS_DEL;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TC_FLOW_RULE,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_TC_FLOW_RULE,
&cmd, sizeof(cmd), &cmd, &out_size);
- if (err != 0 || cmd.head.status != 0 || out_size == 0) {
+ if ((err != 0) || (cmd.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Del tc flow rule failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, cmd.head.status, out_size);
@@ -1895,19 +2000,22 @@ int hinic5_flush_tc_flow_rule(void *hwdev, ulong *bitmap)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL) {
return -EINVAL;
+ }
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL) {
return -EINVAL;
+ }
- memset(&cmd, 0, sizeof(cmd));
- memcpy(cmd.active_bitmap, bitmap, sizeof(cmd.active_bitmap));
+ (void)memset_s(&cmd, sizeof(cmd), 0, sizeof(cmd));
+ memcpy_s(cmd.active_bitmap, sizeof(cmd.active_bitmap), bitmap,
+ sizeof(cmd.active_bitmap));
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FLUSH_TC_FLOW,
- &cmd, sizeof(cmd), &cmd, &out_size);
- if (err != 0 || cmd.head.status != 0 || out_size == 0) {
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_FLUSH_TC_FLOW, &cmd,
+ sizeof(cmd), &cmd, &out_size);
+ if ((err != 0) || (cmd.head.status != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Flush tc flow rule failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, cmd.head.status, out_size);
@@ -1922,15 +2030,16 @@ int hinic5_get_pfe_cfg(void *hwdev, struct hinic5_tc_pfe_cfg_reg_info *cfg_info)
u16 out_size = sizeof(struct hinic5_tc_pfe_cfg_reg_info);
int err;
- if (!hwdev || !cfg_info)
+ if ((hwdev == NULL) || (cfg_info == NULL))
return -EINVAL;
- memset(cfg_info, 0, out_size);
+ (void)memset_s(cfg_info, out_size, 0, out_size);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_PFE_CFG,
- cfg_info, sizeof(struct hinic5_tc_pfe_cfg_reg_info),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_PFE_CFG,
+ cfg_info,
+ sizeof(struct hinic5_tc_pfe_cfg_reg_info),
cfg_info, &out_size);
- if (err != 0 || cfg_info->head.status != 0 || out_size == 0) {
+ if ((err != 0) || (cfg_info->head.status != 0) || (out_size == 0)) {
pr_err("Get pfe cfg failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg_info->head.status, out_size);
return -EIO;
@@ -1939,23 +2048,25 @@ int hinic5_get_pfe_cfg(void *hwdev, struct hinic5_tc_pfe_cfg_reg_info *cfg_info)
return 0;
}
-int hinic5_move_tc_tcam_table(void *hwdev, struct hinic5_tc_move_info *acl_move_info)
+int hinic5_move_tc_tcam_table(void *hwdev,
+ struct hinic5_tc_move_info *acl_move_info)
{
u16 out_size = sizeof(struct hinic5_tc_move_info);
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !acl_move_info)
+ if ((hwdev == NULL) || (acl_move_info == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_MOVE_TC_TBL,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_MOVE_TC_TBL,
acl_move_info, sizeof(*acl_move_info),
acl_move_info, &out_size);
- if (err != 0 || acl_move_info->head.status != 0 || out_size == 0) {
+ if ((err != 0) || (acl_move_info->head.status != 0) ||
+ (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Move tcam table failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, acl_move_info->head.status, out_size);
@@ -1969,13 +2080,12 @@ int hinic5_send_arp_to_mpu(void *hwdev, struct hinic5_arp_pkt_info *info)
{
int err;
u16 out_size = sizeof(struct hinic5_arp_pkt_info);
-
err = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_CFM,
CFM_MPU_CMD_PASS_ARP_PKT, info,
sizeof(struct hinic5_arp_pkt_info), info,
&out_size, HINIC5_BOND_MSG_TIMEOUT_MS,
HINIC5_CHANNEL_NIC);
- if (err != 0 || info->head.status != 0 || out_size == 0) {
+ if ((err != 0) || (info->head.status != 0) || (out_size == 0)) {
pr_err("Send ARP failed, err: %d, status: 0x%x, out size: 0x%x\n",
err, info->head.status, out_size);
return -EIO;
@@ -1986,9 +2096,8 @@ int hinic5_send_arp_to_mpu(void *hwdev, struct hinic5_arp_pkt_info *info)
bool hinic5_check_dev_need_dual_send(void *hwdev)
{
struct hinic5_nic_io *nic_io = NULL;
-
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return false;
}
@@ -2000,7 +2109,8 @@ bool hinic5_check_dev_need_dual_send(void *hwdev)
return false;
}
-int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action, u8 pkt_fmt)
+int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action,
+ u8 pkt_fmt)
{
struct hinic5_cmd_vxlan_port_info vxlan_port_info = {
.opcode = action,
@@ -2017,17 +2127,22 @@ int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action, u8 p
if (!nic_io)
return -EINVAL;
- if (hinic5_func_type(hwdev) == TYPE_VF)
+ if (hinic5_func_type(hwdev) == TYPE_VF) {
return 0;
+ }
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_VXLAN_PORT,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_CFG_VXLAN_PORT,
&vxlan_port_info, sizeof(vxlan_port_info),
&vxlan_port_info, &out_size);
- if (err != 0 || out_size == 0 || vxlan_port_info.msg_head.status != 0) {
- if (vxlan_port_info.msg_head.status == HINIC5_VXLAN_DPORT_SET_UNSUPPORT &&
- err == 0)
+ if ((err != 0) || (out_size == 0) ||
+ (vxlan_port_info.msg_head.status != 0)) {
+ if (vxlan_port_info.msg_head.status ==
+ HINIC5_VXLAN_DPORT_SET_UNSUPPORT &&
+ err == 0) {
return -EOPNOTSUPP;
- if (vxlan_port_info.msg_head.status == HINIC5_VXLAN_DPORT_SET_BY_HINICADM &&
+ }
+ if (vxlan_port_info.msg_head.status ==
+ HINIC5_VXLAN_DPORT_SET_BY_HINICADM &&
err == 0) { // other tool set failed
nic_warn(nic_io->dev_hdl,
"Dst port has already been set\n");
@@ -2035,8 +2150,8 @@ int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action, u8 p
nic_err(nic_io->dev_hdl,
"Failed to %s vxlan dst port, cmd: 0x%x, err: %d, status: 0x%x, out size: 0x%x\n",
action == HINIC5_CMD_OP_ADD ? "add" : "delete",
- HINIC5_NIC_CMD_CFG_VXLAN_PORT,
- err, vxlan_port_info.msg_head.status, out_size);
+ HINIC5_NIC_CMD_CFG_VXLAN_PORT, err,
+ vxlan_port_info.msg_head.status, out_size);
}
return err;
}
@@ -2047,15 +2162,15 @@ int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action, u8 p
int hinic5_set_queue_pooling(void *hwdev, u8 enable_queue_pooling)
{
struct hinic5_nic_io *nic_io = NULL;
-
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return false;
}
- if (nic_io->enable_queue_pooling == 0 && enable_queue_pooling != 0)
+ if (nic_io->enable_queue_pooling == 0 && enable_queue_pooling != 0) {
nic_io->first_enable_queue_pooling = 1;
+ }
nic_io->enable_queue_pooling = enable_queue_pooling;
return 0;
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg_vf.c
index 948724130..b37f1c195 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cfg_vf.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_cfg_vf.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -34,7 +27,9 @@
static unsigned char set_vf_link_state;
module_param(set_vf_link_state, byte, 0444);
-MODULE_PARM_DESC(set_vf_link_state, "Set vf link state, 0: link auto, 1: link always up, 2: link always down (default=0)");
+MODULE_PARM_DESC(
+ set_vf_link_state,
+ "Set vf link state, 0: link auto, 1: link always up, 2: link always down (default=0)");
static int hinic5_set_vlan_ctx(struct hinic5_nic_io *nic_io, u16 func_id,
u16 vlan_tag, u16 q_id, bool add)
@@ -45,23 +40,25 @@ static int hinic5_set_vlan_ctx(struct hinic5_nic_io *nic_io, u16 func_id,
u8 cmd, vlan_mode;
cmd_buf = hinic5_alloc_cmd_buf(nic_io->hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
- vlan_mode = add ? NIC_QINQ_INSERT_ENABLE : NIC_CVLAN_INSERT_ENABLE;
+ vlan_mode = add ? NIC_QINQ_INSERT_ENABLE : NIC_CVLAN_INSERT_ENABLE;
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_modify_svlan(cmd_buf, func_id,
- vlan_tag, q_id, vlan_mode);
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_modify_svlan(
+ cmd_buf, func_id, vlan_tag, q_id, vlan_mode);
- err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC5_CHANNEL_NIC);
+ err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC, cmd,
+ cmd_buf, &out_param, 0,
+ HINIC5_CHANNEL_NIC);
hinic5_free_cmd_buf(nic_io->hwdev, cmd_buf);
- if (err != 0 || out_param != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set vlan context, err: %d, out_param: 0x%llx\n",
+ if ((err != 0) || out_param != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set vlan context, err: %d, out_param: 0x%llx\n",
err, out_param);
return -EFAULT;
}
@@ -69,8 +66,8 @@ static int hinic5_set_vlan_ctx(struct hinic5_nic_io *nic_io, u16 func_id,
return err;
}
-int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid,
- u8 qos, int vf_id)
+int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid, u8 qos,
+ int vf_id)
{
struct hinic5_cmd_vf_vlan_config vf_vlan;
u16 out_size = sizeof(vf_vlan);
@@ -79,21 +76,22 @@ int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid,
u16 vlan_tag;
/* VLAN 0 is a special case, don't allow it to be removed */
- if (vid == 0 && opcode == HINIC5_CMD_OP_DEL)
+ if ((vid == 0) && opcode == HINIC5_CMD_OP_DEL)
return 0;
- memset(&vf_vlan, 0, sizeof(vf_vlan));
+ (void)memset_s(&vf_vlan, sizeof(vf_vlan), 0, sizeof(vf_vlan));
vf_vlan.opcode = opcode;
vf_vlan.func_id = hinic5_glb_pf_vf_offset(nic_io->hwdev) + (u16)vf_id;
vf_vlan.vlan_id = vid;
vf_vlan.qos = qos;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_CFG_VF_VLAN,
- &vf_vlan, sizeof(vf_vlan),
- &vf_vlan, &out_size);
- if (err != 0 || out_size == 0 || vf_vlan.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan, err: %d, status: 0x%x,out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_CFG_VF_VLAN,
+ &vf_vlan, sizeof(vf_vlan), &vf_vlan,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (vf_vlan.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF %d vlan, err: %d, status: 0x%x,out size: 0x%x\n",
HW_VF_ID_TO_OS(vf_id), err, vf_vlan.msg_head.status,
out_size);
return -EFAULT;
@@ -106,7 +104,8 @@ int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC5_CMD_OP_ADD);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
/* rollback vlan config */
@@ -114,7 +113,7 @@ int hinic5_cfg_vf_vlan(struct hinic5_nic_io *nic_io, u8 opcode, u16 vid,
vf_vlan.opcode = HINIC5_CMD_OP_ADD;
else
vf_vlan.opcode = HINIC5_CMD_OP_DEL;
- hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC5_NIC_CMD_CFG_VF_VLAN, &vf_vlan,
sizeof(vf_vlan), &vf_vlan, &out_size);
return err;
@@ -133,7 +132,7 @@ int hinic5_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
@@ -157,7 +156,7 @@ int hinic5_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int err;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
err = hinic5_cfg_vf_vlan(nic_io, HINIC5_CMD_OP_ADD, vlan, qos, vf_id);
@@ -167,8 +166,8 @@ int hinic5_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos = qos;
- nic_info(nic_io->dev_hdl, "Setting VLAN %u, QOS 0x%x on VF %d\n",
- vlan, qos, HW_VF_ID_TO_OS(vf_id));
+ nic_info(nic_io->dev_hdl, "Setting VLAN %u, QOS 0x%x on VF %d\n", vlan,
+ qos, HW_VF_ID_TO_OS(vf_id));
return 0;
}
@@ -180,7 +179,7 @@ int hinic5_kill_vf_vlan(void *hwdev, int vf_id)
int err;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
vf_infos = nic_io->vf_infos;
@@ -208,7 +207,7 @@ u16 hinic5_vf_info_vlanprio(void *hwdev, int vf_id)
u8 pf_qos;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -223,15 +222,15 @@ int hinic5_set_vf_link_state(void *hwdev, u16 vf_id, int link)
struct vf_data_storage *vf_infos = NULL;
struct hinic5_nic_io *nic_io =
hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
vf_infos = nic_io->vf_infos;
switch (link) {
case HINIC5_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
- vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up = (nic_io->link_status != 0) ?
- true : false;
+ vf_infos[HW_VF_ID_TO_OS(vf_id)].link_up =
+ (nic_io->link_status != 0) ? true : false;
link_status = nic_io->link_status;
break;
case HINIC5_IFLA_VF_LINK_STATE_ENABLE:
@@ -262,25 +261,27 @@ int hinic5_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
vf_infos = nic_io->vf_infos;
- memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
+ (void)memset_s(&spoofchk_cfg, sizeof(spoofchk_cfg), 0,
+ sizeof(spoofchk_cfg));
spoofchk_cfg.func_id = hinic5_glb_pf_vf_offset(hwdev) + vf_id;
spoofchk_cfg.state = spoofchk ? 1 : 0;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_SPOOFCHK_STATE,
- &spoofchk_cfg,
- sizeof(spoofchk_cfg), &spoofchk_cfg,
- &out_size);
- if (err != 0 || out_size == 0 || spoofchk_cfg.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF(%d) spoofchk, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_SPOOFCHK_STATE,
+ &spoofchk_cfg, sizeof(spoofchk_cfg),
+ &spoofchk_cfg, &out_size);
+ if ((err != 0) || (out_size == 0) ||
+ (spoofchk_cfg.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF(%d) spoofchk, err: %d, status: 0x%x, out size: 0x%x\n",
HW_VF_ID_TO_OS(vf_id), err,
spoofchk_cfg.msg_head.status, out_size);
err = -EINVAL;
@@ -296,7 +297,7 @@ bool hinic5_vf_info_spoofchk(void *hwdev, int vf_id)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
@@ -306,15 +307,15 @@ bool hinic5_vf_info_spoofchk(void *hwdev, int vf_id)
int hinic5_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
{
struct hinic5_nic_io *nic_io = NULL;
- struct hinic5_cmd_vf_trust_config vf_trust = {0};
+ struct hinic5_cmd_vf_trust_config vf_trust = { 0 };
u16 out_size = sizeof(vf_trust);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io || vf_id > nic_io->max_vfs)
+ if ((nic_io == NULL) || vf_id > nic_io->max_vfs)
return -EINVAL;
vf_trust.func_id = hinic5_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
@@ -322,17 +323,20 @@ int hinic5_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_CFG_VF_TRUST,
- &vf_trust, out_size, &vf_trust,
- &out_size);
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_CFG_VF_TRUST,
+ &vf_trust, out_size, &vf_trust, &out_size);
if (vf_trust.msg_head.status == NIC_VF_TRUST_UNSUPPORT && err == 0) {
- nic_info(nic_io->dev_hdl, "Succeeded to set vf trust to driver, did not set vf trust to chip\n");
+ nic_info(
+ nic_io->dev_hdl,
+ "Successed to set vf trust to driver, did not set vf trust to chip\n");
return 0;
}
- if (err != 0 || out_size == 0 || vf_trust.msg_head.status != 0)
- nic_warn(nic_io->dev_hdl, "Failed to set vf trust, err: %d, out_size: 0x%x, status:0x%x\n",
- err, out_size, vf_trust.msg_head.status);
+ if ((err != 0) || out_size == 0 || vf_trust.msg_head.status != 0) {
+ nic_warn(
+ nic_io->dev_hdl,
+ "Failed to set vf trust, err: %d, out_size: 0x%x, status:0x%x\n",
+ err, out_size, vf_trust.msg_head.status);
+ }
return 0;
}
@@ -341,11 +345,11 @@ bool hinic5_get_vf_trust(void *hwdev, int vf_id)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return false;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io || vf_id > nic_io->max_vfs)
+ if ((nic_io == NULL) || vf_id > nic_io->max_vfs)
return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
@@ -356,23 +360,25 @@ static int hinic5_set_vf_tx_rate_max_min(struct hinic5_nic_io *nic_io,
u16 vf_id, u32 max_rate, u32 min_rate)
{
struct hinic5_cmd_rate_cfg rate_cfg;
- struct hinic5_cmd_rate_cfg_ret rate_cfg_ret = {0};
+ struct hinic5_cmd_rate_cfg_ret rate_cfg_ret = { 0 };
u16 out_size = sizeof(rate_cfg_ret);
int err;
- memset(&rate_cfg, 0, sizeof(rate_cfg));
+ (void)memset_s(&rate_cfg, sizeof(rate_cfg), 0, sizeof(rate_cfg));
rate_cfg.func_id = hinic5_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.pir = max_rate;
rate_cfg.cir = min_rate;
rate_cfg.direct = NIC_RATE_DIRECT_TX_BW;
rate_cfg.cfg_mode = NIC_RATE_OP_SET;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_SET_MAX_MIN_RATE,
- &rate_cfg, sizeof(rate_cfg), &rate_cfg_ret,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ sizeof(rate_cfg), &rate_cfg_ret,
&out_size);
- if (rate_cfg_ret.msg_head.status != 0 || err != 0 || out_size == 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u, err: %d, status: 0x%x, out size: 0x%x\n",
+ if ((rate_cfg_ret.msg_head.status != 0) || (err != 0) ||
+ (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF %d max rate %u, min rate %u, err: %d, status: 0x%x, out size: 0x%x\n",
HW_VF_ID_TO_OS(vf_id), max_rate, min_rate, err,
rate_cfg_ret.msg_head.status, out_size);
return -EIO;
@@ -387,10 +393,11 @@ int hinic5_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (!HINIC5_SUPPORT_RATE_LIMIT(hwdev)) {
- nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
+ nic_err(nic_io->dev_hdl,
+ "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
@@ -410,11 +417,11 @@ void hinic5_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
vfinfo = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
- if (!vfinfo)
+ if (vfinfo == NULL)
return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
@@ -453,8 +460,10 @@ static int hinic5_init_vf_infos(struct hinic5_nic_io *nic_io, u16 vf_id)
u8 vf_link_state;
if (set_vf_link_state > HINIC5_IFLA_VF_LINK_STATE_DISABLE) {
- nic_warn(nic_io->dev_hdl, "Module Parameter set_vf_link_state value %u is out of range, resetting to %d\n",
- set_vf_link_state, HINIC5_IFLA_VF_LINK_STATE_AUTO);
+ nic_warn(
+ nic_io->dev_hdl,
+ "Module Parameter set_vf_link_state value %u is out of range, resetting to %d\n",
+ set_vf_link_state, HINIC5_IFLA_VF_LINK_STATE_AUTO);
set_vf_link_state = HINIC5_IFLA_VF_LINK_STATE_AUTO;
}
@@ -473,7 +482,8 @@ static int hinic5_init_vf_infos(struct hinic5_nic_io *nic_io, u16 vf_id)
vf_infos[vf_id].link_up = false;
break;
default:
- nic_err(nic_io->dev_hdl, "Input parameter set_vf_link_state error: %u\n",
+ nic_err(nic_io->dev_hdl,
+ "Input parameter set_vf_link_state error: %u\n",
vf_link_state);
return -EINVAL;
}
@@ -488,35 +498,43 @@ static int vf_func_register(struct hinic5_nic_io *nic_io)
int err;
err = hinic5_register_vf_mbox_cb(nic_io->hwdev, HINIC5_MOD_L2NIC,
- nic_io->hwdev, hinic5_vf_event_handler);
+ nic_io->hwdev,
+ hinic5_vf_event_handler);
if (err != 0)
return err;
err = hinic5_register_vf_mbox_cb(nic_io->hwdev, HINIC5_MOD_HILINK,
- nic_io->hwdev, hinic5_vf_mag_event_handler);
+ nic_io->hwdev,
+ hinic5_vf_mag_event_handler);
if (err != 0)
goto reg_hilink_err;
if (hinic5_is_slave_host(nic_io->hwdev)) {
- nic_info(nic_io->dev_hdl, "The VF(slave host) does not need to register with the PF.");
+ nic_info(
+ nic_io->dev_hdl,
+ "The VF(slave host) does not need to register with the PF.");
return 0;
}
if (hinic5_is_vf_isolation(nic_io->hwdev)) {
- nic_info(nic_io->dev_hdl, "The isolated VF does not need to register with the PF.");
+ nic_info(
+ nic_io->dev_hdl,
+ "The isolated VF does not need to register with the PF.");
return 0;
}
- memset(®ister_info, 0, sizeof(register_info));
+ (void)memset_s(®ister_info, sizeof(register_info), 0,
+ sizeof(register_info));
register_info.op_register = 1;
register_info.support_extra_feature = 0;
err = hinic5_mbox_to_pf(nic_io->hwdev, HINIC5_MOD_L2NIC,
- HINIC5_NIC_CMD_VF_REGISTER,
- ®ister_info, sizeof(register_info),
- ®ister_info, &out_size, 0,
- HINIC5_CHANNEL_NIC);
- if (err != 0 || out_size == 0 || register_info.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ HINIC5_NIC_CMD_VF_REGISTER, ®ister_info,
+ sizeof(register_info), ®ister_info,
+ &out_size, 0, HINIC5_CHANNEL_NIC);
+ if ((err != 0) || (out_size == 0) ||
+ (register_info.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
goto register_err;
@@ -545,7 +563,7 @@ static int pf_init_vf_infos(struct hinic5_nic_io *nic_io)
return 0;
nic_io->vf_infos = kzalloc(size, GFP_KERNEL);
- if (!nic_io->vf_infos)
+ if (nic_io->vf_infos == NULL)
return -ENOMEM;
for (i = 0; i < nic_io->max_vfs; i++) {
@@ -560,7 +578,8 @@ static int pf_init_vf_infos(struct hinic5_nic_io *nic_io)
goto register_pf_mbox_cb_err;
err = hinic5_register_pf_mbox_cb(nic_io->hwdev, HINIC5_MOD_HILINK,
- nic_io->hwdev, hinic5_pf_mag_mbox_handler);
+ nic_io->hwdev,
+ hinic5_pf_mag_mbox_handler);
if (err != 0)
goto register_pf_mag_mbox_cb_err;
@@ -581,7 +600,8 @@ int hinic5_vf_func_init(struct hinic5_nic_io *nic_io)
int err;
err = hinic5_register_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_L2NIC,
- nic_io->hwdev, hinic5_mgmt_event_handler);
+ nic_io->hwdev,
+ hinic5_mgmt_event_handler);
if (err != 0)
return err;
@@ -589,7 +609,8 @@ int hinic5_vf_func_init(struct hinic5_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic5_register_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_HILINK,
- nic_io->hwdev, hinic5_pf_mag_event_handler);
+ nic_io->hwdev,
+ hinic5_pf_mag_event_handler);
if (err != 0)
goto register_mgmt_msg_cb_err;
@@ -613,16 +634,20 @@ void hinic5_vf_func_free(struct hinic5_nic_io *nic_io)
u16 out_size = sizeof(unregister);
int err;
- memset(&unregister, 0, sizeof(unregister));
+ (void)memset_s(&unregister, sizeof(unregister), 0, sizeof(unregister));
unregister.op_register = 0;
if (hinic5_func_type(nic_io->hwdev) == TYPE_VF) {
do {
if (hinic5_is_slave_host(nic_io->hwdev)) {
- nic_info(nic_io->dev_hdl, "The VF(slave host) does not need to unregister with the PF.");
+ nic_info(
+ nic_io->dev_hdl,
+ "The VF(slave host) does not need to unregister with the PF.");
break;
}
if (hinic5_is_vf_isolation(nic_io->hwdev)) {
- nic_info(nic_io->dev_hdl, "The isolated VF does not need to unregister with the PF.");
+ nic_info(
+ nic_io->dev_hdl,
+ "The isolated VF does not need to unregister with the PF.");
break;
}
err = hinic5_mbox_to_pf(nic_io->hwdev, HINIC5_MOD_L2NIC,
@@ -630,23 +655,29 @@ void hinic5_vf_func_free(struct hinic5_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC5_CHANNEL_NIC);
- if (err != 0 || out_size == 0 || unregister.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if ((err != 0) || (out_size == 0) ||
+ (unregister.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status,
+ out_size);
}
} while (0);
hinic5_unregister_vf_mbox_cb(nic_io->hwdev, HINIC5_MOD_HILINK);
hinic5_unregister_vf_mbox_cb(nic_io->hwdev, HINIC5_MOD_L2NIC);
} else {
- if (nic_io->vf_infos) {
- hinic5_unregister_pf_mbox_cb(nic_io->hwdev, HINIC5_MOD_HILINK);
- hinic5_unregister_pf_mbox_cb(nic_io->hwdev, HINIC5_MOD_L2NIC);
- hinic5_clear_vfs_info(nic_io->hwdev, 0, nic_io->max_vfs);
+ hinic5_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_HILINK);
+ hinic5_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_L2NIC);
+ if (nic_io->vf_infos != NULL) {
+ hinic5_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC5_MOD_HILINK);
+ hinic5_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC5_MOD_L2NIC);
+ hinic5_clear_vfs_info(nic_io->hwdev, 0,
+ nic_io->max_vfs - 1);
kfree(nic_io->vf_infos);
nic_io->vf_infos = NULL;
}
- hinic5_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_HILINK);
- hinic5_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC5_MOD_L2NIC);
}
}
@@ -657,7 +688,7 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
u16 func_id;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
@@ -665,8 +696,8 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
func_id = hinic5_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
if (vf_infos->use_specified_mac)
- hinic5_del_mac(hwdev, vf_infos->drv_mac_addr,
- vf_infos->pf_vlan, func_id, HINIC5_CHANNEL_NIC);
+ hinic5_del_mac(hwdev, vf_infos->drv_mac_addr, vf_infos->pf_vlan,
+ func_id, HINIC5_CHANNEL_NIC);
if (hinic5_vf_info_vlanprio(hwdev, vf_id) != 0)
hinic5_kill_vf_vlan(hwdev, vf_id);
@@ -682,7 +713,7 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
hinic5_set_vf_trust(hwdev, vf_id, false);
#endif
- memset(vf_infos, 0, sizeof(*vf_infos));
+ (void)memset_s(vf_infos, sizeof(*vf_infos), 0, sizeof(*vf_infos));
/* set vf_infos to default */
hinic5_init_vf_infos(nic_io, HW_VF_ID_TO_OS(vf_id));
}
@@ -690,14 +721,26 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic5_clear_vfs_info(void *hwdev, u32 start_vf_id, u32 end_vf_id)
{
struct hinic5_nic_io *nic_io =
- hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
+ u32 i;
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
- for (i = 0; i < nic_io->max_vfs; i++)
- clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
+ if (start_vf_id > end_vf_id) {
+ pr_err("start_vf_id(%u) > end_vf_id(%u)\n", start_vf_id,
+ end_vf_id);
+ return;
+ }
+
+ if (end_vf_id >= nic_io->max_vfs) {
+ pr_err("end_vf_id(%u) >= max_vfs(%u)\n", end_vf_id,
+ nic_io->max_vfs);
+ return;
+ }
+
+ for (i = start_vf_id; i <= end_vf_id; i++)
+ clear_vf_infos(hwdev, (u16)OS_VF_ID_TO_HW(i));
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cmdq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cmdq.h
index 94ea63981..efb5947f0 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_cmdq.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_cmdq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_CMDQ_H
#define HINIC5_NIC_CMDQ_H
@@ -15,48 +8,46 @@
#include "hinic5_hw.h"
#include "hinic5_nic.h"
-#define HINIC5_Q_CTXT_MAX 31U /* (2048 - 8) / 64 */
-#define HINIC5_QP_CTXT_HEADER_SIZE 16U
+#define HINIC5_Q_CTXT_MAX 31U /* (2048 - 8) / 64 */
+#define HINIC5_QP_CTXT_HEADER_SIZE 16U
-#define HINIC5_DEAULT_DROP_THD_ON (0xFFFF)
+#define HINIC5_DEAULT_DROP_THD_ON (0xFFFF)
-#define SQ_CTXT_PKT_DROP_THD_ON_SHIFT 0
-#define SQ_CTXT_PKT_DROP_THD_OFF_SHIFT 16
+#define SQ_CTXT_PKT_DROP_THD_ON_SHIFT 0
+#define SQ_CTXT_PKT_DROP_THD_OFF_SHIFT 16
-#define SQ_CTXT_PKT_DROP_THD_ON_MASK 0xFFFFU
-#define SQ_CTXT_PKT_DROP_THD_OFF_MASK 0xFFFFU
+#define SQ_CTXT_PKT_DROP_THD_ON_MASK 0xFFFFU
+#define SQ_CTXT_PKT_DROP_THD_OFF_MASK 0xFFFFU
-#define SQ_CTXT_PKT_DROP_THD_SET(val, member) (((val) & \
- SQ_CTXT_PKT_DROP_##member##_MASK) \
- << SQ_CTXT_PKT_DROP_##member##_SHIFT)
+#define SQ_CTXT_PKT_DROP_THD_SET(val, member) \
+ (((val)&SQ_CTXT_PKT_DROP_##member##_MASK) \
+ << SQ_CTXT_PKT_DROP_##member##_SHIFT)
-#define SQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT 0
-#define SQ_CTXT_PREF_CACHE_MAX_SHIFT 14
-#define SQ_CTXT_PREF_CACHE_MIN_SHIFT 25
+#define SQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT 0
+#define SQ_CTXT_PREF_CACHE_MAX_SHIFT 14
+#define SQ_CTXT_PREF_CACHE_MIN_SHIFT 25
-#define SQ_CTXT_PREF_CACHE_THRESHOLD_MASK 0x3FFFU
-#define SQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
-#define SQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
+#define SQ_CTXT_PREF_CACHE_THRESHOLD_MASK 0x3FFFU
+#define SQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
+#define SQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
-#define SQ_CTXT_PREF_SET(val, member) (((val) & \
- SQ_CTXT_PREF_##member##_MASK) \
- << SQ_CTXT_PREF_##member##_SHIFT)
+#define SQ_CTXT_PREF_SET(val, member) \
+ (((val)&SQ_CTXT_PREF_##member##_MASK) << SQ_CTXT_PREF_##member##_SHIFT)
-#define RQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT 0
-#define RQ_CTXT_PREF_CACHE_MAX_SHIFT 14
-#define RQ_CTXT_PREF_CACHE_MIN_SHIFT 25
+#define RQ_CTXT_PREF_CACHE_THRESHOLD_SHIFT 0
+#define RQ_CTXT_PREF_CACHE_MAX_SHIFT 14
+#define RQ_CTXT_PREF_CACHE_MIN_SHIFT 25
-#define RQ_CTXT_PREF_CACHE_THRESHOLD_MASK 0x3FFFU
-#define RQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
-#define RQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
+#define RQ_CTXT_PREF_CACHE_THRESHOLD_MASK 0x3FFFU
+#define RQ_CTXT_PREF_CACHE_MAX_MASK 0x7FFU
+#define RQ_CTXT_PREF_CACHE_MIN_MASK 0x7FU
-#define RQ_CTXT_PREF_SET(val, member) (((val) & \
- RQ_CTXT_PREF_##member##_MASK) << \
- RQ_CTXT_PREF_##member##_SHIFT)
+#define RQ_CTXT_PREF_SET(val, member) \
+ (((val)&RQ_CTXT_PREF_##member##_MASK) << RQ_CTXT_PREF_##member##_SHIFT)
-#define RQ_CTXT_CEQ_ATTR_SET(val, member) (((val) & \
- RQ_CTXT_CEQ_ATTR_##member##_MASK) \
- << RQ_CTXT_CEQ_ATTR_##member##_SHIFT)
+#define RQ_CTXT_CEQ_ATTR_SET(val, member) \
+ (((val)&RQ_CTXT_CEQ_ATTR_##member##_MASK) \
+ << RQ_CTXT_CEQ_ATTR_##member##_SHIFT)
enum hinic5_qp_ctxt_type {
HINIC5_QP_CTXT_TYPE_SQ,
@@ -64,70 +55,76 @@ enum hinic5_qp_ctxt_type {
};
struct hinic5_sq_ctxt {
- u32 ci_pi;
- u32 drop_mode_sp;
- u32 wq_pfn_hi_owner;
- u32 wq_pfn_lo;
-
- u32 rsvd0;
- u32 pkt_drop_thd;
- u32 global_sq_id;
- u32 vlan_ceq_attr;
-
- u32 pref_cache;
- u32 pref_ci_owner;
- u32 pref_wq_pfn_hi_ci;
- u32 pref_wq_pfn_lo;
-
- u32 rsvd8;
- u32 rsvd9;
- u32 wq_block_pfn_hi;
- u32 wq_block_pfn_lo;
+ u32 ci_pi;
+ u32 drop_mode_sp;
+ u32 wq_pfn_hi_owner;
+ u32 wq_pfn_lo;
+
+ u32 rsvd0;
+ u32 pkt_drop_thd;
+ u32 global_sq_id;
+ u32 vlan_ceq_attr;
+
+ u32 pref_cache;
+ u32 pref_ci_owner;
+ u32 pref_wq_pfn_hi_ci;
+ u32 pref_wq_pfn_lo;
+
+ u32 rsvd8;
+ u32 rsvd9;
+ u32 wq_block_pfn_hi;
+ u32 wq_block_pfn_lo;
};
struct hinic5_rq_ctxt {
- u32 ci_pi;
- u32 ceq_attr;
- u32 wq_pfn_hi_type_owner;
- u32 wq_pfn_lo;
-
- u32 rsvd[3];
- u32 cqe_sge_len;
-
- u32 pref_cache;
- u32 pref_ci_owner;
- u32 pref_wq_pfn_hi_ci;
- u32 pref_wq_pfn_lo;
-
- u32 pi_paddr_hi;
- u32 pi_paddr_lo;
- u32 wq_block_pfn_hi;
- u32 wq_block_pfn_lo;
+ u32 ci_pi;
+ u32 ceq_attr;
+ u32 wq_pfn_hi_type_owner;
+ u32 wq_pfn_lo;
+
+ u32 rsvd[3];
+ u32 cqe_sge_len;
+
+ u32 pref_cache;
+ u32 pref_ci_owner;
+ u32 pref_wq_pfn_hi_ci;
+ u32 pref_wq_pfn_lo;
+
+ u32 pi_paddr_hi;
+ u32 pi_paddr_lo;
+ u32 wq_block_pfn_hi;
+ u32 wq_block_pfn_lo;
};
struct hinic5_nic_cmdq_ops {
- u8 (*prepare_cmd_buf_clean_tso_lro_space)(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type);
- u8 (*prepare_cmd_buf_qp_context_multi_store)(struct hinic5_nic_io *nic_io,
- struct hinic5_cmd_buf *cmd_buf,
- enum hinic5_qp_ctxt_type ctxt_type,
- u16 start_qid, u16 max_ctxts);
+ u8 (*prepare_cmd_buf_clean_tso_lro_space)(
+ struct hinic5_nic_io *nic_io, struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type);
+ u8 (*prepare_cmd_buf_qp_context_multi_store)(
+ struct hinic5_nic_io *nic_io, struct hinic5_cmd_buf *cmd_buf,
+ enum hinic5_qp_ctxt_type ctxt_type, u16 start_qid,
+ u16 max_ctxts);
u8 (*prepare_cmd_buf_modify_svlan)(struct hinic5_cmd_buf *cmd_buf,
- u16 func_id, u16 vlan_tag, u16 q_id, u8 vlan_mode);
- u8 (*prepare_cmd_buf_set_rss_indir_table)(const struct hinic5_nic_io *nic_io,
- const u32 *indir_table,
- struct hinic5_cmd_buf *cmd_buf);
- u8 (*prepare_cmd_buf_get_rss_indir_table)(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf);
- void (*cmd_buf_to_rss_indir_table)(const struct hinic5_cmd_buf *cmd_buf, u32 *indir_table);
+ u16 func_id, u16 vlan_tag, u16 q_id,
+ u8 vlan_mode);
+ u8 (*prepare_cmd_buf_set_rss_indir_table)(
+ const struct hinic5_nic_io *nic_io, const u32 *indir_table,
+ struct hinic5_cmd_buf *cmd_buf);
+ u8 (*prepare_cmd_buf_get_rss_indir_table)(
+ const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf);
+ void (*cmd_buf_to_rss_indir_table)(const struct hinic5_cmd_buf *cmd_buf,
+ u32 *indir_table);
void (*cmd_buf_to_vport_stats)(const struct hinic5_cmd_buf *cmd_buf,
struct hinic5_vport_stats *stats);
- u8 (*prepare_cmd_buf_get_vport_stats)(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf, u16 func_id);
- u8 (*prepare_cmd_buf_clear_vport_stats)(const struct hinic5_nic_io *nic_io,
- const struct hinic5_cmd_buf *cmd_buf, u16 func_id);
- void (*prepare_sq_ctxt_drop_and_prefetch)(struct hinic5_sq_ctxt *sq_ctxt);
+ u8 (*prepare_cmd_buf_get_vport_stats)(
+ const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf, u16 func_id);
+ u8 (*prepare_cmd_buf_clear_vport_stats)(
+ const struct hinic5_nic_io *nic_io,
+ const struct hinic5_cmd_buf *cmd_buf, u16 func_id);
+ void (*prepare_sq_ctxt_drop_and_prefetch)(
+ struct hinic5_sq_ctxt *sq_ctxt);
void (*prepare_rq_ctxt_ceq_and_prefetch)(struct hinic5_io_queue *rq,
struct hinic5_rq_ctxt *rq_ctxt,
bool support_rq_sw_compact_wqe);
@@ -137,8 +134,10 @@ struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_182x_ops(void);
struct hinic5_nic_cmdq_ops *hinic5_nic_cmdq_get_187x_ops(void);
void hinic5_nic_cmdq_adapt_init(struct hinic5_nic_io *nic_io);
-void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *sq, u16 sq_id,
+void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *sq, u16 sq_id,
struct hinic5_sq_ctxt *sq_ctxt);
-void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *rq,
+void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *rq,
struct hinic5_rq_ctxt *rq_ctxt);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_dbg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_dbg.c
index 3db53730b..4bd543046 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_dbg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_dbg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -24,7 +17,8 @@
#include "hinic5_nic_dbg.h"
int hinic5_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
- u8 *wqe, const u16 *wqe_size, enum hinic5_queue_type q_type)
+ u8 *wqe, const u16 *wqe_size,
+ enum hinic5_queue_type q_type)
{
struct hinic5_io_queue *queue = NULL;
struct hinic5_nic_io *nic_io = NULL;
@@ -49,7 +43,8 @@ int hinic5_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
queue = (q_type == HINIC5_SQ) ? &nic_io->sq[q_id] : &nic_io->rq[q_id];
if ((idx + wqebb_cnt) > queue->wq.q_depth) {
- pr_err("(idx[%u] + idx[%u]) > q_depth[%u].\n", idx, wqebb_cnt, queue->wq.q_depth);
+ pr_err("(idx[%u] + idx[%u]) > q_depth[%u].\n", idx, wqebb_cnt,
+ queue->wq.q_depth);
return -EINVAL;
}
@@ -60,9 +55,13 @@ int hinic5_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
for (i = 0; i < wqebb_cnt; i++) {
- src_wqebb = hinic5_wq_wqebb_addr(&queue->wq, (u16)WQ_MASK_IDX(&queue->wq, idx + i));
+ src_wqebb = hinic5_wq_wqebb_addr(
+ &queue->wq, (u16)WQ_MASK_IDX(&queue->wq, idx + i));
offset = queue->wq.wqebb_size * i;
- memcpy(wqe_tmp + offset, src_wqebb, queue->wq.wqebb_size);
+ if (memcpy_s(wqe_tmp + offset, *wqe_size - offset, src_wqebb,
+ queue->wq.wqebb_size) != 0) {
+ return -ENOMEM;
+ }
}
return 0;
@@ -83,13 +82,15 @@ int hinic5_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
if (!nic_io)
return -EINVAL;
if (q_id >= nic_io->num_qps) {
- nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
+ nic_err(nic_io->dev_hdl,
+ "Input queue id(%u) is larger than the actual queue number\n",
q_id);
return -EINVAL;
}
if (msg_size != sizeof(*sq_info)) {
- nic_err(nic_io->dev_hdl, "Unexpect out buf size from user :%u, expect: %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Unexpect out buf size from user :%u, expect: %lu\n",
msg_size, sizeof(*sq_info));
return -EINVAL;
}
@@ -126,13 +127,15 @@ int hinic5_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
if (!nic_io)
return -EINVAL;
if (q_id >= nic_io->num_qps) {
- nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
+ nic_err(nic_io->dev_hdl,
+ "Input queue id(%u) is larger than the actual queue number\n",
q_id);
return -EINVAL;
}
if (msg_size != sizeof(*rq_info)) {
- nic_err(nic_io->dev_hdl, "Unexpect out buf size from user: %u, expect: %lu\n",
+ nic_err(nic_io->dev_hdl,
+ "Unexpect out buf size from user: %u, expect: %lu\n",
msg_size, sizeof(*rq_info));
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_event.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_event.c
index d0174341e..d0c014da8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_event.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_event.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -43,8 +36,10 @@ enum hinic5_aeq_cb_state {
HINIC5_NIC_AEQ_SW_CB_RUNNING,
};
-#define AEQ_USLEEP_LOW_BOUND 900
-#define AEQ_USLEEP_HIG_BOUND 1000
+#define AEQ_USLEEP_LOW_BOUND 900
+#define AEQ_USLEEP_HIG_BOUND 1000
+
+#define PN_EXPIRED_SIZE_MAX 32
static int hinic5_init_vf_config(struct hinic5_nic_io *nic_io, u16 vf_id)
{
@@ -75,7 +70,8 @@ static int hinic5_init_vf_config(struct hinic5_nic_io *nic_io, u16 vf_id)
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
}
@@ -86,7 +82,8 @@ static int hinic5_init_vf_config(struct hinic5_nic_io *nic_io, u16 vf_id)
vf_info->max_rate,
vf_info->min_rate);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
return err;
@@ -101,7 +98,8 @@ static int register_vf_msg_handler(struct hinic5_nic_io *nic_io, u16 vf_id)
int err;
if (vf_id > nic_io->max_vfs) {
- nic_err(nic_io->dev_hdl, "Register VF id %d exceed limit[0-%d]\n",
+ nic_err(nic_io->dev_hdl,
+ "Register VF id %d exceed limit[0-%d]\n",
HW_VF_ID_TO_OS(vf_id), HW_VF_ID_TO_OS(nic_io->max_vfs));
return -EFAULT;
}
@@ -128,38 +126,41 @@ static int unregister_vf_msg_handler(struct hinic5_nic_io *nic_io, u16 vf_id)
vf_info->registered = false;
- memset(&mac_info, 0, sizeof(mac_info));
+ (void)memset_s(&mac_info, sizeof(mac_info), 0, sizeof(mac_info));
mac_info.func_id = hinic5_glb_pf_vf_offset(nic_io->hwdev) + (u16)vf_id;
mac_info.vlan_id = vf_info->pf_vlan;
ether_addr_copy(mac_info.mac, vf_info->drv_mac_addr);
- if (vf_info->use_specified_mac || vf_info->pf_vlan != 0) {
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_DEL_MAC,
- &mac_info, sizeof(mac_info),
- &mac_info, &out_size);
- if (err != 0 || out_size == 0)
+ if (vf_info->use_specified_mac || (vf_info->pf_vlan != 0)) {
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_DEL_MAC, &mac_info,
+ sizeof(mac_info), &mac_info,
+ &out_size);
+ if (err != 0 || out_size == 0) {
goto ERR_DEL_MAC;
+ }
switch (mac_info.msg_head.status) {
case 0:
break;
case HINIC5_DEL_MAC_NO_MATCH:
- nic_warn(nic_io->dev_hdl, "Del mac no match, Ignore delete operation.\n");
+ nic_warn(
+ nic_io->dev_hdl,
+ "Del mac no match, Ignore delete operation.\n");
break;
default:
goto ERR_DEL_MAC;
}
}
- memset(vf_info->drv_mac_addr, 0, ETH_ALEN);
+ (void)memset_s(vf_info->drv_mac_addr, ETH_ALEN, 0, ETH_ALEN);
return 0;
ERR_DEL_MAC:
- nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC, err: %d, status: 0x%x, out size: 0x%x\n",
- HW_VF_ID_TO_OS(vf_id), err,
- mac_info.msg_head.status, out_size);
+ nic_err(nic_io->dev_hdl,
+ "Failed to delete VF %d MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, mac_info.msg_head.status, out_size);
return -EFAULT;
}
@@ -169,14 +170,16 @@ static int hinic5_register_vf_msg_handler(struct hinic5_nic_io *nic_io,
{
struct hinic5_cmd_register_vf *register_vf = buf_in;
struct hinic5_cmd_register_vf *register_info = buf_out;
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
int err;
- if (!vf_info)
+ if (vf_info == NULL)
return -EINVAL;
if (register_vf->op_register != 0) {
- vf_info->support_extra_feature = register_vf->support_extra_feature;
+ vf_info->support_extra_feature =
+ register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
} else {
err = unregister_vf_msg_handler(nic_io, vf_id);
@@ -193,22 +196,24 @@ static int hinic5_register_vf_msg_handler(struct hinic5_nic_io *nic_io,
void hinic5_unregister_vf(struct hinic5_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf_id);
- if (!vf_info)
+ if (vf_info == NULL)
return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
static int hinic5_get_vf_cos_msg_handler(struct hinic5_nic_io *nic_io,
- u16 vf_id, void *buf_in,
- u16 in_size, void *buf_out,
- u16 *out_size)
+ u16 vf_id, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
{
struct hinic5_cmd_vf_dcb_state *dcb_state = buf_out;
- memcpy(&dcb_state->state, &nic_io->dcb_state, sizeof(nic_io->dcb_state));
+ if (memcpy_s(&dcb_state->state, sizeof(dcb_state->state),
+ &nic_io->dcb_state, sizeof(nic_io->dcb_state)) != 0)
+ return -ENOMEM;
dcb_state->msg_head.status = 0;
*out_size = sizeof(*dcb_state);
return 0;
@@ -218,22 +223,26 @@ static int hinic5_get_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
- struct hinic5_port_mac_set *mac_in = (struct hinic5_port_mac_set *)buf_in;
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
+ struct hinic5_port_mac_set *mac_in =
+ (struct hinic5_port_mac_set *)buf_in;
struct hinic5_port_mac_set *mac_info = buf_out;
int err;
- if (!mac_info || !vf_info)
+ if ((mac_info == NULL) || (vf_info == NULL))
return -EINVAL;
mac_in->func_id = vf + hinic5_glb_pf_vf_offset(nic_io->hwdev);
if (HINIC5_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_GET_MAC, buf_in,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
- ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
+ ether_addr_copy(mac_info->mac,
+ vf_info->drv_mac_addr);
}
return err;
}
@@ -249,20 +258,23 @@ static int hinic5_set_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
struct hinic5_port_mac_set *mac_in = buf_in;
struct hinic5_port_mac_set *mac_out = buf_out;
int err;
- if (!vf_info)
+ if (vf_info == NULL)
return -EINVAL;
mac_in->func_id = vf + hinic5_glb_pf_vf_offset(nic_io->hwdev);
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
- nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
- HW_VF_ID_TO_OS(vf));
+ nic_warn(
+ nic_io->dev_hdl,
+ "PF has already set VF %d MAC address, and vf trust is off.\n",
+ HW_VF_ID_TO_OS(vf));
mac_out->msg_head.status = HINIC5_PF_SET_VF_ALREADY;
*out_size = sizeof(*mac_out);
return 0;
@@ -271,16 +283,17 @@ static int hinic5_set_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
if (is_valid_ether_addr(mac_in->mac))
mac_in->vlan_id = vf_info->pf_vlan;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_SET_MAC,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_SET_MAC,
buf_in, in_size, buf_out, out_size);
- if (err != 0 || (*out_size) == 0) {
- nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC address, err: %d,status: 0x%x, out size: 0x%x\n",
+ if ((err != 0) || ((*out_size) == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set VF %d MAC address, err: %d,status: 0x%x, out size: 0x%x\n",
HW_VF_ID_TO_OS(vf), err, mac_out->msg_head.status,
*out_size);
return -EFAULT;
}
- if (is_valid_ether_addr(mac_in->mac) && mac_out->msg_head.status == 0)
+ if (is_valid_ether_addr(mac_in->mac) && (mac_out->msg_head.status == 0))
ether_addr_copy(vf_info->drv_mac_addr, mac_in->mac);
return err;
@@ -290,20 +303,23 @@ static int hinic5_del_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
struct hinic5_port_mac_set *mac_in = buf_in;
struct hinic5_port_mac_set *mac_out = buf_out;
int err;
- if (!vf_info)
+ if (vf_info == NULL)
return -EINVAL;
mac_in->func_id = vf + hinic5_glb_pf_vf_offset(nic_io->hwdev);
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
- nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
- HW_VF_ID_TO_OS(vf));
+ nic_warn(
+ nic_io->dev_hdl,
+ "PF has already set VF %d MAC address, and vf trust is off.\n",
+ HW_VF_ID_TO_OS(vf));
mac_out->msg_head.status = HINIC5_PF_SET_VF_ALREADY;
*out_size = sizeof(*mac_out);
return 0;
@@ -312,16 +328,18 @@ static int hinic5_del_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
if (is_valid_ether_addr(mac_in->mac))
mac_in->vlan_id = vf_info->pf_vlan;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_DEL_MAC,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_DEL_MAC,
buf_in, in_size, buf_out, out_size);
- if (err != 0 || (*out_size) == 0)
+ if ((err != 0) || ((*out_size) == 0)) {
goto ERR_DEL_MAC;
+ }
switch (mac_out->msg_head.status) {
case 0:
break;
case HINIC5_DEL_MAC_NO_MATCH:
- nic_warn(nic_io->dev_hdl, "Del mac no match, Ignore delete operation.\n");
+ nic_warn(nic_io->dev_hdl,
+ "Del mac no match, Ignore delete operation.\n");
break;
default:
goto ERR_DEL_MAC;
@@ -333,9 +351,9 @@ static int hinic5_del_vf_mac_msg_handler(struct hinic5_nic_io *nic_io, u16 vf,
return err;
ERR_DEL_MAC:
- nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC, err: %d, status: 0x%x, out size: 0x%x\n",
- HW_VF_ID_TO_OS(vf), err, mac_out->msg_head.status,
- *out_size);
+ nic_err(nic_io->dev_hdl,
+ "Failed to delete VF %d MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf), err, mac_out->msg_head.status, *out_size);
return -EFAULT;
}
@@ -343,12 +361,13 @@ static int hinic5_update_vf_mac_msg_handler(struct hinic5_nic_io *nic_io,
u16 vf, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct vf_data_storage *vf_info = HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
+ struct vf_data_storage *vf_info =
+ HW_VF_ID_TO_OS_CO(nic_io->vf_infos, vf);
struct hinic5_port_mac_update *mac_in = buf_in;
struct hinic5_port_mac_update *mac_out = buf_out;
int err;
- if (!vf_info)
+ if (vf_info == NULL)
return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
@@ -359,30 +378,35 @@ static int hinic5_update_vf_mac_msg_handler(struct hinic5_nic_io *nic_io,
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
- nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
- HW_VF_ID_TO_OS(vf));
+ nic_warn(
+ nic_io->dev_hdl,
+ "PF has already set VF %d MAC address, and vf trust is off.\n",
+ HW_VF_ID_TO_OS(vf));
mac_out->msg_head.status = HINIC5_PF_SET_VF_ALREADY;
*out_size = sizeof(*mac_out);
return 0;
}
#else
- err = hinic_config_vf_request(((struct hinic5_hwdev *)nic_io->hwdev)->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
+ err = hinic_config_vf_request(
+ ((struct hinic5_hwdev *)nic_io->hwdev)->pcidev_hdl,
+ HW_VF_ID_TO_OS(vf), HINIC_CFG_VF_MAC_CHANGED,
+ (void *)mac_in->new_mac);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
+ nic_err(nic_io->dev_hdl,
+ "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
}
#endif
mac_in->vlan_id = vf_info->pf_vlan;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_UPDATE_MAC,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC5_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
- if (err != 0 || (*out_size) == 0) {
- nic_warn(nic_io->dev_hdl, "Failed to update VF %d MAC, err: %d,status: 0x%x, out size: 0x%x\n",
- HW_VF_ID_TO_OS(vf), err, mac_out->msg_head.status,
- *out_size);
+ if ((err != 0) || ((*out_size) == 0)) {
+ nic_warn(
+ nic_io->dev_hdl,
+ "Failed to update VF %d MAC, err: %d,status: 0x%x, out size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf), err, mac_out->msg_head.status,
+ *out_size);
return -EFAULT;
}
@@ -392,7 +416,7 @@ static int hinic5_update_vf_mac_msg_handler(struct hinic5_nic_io *nic_io,
return err;
}
-const struct vf_msg_handler hinic5_vf_cmd_handler[] = {
+const struct vf_msg_handler vf_cmd_handler[] = {
{
.cmd = HINIC5_NIC_CMD_VF_REGISTER,
.handler = hinic5_register_vf_msg_handler,
@@ -418,23 +442,23 @@ const struct vf_msg_handler hinic5_vf_cmd_handler[] = {
.handler = hinic5_update_vf_mac_msg_handler,
},
- {
- .cmd = HINIC5_NIC_CMD_VF_COS,
- .handler = hinic5_get_vf_cos_msg_handler
- },
+ { .cmd = HINIC5_NIC_CMD_VF_COS,
+ .handler = hinic5_get_vf_cos_msg_handler },
};
-static int _hinic5_l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
+static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- int i, cmd_cnt = ARRAY_LEN(hinic5_vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
- if (hinic5_func_type(hwdev) == TYPE_VF && (!hinic5_is_slave_host(hwdev))
- && (!hinic5_is_vf_isolation(hwdev))) {
+ if (hinic5_func_type(hwdev) == TYPE_VF &&
+ (!hinic5_is_slave_host(hwdev)) &&
+ (!hinic5_is_vf_isolation(hwdev))) {
for (i = 0; i < cmd_cnt; i++) {
- if (cmd == hinic5_vf_cmd_handler[i].cmd)
- return hinic5_mbox_to_pf(hwdev, HINIC5_MOD_L2NIC, cmd, buf_in,
+ if (cmd == vf_cmd_handler[i].cmd)
+ return hinic5_mbox_to_pf(
+ hwdev, HINIC5_MOD_L2NIC, cmd, buf_in,
in_size, buf_out, out_size, 0, channel);
}
}
@@ -443,44 +467,44 @@ static int _hinic5_l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
in_size, buf_out, out_size, 0, channel);
}
-int hinic5_l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- return _hinic5_l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
+ return _l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, HINIC5_CHANNEL_NIC);
}
-int hinic5_l2nic_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+int l2nic_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u16 channel)
{
- return _hinic5_l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
+ return _l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
/* pf/ppf handler mbox msg from vf */
-int hinic5_pf_mbox_handler(void *hwdev,
- u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
- void *buf_out, u16 *out_size)
+int hinic5_pf_mbox_handler(void *hwdev, u16 vf_id, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
{
- int index, cmd_size = ARRAY_LEN(hinic5_vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EFAULT;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
for (index = 0; index < cmd_size; index++) {
- if (cmd == hinic5_vf_cmd_handler[index].cmd)
- return hinic5_vf_cmd_handler[index].handler(nic_io, vf_id,
+ if (cmd == vf_cmd_handler[index].cmd)
+ return vf_cmd_handler[index].handler(nic_io, vf_id,
buf_in, in_size,
buf_out, out_size);
}
- nic_warn(nic_io->dev_hdl, "NO handler for nic cmd(%u) received from vf id: %u\n",
- cmd, vf_id);
+ nic_warn(nic_io->dev_hdl,
+ "NO handler for nic cmd(%u) received from vf id: %u\n", cmd,
+ vf_id);
return -EINVAL;
}
@@ -488,30 +512,46 @@ int hinic5_pf_mbox_handler(void *hwdev,
void hinic5_notify_dcb_state_event(struct hinic5_nic_io *nic_io,
struct hinic5_dcb_state *dcb_state)
{
- struct hinic5_event_info event_info = {0};
+ struct hinic5_event_info event_info = { 0 };
int i;
if (dcb_state->trust == HINIC5_DCB_PCP) {
/* This is 8 user priority to cos mapping relationships */
- nic_info(nic_io->dev_hdl, "DCB %s, default cos %u, pcp2cos %u%u%u%u%u%u%u%u\n",
- (dcb_state->dcb_on != 0) ? "on" : "off", dcb_state->default_cos,
- dcb_state->pcp2cos[ARRAY_INDEX_0], dcb_state->pcp2cos[ARRAY_INDEX_1],
- dcb_state->pcp2cos[ARRAY_INDEX_2], dcb_state->pcp2cos[ARRAY_INDEX_3],
- dcb_state->pcp2cos[ARRAY_INDEX_4], dcb_state->pcp2cos[ARRAY_INDEX_5],
- dcb_state->pcp2cos[ARRAY_INDEX_6], dcb_state->pcp2cos[ARRAY_INDEX_7]);
+ nic_info(nic_io->dev_hdl,
+ "DCB %s, default cos %u, pcp2cos %u%u%u%u%u%u%u%u\n",
+ (dcb_state->dcb_on != 0) ? "on" : "off",
+ dcb_state->default_cos,
+ dcb_state->pcp2cos[ARRAY_INDEX_0],
+ dcb_state->pcp2cos[ARRAY_INDEX_1],
+ dcb_state->pcp2cos[ARRAY_INDEX_2],
+ dcb_state->pcp2cos[ARRAY_INDEX_3],
+ dcb_state->pcp2cos[ARRAY_INDEX_4],
+ dcb_state->pcp2cos[ARRAY_INDEX_5],
+ dcb_state->pcp2cos[ARRAY_INDEX_6],
+ dcb_state->pcp2cos[ARRAY_INDEX_7]);
} else {
for (i = 0; i < NIC_DCB_DSCP_NUM; i++) {
- nic_info(nic_io->dev_hdl,
- "DCB %s, default cos %u, dscp2cos %u%u%u%u%u%u%u%u\n",
- (dcb_state->dcb_on != 0) ? "on" : "off", dcb_state->default_cos,
- dcb_state->dscp2cos[ARRAY_INDEX_0 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_1 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_2 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_3 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_4 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_5 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_6 + i * NIC_DCB_DSCP_NUM],
- dcb_state->dscp2cos[ARRAY_INDEX_7 + i * NIC_DCB_DSCP_NUM]);
+ nic_info(
+ nic_io->dev_hdl,
+ "DCB %s, default cos %u, dscp2cos %u%u%u%u%u%u%u%u\n",
+ (dcb_state->dcb_on != 0) ? "on" : "off",
+ dcb_state->default_cos,
+ dcb_state->dscp2cos[ARRAY_INDEX_0 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_1 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_2 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_3 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_4 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_5 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_6 +
+ i * NIC_DCB_DSCP_NUM],
+ dcb_state->dscp2cos[ARRAY_INDEX_7 +
+ i * NIC_DCB_DSCP_NUM]);
}
}
/* Saved in sdk for stateful module */
@@ -519,7 +559,12 @@ void hinic5_notify_dcb_state_event(struct hinic5_nic_io *nic_io,
event_info.service = EVENT_SRV_NIC;
event_info.type = EVENT_NIC_DCB_STATE_CHANGE;
- memcpy((void *)event_info.event_data, dcb_state, sizeof(*dcb_state));
+ if (memcpy_s((void *)event_info.event_data,
+ sizeof(event_info.event_data), dcb_state,
+ sizeof(*dcb_state)) != 0) {
+ pr_err("Failed to copy dcb state\n");
+ return;
+ }
hinic5_event_callback(nic_io->hwdev, &event_info);
}
@@ -530,7 +575,7 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
@@ -541,7 +586,8 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
return;
}
- nic_warn(nic_io->dev_hdl, "Receive tx pause exception event, excp: %u, level: %u\n",
+ nic_warn(nic_io->dev_hdl,
+ "Receive tx pause exception event, excp: %u, level: %u\n",
excp_info->tx_pause_except, excp_info->except_level);
hinic5_fault_event_report(hwdev, HINIC5_FAULT_SRC_TX_PAUSE_EXCP,
@@ -553,10 +599,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
{
struct hinic5_bond_active_report_info *active_info = buf_in;
struct hinic5_nic_io *nic_io = NULL;
- struct hinic5_event_info event_info = {0};
+ struct hinic5_event_info event_info = { 0 };
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
@@ -569,46 +615,57 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
event_info.service = EVENT_SRV_NIC;
event_info.type = HINIC5_NIC_CMD_BOND_ACTIVE_NOTICE;
- memcpy((void *)event_info.event_data, active_info, sizeof(*active_info));
+ if (memcpy_s((void *)event_info.event_data,
+ sizeof(event_info.event_data), active_info,
+ sizeof(*active_info)) != 0) {
+ pr_err("Failed to copy dcb state\n");
+ return;
+ }
hinic5_event_callback(nic_io->hwdev, &event_info);
}
-int bond_link_event_handler(struct hinic5_nic_io *nic_io, struct hinic5_bond_link_info *bond_info)
+int bond_link_event_handler(struct hinic5_nic_io *nic_io,
+ struct hinic5_bond_link_info *bond_info)
{
int err;
u8 link_state;
- struct mag_port_info port_info = {0};
- struct hinic5_event_info event_info = {0};
- struct hinic5_event_link_info *link_info = (void *)event_info.event_data;
+ struct mag_port_info port_info = { 0 };
+ struct hinic5_event_info event_info = { 0 };
+ struct hinic5_event_link_info *link_info =
+ (void *)event_info.event_data;
- /* After bond is deleted, need to get link status from mag */
+ /* 删除bond后需要根据mag获取link状态 */
event_info.service = EVENT_SRV_NIC;
if (bond_info->bond_en != 0) {
nic_info(nic_io->dev_hdl, "bond link event, link_status: %u\n",
bond_info->link_status);
nic_io->feature_cap |= NIC_F_HALF_BOND_OFFLOAD;
event_info.type = (bond_info->link_status != 0) ?
- EVENT_NIC_LINK_UP : EVENT_NIC_LINK_DOWN;
+ EVENT_NIC_LINK_UP :
+ EVENT_NIC_LINK_DOWN;
} else {
nic_io->feature_cap &= ~NIC_F_HALF_BOND_OFFLOAD;
err = hinic5_get_link_state(nic_io->hwdev, &link_state);
if (err != 0)
return err;
- event_info.type = (link_state != 0) ? EVENT_NIC_LINK_UP : EVENT_NIC_LINK_DOWN;
+ event_info.type = (link_state != 0) ? EVENT_NIC_LINK_UP :
+ EVENT_NIC_LINK_DOWN;
}
- err = hinic5_get_port_info(nic_io->hwdev, &port_info, HINIC5_CHANNEL_NIC);
+ err = hinic5_get_port_info(nic_io->hwdev, &port_info,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
nic_warn(nic_io->dev_hdl, "Failed to get port info\n");
return err;
+ } else {
+ link_info->valid = 1;
+ link_info->autoneg_cap = port_info.autoneg_cap;
+ link_info->port_type = port_info.port_type;
+ link_info->duplex = port_info.duplex;
+ link_info->speed = port_info.speed;
+ link_info->autoneg_state = port_info.autoneg_state;
}
- link_info->valid = 1;
- link_info->autoneg_cap = port_info.autoneg_cap;
- link_info->port_type = port_info.port_type;
- link_info->duplex = port_info.duplex;
- link_info->speed = port_info.speed;
- link_info->autoneg_state = port_info.autoneg_state;
hinic5_event_callback(nic_io->hwdev, &event_info);
@@ -623,7 +680,7 @@ void half_bond_link_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
@@ -636,37 +693,49 @@ void half_bond_link_event_handler(void *hwdev, void *buf_in, u16 in_size,
err = bond_link_event_handler(nic_io, bond_info);
if (err != 0)
- nic_err(nic_io->dev_hdl, "Failed to handle bond pf link event\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to handle bond pf link event\n");
}
void macsec_pn_expired_msg_handler(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct macsec_pn_expired_report_cmd *cmd_in = (struct macsec_pn_expired_report_cmd *)buf_in;
+ struct macsec_pn_expired_report_cmd *cmd_in =
+ (struct macsec_pn_expired_report_cmd *)buf_in;
struct hinic5_nic_io *nic_io = NULL;
u8 index = 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
- if (!buf_in) {
- nic_err(nic_io->dev_hdl, "MACsec event process error, in buf is null");
+ if (buf_in == NULL) {
+ nic_err(nic_io->dev_hdl,
+ "MACsec event process error, in buf is null");
return;
}
if (in_size != sizeof(struct macsec_pn_expired_report_cmd)) {
- nic_err(nic_io->dev_hdl, "MACsec event process error, in size(0x%x) is invalid",
+ nic_err(nic_io->dev_hdl,
+ "MACsec event process error, in size(0x%u) is invalid",
in_size);
return;
}
+ if (cmd_in->info.pn_expired_size > PN_EXPIRED_SIZE_MAX) {
+ nic_err(nic_io->dev_hdl,
+ "MACsec event process error, pn_expired_size(%u) exceeds max(%u)",
+ cmd_in->info.pn_expired_size, PN_EXPIRED_SIZE_MAX);
+ return;
+ }
+
for (; index < cmd_in->info.pn_expired_size; index++) {
- nic_info(nic_io->dev_hdl, "MACsec pn exceeding threshold, sci=0x%llx, an=0x%x",
+ nic_info(nic_io->dev_hdl,
+ "MACsec pn exceeding threshold, sci=0x%llx, an=0x%x",
cmd_in->info.sci[index], cmd_in->info.an[index]);
- /* TODO: Report to MKA software */
+ /* TODO 上报MKA软件 */
}
}
@@ -677,7 +746,7 @@ void offload_bond_cfg_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic5_nic_io *nic_io = NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Nic io is null\n");
return;
}
@@ -688,14 +757,17 @@ void offload_bond_cfg_event_handler(void *hwdev, void *buf_in, u16 in_size,
return;
}
- /* Get the enable status of offload bond arp dual send */
- if (bond_info->arp_en != 0)
+ /* 获取卸载bond arp双发使能情况 */
+ if (bond_info->arp_en != 0) {
nic_io->feature_cap |= NIC_F_ARP_DUAL;
- else
+ } else {
nic_io->feature_cap &= ~NIC_F_ARP_DUAL;
+ }
nic_info(nic_io->dev_hdl, "Arp dual status: %s\n",
(bond_info->arp_en != 0) ? "Enable" : "Disable");
+
+ return;
}
static const struct nic_event_handler nic_cmd_handler[] = {
@@ -732,12 +804,12 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
u32 size = sizeof(nic_cmd_handler) / sizeof(struct nic_event_handler);
u32 i;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
*out_size = 0;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
for (i = 0; i < size; i++) {
@@ -760,16 +832,14 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
/* vf link change event
* vf fault report event, TBD
*/
-int hinic5_vf_event_handler(void *hwdev,
- u16 cmd, void *buf_in, u16 in_size,
+int hinic5_vf_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
return _event_handler(hwdev, cmd, buf_in, in_size, buf_out, out_size);
}
/* pf/ppf handler mgmt cpu report nic event */
-void hinic5_mgmt_event_handler(void *hwdev, u16 cmd,
- void *buf_in, u16 in_size,
+void hinic5_mgmt_event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
_event_handler(hwdev, cmd, buf_in, in_size, buf_out, out_size);
@@ -806,11 +876,12 @@ int hinic5_nic_aeq_register_swe_cb(void *hwdev, void *pri_handle,
struct hinic5_nic_aeqs *nic_aeqs = NULL;
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !pri_handle || !nic_aeq_swe_cb || event >= HINIC5_NIC_FATAL_ERROR_MAX)
+ if (!hwdev || !pri_handle || !nic_aeq_swe_cb ||
+ event >= HINIC5_NIC_FATAL_ERROR_MAX)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
nic_aeqs = nic_io->nic_aeqs;
@@ -822,7 +893,8 @@ int hinic5_nic_aeq_register_swe_cb(void *hwdev, void *pri_handle,
nic_aeqs->nic_aeq_swe_cb[event] = nic_aeq_swe_cb;
nic_aeqs->nic_aeq_swe_data[event] = pri_handle;
- set_bit(HINIC5_NIC_AEQ_SW_CB_REG, &nic_aeqs->nic_aeq_sw_cb_state[event]);
+ set_bit(HINIC5_NIC_AEQ_SW_CB_REG,
+ &nic_aeqs->nic_aeq_sw_cb_state[event]);
return 0;
}
@@ -832,23 +904,27 @@ int hinic5_nic_aeq_register_swe_cb(void *hwdev, void *pri_handle,
* @hwdev: the pointer to hwdev
* @event: soft event for the handler
**/
-void hinic5_nic_aeq_unregister_swe_cb(void *hwdev, enum hinic5_ucode_event_type event)
+void hinic5_nic_aeq_unregister_swe_cb(void *hwdev,
+ enum hinic5_ucode_event_type event)
{
struct hinic5_nic_aeqs *nic_aeqs = NULL;
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || event >= HINIC5_NIC_FATAL_ERROR_MAX)
+ if (!hwdev || event >= HINIC5_NIC_FATAL_ERROR_MAX) {
return;
+ }
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
nic_aeqs = nic_io->nic_aeqs;
- if (!nic_aeqs)
+ if (!nic_aeqs) {
return;
+ }
- clear_bit(HINIC5_NIC_AEQ_SW_CB_REG, &nic_aeqs->nic_aeq_sw_cb_state[event]);
+ clear_bit(HINIC5_NIC_AEQ_SW_CB_REG,
+ &nic_aeqs->nic_aeq_sw_cb_state[event]);
while (test_bit(HINIC5_NIC_AEQ_SW_CB_RUNNING,
&nic_aeqs->nic_aeq_sw_cb_state[event]))
@@ -872,7 +948,7 @@ u8 hinic5_nic_aeqe_handler(void *hwdev, u8 event, u8 *data)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
nic_aeqs = nic_io->nic_aeqs;
@@ -884,10 +960,13 @@ u8 hinic5_nic_aeqe_handler(void *hwdev, u8 event, u8 *data)
set_bit(HINIC5_NIC_AEQ_SW_CB_RUNNING,
&nic_aeqs->nic_aeq_sw_cb_state[event]);
- if (test_bit(HINIC5_NIC_AEQ_SW_CB_REG, &nic_aeqs->nic_aeq_sw_cb_state[event]))
- nic_aeqs->nic_aeq_swe_cb[event](nic_aeqs->nic_aeq_swe_data[event], event, data);
+ if (test_bit(HINIC5_NIC_AEQ_SW_CB_REG,
+ &nic_aeqs->nic_aeq_sw_cb_state[event]))
+ nic_aeqs->nic_aeq_swe_cb[event](
+ nic_aeqs->nic_aeq_swe_data[event], event, data);
- clear_bit(HINIC5_NIC_AEQ_SW_CB_RUNNING, &nic_aeqs->nic_aeq_sw_cb_state[event]);
+ clear_bit(HINIC5_NIC_AEQ_SW_CB_RUNNING,
+ &nic_aeqs->nic_aeq_sw_cb_state[event]);
return 0;
}
@@ -915,18 +994,22 @@ int hinic5_nic_aeqs_init(struct hinic5_nic_io *nic_io)
HINIC5_INTERNAL_OTHER_FATAL_ERROR,
hinic5_nic_sw_aeqe_cnt_handler);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to register HINIC5_INTERNAL_OTHER_FATAL_ERROR\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to register HINIC5_INTERNAL_OTHER_FATAL_ERROR\n");
goto err_out;
}
- err = hinic5_nic_aeq_register_swe_cb(nic_io->hwdev, nic_io, HINIC5_CHANNEL_BUSY,
+ err = hinic5_nic_aeq_register_swe_cb(nic_io->hwdev, nic_io,
+ HINIC5_CHANNEL_BUSY,
hinic5_nic_sw_aeqe_cnt_handler);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to register HINIC5_CHANNEL_BUSY\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to register HINIC5_CHANNEL_BUSY\n");
goto err_out;
}
- err = hinic5_register_stateless_aeqs(nic_io->hwdev, nic_io->hwdev,
- (hinic5_aeq_swe_cb)hinic5_nic_aeqe_handler);
+ err = hinic5_register_stateless_aeqs(
+ nic_io->hwdev, nic_io->hwdev,
+ (hinic5_aeq_swe_cb)hinic5_nic_aeqe_handler);
if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register stateless aeqs\n");
goto err_out;
@@ -949,20 +1032,24 @@ void hinic5_nic_aeqs_free(struct hinic5_nic_io *nic_io)
struct hinic5_nic_aeqs *nic_aeqs = NULL;
u32 stateless_aeq_event;
- if (!nic_io)
+ if (!nic_io) {
return;
+ }
hinic5_unregister_stateless_aeqs(nic_io->hwdev);
stateless_aeq_event = (u32)HINIC5_INTERNAL_OTHER_FATAL_ERROR;
nic_aeqs = nic_io->nic_aeqs;
- if (!nic_aeqs)
+ if (!nic_aeqs) {
return;
+ }
- for (; stateless_aeq_event < (u32)HINIC5_NIC_FATAL_ERROR_MAX; stateless_aeq_event++)
- hinic5_nic_aeq_unregister_swe_cb(nic_io->hwdev,
- (enum hinic5_ucode_event_type)stateless_aeq_event);
+ for (; stateless_aeq_event < (u32)HINIC5_NIC_FATAL_ERROR_MAX;
+ stateless_aeq_event++)
+ hinic5_nic_aeq_unregister_swe_cb(
+ nic_io->hwdev,
+ (enum hinic5_ucode_event_type)stateless_aeq_event);
kfree(nic_aeqs);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_io.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_io.c
index 841c2dd76..9d6fe51de 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_nic_io.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_io.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -27,25 +20,30 @@
#include "hinic5_nic_cmdq.h"
#include "hinic5_nic_io.h"
-#define HINIC5_DEAULT_TX_CI_PENDING_LIMIT 1
-#define HINIC5_DEAULT_TX_CI_COALESCING_TIME 1
+#define HINIC5_DEAULT_TX_CI_PENDING_LIMIT 1
+#define HINIC5_DEAULT_TX_CI_COALESCING_TIME 1
#define HINIC5_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG 7
-#define RX_CQE_TIMER_LOOP 0
-#define RX_CQE_COALESCE_NUM 0
+#define RX_CQE_TIMER_LOOP 0
+#define RX_CQE_COALESCE_NUM 0
static unsigned char tx_pending_limit = HINIC5_DEAULT_TX_CI_PENDING_LIMIT;
module_param(tx_pending_limit, byte, 0444);
-MODULE_PARM_DESC(tx_pending_limit, "TX CI coalescing parameter pending_limit (default=1, unit=16 pkts)");
+MODULE_PARM_DESC(
+ tx_pending_limit,
+ "TX CI coalescing parameter pending_limit (default=1, unit=16 pkts)");
static unsigned char tx_coalescing_time = HINIC5_DEAULT_TX_CI_COALESCING_TIME;
module_param(tx_coalescing_time, byte, 0444);
-MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time (default=1, unit=5 us)");
+MODULE_PARM_DESC(
+ tx_coalescing_time,
+ "TX CI coalescing parameter coalescing_time (default=1, unit=5 us)");
static unsigned char rq_wqe_type = HINIC5_COMPACT_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type, 0: COMPACT, 1: NORMAL, 2: EXTEND (default=0)");
+MODULE_PARM_DESC(rq_wqe_type,
+ "RQ WQE type, 0: COMPACT, 1: NORMAL, 2: EXTEND (default=0)");
-#define HINIC5_MAX_CQE_AGGREGATE_NUM 1023
+#define HINIC5_MAX_CQE_AGGREGATE_NUM 1023
#define HINIC5_DEFAULT_CQE_AGGREGATE_NUM 64
static unsigned short cqe_aggregate_num = HINIC5_DEFAULT_CQE_AGGREGATE_NUM;
@@ -54,163 +52,159 @@ MODULE_PARM_DESC(cqe_aggregate_num, "CQE aggregate num, 0-1023 (default=64)");
inline void hinic5_nic_io_param_validate(void)
{
- if (cqe_aggregate_num > HINIC5_MAX_CQE_AGGREGATE_NUM)
+ if (cqe_aggregate_num > HINIC5_MAX_CQE_AGGREGATE_NUM) {
cqe_aggregate_num = HINIC5_DEFAULT_CQE_AGGREGATE_NUM;
+ }
}
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC5_CI_Q_ADDR_SIZE (64U)
+#define HINIC5_CI_Q_ADDR_SIZE (64U)
-#define CI_TABLE_SIZE(num_qps, pg_sz) \
- (ALIGN((num_qps) * HINIC5_CI_Q_ADDR_SIZE, pg_sz))
+#define CI_TABLE_SIZE(num_qps, pg_sz) \
+ (ALIGN((num_qps)*HINIC5_CI_Q_ADDR_SIZE, pg_sz))
-#define HINIC5_CI_VADDR(base_addr, q_id) ((u8 *)(base_addr) + \
- (u32)((q_id) * HINIC5_CI_Q_ADDR_SIZE))
+#define HINIC5_CI_VADDR(base_addr, q_id) \
+ ((u8 *)(base_addr) + (u32)((q_id)*HINIC5_CI_Q_ADDR_SIZE))
-#define HINIC5_CI_PADDR(base_paddr, q_id) ((base_paddr) + \
- (q_id) * HINIC5_CI_Q_ADDR_SIZE)
+#define HINIC5_CI_PADDR(base_paddr, q_id) \
+ ((base_paddr) + (q_id)*HINIC5_CI_Q_ADDR_SIZE)
-#define CI_IDX_HIGH_SHIFH 12
+#define CI_IDX_HIGH_SHIFH 12
-#define CI_HIGN_IDX(val) ((val) >> CI_IDX_HIGH_SHIFH)
+#define CI_HIGN_IDX(val) ((val) >> CI_IDX_HIGH_SHIFH)
-#define SQ_CTXT_PI_IDX_SHIFT 0
-#define SQ_CTXT_CI_IDX_SHIFT 16
+#define SQ_CTXT_PI_IDX_SHIFT 0
+#define SQ_CTXT_CI_IDX_SHIFT 16
-#define SQ_CTXT_PI_IDX_MASK 0xFFFFU
-#define SQ_CTXT_CI_IDX_MASK 0xFFFFU
+#define SQ_CTXT_PI_IDX_MASK 0xFFFFU
+#define SQ_CTXT_CI_IDX_MASK 0xFFFFU
-#define SQ_CTXT_CI_PI_SET(val, member) (((val) & \
- SQ_CTXT_##member##_MASK) \
- << SQ_CTXT_##member##_SHIFT)
+#define SQ_CTXT_CI_PI_SET(val, member) \
+ (((val)&SQ_CTXT_##member##_MASK) << SQ_CTXT_##member##_SHIFT)
-#define SQ_CTXT_MODE_SP_FLAG_SHIFT 0
-#define SQ_CTXT_MODE_PKT_DROP_SHIFT 1
+#define SQ_CTXT_MODE_SP_FLAG_SHIFT 0
+#define SQ_CTXT_MODE_PKT_DROP_SHIFT 1
-#define SQ_CTXT_MODE_SP_FLAG_MASK 0x1U
-#define SQ_CTXT_MODE_PKT_DROP_MASK 0x1U
+#define SQ_CTXT_MODE_SP_FLAG_MASK 0x1U
+#define SQ_CTXT_MODE_PKT_DROP_MASK 0x1U
-#define SQ_CTXT_MODE_SET(val, member) (((val) & \
- SQ_CTXT_MODE_##member##_MASK) \
- << SQ_CTXT_MODE_##member##_SHIFT)
+#define SQ_CTXT_MODE_SET(val, member) \
+ (((val)&SQ_CTXT_MODE_##member##_MASK) << SQ_CTXT_MODE_##member##_SHIFT)
-#define SQ_CTXT_WQ_PAGE_HI_PFN_SHIFT 0
-#define SQ_CTXT_WQ_PAGE_OWNER_SHIFT 23
+#define SQ_CTXT_WQ_PAGE_HI_PFN_SHIFT 0
+#define SQ_CTXT_WQ_PAGE_OWNER_SHIFT 23
-#define SQ_CTXT_WQ_PAGE_HI_PFN_MASK 0xFFFFFU
-#define SQ_CTXT_WQ_PAGE_OWNER_MASK 0x1U
+#define SQ_CTXT_WQ_PAGE_HI_PFN_MASK 0xFFFFFU
+#define SQ_CTXT_WQ_PAGE_OWNER_MASK 0x1U
-#define SQ_CTXT_WQ_PAGE_SET(val, member) (((val) & \
- SQ_CTXT_WQ_PAGE_##member##_MASK) \
- << SQ_CTXT_WQ_PAGE_##member##_SHIFT)
+#define SQ_CTXT_WQ_PAGE_SET(val, member) \
+ (((val)&SQ_CTXT_WQ_PAGE_##member##_MASK) \
+ << SQ_CTXT_WQ_PAGE_##member##_SHIFT)
-#define SQ_CTXT_GLOBAL_SQ_ID_SHIFT 0
+#define SQ_CTXT_GLOBAL_SQ_ID_SHIFT 0
-#define SQ_CTXT_GLOBAL_SQ_ID_MASK 0x1FFFU
+#define SQ_CTXT_GLOBAL_SQ_ID_MASK 0x1FFFU
-#define SQ_CTXT_GLOBAL_QUEUE_ID_SET(val, member) (((val) & \
- SQ_CTXT_##member##_MASK) \
- << SQ_CTXT_##member##_SHIFT)
+#define SQ_CTXT_GLOBAL_QUEUE_ID_SET(val, member) \
+ (((val)&SQ_CTXT_##member##_MASK) << SQ_CTXT_##member##_SHIFT)
-#define SQ_CTXT_VLAN_TAG_SHIFT 0
-#define SQ_CTXT_VLAN_TYPE_SEL_SHIFT 16
-#define SQ_CTXT_VLAN_INSERT_MODE_SHIFT 19
-#define SQ_CTXT_VLAN_CEQ_EN_SHIFT 23
+#define SQ_CTXT_VLAN_TAG_SHIFT 0
+#define SQ_CTXT_VLAN_TYPE_SEL_SHIFT 16
+#define SQ_CTXT_VLAN_INSERT_MODE_SHIFT 19
+#define SQ_CTXT_VLAN_CEQ_EN_SHIFT 23
-#define SQ_CTXT_VLAN_TAG_MASK 0xFFFFU
-#define SQ_CTXT_VLAN_TYPE_SEL_MASK 0x7U
-#define SQ_CTXT_VLAN_INSERT_MODE_MASK 0x3U
-#define SQ_CTXT_VLAN_CEQ_EN_MASK 0x1U
+#define SQ_CTXT_VLAN_TAG_MASK 0xFFFFU
+#define SQ_CTXT_VLAN_TYPE_SEL_MASK 0x7U
+#define SQ_CTXT_VLAN_INSERT_MODE_MASK 0x3U
+#define SQ_CTXT_VLAN_CEQ_EN_MASK 0x1U
-#define SQ_CTXT_VLAN_CEQ_SET(val, member) (((val) & \
- SQ_CTXT_VLAN_##member##_MASK) \
- << SQ_CTXT_VLAN_##member##_SHIFT)
+#define SQ_CTXT_VLAN_CEQ_SET(val, member) \
+ (((val)&SQ_CTXT_VLAN_##member##_MASK) << SQ_CTXT_VLAN_##member##_SHIFT)
-#define SQ_CTXT_PREF_CI_HI_SHIFT 0
-#define SQ_CTXT_PREF_OWNER_SHIFT 4
+#define SQ_CTXT_PREF_CI_HI_SHIFT 0
+#define SQ_CTXT_PREF_OWNER_SHIFT 4
-#define SQ_CTXT_PREF_CI_HI_MASK 0xFU
-#define SQ_CTXT_PREF_OWNER_MASK 0x1U
+#define SQ_CTXT_PREF_CI_HI_MASK 0xFU
+#define SQ_CTXT_PREF_OWNER_MASK 0x1U
-#define SQ_CTXT_PREF_WQ_PFN_HI_SHIFT 0
-#define SQ_CTXT_PREF_CI_LOW_SHIFT 20
+#define SQ_CTXT_PREF_WQ_PFN_HI_SHIFT 0
+#define SQ_CTXT_PREF_CI_LOW_SHIFT 20
-#define SQ_CTXT_PREF_WQ_PFN_HI_MASK 0xFFFFFU
-#define SQ_CTXT_PREF_CI_LOW_MASK 0xFFFU
+#define SQ_CTXT_PREF_WQ_PFN_HI_MASK 0xFFFFFU
+#define SQ_CTXT_PREF_CI_LOW_MASK 0xFFFU
-#define SQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
+#define SQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
-#define SQ_CTXT_WQ_BLOCK_PFN_HI_MASK 0x7FFFFFU
+#define SQ_CTXT_WQ_BLOCK_PFN_HI_MASK 0x7FFFFFU
-#define SQ_CTXT_WQ_BLOCK_SET(val, member) (((val) & \
- SQ_CTXT_WQ_BLOCK_##member##_MASK) \
- << SQ_CTXT_WQ_BLOCK_##member##_SHIFT)
+#define SQ_CTXT_WQ_BLOCK_SET(val, member) \
+ (((val)&SQ_CTXT_WQ_BLOCK_##member##_MASK) \
+ << SQ_CTXT_WQ_BLOCK_##member##_SHIFT)
-#define RQ_CTXT_PI_IDX_SHIFT 0
-#define RQ_CTXT_CI_IDX_SHIFT 16
+#define RQ_CTXT_PI_IDX_SHIFT 0
+#define RQ_CTXT_CI_IDX_SHIFT 16
-#define RQ_CTXT_PI_IDX_MASK 0xFFFFU
-#define RQ_CTXT_CI_IDX_MASK 0xFFFFU
+#define RQ_CTXT_PI_IDX_MASK 0xFFFFU
+#define RQ_CTXT_CI_IDX_MASK 0xFFFFU
-#define RQ_CTXT_CI_PI_SET(val, member) (((val) & \
- RQ_CTXT_##member##_MASK) \
- << RQ_CTXT_##member##_SHIFT)
+#define RQ_CTXT_CI_PI_SET(val, member) \
+ (((val)&RQ_CTXT_##member##_MASK) << RQ_CTXT_##member##_SHIFT)
-#define RQ_CTXT_WQ_PAGE_HI_PFN_SHIFT 0
-#define RQ_CTXT_WQ_PAGE_WQE_TYPE_SHIFT 28
-#define RQ_CTXT_WQ_PAGE_OWNER_SHIFT 31
+#define RQ_CTXT_WQ_PAGE_HI_PFN_SHIFT 0
+#define RQ_CTXT_WQ_PAGE_WQE_TYPE_SHIFT 28
+#define RQ_CTXT_WQ_PAGE_OWNER_SHIFT 31
-#define RQ_CTXT_WQ_PAGE_HI_PFN_MASK 0xFFFFFU
-#define RQ_CTXT_WQ_PAGE_WQE_TYPE_MASK 0x3U
-#define RQ_CTXT_WQ_PAGE_OWNER_MASK 0x1U
+#define RQ_CTXT_WQ_PAGE_HI_PFN_MASK 0xFFFFFU
+#define RQ_CTXT_WQ_PAGE_WQE_TYPE_MASK 0x3U
+#define RQ_CTXT_WQ_PAGE_OWNER_MASK 0x1U
-#define RQ_CTXT_WQ_PAGE_SET(val, member) (((val) & \
- RQ_CTXT_WQ_PAGE_##member##_MASK) << \
- RQ_CTXT_WQ_PAGE_##member##_SHIFT)
+#define RQ_CTXT_WQ_PAGE_SET(val, member) \
+ (((val)&RQ_CTXT_WQ_PAGE_##member##_MASK) \
+ << RQ_CTXT_WQ_PAGE_##member##_SHIFT)
-#define RQ_CTXT_CQE_LEN_SHIFT 28
-#define RQ_CTXT_MAX_COUNT_SHIFT 18
+#define RQ_CTXT_CQE_LEN_SHIFT 28
+#define RQ_CTXT_MAX_COUNT_SHIFT 18
-#define RQ_CTXT_CQE_LEN_MASK 0x3U
-#define RQ_CTXT_MAX_COUNT_MASK 0x3FFU
+#define RQ_CTXT_CQE_LEN_MASK 0x3U
+#define RQ_CTXT_MAX_COUNT_MASK 0x3FFU
-#define RQ_CTXT_CQE_LEN_SET(val, member) (((val) & \
- RQ_CTXT_##member##_MASK) << \
- RQ_CTXT_##member##_SHIFT)
+#define RQ_CTXT_CQE_LEN_SET(val, member) \
+ (((val)&RQ_CTXT_##member##_MASK) << RQ_CTXT_##member##_SHIFT)
-#define RQ_CTXT_PREF_CI_HI_SHIFT 0
-#define RQ_CTXT_PREF_OWNER_SHIFT 4
+#define RQ_CTXT_PREF_CI_HI_SHIFT 0
+#define RQ_CTXT_PREF_OWNER_SHIFT 4
-#define RQ_CTXT_PREF_CI_HI_MASK 0xFU
-#define RQ_CTXT_PREF_OWNER_MASK 0x1U
+#define RQ_CTXT_PREF_CI_HI_MASK 0xFU
+#define RQ_CTXT_PREF_OWNER_MASK 0x1U
-#define RQ_CTXT_PREF_WQ_PFN_HI_SHIFT 0
-#define RQ_CTXT_PREF_CI_LOW_SHIFT 20
+#define RQ_CTXT_PREF_WQ_PFN_HI_SHIFT 0
+#define RQ_CTXT_PREF_CI_LOW_SHIFT 20
-#define RQ_CTXT_PREF_WQ_PFN_HI_MASK 0xFFFFFU
-#define RQ_CTXT_PREF_CI_LOW_MASK 0xFFFU
+#define RQ_CTXT_PREF_WQ_PFN_HI_MASK 0xFFFFFU
+#define RQ_CTXT_PREF_CI_LOW_MASK 0xFFFU
-#define RQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
+#define RQ_CTXT_WQ_BLOCK_PFN_HI_SHIFT 0
-#define RQ_CTXT_WQ_BLOCK_PFN_HI_MASK 0x7FFFFFU
+#define RQ_CTXT_WQ_BLOCK_PFN_HI_MASK 0x7FFFFFU
-#define RQ_CTXT_WQ_BLOCK_SET(val, member) (((val) & \
- RQ_CTXT_WQ_BLOCK_##member##_MASK) << \
- RQ_CTXT_WQ_BLOCK_##member##_SHIFT)
+#define RQ_CTXT_WQ_BLOCK_SET(val, member) \
+ (((val)&RQ_CTXT_WQ_BLOCK_##member##_MASK) \
+ << RQ_CTXT_WQ_BLOCK_##member##_SHIFT)
-#define SIZE_16BYTES(size) (ALIGN((size), 16) >> 4)
+#define SIZE_16BYTES(size) (ALIGN((size), 16) >> 4)
-#define WQ_PAGE_PFN_SHIFT 12
-#define WQ_BLOCK_PFN_SHIFT 9
+#define WQ_PAGE_PFN_SHIFT 12
+#define WQ_BLOCK_PFN_SHIFT 9
-#define WQ_PAGE_PFN(page_addr) ((page_addr) >> WQ_PAGE_PFN_SHIFT)
-#define WQ_BLOCK_PFN(page_addr) ((page_addr) >> WQ_BLOCK_PFN_SHIFT)
+#define WQ_PAGE_PFN(page_addr) ((page_addr) >> WQ_PAGE_PFN_SHIFT)
+#define WQ_BLOCK_PFN(page_addr) ((page_addr) >> WQ_BLOCK_PFN_SHIFT)
/* sq and rq */
-#define TOTAL_DB_NUM(num_qps) ((u16)(2 * (num_qps)))
+#define TOTAL_DB_NUM(num_qps) ((u16)(2 * (num_qps)))
-static int hinic5_create_sq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *sq,
- u16 q_id, u32 sq_depth, u16 sq_msix_idx)
+static int hinic5_create_sq(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *sq, u16 q_id, u32 sq_depth,
+ u16 sq_msix_idx)
{
int err;
@@ -229,12 +223,14 @@ static int hinic5_create_sq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue
}
sq->head_addr = (u64)hinic5_wq_wqebb_addr(&sq->wq, 0);
- sq->tail_addr = (u64)(sq->head_addr + sq_depth * BIT(HINIC5_SQ_WQEBB_SHIFT));
+ sq->tail_addr =
+ (u64)(sq->head_addr + sq_depth * BIT(HINIC5_SQ_WQEBB_SHIFT));
return 0;
}
-static void hinic5_destroy_sq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *sq)
+static void hinic5_destroy_sq(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *sq)
{
hinic5_wq_destroy(&sq->wq);
}
@@ -247,30 +243,34 @@ int hinic5_get_rq_wqe_type(void *hwdev)
struct hinic5_hwdev *dev = hwdev;
- /* rq_wqe_type is the configuration when the driver is installed,
- * but it may not be the actual configuration.
- */
- if (HINIC5_SUPPORT_RX_HW_COMPACT_CQE(hwdev) || HINIC5_SUPPORT_RX_SW_COMPACT_CQE(hwdev)) {
- if (rq_wqe_type != HINIC5_COMPACT_RQ_WQE && rq_wqe_type != HINIC5_NORMAL_RQ_WQE &&
+ /* rq_wqe_type is the configuration when the driver is installed, but it may not be the actual configuration. */
+ if (HINIC5_SUPPORT_RX_HW_COMPACT_CQE(hwdev) ||
+ HINIC5_SUPPORT_RX_SW_COMPACT_CQE(hwdev)) {
+ if (rq_wqe_type != HINIC5_COMPACT_RQ_WQE &&
+ rq_wqe_type != HINIC5_NORMAL_RQ_WQE &&
rq_wqe_type != HINIC5_EXTEND_RQ_WQE) {
return HINIC5_NORMAL_RQ_WQE;
}
} else {
- if (rq_wqe_type != HINIC5_NORMAL_RQ_WQE && rq_wqe_type != HINIC5_EXTEND_RQ_WQE)
+ if (rq_wqe_type != HINIC5_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC5_EXTEND_RQ_WQE)
return HINIC5_NORMAL_RQ_WQE;
}
- if (HINIC5_SUPPORT_FEATURE(dev, TC_FLOWER_OFFLOAD))
- return (rq_wqe_type != HINIC5_COMPACT_RQ_WQE) ? rq_wqe_type : HINIC5_NORMAL_RQ_WQE;
+ if (HINIC5_SUPPORT_FEATURE(dev, TC_FLOWER_OFFLOAD)) {
+ return (rq_wqe_type != HINIC5_COMPACT_RQ_WQE) ?
+ rq_wqe_type :
+ HINIC5_NORMAL_RQ_WQE;
+ }
return rq_wqe_type;
}
-static int hinic5_create_rq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *rq,
- u16 q_id, u32 rq_depth, u16 rq_msix_idx)
+static int hinic5_create_rq(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *rq, u16 q_id, u32 rq_depth,
+ u16 rq_msix_idx)
{
int err;
-
rq->wqe_type = (u8)(hinic5_get_rq_wqe_type(nic_io->hwdev));
rq->q_id = q_id;
@@ -287,7 +287,8 @@ static int hinic5_create_rq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue
return 0;
}
-static void hinic5_destroy_rq(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *rq)
+static void hinic5_destroy_rq(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *rq)
{
hinic5_wq_destroy(&rq->wq);
}
@@ -327,81 +328,107 @@ static void destroy_qp(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *sq,
hinic5_destroy_rq(nic_io, rq);
}
-int hinic5_init_nicio_res(void *hwdev, u16 usr_qps_num)
+static int init_nicio_db_addr(void *hwdev, struct hinic5_nic_io *nic_io)
{
- struct hinic5_nic_io *nic_io = NULL;
void __iomem *db_base = NULL;
int err;
- if (!hwdev)
- return -EINVAL;
-
- nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
- pr_err("Failed to get nic service adapter\n");
- goto fail_to_out;
- }
-
- nic_io->max_qps = hinic5_func_max_qnum(hwdev) - usr_qps_num;
-
err = hinic5_alloc_db_addr(hwdev, &db_base, NULL);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
- goto alloc_sq_db_fail;
+ nic_err(nic_io->dev_hdl,
+ "Failed to allocate doorbell for sqs\n");
+ return err;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic5_alloc_db_addr(hwdev, &db_base, NULL);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
nic_io->rqs_db_addr = (u8 *)db_base;
- nic_io->sq_ci_vaddr_base =
- dma_zalloc_coherent(nic_io->dev_hdl, CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
- &nic_io->sq_ci_dma_base, GFP_KERNEL);
- if (!nic_io->sq_ci_vaddr_base) {
+ return 0;
+
+alloc_rq_db_fail:
+ hinic5_free_db_addr(hwdev, nic_io->sqs_db_addr, NULL);
+ return err;
+}
+
+static int init_nicio_ci_table(struct hinic5_nic_io *nic_io)
+{
+ nic_io->sq_ci_vaddr_base = dma_zalloc_coherent(
+ nic_io->dev_hdl, CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
+ &nic_io->sq_ci_dma_base, GFP_KERNEL);
+ if (nic_io->sq_ci_vaddr_base == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate sq ci area\n");
- goto alloc_tx_vaddr_base_fail;
+ goto alloc_sq_ci_fail;
}
- nic_io->rq_ci_vaddr_base =
- dma_zalloc_coherent(nic_io->dev_hdl, CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
- &nic_io->rq_ci_dma_base, GFP_KERNEL);
- if (!nic_io->rq_ci_vaddr_base) {
+ nic_io->rq_ci_vaddr_base = dma_zalloc_coherent(
+ nic_io->dev_hdl, CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
+ &nic_io->rq_ci_dma_base, GFP_KERNEL);
+ if (nic_io->rq_ci_vaddr_base == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate rq ci area\n");
- goto alloc_rx_vaddr_base_fail;
+ goto alloc_rq_ci_fail;
}
return 0;
-alloc_rx_vaddr_base_fail:
- dma_free_coherent(nic_io->dev_hdl, CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
+alloc_rq_ci_fail:
+ dma_free_coherent(nic_io->dev_hdl,
+ CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
nic_io->sq_ci_vaddr_base, nic_io->sq_ci_dma_base);
+ nic_io->sq_ci_vaddr_base = NULL;
-alloc_tx_vaddr_base_fail:
- hinic5_free_db_addr(hwdev, nic_io->rqs_db_addr, NULL);
+alloc_sq_ci_fail:
+ return -ENOMEM;
+}
-alloc_rq_db_fail:
- hinic5_free_db_addr(hwdev, nic_io->sqs_db_addr, NULL);
+int hinic5_init_nicio_res(void *hwdev, u16 usr_qps_num)
+{
+ struct hinic5_nic_io *nic_io = NULL;
+ int err;
-alloc_sq_db_fail:
- return -ENOMEM;
+ if (hwdev == NULL)
+ return -EINVAL;
+
+ nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL) {
+ pr_err("Failed to get nic service adapter\n");
+ return -EFAULT;
+ }
+
+ nic_io->max_qps = hinic5_func_max_qnum(hwdev) - usr_qps_num;
+
+ err = init_nicio_db_addr(hwdev, nic_io);
+ if (err != 0)
+ goto alloc_db_fail;
+
+ err = init_nicio_ci_table(nic_io);
+ if (err != 0)
+ goto alloc_ci_fail;
+
+ return 0;
+
+alloc_ci_fail:
+ hinic5_free_db_addr(hwdev, nic_io->rqs_db_addr, NULL);
+ hinic5_free_db_addr(hwdev, nic_io->sqs_db_addr, NULL);
-fail_to_out:
- return -EFAULT;
+alloc_db_fail:
+ return err;
}
void hinic5_deinit_nicio_res(void *hwdev)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return;
}
@@ -413,7 +440,7 @@ void hinic5_deinit_nicio_res(void *hwdev)
dma_free_coherent(nic_io->dev_hdl,
CI_TABLE_SIZE(nic_io->max_qps, PAGE_SIZE),
nic_io->rq_ci_vaddr_base, nic_io->rq_ci_dma_base);
-/* free all doorbell */
+ /* free all doorbell */
hinic5_free_db_addr(hwdev, nic_io->sqs_db_addr, NULL);
hinic5_free_db_addr(hwdev, nic_io->rqs_db_addr, NULL);
}
@@ -427,36 +454,42 @@ int hinic5_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
u16 q_id, i, total_num_qps;
int err;
- if (!hwdev || !qps_msix_arry || !qp_params)
+ if ((hwdev == NULL) || (qps_msix_arry == NULL) || (qp_params == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return -EFAULT;
}
total_num_qps = qp_params->num_qps + qp_params->xdp_qps;
- if (total_num_qps > nic_io->max_qps || qp_params->num_qps == 0)
+ if (total_num_qps > nic_io->max_qps || qp_params->num_qps == 0) {
return -EINVAL;
+ }
sqs = kcalloc(total_num_qps, sizeof(*sqs), GFP_KERNEL);
- if (!sqs) {
+ if (sqs == NULL) {
+ nic_err(nic_io->dev_hdl, "Failed to allocate sq\n");
err = -ENOMEM;
goto alloc_sqs_err;
}
rqs = kcalloc(total_num_qps, sizeof(*rqs), GFP_KERNEL);
- if (!rqs) {
+ if (rqs == NULL) {
+ nic_err(nic_io->dev_hdl, "Failed to allocate rq\n");
err = -ENOMEM;
goto alloc_rqs_err;
}
for (q_id = 0; q_id < total_num_qps; q_id++) {
- err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
- qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
+ err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id,
+ qp_params->sq_depth, qp_params->rq_depth,
+ qps_msix_arry[q_id].msix_entry_idx);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
+ nic_err(nic_io->dev_hdl,
+ "Failed to allocate qp %u, err: %d\n", q_id,
+ err);
goto create_qp_err;
}
}
@@ -485,11 +518,11 @@ void hinic5_free_qps(void *hwdev, struct hinic5_dyna_qp_params *qp_params)
struct hinic5_nic_io *nic_io = NULL;
u16 q_id, total_num_qps;
- if (!hwdev || !qp_params)
+ if ((hwdev == NULL) || (qp_params == NULL))
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return;
}
@@ -517,12 +550,14 @@ static void init_qps_info(struct hinic5_nic_io *nic_io,
nic_io->sq = qp_params->sqs;
nic_io->rq = qp_params->rqs;
for (q_id = 0; q_id < total_num_qps; q_id++) {
- sqs[q_id].cons_idx_addr = HINIC5_CI_VADDR(nic_io->sq_ci_vaddr_base, q_id);
+ sqs[q_id].cons_idx_addr =
+ HINIC5_CI_VADDR(nic_io->sq_ci_vaddr_base, q_id);
/* clear ci value */
*(u16 *)sqs[q_id].cons_idx_addr = 0;
sqs[q_id].db_addr = nic_io->sqs_db_addr;
- rqs[q_id].cons_idx_addr = HINIC5_CI_VADDR(nic_io->rq_ci_vaddr_base, q_id);
+ rqs[q_id].cons_idx_addr =
+ HINIC5_CI_VADDR(nic_io->rq_ci_vaddr_base, q_id);
*(u32 *)rqs[q_id].cons_idx_addr = 0;
/* The first num_qps doorbell is used by sq */
rqs[q_id].db_addr = nic_io->rqs_db_addr;
@@ -533,11 +568,11 @@ int hinic5_init_qps(void *hwdev, struct hinic5_dyna_qp_params *qp_params)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !qp_params)
+ if ((hwdev == NULL) || (qp_params == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return -EFAULT;
}
@@ -551,11 +586,11 @@ void hinic5_deinit_qps(void *hwdev, struct hinic5_dyna_qp_params *qp_params)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !qp_params)
+ if ((hwdev == NULL) || (qp_params == NULL))
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return;
}
@@ -565,22 +600,23 @@ void hinic5_deinit_qps(void *hwdev, struct hinic5_dyna_qp_params *qp_params)
qp_params->num_qps = nic_io->num_qps;
qp_params->xdp_qps = nic_io->xdp_qps;
- if (nic_io->enable_queue_pooling == 0)
+ if (nic_io->enable_queue_pooling == 0) {
hinic5_free_qp_ctxts(hwdev);
+ }
}
int hinic5_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
struct irq_info *qps_msix_arry)
{
struct hinic5_nic_io *nic_io = NULL;
- struct hinic5_dyna_qp_params qp_params = {0};
+ struct hinic5_dyna_qp_params qp_params = { 0 };
int err;
- if (!hwdev || !qps_msix_arry)
+ if ((hwdev == NULL) || (qps_msix_arry == NULL))
return -EFAULT;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io) {
+ if (nic_io == NULL) {
pr_err("Failed to get nic service adapter\n");
return -EFAULT;
}
@@ -595,8 +631,8 @@ int hinic5_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
err = hinic5_alloc_qps(hwdev, qps_msix_arry, &qp_params);
if (err != 0) {
hinic5_deinit_nicio_res(hwdev);
- nic_err(nic_io->dev_hdl,
- "Failed to allocate qps, err: %d\n", err);
+ nic_err(nic_io->dev_hdl, "Failed to allocate qps, err: %d\n",
+ err);
return err;
}
@@ -608,13 +644,13 @@ int hinic5_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
void hinic5_destroy_qps(void *hwdev)
{
struct hinic5_nic_io *nic_io = NULL;
- struct hinic5_dyna_qp_params qp_params = {0};
+ struct hinic5_dyna_qp_params qp_params = { 0 };
- if (!hwdev)
+ if (hwdev == NULL)
return;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return;
hinic5_deinit_qps(hwdev, &qp_params);
@@ -626,11 +662,11 @@ void *hinic5_get_nic_queue(void *hwdev, u16 q_id, enum hinic5_queue_type q_type)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || q_type >= HINIC5_MAX_QUEUE_TYPE)
+ if ((hwdev == NULL) || q_type >= HINIC5_MAX_QUEUE_TYPE)
return NULL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return NULL;
if (q_id >= nic_io->max_qps)
return NULL;
@@ -638,8 +674,9 @@ void *hinic5_get_nic_queue(void *hwdev, u16 q_id, enum hinic5_queue_type q_type)
return ((q_type == HINIC5_SQ) ? &nic_io->sq[q_id] : &nic_io->rq[q_id]);
}
-void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue *sq,
- u16 sq_id, struct hinic5_sq_ctxt *sq_ctxt)
+void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *sq, u16 sq_id,
+ struct hinic5_sq_ctxt *sq_ctxt)
{
u64 wq_page_addr;
u64 wq_page_pfn, wq_block_pfn;
@@ -662,17 +699,14 @@ void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue
wq_block_pfn_hi = upper_32_bits(wq_block_pfn);
wq_block_pfn_lo = lower_32_bits(wq_block_pfn);
- sq_ctxt->ci_pi =
- SQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |
- SQ_CTXT_CI_PI_SET(pi_start, PI_IDX);
+ sq_ctxt->ci_pi = SQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |
+ SQ_CTXT_CI_PI_SET(pi_start, PI_IDX);
- sq_ctxt->drop_mode_sp =
- SQ_CTXT_MODE_SET(0, SP_FLAG) |
- SQ_CTXT_MODE_SET(0, PKT_DROP);
+ sq_ctxt->drop_mode_sp = SQ_CTXT_MODE_SET(0, SP_FLAG) |
+ SQ_CTXT_MODE_SET(0, PKT_DROP);
- sq_ctxt->wq_pfn_hi_owner =
- SQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |
- SQ_CTXT_WQ_PAGE_SET(1, OWNER);
+ sq_ctxt->wq_pfn_hi_owner = SQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |
+ SQ_CTXT_WQ_PAGE_SET(1, OWNER);
sq_ctxt->wq_pfn_lo = wq_page_pfn_lo;
@@ -680,9 +714,8 @@ void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue
SQ_CTXT_GLOBAL_QUEUE_ID_SET(sq_id, GLOBAL_SQ_ID);
/* enable insert c-vlan in default */
- sq_ctxt->vlan_ceq_attr =
- SQ_CTXT_VLAN_CEQ_SET(0, CEQ_EN) |
- SQ_CTXT_VLAN_CEQ_SET(1, INSERT_MODE);
+ sq_ctxt->vlan_ceq_attr = SQ_CTXT_VLAN_CEQ_SET(0, CEQ_EN) |
+ SQ_CTXT_VLAN_CEQ_SET(1, INSERT_MODE);
sq_ctxt->rsvd0 = 0;
@@ -705,8 +738,10 @@ void hinic5_sq_prepare_ctxt(struct hinic5_nic_io *nic_io, struct hinic5_io_queue
}
static void hinic5_rq_prepare_ctxt_get_wq_info(struct hinic5_io_queue *rq,
- u32 *wq_page_pfn_hi, u32 *wq_page_pfn_lo,
- u32 *wq_block_pfn_hi, u32 *wq_block_pfn_lo)
+ u32 *wq_page_pfn_hi,
+ u32 *wq_page_pfn_lo,
+ u32 *wq_block_pfn_hi,
+ u32 *wq_block_pfn_lo)
{
u64 wq_page_addr;
u64 wq_page_pfn, wq_block_pfn;
@@ -722,6 +757,46 @@ static void hinic5_rq_prepare_ctxt_get_wq_info(struct hinic5_io_queue *rq,
*wq_block_pfn_lo = lower_32_bits(wq_block_pfn);
}
+static void rq_prepare_ctxt_set_wqe_type(struct hinic5_nic_io *nic_io,
+ struct hinic5_io_queue *rq,
+ struct hinic5_rq_ctxt *rq_ctxt,
+ bool support_rq_sw_compact_wqe)
+{
+ u16 wqe_type = rq->wqe_type;
+ u64 ci_dma_base;
+
+ switch (wqe_type) {
+ case HINIC5_EXTEND_RQ_WQE:
+ /* use 32Byte WQE with SGE for CQE */
+ rq_ctxt->wq_pfn_hi_type_owner |=
+ RQ_CTXT_WQ_PAGE_SET(0, WQE_TYPE);
+ break;
+ case HINIC5_NORMAL_RQ_WQE:
+ /* use 16Byte WQE with 32Bytes SGE for CQE */
+ rq_ctxt->wq_pfn_hi_type_owner |=
+ RQ_CTXT_WQ_PAGE_SET(2, WQE_TYPE);
+ rq_ctxt->cqe_sge_len = RQ_CTXT_CQE_LEN_SET(1, CQE_LEN);
+ break;
+ case HINIC5_COMPACT_RQ_WQE:
+ /* use 8Byte WQE */
+ rq_ctxt->wq_pfn_hi_type_owner |=
+ RQ_CTXT_WQ_PAGE_SET(3, WQE_TYPE);
+ if (support_rq_sw_compact_wqe) {
+ rq_ctxt->cqe_sge_len |= RQ_CTXT_CQE_LEN_SET(
+ cqe_aggregate_num, MAX_COUNT);
+ ci_dma_base = HINIC5_CI_PADDR(nic_io->rq_ci_dma_base,
+ rq->q_id);
+ rq_ctxt->pi_paddr_hi =
+ upper_32_bits(ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ rq_ctxt->pi_paddr_lo =
+ lower_32_bits(ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ }
+ break;
+ default:
+ pr_err("Invalid rq wqe type: %u", wqe_type);
+ }
+}
+
void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io,
struct hinic5_io_queue *rq,
struct hinic5_rq_ctxt *rq_ctxt)
@@ -730,8 +805,7 @@ void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io,
u32 wq_block_pfn_hi, wq_block_pfn_lo;
u16 pi_start, ci_start;
u16 wqe_type = rq->wqe_type;
- u64 ci_dma_base;
- bool support_rq_sw_compact_wqe = false;
+ bool support_rq_sw_compact_wqe;
/* RQ depth is in unit of 8Bytes */
ci_start = (u16)((u32)hinic5_get_rq_local_ci(rq) << wqe_type);
@@ -740,40 +814,20 @@ void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io,
hinic5_rq_prepare_ctxt_get_wq_info(rq, &wq_page_pfn_hi, &wq_page_pfn_lo,
&wq_block_pfn_hi, &wq_block_pfn_lo);
- support_rq_sw_compact_wqe = HINIC5_SUPPORT_RX_SW_COMPACT_CQE(nic_io->hwdev);
- nic_io->cmdq_ops->prepare_rq_ctxt_ceq_and_prefetch(rq, rq_ctxt, support_rq_sw_compact_wqe);
+ support_rq_sw_compact_wqe =
+ HINIC5_SUPPORT_RX_SW_COMPACT_CQE(nic_io->hwdev);
+ nic_io->cmdq_ops->prepare_rq_ctxt_ceq_and_prefetch(
+ rq, rq_ctxt, support_rq_sw_compact_wqe);
- rq_ctxt->ci_pi =
- RQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |
- RQ_CTXT_CI_PI_SET(pi_start, PI_IDX);
+ rq_ctxt->ci_pi = RQ_CTXT_CI_PI_SET(ci_start, CI_IDX) |
+ RQ_CTXT_CI_PI_SET(pi_start, PI_IDX);
rq_ctxt->wq_pfn_hi_type_owner =
RQ_CTXT_WQ_PAGE_SET(wq_page_pfn_hi, HI_PFN) |
RQ_CTXT_WQ_PAGE_SET(1, OWNER);
- switch (wqe_type) {
- case HINIC5_EXTEND_RQ_WQE:
- /* use 32Byte WQE with SGE for CQE */
- rq_ctxt->wq_pfn_hi_type_owner |= RQ_CTXT_WQ_PAGE_SET(0, WQE_TYPE);
- break;
- case HINIC5_NORMAL_RQ_WQE:
- /* use 16Byte WQE with 32Bytes SGE for CQE */
- rq_ctxt->wq_pfn_hi_type_owner |= RQ_CTXT_WQ_PAGE_SET(2, WQE_TYPE);
- rq_ctxt->cqe_sge_len = RQ_CTXT_CQE_LEN_SET(1, CQE_LEN);
- break;
- case HINIC5_COMPACT_RQ_WQE:
- /* use 8Byte WQE */
- rq_ctxt->wq_pfn_hi_type_owner |= RQ_CTXT_WQ_PAGE_SET(3, WQE_TYPE);
- if (support_rq_sw_compact_wqe) {
- rq_ctxt->cqe_sge_len |= RQ_CTXT_CQE_LEN_SET(cqe_aggregate_num, MAX_COUNT);
- ci_dma_base = HINIC5_CI_PADDR(nic_io->rq_ci_dma_base, rq->q_id);
- rq_ctxt->pi_paddr_hi = upper_32_bits(ci_dma_base >> RQ_CI_ADDR_SHIFT);
- rq_ctxt->pi_paddr_lo = lower_32_bits(ci_dma_base >> RQ_CI_ADDR_SHIFT);
- }
- break;
- default:
- pr_err("Invalid rq wqe type: %u", wqe_type);
- }
+ rq_prepare_ctxt_set_wqe_type(nic_io, rq, rq_ctxt,
+ support_rq_sw_compact_wqe);
rq_ctxt->wq_pfn_lo = wq_page_pfn_lo;
@@ -797,9 +851,10 @@ void hinic5_rq_prepare_ctxt(struct hinic5_nic_io *nic_io,
static inline u16 hinic5_get_max_ctxts(u16 num_qps, u16 cmd_buf_size)
{
- u16 max_ctxts = (cmd_buf_size - HINIC5_QP_CTXT_HEADER_SIZE) / sizeof(struct hinic5_rq_ctxt);
+ u16 max_ctxts = (cmd_buf_size - HINIC5_QP_CTXT_HEADER_SIZE) /
+ sizeof(struct hinic5_rq_ctxt);
- max_ctxts = min_t(u16, HINIC5_Q_CTXT_MAX, max_ctxts);
+ max_ctxts = (u16)min((u16)HINIC5_Q_CTXT_MAX, max_ctxts);
return (u16)min(max_ctxts, num_qps);
}
@@ -813,25 +868,29 @@ static int init_sq_ctxts(struct hinic5_nic_io *nic_io)
u32 qp_nums = nic_io->num_qps + nic_io->xdp_qps;
cmd_buf = hinic5_alloc_cmd_buf(nic_io->hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
q_id = 0;
while (q_id < qp_nums) {
- max_ctxts = hinic5_get_max_ctxts(qp_nums - q_id, cmd_buf->size);
- use_buf_size =
- HINIC5_QP_CTXT_HEADER_SIZE + max_ctxts * sizeof(struct hinic5_sq_ctxt);
- memset(cmd_buf->buf, 0, use_buf_size);
+ max_ctxts = hinic5_get_max_ctxts((u16)(qp_nums - q_id),
+ cmd_buf->size);
+ use_buf_size = HINIC5_QP_CTXT_HEADER_SIZE +
+ max_ctxts * sizeof(struct hinic5_sq_ctxt);
+ memset_s(cmd_buf->buf, use_buf_size, 0, use_buf_size);
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(nic_io, cmd_buf,
- HINIC5_QP_CTXT_TYPE_SQ, q_id, max_ctxts);
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(
+ nic_io, cmd_buf, HINIC5_QP_CTXT_TYPE_SQ, q_id,
+ max_ctxts);
err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC5_CHANNEL_NIC);
- if (err != 0 || out_param != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set SQ ctxts, err: %d, out_param: 0x%llx\n",
+ cmd, cmd_buf, &out_param, 0,
+ HINIC5_CHANNEL_NIC);
+ if ((err != 0) || out_param != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set SQ ctxts, err: %d, out_param: 0x%llx\n",
err, out_param);
err = -EFAULT;
@@ -855,25 +914,28 @@ static int init_rq_ctxts(struct hinic5_nic_io *nic_io)
int err = 0;
cmd_buf = hinic5_alloc_cmd_buf(nic_io->hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
q_id = 0;
while (q_id < nic_io->num_qps) {
- max_ctxts = hinic5_get_max_ctxts(nic_io->num_qps - q_id, cmd_buf->size);
- use_buf_size =
- HINIC5_QP_CTXT_HEADER_SIZE + max_ctxts * sizeof(struct hinic5_rq_ctxt);
- memset(cmd_buf->buf, 0, use_buf_size);
-
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(nic_io, cmd_buf,
- HINIC5_QP_CTXT_TYPE_RQ, q_id, max_ctxts);
+ max_ctxts = hinic5_get_max_ctxts(nic_io->num_qps - q_id,
+ cmd_buf->size);
+ use_buf_size = HINIC5_QP_CTXT_HEADER_SIZE +
+ max_ctxts * sizeof(struct hinic5_rq_ctxt);
+ memset_s(cmd_buf->buf, use_buf_size, 0, use_buf_size);
+
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_qp_context_multi_store(
+ nic_io, cmd_buf, HINIC5_QP_CTXT_TYPE_RQ, q_id,
+ max_ctxts);
err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC,
cmd, cmd_buf, &out_param, 0,
HINIC5_CHANNEL_NIC);
- if (err != 0 || out_param != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set RQ ctxts, err: %d, out_param: 0x%llx\n",
+ if ((err != 0) || out_param != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set RQ ctxts, err: %d, out_param: 0x%llx\n",
err, out_param);
err = -EFAULT;
@@ -912,22 +974,25 @@ static int clean_queue_offload_ctxt(struct hinic5_nic_io *nic_io,
int err;
cmd_buf = hinic5_alloc_cmd_buf(nic_io->hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
if (nic_io->cmdq_ops)
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_clean_tso_lro_space(nic_io, cmd_buf,
- ctxt_type);
- else
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_clean_tso_lro_space(
+ nic_io, cmd_buf, ctxt_type);
+ else {
+ hinic5_free_cmd_buf(nic_io->hwdev, cmd_buf);
return -ENOMEM;
+ }
- err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0,
+ err = hinic5_cmdq_direct_resp(nic_io->hwdev, HINIC5_MOD_L2NIC, cmd,
+ cmd_buf, &out_param, 0,
HINIC5_CHANNEL_NIC);
- if (err != 0 || out_param != 0) {
- nic_err(nic_io->dev_hdl, "Failed to clean queue offload ctxts, err: %d,out_param: 0x%llx\n",
+ if ((err != 0) || (out_param != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to clean queue offload ctxts, err: %d,out_param: 0x%llx\n",
err, out_param);
err = -EFAULT;
@@ -941,14 +1006,16 @@ static int clean_queue_offload_ctxt(struct hinic5_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic5_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return ((clean_queue_offload_ctxt(nic_io, HINIC5_QP_CTXT_TYPE_SQ) != 0) ||
- (clean_queue_offload_ctxt(nic_io, HINIC5_QP_CTXT_TYPE_RQ) != 0));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC5_QP_CTXT_TYPE_SQ) !=
+ 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC5_QP_CTXT_TYPE_RQ) !=
+ 0));
}
static int init_sq_ci_ctxts(struct hinic5_nic_io *nic_io)
{
struct hinic5_sq_attr sq_attr;
- u16 q_id;
+ u32 q_id;
int err;
u32 qp_nums;
@@ -965,37 +1032,8 @@ static int init_sq_ci_ctxts(struct hinic5_nic_io *nic_io)
sq_attr.dma_attr_off = 0;
err = hinic5_set_sq_ci_ctx(nic_io, &sq_attr);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set sq ci context\n");
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static int init_rq_ci_ctxts(struct hinic5_nic_io *nic_io)
-{
- struct hinic5_rq_attr rq_attr;
- u16 q_id;
- int err;
-
- for (q_id = 0; q_id < nic_io->num_qps; q_id++) {
- rq_attr.ci_dma_base = 0;
- rq_attr.pending_limit = 0;
- rq_attr.coalescing_time = 0;
- rq_attr.intr_idx = nic_io->rq[q_id].msix_entry_idx;
- rq_attr.l2nic_rqn = q_id;
- rq_attr.cqe_type = 0;
- if (hinic5_get_rq_wqe_type(nic_io->hwdev) == HINIC5_COMPACT_RQ_WQE) {
- rq_attr.cqe_type = 1;
- rq_attr.ci_dma_base = HINIC5_CI_PADDR(nic_io->rq_ci_dma_base, q_id);
- rq_attr.coalescing_time = RX_CQE_TIMER_LOOP;
- rq_attr.pending_limit = RX_CQE_COALESCE_NUM;
- }
-
- err = hinic5_set_rq_ci_ctx(nic_io, &rq_attr);
- if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set rq ci context\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to set sq ci context\n");
return -EFAULT;
}
}
@@ -1010,11 +1048,11 @@ int hinic5_init_qp_ctxts(void *hwdev)
u32 rq_depth;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EFAULT;
err = init_qp_ctxts(nic_io);
@@ -1030,26 +1068,24 @@ int hinic5_init_qp_ctxts(void *hwdev)
return err;
}
- if (nic_io->enable_queue_pooling == 0 || nic_io->first_enable_queue_pooling != 0) {
+ if (nic_io->enable_queue_pooling == 0 ||
+ nic_io->first_enable_queue_pooling != 0) {
nic_io->first_enable_queue_pooling = 0;
rq_depth = nic_io->rq[0].wq.q_depth << nic_io->rq[0].wqe_type;
- err = hinic5_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
- nic_io->rx_buff_len, HINIC5_CHANNEL_NIC);
+ err = hinic5_set_root_ctxt(hwdev, rq_depth,
+ nic_io->sq[0].wq.q_depth,
+ nic_io->rx_buff_len,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set root context\n");
+ nic_err(nic_io->dev_hdl,
+ "Failed to set root context\n");
return err;
}
}
err = init_sq_ci_ctxts(nic_io);
- if (err != 0)
+ if (err != 0) {
goto clean_root_ctxt;
-
- if (HINIC5_SUPPORT_RX_HW_COMPACT_CQE(hwdev)) {
- /* init rxq cqe context */
- err = init_rq_ci_ctxts(nic_io);
- if (err != 0)
- goto clean_root_ctxt;
}
return 0;
@@ -1062,15 +1098,16 @@ int hinic5_init_qp_ctxts(void *hwdev)
void hinic5_free_qp_ctxts(void *hwdev)
{
- if (!hwdev)
+ if (hwdev == NULL)
return;
hinic5_clean_root_ctxt(hwdev, HINIC5_CHANNEL_NIC);
}
-static int hinic5_update_sq_coalesce(struct hinic5_nic_io *nic_io, u32 sq_id, u8 num, u8 time)
+static int hinic5_update_sq_coalesce(struct hinic5_nic_io *nic_io, u32 sq_id,
+ u8 num, u8 time)
{
- struct hinic5_sq_attr sq_attr = {0};
+ struct hinic5_sq_attr sq_attr = { 0 };
int err;
sq_attr.ci_dma_base = HINIC5_CI_PADDR(nic_io->sq_ci_dma_base, sq_id);
@@ -1088,9 +1125,10 @@ static int hinic5_update_sq_coalesce(struct hinic5_nic_io *nic_io, u32 sq_id, u8
return 0;
}
-static int hinic5_update_rq_coalesce(struct hinic5_nic_io *nic_io, u32 rq_id, u8 num, u8 time)
+static int hinic5_update_rq_coalesce(struct hinic5_nic_io *nic_io, u32 rq_id,
+ u8 num, u8 time)
{
- struct hinic5_rq_attr rq_attr = {0};
+ struct hinic5_rq_attr rq_attr = { 0 };
int err;
rq_attr.ci_dma_base = 0;
@@ -1101,7 +1139,8 @@ static int hinic5_update_rq_coalesce(struct hinic5_nic_io *nic_io, u32 rq_id, u8
rq_attr.cqe_type = 0;
if (hinic5_get_rq_wqe_type(nic_io->hwdev) == HINIC5_COMPACT_RQ_WQE) {
rq_attr.cqe_type = 1;
- rq_attr.ci_dma_base = HINIC5_CI_PADDR(nic_io->rq_ci_dma_base, rq_id);
+ rq_attr.ci_dma_base =
+ HINIC5_CI_PADDR(nic_io->rq_ci_dma_base, rq_id);
}
err = hinic5_set_rq_ci_ctx(nic_io, &rq_attr);
if (err != 0) {
@@ -1116,14 +1155,14 @@ int hinic5_set_sq_rq_coalesce_cfg(void *hwdev, u32 q_id, u32 type,
struct hinic5_qp_coalesce_info *coal_info)
{
struct hinic5_nic_io *nic_io = NULL;
- struct interrupt_info info = {0};
+ struct interrupt_info info = { 0 };
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
if (!HINIC5_SUPPORT_SQ_RQ_CI_COALESCE(hwdev)) {
@@ -1131,20 +1170,24 @@ int hinic5_set_sq_rq_coalesce_cfg(void *hwdev, u32 q_id, u32 type,
info.pending_limt = coal_info->pending_limt;
info.interrupt_coalesc_set = 1;
info.msix_index = nic_io->sq[q_id].msix_entry_idx;
- info.resend_timer_cfg = HINIC5_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
- return hinic5_set_interrupt_cfg(hwdev, info, HINIC5_CHANNEL_NIC);
+ info.resend_timer_cfg =
+ HINIC5_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ return hinic5_set_interrupt_cfg(hwdev, info,
+ HINIC5_CHANNEL_NIC);
}
if ((type & HINIC5_SQ_COALESCE) != 0) {
- err = hinic5_update_sq_coalesce(nic_io, q_id, coal_info->tx_pending_limt,
- coal_info->tx_coalesce_timer_cfg);
+ err = hinic5_update_sq_coalesce(
+ nic_io, q_id, coal_info->tx_pending_limt,
+ coal_info->tx_coalesce_timer_cfg);
if (err != 0)
return err;
}
if ((type & HINIC5_RQ_COALESCE) != 0) {
- err = hinic5_update_rq_coalesce(nic_io, q_id, coal_info->rx_pending_limt,
- coal_info->rx_coalesce_timer_cfg);
+ err = hinic5_update_rq_coalesce(
+ nic_io, q_id, coal_info->rx_pending_limt,
+ coal_info->rx_coalesce_timer_cfg);
if (err != 0)
return err;
}
@@ -1159,9 +1202,8 @@ void hinic5_write_db(void *pcidev, struct hinic5_io_queue *queue, int cos,
BUS_IO_PROTOCOL *BusIo = pcidev;
EFI_STATUS Status;
- db.db_info =
- DB_INFO_SET(SRC_TYPE, TYPE) | DB_INFO_SET(cflag, CFLAG) |
- DB_INFO_SET(cos, COS) | DB_INFO_SET(queue->q_id, QID);
+ db.db_info = DB_INFO_SET(SRC_TYPE, TYPE) | DB_INFO_SET(cflag, CFLAG) |
+ DB_INFO_SET(cos, COS) | DB_INFO_SET(queue->q_id, QID);
db.pi_hi = DB_PI_HIGH(pi);
/* Data should be written to HW in Big Endian Format */
db.db_info = hinic5_hw_be32(db.db_info);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_rss_cfg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_rss_cfg.c
index 8d5314b7f..6611c628b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/comm/hinic5_rss_cfg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_rss_cfg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -37,26 +30,30 @@ static int hinic5_rss_cfg_hash_key(struct hinic5_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_key);
int err;
- memset(&hash_key, 0, out_size);
+ (void)memset_s(&hash_key, out_size, 0, out_size);
hash_key.func_id = hinic5_global_func_id(nic_io->hwdev);
hash_key.opcode = opcode;
if (opcode == HINIC5_CMD_OP_SET)
- memcpy(hash_key.key, key, key_size);
-
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
- HINIC5_NIC_CMD_CFG_RSS_HASH_KEY,
- &hash_key, sizeof(hash_key),
- &hash_key, &out_size);
- if (err != 0 || out_size == 0 || hash_key.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to %s hash key, err: %d, status: 0x%x, out size: 0x%x\n",
- opcode == HINIC5_CMD_OP_SET ? "set" : "get",
- err, hash_key.msg_head.status, out_size);
+ if (memcpy_s(hash_key.key, sizeof(hash_key.key), key,
+ key_size) != 0)
+ return -ENOMEM;
+
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC5_NIC_CMD_CFG_RSS_HASH_KEY, &hash_key,
+ sizeof(hash_key), &hash_key, &out_size);
+ if ((err != 0) || (out_size == 0) || (hash_key.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s hash key, err: %d, status: 0x%x, out size: 0x%x\n",
+ opcode == HINIC5_CMD_OP_SET ? "set" : "get", err,
+ hash_key.msg_head.status, out_size);
return -EINVAL;
}
if (opcode == HINIC5_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ if (memcpy_s(key, key_size, hash_key.key, NIC_RSS_KEY_SIZE) !=
+ 0)
+ return -ENOMEM;
return 0;
}
@@ -66,29 +63,32 @@ int hinic5_rss_set_hash_key(void *hwdev, const u8 *key)
struct hinic5_nic_io *nic_io = NULL;
u8 hash_key[NIC_RSS_KEY_SIZE];
- if (!hwdev || !key)
+ if ((hwdev == NULL) || (key == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic5_rss_cfg_hash_key(nic_io, HINIC5_CMD_OP_SET, hash_key, NIC_RSS_KEY_SIZE);
+ if (memcpy_s(hash_key, sizeof(hash_key), key, NIC_RSS_KEY_SIZE) != 0)
+ return -ENOMEM;
+ return hinic5_rss_cfg_hash_key(nic_io, HINIC5_CMD_OP_SET, hash_key,
+ NIC_RSS_KEY_SIZE);
}
int hinic5_rss_get_hash_key(void *hwdev, u8 *key)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !key)
+ if ((hwdev == NULL) || (key == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- return hinic5_rss_cfg_hash_key(nic_io, HINIC5_CMD_OP_GET, key, NIC_RSS_KEY_SIZE);
+ return hinic5_rss_cfg_hash_key(nic_io, HINIC5_CMD_OP_GET, key,
+ NIC_RSS_KEY_SIZE);
}
int hinic5_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
@@ -99,24 +99,25 @@ int hinic5_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
u64 out_param = 0;
int err;
- if (!hwdev || !indir_table)
+ if ((hwdev == NULL) || (indir_table == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
- cmd = nic_io->cmdq_ops->prepare_cmd_buf_set_rss_indir_table(nic_io, indir_table, cmd_buf);
+ cmd = nic_io->cmdq_ops->prepare_cmd_buf_set_rss_indir_table(
+ nic_io, indir_table, cmd_buf);
- err = hinic5_cmdq_direct_resp(hwdev, HINIC5_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC5_CHANNEL_NIC);
- if (err != 0 || out_param != 0) {
+ err = hinic5_cmdq_direct_resp(hwdev, HINIC5_MOD_L2NIC, cmd, cmd_buf,
+ &out_param, 0, HINIC5_CHANNEL_NIC);
+ if ((err != 0) || (out_param != 0)) {
nic_err(nic_io->dev_hdl, "Failed to set rss indir table\n");
err = -EFAULT;
}
@@ -134,14 +135,14 @@ static int hinic5_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
u64 out_param = 0;
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
return -ENOMEM;
}
@@ -158,7 +159,7 @@ static int hinic5_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
cmd_buf->size = sizeof(struct nic_rss_context_tbl);
ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
- memset(ctx_tbl, 0, sizeof(*ctx_tbl));
+ (void)memset_s(ctx_tbl, sizeof(*ctx_tbl), 0, sizeof(*ctx_tbl));
ctx_tbl->ctx = cpu_to_be32(ctx);
/* cfg the rss context table by command queue */
@@ -169,8 +170,9 @@ static int hinic5_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
hinic5_free_cmd_buf(hwdev, cmd_buf);
- if (err != 0 || out_param != 0) {
- nic_err(nic_io->dev_hdl, "cmdq set set rss context table failed, err: %d\n",
+ if ((err != 0) || (out_param != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "cmdq set set rss context table failed, err: %d\n",
err);
return -EFAULT;
}
@@ -186,13 +188,13 @@ static int hinic5_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
u16 out_size = sizeof(ctx_tbl);
int err;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&ctx_tbl, 0, sizeof(ctx_tbl));
+ (void)memset_s(&ctx_tbl, sizeof(ctx_tbl), 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic5_global_func_id(hwdev);
ctx |= HINIC5_RSS_TYPE_SET(1, VALID) |
HINIC5_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
@@ -204,14 +206,17 @@ static int hinic5_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
HINIC5_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
HINIC5_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
ctx_tbl.context = ctx;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
- &ctx_tbl, sizeof(ctx_tbl),
- &ctx_tbl, &out_size);
+ err = l2nic_msg_to_mgmt_sync(hwdev,
+ HINIC5_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
+ &ctx_tbl, sizeof(ctx_tbl), &ctx_tbl,
+ &out_size);
if (ctx_tbl.msg_head.status == HINIC5_MGMT_CMD_UNSUPPORTED) {
return HINIC5_MGMT_CMD_UNSUPPORTED;
- } else if ((err != 0) || (out_size == 0) || (ctx_tbl.msg_head.status != 0)) {
- nic_err(nic_io->dev_hdl, "mgmt Failed to set rss context offload, err: %d, status: 0x%x, out size: 0x%x\n",
+ } else if ((err != 0) || (out_size == 0) ||
+ (ctx_tbl.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "mgmt Failed to set rss context offload, err: %d, status: 0x%x, out size: 0x%x\n",
err, ctx_tbl.msg_head.status, out_size);
return -EINVAL;
}
@@ -237,34 +242,35 @@ int hinic5_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
struct hinic5_nic_io *nic_io = NULL;
int err;
- if (!hwdev || !rss_type)
+ if ((hwdev == NULL) || (rss_type == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&ctx_tbl, 0, out_size);
+ (void)memset_s(&ctx_tbl, out_size, 0, out_size);
ctx_tbl.func_id = hinic5_global_func_id(hwdev);
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_RSS_CTX_TBL,
- &ctx_tbl, sizeof(ctx_tbl),
- &ctx_tbl, &out_size);
- if (err != 0 || out_size == 0 || ctx_tbl.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_GET_RSS_CTX_TBL,
+ &ctx_tbl, sizeof(ctx_tbl), &ctx_tbl,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (ctx_tbl.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
err, ctx_tbl.msg_head.status, out_size);
- return -EINVAL;
+ return -EINVAL;
}
- rss_type->ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV4);
- rss_type->ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV6);
- rss_type->ipv6_ext = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
- rss_type->tcp_ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
- rss_type->tcp_ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
- rss_type->tcp_ipv6_ext = HINIC5_RSS_TYPE_GET(ctx_tbl.context,
- TCP_IPV6_EXT);
- rss_type->udp_ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
- rss_type->udp_ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
+ rss_type->ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV4);
+ rss_type->ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV6);
+ rss_type->ipv6_ext = HINIC5_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
+ rss_type->tcp_ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
+ rss_type->tcp_ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
+ rss_type->tcp_ipv6_ext =
+ HINIC5_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6_EXT);
+ rss_type->udp_ipv4 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
+ rss_type->udp_ipv6 = HINIC5_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
return 0;
}
@@ -276,10 +282,10 @@ static int hinic5_rss_cfg_hash_engine(struct hinic5_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&hash_type, 0, out_size);
+ (void)memset_s(&hash_type, out_size, 0, out_size);
hash_type.func_id = hinic5_global_func_id(nic_io->hwdev);
hash_type.opcode = opcode;
@@ -287,14 +293,15 @@ static int hinic5_rss_cfg_hash_engine(struct hinic5_nic_io *nic_io, u8 opcode,
if (opcode == HINIC5_CMD_OP_SET)
hash_type.hash_engine = *type;
- err = hinic5_l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC5_NIC_CMD_CFG_RSS_HASH_ENGINE,
- &hash_type, sizeof(hash_type),
- &hash_type, &out_size);
- if (err != 0 || out_size == 0 || hash_type.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to %s hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
- opcode == HINIC5_CMD_OP_SET ? "set" : "get",
- err, hash_type.msg_head.status, out_size);
+ &hash_type, sizeof(hash_type), &hash_type,
+ &out_size);
+ if ((err != 0) || (out_size == 0) || (hash_type.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
+ opcode == HINIC5_CMD_OP_SET ? "set" : "get", err,
+ hash_type.msg_head.status, out_size);
return -EIO;
}
@@ -308,11 +315,11 @@ int hinic5_rss_set_hash_engine(void *hwdev, u8 type)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev)
+ if (hwdev == NULL)
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
return hinic5_rss_cfg_hash_engine(nic_io, HINIC5_CMD_OP_SET, &type);
}
@@ -321,11 +328,11 @@ int hinic5_rss_get_hash_engine(void *hwdev, u8 *type)
{
struct hinic5_nic_io *nic_io = NULL;
- if (!hwdev || !type)
+ if ((hwdev == NULL) || (type == NULL))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
return hinic5_rss_cfg_hash_engine(nic_io, HINIC5_CMD_OP_GET, type);
}
@@ -338,30 +345,32 @@ int hinic5_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
int err;
/* micro code required: number of TC should be power of 2 */
- if (!hwdev || !prio_tc || ((cos_num & (cos_num - 1)) != 0))
+ if ((hwdev == NULL) || (prio_tc == NULL) ||
+ ((cos_num & (cos_num - 1)) != 0))
return -EINVAL;
nic_io = hinic5_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
+ if (nic_io == NULL)
return -EINVAL;
- memset(&rss_cfg, 0, out_size);
+ (void)memset_s(&rss_cfg, out_size, 0, out_size);
rss_cfg.func_id = hinic5_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
rss_cfg.rq_priority_number = (cos_num != 0) ? (u8)ilog2(cos_num) : 0;
rss_cfg.num_qps = num_qps;
- memcpy(rss_cfg.prio_tc, prio_tc, NIC_DCB_UP_MAX);
+ if (memcpy_s(rss_cfg.prio_tc, sizeof(rss_cfg.prio_tc), prio_tc,
+ NIC_DCB_UP_MAX) != 0)
+ return -ENOMEM;
- err = hinic5_l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_RSS_CFG,
- &rss_cfg, sizeof(rss_cfg),
- &rss_cfg, &out_size);
- if (err != 0 || out_size == 0 || rss_cfg.msg_head.status != 0) {
- nic_err(nic_io->dev_hdl, "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC5_NIC_CMD_RSS_CFG, &rss_cfg,
+ sizeof(rss_cfg), &rss_cfg, &out_size);
+ if ((err != 0) || (out_size == 0) || (rss_cfg.msg_head.status != 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
err, rss_cfg.msg_head.status, out_size);
return -EINVAL;
}
return 0;
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_mag_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_mag_cfg.h
index 5d2900e6f..e6d345893 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_mag_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_mag_cfg.h
@@ -1,41 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_mag_cfg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_MAG_CFG_H
#define HINIC5_MAG_CFG_H
#include <linux/types.h>
-#define CAP_INFO_MAX_LEN 512
-#define VENDOR_MAX_LEN 17
+#define CAP_INFO_MAX_LEN 512
+#define VENDOR_MAX_LEN 17
#define LOOP_MODE_MIN 1
#define LOOP_MODE_MAX 6
/**
- * @brief Set device physical port state
+ * @brief 设置设备物理端口状态
*
* @param hwdev device pointer to hwdev
- * @param enable Set port state value, true--enable, false--disable
- * @param channel, mailbox channel id used for sending
+ * @param enable 设置端口状态值,true--使能,false--去使能
+ * @param channel channel id, mailbox发送使用的channel id
+ *
+ * @details 设置该设备关联的物理端口状态,通过mailbox发给MPU设置MAG端口状态
*
- * @details Set the physical port state associated with this device, sent to MPU via mailbox to configure MAG port state
+ * @attention: 仅PF支持,VF调用返回0;函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
*
- * @attention: Only PF is supported, VF returns 0; This function involves sending mailbox messages and may sleep,
- * prohibited from being called in interrupt context or other contexts where sleeping is not allowed
- * @return: Returns success or failure for device physical port state setting.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 设备物理端口状态设置返回成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_set_port_enable(void *hwdev, bool enable, u16 channel);
int hinic5_get_fec(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
int hinic5_set_fec(void *hwdev, u8 advertised_fec);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg.h
index c5a47b3de..5d566e294 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_cfg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_CFG_H
#define HINIC5_NIC_CFG_H
@@ -20,11 +13,12 @@
#define nic_err(dev, format, ...) dev_err(dev, "[NIC]" format, ##__VA_ARGS__)
#define nic_warn(dev, format, ...) dev_warn(dev, "[NIC]" format, ##__VA_ARGS__)
-#define nic_notice(dev, format, ...) dev_notice(dev, "[NIC]" format, ##__VA_ARGS__)
+#define nic_notice(dev, format, ...) \
+ dev_notice(dev, "[NIC]" format, ##__VA_ARGS__)
#define nic_info(dev, format, ...) dev_info(dev, "[NIC]" format, ##__VA_ARGS__)
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
-#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
+#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id)-1)
#define HINIC5_VLAN_PRIORITY_SHIFT 13
@@ -37,12 +31,12 @@
#define HINIC5_MIN_MTU_SIZE 256
#define HINIC5_MAX_JUMBO_FRAME_SIZE 9600
-#define HINIC5_DEL_MAC_NO_MATCH 0x5
+#define HINIC5_DEL_MAC_NO_MATCH 0x5
#define HINIC5_MGMT_STATUS_EXIST 0x6
#define CHECK_IPSU_15BIT 0x8000
#define HINIC5_MGMT_STATUS_TABLE_EMPTY 0xB /* Table empty */
-#define HINIC5_MGMT_STATUS_TABLE_FULL 0xC /* Table full */
+#define HINIC5_MGMT_STATUS_TABLE_FULL 0xC /* Table full */
#define HINIC5_LOWEST_LATENCY 3
#define HINIC5_MULTI_VM_LATENCY 32
@@ -85,9 +79,9 @@ enum hinic5_link_follow_status {
struct hinic5_link_ksettings {
u32 valid_bitmap;
- u8 speed; /* enum nic_speed_level */
+ u8 speed; /* enum nic_speed_level */
u8 autoneg; /* 0 - off; 1 - on */
- u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */
+ u8 fec; /* 0 - RSFEC; 1 - BASEFEC; 2 - NOFEC */
};
u64 hinic5_get_feature_cap(void *hwdev);
@@ -102,7 +96,7 @@ u64 hinic5_get_feature_cap(void *hwdev);
#define HINIC5_SUPPORT_RSS(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, RSS)
#define HINIC5_SUPPORT_RXVLAN_FILTER(hwdev) \
HINIC5_SUPPORT_FEATURE(hwdev, RX_VLAN_FILTER)
-#define HINIC5_SUPPORT_VLAN_OFFLOAD(hwdev) \
+#define HINIC5_SUPPORT_VLAN_OFFLOAD(hwdev) \
(HINIC5_SUPPORT_FEATURE(hwdev, RX_VLAN_STRIP) && \
HINIC5_SUPPORT_FEATURE(hwdev, TX_VLAN_INSERT))
#define HINIC5_SUPPORT_VXLAN_OFFLOAD(hwdev) \
@@ -117,15 +111,23 @@ u64 hinic5_get_feature_cap(void *hwdev);
#define HINIC5_SUPPORT_PROMISC(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, PROMISC)
#define HINIC5_SUPPORT_ALLMULTI(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, ALLMULTI)
#define HINIC5_SUPPORT_VF_MAC(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, VF_MAC)
-#define HINIC5_SUPPORT_RATE_LIMIT(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, RATE_LIMIT)
-#define HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, TX_WQE_COMPACT_TASK)
-#define HINIC5_SUPPORT_RX_HW_COMPACT_CQE(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, RX_HW_COMPACT_CQE)
-#define HINIC5_SUPPORT_RX_SW_COMPACT_CQE(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, RX_SW_COMPACT_CQE)
-
-#define HINIC5_SUPPORT_RXQ_RECOVERY(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, RXQ_RECOVERY)
-#define HINIC5_SUPPORT_PTP_1588_V2(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, PTP_1588_V2)
-#define HINIC5_SUPPORT_SQ_RQ_CI_COALESCE(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, SQ_RQ_CI_COALESCE)
-#define HINIC5_SUPPORT_GET_COUNTER_BY_CMDQ(hwdev) HINIC5_SUPPORT_FEATURE(hwdev, GET_COUNTER_BY_CMDQ)
+#define HINIC5_SUPPORT_RATE_LIMIT(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, RATE_LIMIT)
+#define HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, TX_WQE_COMPACT_TASK)
+#define HINIC5_SUPPORT_RX_HW_COMPACT_CQE(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, RX_HW_COMPACT_CQE)
+#define HINIC5_SUPPORT_RX_SW_COMPACT_CQE(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, RX_SW_COMPACT_CQE)
+
+#define HINIC5_SUPPORT_RXQ_RECOVERY(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, RXQ_RECOVERY)
+#define HINIC5_SUPPORT_PTP_1588_V2(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, PTP_1588_V2)
+#define HINIC5_SUPPORT_SQ_RQ_CI_COALESCE(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, SQ_RQ_CI_COALESCE)
+#define HINIC5_SUPPORT_GET_COUNTER_BY_CMDQ(hwdev) \
+ HINIC5_SUPPORT_FEATURE(hwdev, GET_COUNTER_BY_CMDQ)
struct nic_rss_type {
u8 tcp_ipv6_ext;
@@ -164,10 +166,7 @@ struct nic_vlan_ctx {
u32 vlan_sel;
};
-enum hinic5_link_status {
- HINIC5_LINK_DOWN = 0,
- HINIC5_LINK_UP
-};
+enum hinic5_link_status { HINIC5_LINK_DOWN = 0, HINIC5_LINK_UP };
struct nic_pause_config {
u8 auto_neg;
@@ -176,27 +175,27 @@ struct nic_pause_config {
};
struct rxq_check_info {
- u16 hw_pi;
- u16 hw_ci;
+ u16 hw_pi;
+ u16 hw_ci;
};
struct hinic5_rxq_hw {
- u32 func_id;
- u32 num_queues;
+ u32 func_id;
+ u32 num_queues;
- u32 rsvd[14];
+ u32 rsvd[14];
};
-#define MODULE_TYPE_SFP 0x3
-#define MODULE_TYPE_QSFP28 0x11
-#define MODULE_TYPE_QSFP 0x0C
-#define MODULE_TYPE_QSFP_PLUS 0x0D
-#define MODULE_TYPE_SFF8024_ID_QSFP_PLUS_CMIS 0x1E
-#define MODULE_TYPE_SFF8024_ID_DSFP 0x1B
+#define MODULE_TYPE_SFP 0x3
+#define MODULE_TYPE_QSFP28 0x11
+#define MODULE_TYPE_QSFP 0x0C
+#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_SFF8024_ID_QSFP_PLUS_CMIS 0x1E
+#define MODULE_TYPE_SFF8024_ID_DSFP 0x1B
-#define TCAM_IP_TYPE_MASK 0x1
+#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
-#define TCAM_FUNC_ID_MASK 0x7FFF
+#define TCAM_FUNC_ID_MASK 0x7FFF
int hinic5_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic5_del_tcam_rule(void *hwdev, u32 index);
@@ -256,7 +255,8 @@ int hinic5_get_link_state(void *hwdev, u8 *link_state);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_get_vport_stats(void *hwdev, u16 func_id, struct hinic5_vport_stats *stats);
+int hinic5_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic5_vport_stats *stats);
/* *
* @brief hinic5_notify_all_vfs_link_changed - notify to all vfs link changed
@@ -579,12 +579,14 @@ int hinic5_get_sfp_cmis_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic5_get_sfp_eeprom(void *hwdev, u8 *data, u32 len, u32 offset);
int hinic5_get_cmis_eeprom(void *hwdev, u8 *data, u32 len, u32 offset);
int hinic5_eeprom_page_check(u8 page_id, u32 offset, u32 len);
-int hinic5_get_cmis_eeprom_by_page(void *hwdev, u8 page_id, u32 offset, u8 *data, u32 len);
+int hinic5_get_cmis_eeprom_by_page(void *hwdev, u8 page_id, u32 offset,
+ u8 *data, u32 len);
bool hinic5_if_sfp_absent(void *hwdev);
int hinic5_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-int hinic5_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
- const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
+int hinic5_get_sfp_tlv_info(
+ void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic5_set_nic_feature_to_hw - sync nic feature to hardware
@@ -607,7 +609,8 @@ void hinic5_update_nic_feature(void *hwdev, u64 s_feature);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_set_link_status_follow(void *hwdev, enum hinic5_link_follow_status status);
+int hinic5_set_link_status_follow(void *hwdev,
+ enum hinic5_link_follow_status status);
/* *
* @brief hinic5_update_pf_bw - update pf bandwidth
@@ -644,7 +647,8 @@ int hinic5_get_pf_bw_limit(void *hwdev, u32 *bw_limit);
*/
int hinic5_set_pf_rate(void *hwdev, u8 speed_level);
-int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type);
/* *
* @brief hinic5_add_tc_flow_rule - add tc flow rule
@@ -654,7 +658,8 @@ int hinic5_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_add_tc_flow_rule(void *hwdev, struct hinic5_tc_cfg_info *tc_flow_rule,
+int hinic5_add_tc_flow_rule(void *hwdev,
+ struct hinic5_tc_cfg_info *tc_flow_rule,
bool default_rule);
/* *
@@ -682,7 +687,8 @@ int hinic5_flush_tc_flow_rule(void *hwdev, ulong *bitmap);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_get_pfe_cfg(void *hwdev, struct hinic5_tc_pfe_cfg_reg_info *cfg_info);
+int hinic5_get_pfe_cfg(void *hwdev,
+ struct hinic5_tc_pfe_cfg_reg_info *cfg_info);
/* *
* @brief hinic5_move_tc_tcam_table - move tcam table
@@ -691,7 +697,8 @@ int hinic5_get_pfe_cfg(void *hwdev, struct hinic5_tc_pfe_cfg_reg_info *cfg_info)
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic5_move_tc_tcam_table(void *hwdev, struct hinic5_tc_move_info *acl_move_info);
+int hinic5_move_tc_tcam_table(void *hwdev,
+ struct hinic5_tc_move_info *acl_move_info);
/* *
* @brief hinic5_cache_out_qps_res - cache out queue pairs wqe resource in hardware
@@ -738,40 +745,41 @@ int hinic5_flush_qps_res(void *hwdev);
int hinic5_flush_qps_res_by_nums(void *hwdev, u16 qp_num);
/**
- * @brief Set vport state
+ * @brief 设置vport状态
*
* @param hwdev device pointer to hwdev
* @param func_id global function index
- * @param enable Set vport state value, true--enable, false--disable
- * @param channel, mailbox channel id used for sending
+ * @param enable 设置vport状态值,true--使能,false--去使能
+ * @param channel channel id,mailbox发送使用的channel id
+ *
+ * @details 设置对应function vport使能(function表valid标志位)状态,通过mailbox发给MPU设置MAG端口状态
+ *
+ * @attention: 函数内部涉及发送mailbox消息会休眠,禁止中断上下文等不允许休眠的流程中调用
*
- * @details Set the vport enable state (function table valid flag) for the corresponding function,
- * sent to MPU via mailbox to configure MAG port state
- * @attention: This function involves sending mailbox messages and may sleep,
- * prohibited from being called in interrupt context or other contexts where sleeping is not allowed
- * @return: Returns success or failure for device vport state setting.
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 设备vport状态设置返回成功或者失败.
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_set_vport_enable(void *hwdev, u16 func_id, bool enable, u16 channel);
-/* Modify vxlan dport */
-int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action, u8 pkt_fmt);
+/* 修改vxlan dport */
+int hinic5_vxlan_port_config(void *hwdev, u16 func_id, u16 port, u8 action,
+ u8 pkt_fmt);
/**
- * @brief Get chip NIC feature capability
+ * @brief 获取芯片nic特性能力
*
* @param hwdev device pointer to hwdev
- * @param s_feature: Returned chip capability bitmap
- * @param size: Number of bitmaps
+ * @param s_feature:返回的芯片能力bitmap
+ * @param size:bitmap个数
*
- * @details Send mailbox message to get chip NIC feature capability
+ * @details 发送mbox消息,获取芯片nic特性能力
*
* @attention: N/A
*
- * @return: Returns success or failure
- * @retval 0 Success
- * @retval non-zero Failure
+ * @return: 获取结果返回成功或者失败
+ * @retval 0 成功
+ * @retval 非0 失败
*/
int hinic5_get_nic_feature_from_hw(void *hwdev, u64 *s_feature, u16 size);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg_vf.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg_vf.h
index 7188d8623..c41e9e2ce 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg_vf.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_cfg_vf.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_cfg_vf.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_CFG_VF_H
#define HINIC5_NIC_CFG_VF_H
@@ -19,7 +12,7 @@ enum {
};
#define NIC_CVLAN_INSERT_ENABLE 0x1
-#define NIC_QINQ_INSERT_ENABLE 0x3
-#define NIC_VF_TRUST_UNSUPPORT 0xFF
+#define NIC_QINQ_INSERT_ENABLE 0x3
+#define NIC_VF_TRUST_UNSUPPORT 0xFF
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_dbg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_dbg.h
index 48d058614..395bbdce5 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_dbg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_dbg.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_dbg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_DBG_H
#define HINIC5_NIC_DBG_H
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_event.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_event.h
index 3242273d4..b75eb461f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_event.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_event.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_event.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_EVENT_H
#define HINIC5_NIC_EVENT_H
@@ -23,6 +16,7 @@ int hinic5_nic_aeq_register_swe_cb(void *hwdev, void *pri_handle,
enum hinic5_ucode_event_type event,
hinic5_aeq_swe_cb nic_aeq_swe_cb);
-void hinic5_nic_aeq_unregister_swe_cb(void *hwdev, enum hinic5_ucode_event_type event);
+void hinic5_nic_aeq_unregister_swe_cb(void *hwdev,
+ enum hinic5_ucode_event_type event);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_io.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_io.h
index ad9a9b54c..e8df7fbd1 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_io.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_io.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_IO_H
#define HINIC5_NIC_IO_H
@@ -17,16 +10,16 @@
#include "hinic5_nic_sq.h"
#include "hinic5_nic_rq.h"
-#define HINIC5_MAX_TX_QUEUE_DEPTH 16384
-#define HINIC5_MAX_RX_QUEUE_DEPTH 16384
+#define HINIC5_MAX_TX_QUEUE_DEPTH 16384
+#define HINIC5_MAX_RX_QUEUE_DEPTH 16384
-#define HINIC5_MIN_QUEUE_DEPTH 128
+#define HINIC5_MIN_QUEUE_DEPTH 128
-#define HINIC5_SQ_WQEBB_SHIFT 4
-#define HINIC5_RQ_WQEBB_SHIFT 3
+#define HINIC5_SQ_WQEBB_SHIFT 4
+#define HINIC5_RQ_WQEBB_SHIFT 3
-#define HINIC5_SQ_WQEBB_SIZE BIT(HINIC5_SQ_WQEBB_SHIFT)
-#define HINIC5_CQE_SIZE_SHIFT 4
+#define HINIC5_SQ_WQEBB_SIZE BIT(HINIC5_SQ_WQEBB_SHIFT)
+#define HINIC5_CQE_SIZE_SHIFT 4
enum hinic5_rq_wqe_type {
HINIC5_COMPACT_RQ_WQE,
@@ -48,8 +41,8 @@ struct hinic5_io_queue {
u8 wqe_type; /* for rq */
u8 owner; /* for sq */
};
- u8 rsvd1;
- u16 rsvd2;
+ u8 rsvd1;
+ u16 rsvd2;
u16 q_id;
u16 msix_entry_idx;
@@ -121,8 +114,7 @@ static inline u16 hinic5_get_sq_local_pi(const struct hinic5_io_queue *sq)
*/
static inline u16 hinic5_get_sq_hw_ci(const struct hinic5_io_queue *sq)
{
- return WQ_MASK_IDX(&sq->wq,
- hinic5_hw_cpu16(*(u16 *)sq->cons_idx_addr));
+ return WQ_MASK_IDX(&sq->wq, hinic5_hw_cpu16(*(u16 *)sq->cons_idx_addr));
}
static inline u16 hinic5_get_rq_hw_ci(const struct hinic5_io_queue *rq)
@@ -145,7 +137,8 @@ static inline void *hinic5_get_sq_one_wqebb(struct hinic5_io_queue *sq, u16 *pi)
return hinic5_wq_get_one_wqebb(&sq->wq, pi);
}
-static inline void *hinic5_get_sq_wqebbs(struct hinic5_io_queue *sq, u16 wqebb_cnt, u16 *pi)
+static inline void *hinic5_get_sq_wqebbs(struct hinic5_io_queue *sq,
+ u16 wqebb_cnt, u16 *pi)
{
return hinic5_wq_get_wqebbs(&sq->wq, wqebb_cnt, pi);
}
@@ -271,32 +264,31 @@ static inline u16 hinic5_get_rq_local_pi(const struct hinic5_io_queue *rq)
}
/* ******************** DB INFO ******************** */
-#define DB_INFO_QID_SHIFT 0
-#define DB_INFO_NON_FILTER_SHIFT 22
-#define DB_INFO_CFLAG_SHIFT 23
-#define DB_INFO_COS_SHIFT 24
-#define DB_INFO_TYPE_SHIFT 27
-
-#define DB_INFO_QID_MASK 0x1FFFU
-#define DB_INFO_NON_FILTER_MASK 0x1U
-#define DB_INFO_CFLAG_MASK 0x1U
-#define DB_INFO_COS_MASK 0x7U
-#define DB_INFO_TYPE_MASK 0x1FU
-#define DB_INFO_SET(val, member) \
- (((u32)(val) & DB_INFO_##member##_MASK) << \
- DB_INFO_##member##_SHIFT)
-
-#define DB_PI_LOW_MASK 0xFFU
-#define DB_PI_HIGH_MASK 0xFFU
-#define DB_PI_LOW(pi) ((pi) & DB_PI_LOW_MASK)
-#define DB_PI_HI_SHIFT 8
-#define DB_PI_HIGH(pi) (((pi) >> DB_PI_HI_SHIFT) & DB_PI_HIGH_MASK)
-#define DB_ADDR(queue, pi) ((u64 *)((queue)->db_addr) + (u16)DB_PI_LOW(pi))
-#define SRC_TYPE 1
+#define DB_INFO_QID_SHIFT 0
+#define DB_INFO_NON_FILTER_SHIFT 22
+#define DB_INFO_CFLAG_SHIFT 23
+#define DB_INFO_COS_SHIFT 24
+#define DB_INFO_TYPE_SHIFT 27
+
+#define DB_INFO_QID_MASK 0x1FFFU
+#define DB_INFO_NON_FILTER_MASK 0x1U
+#define DB_INFO_CFLAG_MASK 0x1U
+#define DB_INFO_COS_MASK 0x7U
+#define DB_INFO_TYPE_MASK 0x1FU
+#define DB_INFO_SET(val, member) \
+ (((u32)(val)&DB_INFO_##member##_MASK) << DB_INFO_##member##_SHIFT)
+
+#define DB_PI_LOW_MASK 0xFFU
+#define DB_PI_HIGH_MASK 0xFFU
+#define DB_PI_LOW(pi) ((pi)&DB_PI_LOW_MASK)
+#define DB_PI_HI_SHIFT 8
+#define DB_PI_HIGH(pi) (((pi) >> DB_PI_HI_SHIFT) & DB_PI_HIGH_MASK)
+#define DB_ADDR(queue, pi) ((u64 *)((queue)->db_addr) + (u16)DB_PI_LOW(pi))
+#define SRC_TYPE 1
/* CFLAG_DATA_PATH */
-#define SQ_CFLAG_DP 0U
-#define RQ_CFLAG_DP 1U
+#define SQ_CFLAG_DP 0U
+#define RQ_CFLAG_DP 1U
/* *
* @brief hinic5_write_db - write doorbell
* @param queue: nic io queue
@@ -311,7 +303,7 @@ static inline void hinic5_write_db(struct hinic5_io_queue *queue, int cos,
struct hinic5_nic_db db;
db.db_info = DB_INFO_SET(SRC_TYPE, TYPE) | DB_INFO_SET(cflag, CFLAG) |
- DB_INFO_SET(cos, COS) | DB_INFO_SET(queue->q_id, QID);
+ DB_INFO_SET(cos, COS) | DB_INFO_SET(queue->q_id, QID);
db.pi_hi = DB_PI_HIGH(pi);
/* Data should be written to HW in Big Endian Format */
db.db_info = hinic5_hw_be32(db.db_info);
@@ -327,10 +319,10 @@ void hinic5_write_db(void *pcidev, struct hinic5_io_queue *queue, int cos,
#endif
struct hinic5_dyna_qp_params {
- u16 num_qps;
- u16 xdp_qps;
- u32 sq_depth;
- u32 rq_depth;
+ u16 num_qps;
+ u16 xdp_qps;
+ u32 sq_depth;
+ u32 rq_depth;
struct hinic5_io_queue *sqs;
struct hinic5_io_queue *rqs;
@@ -360,11 +352,7 @@ struct hinic5_qp_coalesce_info {
u8 rx_pending_limt_high;
};
-enum hinic5_queue_type {
- HINIC5_SQ,
- HINIC5_RQ,
- HINIC5_MAX_QUEUE_TYPE
-};
+enum hinic5_queue_type { HINIC5_SQ, HINIC5_RQ, HINIC5_MAX_QUEUE_TYPE };
int hinic5_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
struct hinic5_dyna_qp_params *qp_params);
@@ -404,7 +392,8 @@ void hinic5_destroy_qps(void *hwdev);
* @param q_type: queue type
* @retval queue address
*/
-void *hinic5_get_nic_queue(void *hwdev, u16 q_id, enum hinic5_queue_type q_type);
+void *hinic5_get_nic_queue(void *hwdev, u16 q_id,
+ enum hinic5_queue_type q_type);
/* *
* @brief hinic5_init_qp_ctxts - init queue pair context
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_rq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_rq.h
index 097f05782..29b86847e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_rq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_rq.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_rq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_RQ_H
#define HINIC5_NIC_RQ_H
@@ -29,7 +22,7 @@
#define RQ_CQE_OFFOLAD_TYPE_VLAN_EN_MASK 0x1U
#define RQ_CQE_OFFOLAD_TYPE_RSS_TYPE_MASK 0xFFU
-#define RQ_CQE_OFFOLAD_TYPE_GET(val, member) \
+#define RQ_CQE_OFFOLAD_TYPE_GET(val, member) \
(((val) >> RQ_CQE_OFFOLAD_TYPE_##member##_SHIFT) & \
RQ_CQE_OFFOLAD_TYPE_##member##_MASK)
@@ -85,7 +78,7 @@
#define RQ_CQE_STATUS_FLUSH_MASK 0x1U
#define RQ_CQE_STATUS_DECRY_PKT_MASK 0x1U
-#define RQ_CQE_STATUS_GET(val, member) \
+#define RQ_CQE_STATUS_GET(val, member) \
(((val) >> RQ_CQE_STATUS_##member##_SHIFT) & \
RQ_CQE_STATUS_##member##_MASK)
@@ -129,7 +122,7 @@
#define RQ_CQE_DECRY_INFO_DECRY_STATUS_MASK 0xFFU
#define RQ_CQE_DECRY_INFO_ESP_NEXT_HEAD_MASK 0xFFU
-#define RQ_CQE_DECRY_INFO_GET(val, member) \
+#define RQ_CQE_DECRY_INFO_GET(val, member) \
(((val) >> RQ_CQE_DECRY_INFO_##member##_SHIFT) & \
RQ_CQE_DECRY_INFO_##member##_MASK)
@@ -141,62 +134,62 @@
/* compact cqe field */
/* cqe dw0 */
-#define RQ_COMPACT_CQE_STATUS_RXDONE_SHIFT 31
-#define RQ_COMPACT_CQE_STATUS_CQE_TYPE_SHIFT 30
-#define RQ_COMPACT_CQE_STATUS_TS_FLAG_SHIFT 29
-#define RQ_COMPACT_CQE_STATUS_VLAN_EN_SHIFT 28
-#define RQ_COMPACT_CQE_STATUS_PKT_FORMAT_SHIFT 25
-#define RQ_COMPACT_CQE_STATUS_IP_TYPE_SHIFT 24
-#define RQ_COMPACT_CQE_STATUS_CQE_LEN_SHIFT 23
-#define RQ_COMPACT_CQE_STATUS_PKT_MC_SHIFT 21
-#define RQ_COMPACT_CQE_STATUS_CSUM_ERR_SHIFT 19
-#define RQ_COMPACT_CQE_STATUS_PKT_TYPE_SHIFT 16
-#define RQ_COMPACT_CQE_STATUS_PKT_LEN_SHIFT 0
-
-#define RQ_COMPACT_CQE_STATUS_RXDONE_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_CQE_TYPE_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_TS_FLAG_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_VLAN_EN_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_PKT_FORMAT_MASK 0x7U
-#define RQ_COMPACT_CQE_STATUS_IP_TYPE_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_PKT_MC_MASK 0x3U
-#define RQ_COMPACT_CQE_STATUS_CQE_LEN_MASK 0x1U
-#define RQ_COMPACT_CQE_STATUS_CSUM_ERR_MASK 0x3U
-#define RQ_COMPACT_CQE_STATUS_PKT_TYPE_MASK 0x7U
-#define RQ_COMPACT_CQE_STATUS_PKT_LEN_MASK 0xFFFFU
-
-#define RQ_COMPACT_CQE_STATUS_GET(val, member) \
+#define RQ_COMPACT_CQE_STATUS_RXDONE_SHIFT 31
+#define RQ_COMPACT_CQE_STATUS_CQE_TYPE_SHIFT 30
+#define RQ_COMPACT_CQE_STATUS_TS_FLAG_SHIFT 29
+#define RQ_COMPACT_CQE_STATUS_VLAN_EN_SHIFT 28
+#define RQ_COMPACT_CQE_STATUS_PKT_FORMAT_SHIFT 25
+#define RQ_COMPACT_CQE_STATUS_IP_TYPE_SHIFT 24
+#define RQ_COMPACT_CQE_STATUS_CQE_LEN_SHIFT 23
+#define RQ_COMPACT_CQE_STATUS_PKT_MC_SHIFT 21
+#define RQ_COMPACT_CQE_STATUS_CSUM_ERR_SHIFT 19
+#define RQ_COMPACT_CQE_STATUS_PKT_TYPE_SHIFT 16
+#define RQ_COMPACT_CQE_STATUS_PKT_LEN_SHIFT 0
+
+#define RQ_COMPACT_CQE_STATUS_RXDONE_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_CQE_TYPE_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_TS_FLAG_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_VLAN_EN_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_PKT_FORMAT_MASK 0x7U
+#define RQ_COMPACT_CQE_STATUS_IP_TYPE_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_PKT_MC_MASK 0x3U
+#define RQ_COMPACT_CQE_STATUS_CQE_LEN_MASK 0x1U
+#define RQ_COMPACT_CQE_STATUS_CSUM_ERR_MASK 0x3U
+#define RQ_COMPACT_CQE_STATUS_PKT_TYPE_MASK 0x7U
+#define RQ_COMPACT_CQE_STATUS_PKT_LEN_MASK 0xFFFFU
+
+#define RQ_COMPACT_CQE_STATUS_GET(val, member) \
((((val) >> RQ_COMPACT_CQE_STATUS_##member##_SHIFT) & \
- RQ_COMPACT_CQE_STATUS_##member##_MASK))
+ RQ_COMPACT_CQE_STATUS_##member##_MASK))
/* cqe dw2 */
-#define RQ_COMPACT_CQE_OFFLOAD_NUM_LRO_SHIFT 24
-#define RQ_COMPACT_CQE_OFFLOAD_VLAN_SHIFT 8
-#define RQ_COMPACT_CQE_OFFLOAD_PFE_PKT_SRC_SHIFT 5
-#define RQ_COMPACT_CQE_OFFLOAD_PFE_PORT_ID_SHIFT 3
-#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_VLD_SHIFT 2
-#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_HIGH_SHIFT 0
-#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_SHIFT 8
+#define RQ_COMPACT_CQE_OFFLOAD_NUM_LRO_SHIFT 24
+#define RQ_COMPACT_CQE_OFFLOAD_VLAN_SHIFT 8
+#define RQ_COMPACT_CQE_OFFLOAD_PFE_PKT_SRC_SHIFT 5
+#define RQ_COMPACT_CQE_OFFLOAD_PFE_PORT_ID_SHIFT 3
+#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_VLD_SHIFT 2
+#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_HIGH_SHIFT 0
+#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_SHIFT 8
/* cqe dw3 */
-#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_LOW_SHIFT 24
-#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_SHIFT 0
-
-#define RQ_COMPACT_CQE_OFFLOAD_NUM_LRO_MASK 0xFFU
-#define RQ_COMPACT_CQE_OFFLOAD_VLAN_MASK 0xFFFFU
-#define RQ_COMPACT_CQE_OFFLOAD_PFE_PKT_SRC_MASK 0x1U
-#define RQ_COMPACT_CQE_OFFLOAD_PFE_PORT_ID_MASK 0x3U
-#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_VLD_MASK 0x1U
-#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_HIGH_MASK 0x3U
-#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_LOW_MASK 0xFFU
-#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_MASK 0xFFFFFFU
-
-#define RQ_COMPACT_CQE_OFFLOAD_GET(val, member) \
+#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_LOW_SHIFT 24
+#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_SHIFT 0
+
+#define RQ_COMPACT_CQE_OFFLOAD_NUM_LRO_MASK 0xFFU
+#define RQ_COMPACT_CQE_OFFLOAD_VLAN_MASK 0xFFFFU
+#define RQ_COMPACT_CQE_OFFLOAD_PFE_PKT_SRC_MASK 0x1U
+#define RQ_COMPACT_CQE_OFFLOAD_PFE_PORT_ID_MASK 0x3U
+#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_VLD_MASK 0x1U
+#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_HIGH_MASK 0x3U
+#define RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_LOW_MASK 0xFFU
+#define RQ_COMPACT_CQE_OFFLOAD_FLOW_MARK_MASK 0xFFFFFFU
+
+#define RQ_COMPACT_CQE_OFFLOAD_GET(val, member) \
(((val) >> RQ_COMPACT_CQE_OFFLOAD_##member##_SHIFT) & \
RQ_COMPACT_CQE_OFFLOAD_##member##_MASK)
-#define RQ_COMPACT_CQE_16BYTE 0
-#define RQ_COMPACT_CQE_8BYTE 1
+#define RQ_COMPACT_CQE_16BYTE 0
+#define RQ_COMPACT_CQE_8BYTE 1
enum RQ_CAST_TYPE {
UNICAST = 0,
@@ -248,7 +241,7 @@ struct hinic5_cqe_info {
u8 rsvd0;
u32 flow_mark;
-} __aligned(32);
+} __attribute__((aligned(32)));
struct hinic5_sge_sect {
struct hinic5_sge sge;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_sq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_sq.h
index b8e0c4697..01cc316db 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_sq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/include/hinic5_nic_sq.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_sq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NIC_SQ_H
#define HINIC5_NIC_SQ_H
@@ -49,7 +42,7 @@ struct hinic5_sq_compact_wqe {
struct hinic5_sq_extend_wqe {
struct hinic5_sq_wqe_desc wqe_desc;
struct hinic5_sq_task task;
- struct hinic5_sq_bufdesc buf_desc[];
+ struct hinic5_sq_bufdesc buf_desc[0];
};
struct hinic5_sq_wqe {
@@ -104,7 +97,6 @@ struct hinic5_offload_info {
u16 vlan1_tag;
u32 ip_identify;
};
-
struct hinic5_queue_info {
u8 pri;
u8 uc;
@@ -136,7 +128,7 @@ struct hinic5_queue_info {
#define SQ_CTRL_OWNER_MASK 0x1U
#define SQ_CTRL_SET(val, member) \
- (((u32)(val) & SQ_CTRL_##member##_MASK) << SQ_CTRL_##member##_SHIFT)
+ (((u32)(val)&SQ_CTRL_##member##_MASK) << SQ_CTRL_##member##_SHIFT)
#define SQ_CTRL_GET(val, member) \
(((val) >> SQ_CTRL_##member##_SHIFT) & SQ_CTRL_##member##_MASK)
@@ -164,17 +156,17 @@ struct hinic5_queue_info {
#define SQ_CTRL_QUEUE_INFO_UC_MASK 0x1U
#define SQ_CTRL_QUEUE_INFO_PRI_MASK 0x7U
-#define SQ_CTRL_QUEUE_INFO_SET(val, member) \
- (((u32)(val) & SQ_CTRL_QUEUE_INFO_##member##_MASK) << \
- SQ_CTRL_QUEUE_INFO_##member##_SHIFT)
+#define SQ_CTRL_QUEUE_INFO_SET(val, member) \
+ (((u32)(val)&SQ_CTRL_QUEUE_INFO_##member##_MASK) \
+ << SQ_CTRL_QUEUE_INFO_##member##_SHIFT)
-#define SQ_CTRL_QUEUE_INFO_GET(val, member) \
+#define SQ_CTRL_QUEUE_INFO_GET(val, member) \
(((val) >> SQ_CTRL_QUEUE_INFO_##member##_SHIFT) & \
SQ_CTRL_QUEUE_INFO_##member##_MASK)
-#define SQ_CTRL_QUEUE_INFO_CLEAR(val, member) \
- ((val) & (~(SQ_CTRL_QUEUE_INFO_##member##_MASK << \
- SQ_CTRL_QUEUE_INFO_##member##_SHIFT)))
+#define SQ_CTRL_QUEUE_INFO_CLEAR(val, member) \
+ ((val) & (~(SQ_CTRL_QUEUE_INFO_##member##_MASK \
+ << SQ_CTRL_QUEUE_INFO_##member##_SHIFT)))
#define SQ_TASK_INFO0_TUNNEL_FLAG_SHIFT 19
#define SQ_TASK_INFO0_ESP_NEXT_PROTO_SHIFT 22
@@ -198,17 +190,17 @@ struct hinic5_queue_info {
#define SQ_TASK_INFO0_ESP_OFFLOAD_MASK 0x1U
#define SQ_TASK_INFO0_IPSEC_PROTO_MASK 0x1U
-#define SQ_TASK_INFO0_SET(val, member) \
- (((u32)(val) & SQ_TASK_INFO0_##member##_MASK) << \
- SQ_TASK_INFO0_##member##_SHIFT)
-#define SQ_TASK_INFO0_GET(val, member) \
+#define SQ_TASK_INFO0_SET(val, member) \
+ (((u32)(val)&SQ_TASK_INFO0_##member##_MASK) \
+ << SQ_TASK_INFO0_##member##_SHIFT)
+#define SQ_TASK_INFO0_GET(val, member) \
(((val) >> SQ_TASK_INFO0_##member##_SHIFT) & \
SQ_TASK_INFO0_##member##_MASK)
-#define SQ_TASK_INFO1_SET(val, member) \
- (((val) & SQ_TASK_INFO1_##member##_MASK) << \
- SQ_TASK_INFO1_##member##_SHIFT)
-#define SQ_TASK_INFO1_GET(val, member) \
+#define SQ_TASK_INFO1_SET(val, member) \
+ (((val)&SQ_TASK_INFO1_##member##_MASK) \
+ << SQ_TASK_INFO1_##member##_SHIFT)
+#define SQ_TASK_INFO1_GET(val, member) \
(((val) >> SQ_TASK_INFO1_##member##_SHIFT) & \
SQ_TASK_INFO1_##member##_MASK)
@@ -220,42 +212,42 @@ struct hinic5_queue_info {
#define SQ_TASK_INFO3_VLAN_TYPE_MASK 0x7U
#define SQ_TASK_INFO3_VLAN_TAG_VALID_MASK 0x1U
-#define SQ_TASK_INFO3_SET(val, member) \
- (((val) & SQ_TASK_INFO3_##member##_MASK) << \
- SQ_TASK_INFO3_##member##_SHIFT)
-#define SQ_TASK_INFO3_GET(val, member) \
+#define SQ_TASK_INFO3_SET(val, member) \
+ (((val)&SQ_TASK_INFO3_##member##_MASK) \
+ << SQ_TASK_INFO3_##member##_SHIFT)
+#define SQ_TASK_INFO3_GET(val, member) \
(((val) >> SQ_TASK_INFO3_##member##_SHIFT) & \
SQ_TASK_INFO3_##member##_MASK)
/* the task section format in compact wqe */
-#define SQ_TASK_INFO_PKT_1588_SHIFT 31
-#define SQ_TASK_INFO_IPSEC_PROTO_SHIFT 30
-#define SQ_TASK_INFO_OUT_L3_EN_SHIFT 28
-#define SQ_TASK_INFO_OUT_L4_EN_SHIFT 27
-#define SQ_TASK_INFO_INNER_L3_EN_SHIFT 25
-#define SQ_TASK_INFO_INNER_L4_EN_SHIFT 24
-#define SQ_TASK_INFO_ESP_NEXT_PROTO_SHIFT 22
-#define SQ_TASK_INFO_VLAN_VALID_SHIFT 19
-#define SQ_TASK_INFO_VLAN_SEL_SHIFT 16
-#define SQ_TASK_INFO_VLAN_TAG_SHIFT 0
-
-#define SQ_TASK_INFO_PKT_1588_MASK 0x1U
-#define SQ_TASK_INFO_IPSEC_PROTO_MASK 0x1U
-#define SQ_TASK_INFO_OUT_L3_EN_MASK 0x1U
-#define SQ_TASK_INFO_OUT_L4_EN_MASK 0x1U
-#define SQ_TASK_INFO_INNER_L3_EN_MASK 0x1U
-#define SQ_TASK_INFO_INNER_L4_EN_MASK 0x1U
-#define SQ_TASK_INFO_ESP_NEXT_PROTO_MASK 0x3U
-#define SQ_TASK_INFO_VLAN_VALID_MASK 0x1U
-#define SQ_TASK_INFO_VLAN_SEL_MASK 0x7U
-#define SQ_TASK_INFO_VLAN_TAG_MASK 0xFFFFU
-
-#define SQ_TASK_INFO_SET(val, member) \
- (((u32)(val) & SQ_TASK_INFO_##member##_MASK) << \
- SQ_TASK_INFO_##member##_SHIFT)
-#define SQ_TASK_INFO_GET(val, member) \
- (((val) >> SQ_TASK_INFO_##member##_SHIFT) & \
- SQ_TASK_INFO_##member##_MASK)
+#define SQ_TASK_INFO_PKT_1588_SHIFT 31
+#define SQ_TASK_INFO_IPSEC_PROTO_SHIFT 30
+#define SQ_TASK_INFO_OUT_L3_EN_SHIFT 28
+#define SQ_TASK_INFO_OUT_L4_EN_SHIFT 27
+#define SQ_TASK_INFO_INNER_L3_EN_SHIFT 25
+#define SQ_TASK_INFO_INNER_L4_EN_SHIFT 24
+#define SQ_TASK_INFO_ESP_NEXT_PROTO_SHIFT 22
+#define SQ_TASK_INFO_VLAN_VALID_SHIFT 19
+#define SQ_TASK_INFO_VLAN_SEL_SHIFT 16
+#define SQ_TASK_INFO_VLAN_TAG_SHIFT 0
+
+#define SQ_TASK_INFO_PKT_1588_MASK 0x1U
+#define SQ_TASK_INFO_IPSEC_PROTO_MASK 0x1U
+#define SQ_TASK_INFO_OUT_L3_EN_MASK 0x1U
+#define SQ_TASK_INFO_OUT_L4_EN_MASK 0x1U
+#define SQ_TASK_INFO_INNER_L3_EN_MASK 0x1U
+#define SQ_TASK_INFO_INNER_L4_EN_MASK 0x1U
+#define SQ_TASK_INFO_ESP_NEXT_PROTO_MASK 0x3U
+#define SQ_TASK_INFO_VLAN_VALID_MASK 0x1U
+#define SQ_TASK_INFO_VLAN_SEL_MASK 0x7U
+#define SQ_TASK_INFO_VLAN_TAG_MASK 0xFFFFU
+
+#define SQ_TASK_INFO_SET(val, member) \
+ (((u32)(val)&SQ_TASK_INFO_##member##_MASK) \
+ << SQ_TASK_INFO_##member##_SHIFT)
+#define SQ_TASK_INFO_GET(val, member) \
+ (((val) >> SQ_TASK_INFO_##member##_SHIFT) & \
+ SQ_TASK_INFO_##member##_MASK)
#define SQ_CTRL_15BIT_QUEUE_INFO_PKT_TYPE_SHIFT 14
#define SQ_CTRL_15BIT_QUEUE_INFO_PLDOFF_SHIFT 16
@@ -271,16 +263,16 @@ struct hinic5_queue_info {
#define SQ_CTRL_15BIT_QUEUE_INFO_UDP_DP_EN_MASK 0x1U
#define SQ_CTRL_15BIT_QUEUE_INFO_SCTP_MASK 0x1U
-#define SQ_CTRL_15BIT_QUEUE_INFO_SET(val, member) \
- (((u32)(val) & SQ_CTRL_15BIT_QUEUE_INFO_##member##_MASK) << \
- SQ_CTRL_15BIT_QUEUE_INFO_##member##_SHIFT)
+#define SQ_CTRL_15BIT_QUEUE_INFO_SET(val, member) \
+ (((u32)(val)&SQ_CTRL_15BIT_QUEUE_INFO_##member##_MASK) \
+ << SQ_CTRL_15BIT_QUEUE_INFO_##member##_SHIFT)
-#define SQ_CTRL_15BIT_QUEUE_INFO_GET(val, member) \
+#define SQ_CTRL_15BIT_QUEUE_INFO_GET(val, member) \
(((val) >> SQ_CTRL_15BIT_QUEUE_INFO_##member##_SHIFT) & \
SQ_CTRL_15BIT_QUEUE_INFO_##member##_MASK)
-#define SQ_CTRL_15BIT_QUEUE_INFO_CLEAR(val, member) \
- ((val) & (~(SQ_CTRL_15BIT_QUEUE_INFO_##member##_MASK << \
- SQ_CTRL_15BIT_QUEUE_INFO_##member##_SHIFT)))
+#define SQ_CTRL_15BIT_QUEUE_INFO_CLEAR(val, member) \
+ ((val) & (~(SQ_CTRL_15BIT_QUEUE_INFO_##member##_MASK \
+ << SQ_CTRL_15BIT_QUEUE_INFO_##member##_SHIFT)))
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.c
index 848c0a155..228d080ec 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ptp.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#include <linux/skbuff.h>
#include <linux/ptp_clock_kernel.h>
@@ -20,12 +13,15 @@
static unsigned int ptp_clock_pf;
module_param(ptp_clock_pf, uint, 0444);
-MODULE_PARM_DESC(ptp_clock_pf, "ptp_clock_pf, 0: pf0, 1: pf1, 2: pf2, 3: pf3 (default=0)");
+MODULE_PARM_DESC(ptp_clock_pf,
+ "ptp_clock_pf, 0: pf0, 1: pf1, 2: pf2, 3: pf3 (default=0)");
-static int hinic5_ptp_gettime64(struct ptp_clock_info *ptp_info, struct timespec64 *ts)
+static int hinic5_ptp_gettime64(struct ptp_clock_info *ptp_info,
+ struct timespec64 *ts)
{
int ret;
- struct hinic5_ptp_ctrl *ptp_ctrl = container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
+ struct hinic5_ptp_ctrl *ptp_ctrl =
+ container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
spin_lock_bh(&ptp_ctrl->ptp_clock_lock);
ret = hinic5_ts_up_en(ptp_ctrl->hwdev, PTP_RD_UP_EN_FLAG);
@@ -37,11 +33,13 @@ static int hinic5_ptp_gettime64(struct ptp_clock_info *ptp_info, struct timespec
}
#ifdef HAVE_PTP_INFO_GETTIMEX64
-static int hinic5_ptp_gettimex64(struct ptp_clock_info *ptp_info, struct timespec64 *ts,
+static int hinic5_ptp_gettimex64(struct ptp_clock_info *ptp_info,
+ struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
int ret;
- struct hinic5_ptp_ctrl *ptp_ctrl = container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
+ struct hinic5_ptp_ctrl *ptp_ctrl =
+ container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
spin_lock_bh(&ptp_ctrl->ptp_clock_lock);
ptp_read_system_prets(sts);
@@ -56,9 +54,11 @@ static int hinic5_ptp_gettimex64(struct ptp_clock_info *ptp_info, struct timespe
}
#endif
-static int hinic5_ptp_settime64(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
+static int hinic5_ptp_settime64(struct ptp_clock_info *ptp_info,
+ const struct timespec64 *ts)
{
- struct hinic5_ptp_ctrl *ptp_ctrl = container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
+ struct hinic5_ptp_ctrl *ptp_ctrl =
+ container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
spin_lock_bh(&ptp_ctrl->ptp_clock_lock);
hinic5_write_ts_data(ptp_ctrl->hwdev, ts);
@@ -71,9 +71,11 @@ static int hinic5_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
int ret;
s32 update_val;
struct timespec64 ts, delta_ts;
- struct hinic5_ptp_ctrl *ptp_ctrl = container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
+ struct hinic5_ptp_ctrl *ptp_ctrl =
+ container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
- if (delta > PTP_CLOCK_MAX_ADJ_TIME_VALUE || -delta > PTP_CLOCK_MAX_ADJ_TIME_VALUE) {
+ if (delta > PTP_CLOCK_MAX_ADJ_TIME_VALUE ||
+ -delta > PTP_CLOCK_MAX_ADJ_TIME_VALUE) {
delta_ts = ns_to_timespec64(delta);
ret = hinic5_ptp_gettime64(ptp_info, &ts);
if (ret != 0)
@@ -95,7 +97,8 @@ static int hinic5_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
return 0;
}
-static void hinic5_ptp_set_inc_per_cycle(struct hinic5_ptp_ctrl *ptp_ctrl, u32 inc_val)
+static void hinic5_ptp_set_inc_per_cycle(struct hinic5_ptp_ctrl *ptp_ctrl,
+ u32 inc_val)
{
spin_lock_bh(&ptp_ctrl->ptp_clock_lock);
hinic5_set_ptp_inc(ptp_ctrl->hwdev, inc_val);
@@ -104,8 +107,10 @@ static void hinic5_ptp_set_inc_per_cycle(struct hinic5_ptp_ctrl *ptp_ctrl, u32 i
static int hinic5_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
{
- struct hinic5_ptp_ctrl *ptp_ctrl = container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
- u32 adj_inc_val = (u32)adjust_by_scaled_ppm(ptp_ctrl->inc_val, scaled_ppm);
+ struct hinic5_ptp_ctrl *ptp_ctrl =
+ container_of(ptp_info, struct hinic5_ptp_ctrl, ptp_info);
+ u32 adj_inc_val =
+ (u32)adjust_by_scaled_ppm(ptp_ctrl->inc_val, scaled_ppm);
hinic5_ptp_set_inc_per_cycle(ptp_ctrl, adj_inc_val);
return 0;
@@ -125,13 +130,15 @@ static void hinic5_ptp_tx_time_out(struct hinic5_nic_dev *nic_dev)
int hinic5_ptp_tx_process(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb)
{
- if (!nic_dev->hwdev || test_bit(HINIC5_PTP_CLOCK, &nic_dev->flags) == 0 ||
+ if (!nic_dev->hwdev ||
+ test_bit(HINIC5_PTP_CLOCK, &nic_dev->flags) == 0 ||
nic_dev->ptp_ctrl.tx_enable == 0)
return -EINVAL;
if (test_and_set_bit(HINIC5_PTP_TX_BUSY, &nic_dev->ptp_ctrl.flags)) {
hinic5_ptp_tx_time_out(nic_dev);
- if (test_and_set_bit(HINIC5_PTP_TX_BUSY, &nic_dev->ptp_ctrl.flags))
+ if (test_and_set_bit(HINIC5_PTP_TX_BUSY,
+ &nic_dev->ptp_ctrl.flags))
return -EBUSY;
}
@@ -144,7 +151,7 @@ int hinic5_ptp_tx_process(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb)
u8 hinic5_ptp_tx_event_handle(void *dev, u8 event, const u8 *data)
{
struct hinic5_nic_dev *nic_dev = (struct hinic5_nic_dev *)dev;
- struct timespec64 ts = {0};
+ struct timespec64 ts = { 0 };
struct skb_shared_hwtstamps shhwtstamps;
union hinic5_hw_ts32 hw_ts = { .val = *(u32 *)data };
struct sk_buff *skb = nic_dev->ptp_ctrl.tx_saved_skb;
@@ -154,11 +161,12 @@ u8 hinic5_ptp_tx_event_handle(void *dev, u8 event, const u8 *data)
hinic5_ptp_gettime64(&nic_dev->ptp_ctrl.ptp_info, &ts);
ts.tv_nsec = hw_ts.time_ns;
- if (((u32)ts.tv_sec & 0x3) < hw_ts.time_s && ts.tv_sec != 0) { // 0x3 :lower 2bit sec
+ if (((u32)ts.tv_sec & 0x3) < hw_ts.time_s &&
+ ts.tv_sec != 0) { // 0x3 :lower 2bit sec
ts.tv_sec--;
}
- /* 0x3 :lower 2bit sec */
- ts.tv_sec = (u32)(ts.tv_sec - ((u32)ts.tv_sec & 0x3)) + hw_ts.time_s;
+ ts.tv_sec = (u32)(ts.tv_sec - ((u32)ts.tv_sec & 0x3)) +
+ hw_ts.time_s; // 0x3 :lower 2bit sec
nic_dev->ptp_ctrl.tx_saved_skb = NULL;
clear_bit(HINIC5_PTP_TX_BUSY, &nic_dev->ptp_ctrl.flags);
shhwtstamps.hwtstamp = timespec64_to_ktime(ts);
@@ -169,24 +177,27 @@ u8 hinic5_ptp_tx_event_handle(void *dev, u8 event, const u8 *data)
void hinic5_ptp_rx_hwtstamp(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb)
{
- struct timespec64 ts = {0};
+ struct timespec64 ts = { 0 };
union hinic5_hw_ts32 hw_ts32;
- if (test_bit(HINIC5_PTP_CLOCK, &nic_dev->flags) == 0 || nic_dev->ptp_ctrl.rx_enable == 0)
+ if (test_bit(HINIC5_PTP_CLOCK, &nic_dev->flags) == 0 ||
+ nic_dev->ptp_ctrl.rx_enable == 0)
return;
hinic5_ptp_gettime64(&nic_dev->ptp_ctrl.ptp_info, &ts);
- hw_ts32 = *(union hinic5_hw_ts32 *)(skb_tail_pointer(skb) - sizeof(union hinic5_hw_ts32));
- /* Timestamp is filled at the end of the packet, removed after conversion */
- skb->len = skb->len - PTP_SKB_HWTSTAMPS_LENGTH;
+ hw_ts32 = *(union hinic5_hw_ts32 *)(skb_tail_pointer(skb) -
+ sizeof(union hinic5_hw_ts32));
+ skb->len = skb->len -
+ PTP_SKB_HWTSTAMPS_LENGTH; // 时戳会填到报文尾部,转换后删除
skb_set_tail_pointer(skb, (int)(skb->len));
hw_ts32.val = be32_to_cpu(hw_ts32.val);
- /* 0x3 :lower 2bit sec */
- if (((u32)ts.tv_sec & 0x3) < hw_ts32.time_s && ts.tv_sec != 0)
+ if (((u32)ts.tv_sec & 0x3) < hw_ts32.time_s &&
+ ts.tv_sec != 0) { // 0x3 :lower 2bit sec
ts.tv_sec--;
- /* 0x3 :lower 2bit sec */
- ts.tv_sec = (u32)(ts.tv_sec - ((u32)ts.tv_sec & 0x3)) + hw_ts32.time_s;
+ }
+ ts.tv_sec = (u32)(ts.tv_sec - ((u32)ts.tv_sec & 0x3)) +
+ hw_ts32.time_s; // 0x3 :lower 2bit sec
ts.tv_nsec = hw_ts32.time_ns;
skb_hwtstamps(skb)->hwtstamp = timespec64_to_ktime(ts);
@@ -198,10 +209,13 @@ int hinic5_ptp_get_ts_config(struct hinic5_nic_dev *nic_dev, struct ifreq *ifr)
return -EOPNOTSUPP;
return copy_to_user(ifr->ifr_data, &nic_dev->ptp_ctrl.config,
- sizeof(struct hwtstamp_config)) != 0 ? -EFAULT : 0;
+ sizeof(struct hwtstamp_config)) != 0 ?
+ -EFAULT :
+ 0;
}
-static int hinic5_ptp_set_config(struct hinic5_nic_dev *nic_dev, struct hwtstamp_config *config)
+static int hinic5_ptp_set_config(struct hinic5_nic_dev *nic_dev,
+ struct hwtstamp_config *config)
{
if (config->tx_type == HWTSTAMP_TX_ON)
nic_dev->ptp_ctrl.tx_enable = 1;
@@ -210,10 +224,14 @@ static int hinic5_ptp_set_config(struct hinic5_nic_dev *nic_dev, struct hwtstamp
else
return -ERANGE;
- if (config->rx_filter != HWTSTAMP_FILTER_NONE) {
+ if (config->rx_filter == HWTSTAMP_FILTER_NONE) {
+ nic_dev->ptp_ctrl.rx_enable = 0;
+ } else {
+ nic_dev->ptp_ctrl.rx_enable = 1;
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
}
+ // TBM : call MPU API to turn off rx hw PTP offload
return 0;
}
@@ -235,7 +253,8 @@ int hinic5_ptp_set_ts_config(struct hinic5_nic_dev *nic_dev, struct ifreq *ifr)
nic_dev->ptp_ctrl.config = config;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) != 0 ?
- -EFAULT : 0;
+ -EFAULT :
+ 0;
}
void hinic5_ptp_init(struct hinic5_nic_dev *nic_dev)
@@ -243,13 +262,17 @@ void hinic5_ptp_init(struct hinic5_nic_dev *nic_dev)
struct timespec64 ts;
struct ptp_clock_info *ptp_info = NULL;
- if (!nic_dev->hwdev || hinic5_global_func_id(nic_dev->hwdev) != ptp_clock_pf ||
+ if (!nic_dev->hwdev ||
+ hinic5_global_func_id(nic_dev->hwdev) != ptp_clock_pf ||
!HINIC5_SUPPORT_PTP_1588_V2(nic_dev->hwdev))
return;
ptp_info = &nic_dev->ptp_ctrl.ptp_info;
nic_dev->ptp_ctrl.hwdev = nic_dev->hwdev;
- strscpy(ptp_info->name, HINIC5_CHIP_NAME, sizeof(ptp_info->name) - 1);
+ if (strncpy_s(ptp_info->name, sizeof(ptp_info->name), HINIC5_CHIP_NAME,
+ sizeof(ptp_info->name)) != 0) {
+ return;
+ };
ptp_info->name[sizeof(ptp_info->name) - 1] = '\0';
ptp_info->owner = THIS_MODULE;
@@ -263,7 +286,8 @@ void hinic5_ptp_init(struct hinic5_nic_dev *nic_dev)
ptp_info->adjtime = hinic5_ptp_adjtime;
spin_lock_init(&nic_dev->ptp_ctrl.ptp_clock_lock);
- nic_dev->ptp_ctrl.ptp_clock = ptp_clock_register(ptp_info, nic_dev->lld_dev->dev);
+ nic_dev->ptp_ctrl.ptp_clock =
+ ptp_clock_register(ptp_info, nic_dev->lld_dev->dev);
if (IS_ERR(nic_dev->ptp_ctrl.ptp_clock))
return;
@@ -274,15 +298,15 @@ void hinic5_ptp_init(struct hinic5_nic_dev *nic_dev)
// lower 16bit: 0.xx ns , 2: 2ns per cycle
nic_dev->ptp_ctrl.inc_val = 2 << 16;
nic_dev->ptp_ctrl.tx_saved_skb = NULL;
- /* Software 1588 mode also needs to strip the 4B timestamp from the end of the packet */
- nic_dev->ptp_ctrl.rx_enable = 1;
hinic5_ptp_set_config(nic_dev, &nic_dev->ptp_ctrl.config);
- hinic5_ptp_set_inc_per_cycle(&nic_dev->ptp_ctrl, nic_dev->ptp_ctrl.inc_val);
+ hinic5_ptp_set_inc_per_cycle(&nic_dev->ptp_ctrl,
+ nic_dev->ptp_ctrl.inc_val);
ktime_get_real_ts64(&ts);
hinic5_ptp_settime64(&nic_dev->ptp_ctrl.ptp_info, &ts);
- hinic5_nic_aeq_register_swe_cb(nic_dev->hwdev, nic_dev, HINIC5_HTN_PTP_EVENT,
- (hinic5_aeq_swe_cb)hinic5_ptp_tx_event_handle);
+ hinic5_nic_aeq_register_swe_cb(
+ nic_dev->hwdev, nic_dev, HINIC5_HTN_PTP_EVENT,
+ (hinic5_aeq_swe_cb)hinic5_ptp_tx_event_handle);
set_bit(HINIC5_PTP_CLOCK, &nic_dev->flags);
}
@@ -300,7 +324,8 @@ void hinic5_ptp_deinit(struct hinic5_nic_dev *nic_dev)
nic_dev->ptp_ctrl.tx_enable = 0;
nic_dev->ptp_ctrl.rx_enable = 0;
ptp_clock_unregister(nic_dev->ptp_ctrl.ptp_clock);
- hinic5_nic_aeq_unregister_swe_cb(nic_dev->hwdev, HINIC5_HTN_PTP_EVENT);
+ hinic5_nic_aeq_unregister_swe_cb(nic_dev->hwdev,
+ HINIC5_HTN_PTP_EVENT);
nic_dev->ptp_ctrl.ptp_clock = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.h
index 3f90294af..749736c6f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/1588/hinic5_ptp.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ptp.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_PTP_H
#define HINIC5_PTP_H
@@ -34,12 +27,13 @@ enum hinic5_ptp_flags {
#endif
#define PTP_CLOCK_MAX_ADJ_TIME_VALUE 0x3FFFFFFF
-#define PTP_SKB_HWTSTAMPS_LENGTH 0x4
+#define PTP_SKB_HWTSTAMPS_LENGTH 0x4
#define PTP_WR_UP_EN_FLAG BIT(0)
#define PTP_RD_UP_EN_FLAG BIT(1)
int hinic5_ptp_tx_process(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb);
-void hinic5_ptp_rx_hwtstamp(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb);
+void hinic5_ptp_rx_hwtstamp(struct hinic5_nic_dev *nic_dev,
+ struct sk_buff *skb);
int hinic5_ptp_set_ts_config(struct hinic5_nic_dev *nic_dev, struct ifreq *ifr);
int hinic5_ptp_get_ts_config(struct hinic5_nic_dev *nic_dev, struct ifreq *ifr);
void hinic5_ptp_init(struct hinic5_nic_dev *nic_dev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/Makefile b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/Makefile
index 61fac6dae..a7fccc27d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/Makefile
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/Makefile
@@ -1,87 +1,69 @@
# NIC Makefile
EXPORT_SYMBOL := true
+#HUAWEI SEC
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/platform/huawei_secure_c/include
EXTRA_CFLAGS += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
-TRUNK_DIR = $(srctree)/drivers/net/ethernet/huawei/hinic5
-HWSDK_SRC_PATH = $(TRUNK_DIR)/src/dpu_platform_library/host/sdk/knldk
-SDK_DIR := ../../../sdk/knldk/lld
-
-# HWSDK INNER
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/hinic5_cqm
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/crm
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/lld
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/hwif
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/mt
-EXTRA_CFLAGS += -I$(HWSDK_SRC_PATH)/include
-
-# HWSDK HEADER
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include/drv_tool_msg
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/mpu
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/include/sdk/knldk
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/include/cfm/fast_msg
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/ossl
-
-# DBGTOOL
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/public
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mag
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/hinic5_cqm
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/tools/micro_log
-
#SDK
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_srvc_intf
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/ossl
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/public
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/include/sdk/knldk
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/sdk/knldk/lld
-
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_srvc_intf
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/ossl
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/public
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/include/sdk/knldk
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/sdk/knldk/lld
#NIC
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include/drv_tool_msg
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/1588
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ctrl
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ethtool
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ioctl
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/netdev
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/nicio
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/include
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/include
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/common/nic
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/comm
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/nic
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mag
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/drv_srvc_intf/nic
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include/drv_tool_msg
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/1588
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ctrl
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ethtool
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/ioctl
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/netdev
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/nicio
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/include
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/include
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/common/nic
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/comm
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/nic
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/mag
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/drv_srvc_intf/nic
#BOND
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/cfm
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/include/cfm/bond
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/cfm
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/include/cfm/bond
#MPU
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/mpu
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/include/drv_fw_msg/mpu
#MACsec
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/macsec
-EXTRA_CFLAGS += -I$(TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/macsec
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_develop_interface/fw_msg_intf/macsec
+EXTRA_CFLAGS += -I$(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/nic/linux/macsec
+
+EXTRA_CFLAGS += -Wno-implicit-fallthrough
+EXTRA_CFLAGS += -Wframe-larger-than=2048
+EXTRA_CFLAGS += -Wno-misleading-indentation
-ifeq ($(CONFIG_SP_DEVICE), y)
-EXTRA_CFLAGS += -DCONFIG_SP_VID_DID
+ifndef HISDK5_SYMVERS
+HISDK5_SYMVERS = ${HI1823_TRUNK_DIR}/ci/lib/SDK_Module.symvers
endif
+KBUILD_EXTRA_SYMBOLS += $(HISDK5_SYMVERS)
-EXTRA_CFLAGS += -Werror -Wno-error=missing-prototypes -Wno-missing-braces
+EXTRA_CFLAGS += -Werror -Wno-error=missing-prototypes
+
+ifndef __TIME_STR__
+SYS_TIME=$(shell date +%Y-%m-%d_%H:%M:%S)
+ccflags-y += -D __TIME_STR__=\"$(SYS_TIME)\"
+endif
+GLOBAL_VERSION=$(shell cat $(HI1823_TRUNK_DIR)/src/GLOBAL_VERSION_NEW | grep driver | awk -F ':' '{print $$2}')
+ccflags-y += -DGLOBAL_VERSION_STR=\"$(GLOBAL_VERSION)\"
+$(warning cflags, $(ccflags-y))
V ?= 0
-ifeq ($(RELEASE_TYPE), LLT)
+ifeq ($(HI1823_RELEASE_TYPE), LLT)
ccflags-y += -D_LLT_TEST_
else
ccflags-y += -DHW_CONVERT_ENDIAN
@@ -89,127 +71,64 @@ endif
ccflags-y += -D__LINUX__
-hisdk5-objs := \
- $(SDK_DIR)/../hinic5_vram/hinic5_vram_common.o \
- $(SDK_DIR)/../hinic5_vram/hinic5_hinic5_vram.o \
- $(SDK_DIR)/../../../cfm/fast_msg/hinic5_fast_msg_init.o \
- $(SDK_DIR)/../../../cfm/fast_msg/hinic5_fast_msg.o \
- $(SDK_DIR)/../crm/hinic5_hwdev.o \
- $(SDK_DIR)/../crm/hinic5_hw_cfg.o \
- $(SDK_DIR)/../crm/hinic5_hw_comm.o \
- $(SDK_DIR)/../crm/hinic5_prof_adap.o \
- $(SDK_DIR)/hinic5_sriov.o \
- $(SDK_DIR)/hinic5_lld.o \
- $(SDK_DIR)/hinic5_bus.o \
- $(SDK_DIR)/hinic5_pcie.o \
- $(SDK_DIR)/hinic5_sysfs.o \
- $(SDK_DIR)/hinic5_dev_mgmt.o \
- $(SDK_DIR)/../hwif/hinic5_common.o \
- $(SDK_DIR)/../hwif/hinic5_hwif.o \
- $(SDK_DIR)/../hwif/hinic5_wq.o \
- $(SDK_DIR)/../hwif/hinic5_cmdq.o \
- $(SDK_DIR)/../hwif/hinic5_enhance_cmdq.o \
- $(SDK_DIR)/../hwif/hinic5_eqs.o \
- $(SDK_DIR)/../hwif/hinic5_mbox.o \
- $(SDK_DIR)/../hwif/hinic5_mgmt.o \
- $(SDK_DIR)/../hwif/hinic5_api_cmd.o \
- $(SDK_DIR)/../hwif/hinic5_hw_api.o \
- $(SDK_DIR)/../hwif/hinic5_sml_lt.o \
- $(SDK_DIR)/../../../../../../src/tools/micro_log/micro_log_comm.o \
- $(SDK_DIR)/../../../../../../src/tools/micro_log/micro_log_procfs_cmd.o \
- $(SDK_DIR)/../../../../../../src/tools/micro_log/micro_log_index.o \
- $(SDK_DIR)/../../../../../../src/tools/micro_log/hinic5_micro_log.o \
- $(SDK_DIR)/../mt/hinic5_fw_update.o \
- $(SDK_DIR)/../mt/hinic5_hw_mt.o \
- $(SDK_DIR)/../mt/hinic5_nictool.o \
- $(SDK_DIR)/../mt/hinic5_non_ptp.o \
- $(SDK_DIR)/../mt/hinic5_devlink.o \
- $(SDK_DIR)/../../ossl/linux/kernel/ossl_knl_linux.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_bat_cla.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_bitmap_table.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_object_intern.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_bloomfilter.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_cmd.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_db.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_fast_msg.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_object.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_main.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_cmdq_adapt.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_182x_cmdq_adapt/hinic5_cqm_182x_cmdq_ops.o \
- $(SDK_DIR)/../hinic5_cqm/hinic5_cqm_187x_cmdq_adapt/hinic5_cqm_187x_cmdq_ops.o \
-
+obj-m += hinic5.o
hinic5-objs := \
- ./1588/hinic5_ptp.o \
- ./ctrl/hinic5_main.o \
- ./ctrl/hinic5_irq.o \
- ./ethtool/hinic5_rss.o \
- ./ethtool/hinic5_ntuple.o \
- ./ethtool/hinic5_ethtool.o \
- ./ethtool/hinic5_ethtool_coalesce.o \
- ./ethtool/hinic5_ethtool_lb_test.o \
- ./ethtool/hinic5_ethtool_priv_flags.o \
- ./ethtool/hinic5_ethtool_port_stats.o \
- ./ethtool/hinic5_ethtool_link_stats.o \
- ./ethtool/hinic5_tc.o \
- ./ioctl/hinic5_dcb.o \
- ./ioctl/hinic5_dbg.o \
- ./netdev/hinic5_netdev_ops.o \
- ./netdev/hinic5_filter.o \
- ./nicio/hinic5_tx.o \
- ./nicio/hinic5_rx.o \
- ./nicio/hinic5_xdp.o \
- ./macsec/hinic5_macsec_dfx.o \
- ./macsec/hinic5_macsec_main.o \
- ./macsec/hinic5_macsec_mgmt.o \
- ./macsec/hinic5_macsec_nictool.o \
- ./macsec/hinic5_macsec_protocol.o \
- ./macsec/hinic5_macsec_service.o \
- ../comm/hinic5_nic_cfg.o \
- ../comm/hinic5_mag_cfg.o \
- ../comm/hinic5_nic_cfg_vf.o \
- ../comm/hinic5_rss_cfg.o \
- ../comm/hinic5_nic_event.o \
- ../comm/hinic5_nic_io.o \
- ../comm/hinic5_nic_dbg.o \
- ../comm/hinic5_cmdq_adapt.o \
- ../comm/182x_cmdq_adapt/182x_cmdq_ops.o \
- ../comm/187x_cmdq_adapt/187x_cmdq_ops.o \
- ../../../cfm/bond/hinic5_bond_event.o \
- ../../../cfm/bond/hinic5_bond.o \
-
-# sdk_attack support
-ifneq ($(CONFIG_HINIC5_SDK_DEBUG),)
-hisdk5-objs += $(SDK_DIR)/../mt/hinic5_sdk_attack.o
-endif
-
-# UB release support
-ifeq ($(CONFIG_UB), y)
-hisdk5-objs += $(SDK_DIR)/hinic5_ubus.o $(SDK_DIR)/hinic5_ubus_sriov.o
-EXTRA_CFLAGS += -D__UBUS_DRIVER__ -DUB_SUPPORT_ENTITY -DUB_SUPPORT_B177
-endif
-
-# UB devel support
-ifeq ($(CONFIG_UBUS_DEVICE), y)
-KBUILD_EXTRA_SYMBOLS += $(UBUS_UBC_BUILD_DIR)/Module.symvers
-KBUILD_EXTRA_SYMBOLS += $(UMMU_CORE_BUILD_DIR)/Module.symvers
-EXTRA_CFLAGS += -D__UBUS_DRIVER__
-hisdk5-objs += $(SDK_DIR)/hinic5_ubus.o
-hisdk5-objs += $(SDK_DIR)/hinic5_ubus_sriov.o
-ifeq ($(UB_BUILD_B173), y)
-EXTRA_CFLAGS += -DUB_SUPPORT_ENTITY
-endif
-ifeq ($(UB_BUILD_B177), y)
-EXTRA_CFLAGS += -DUB_SUPPORT_B177
-endif
-endif
+ ../../../../../../platform/huawei_secure_c/src/securecutil.o \
+ ../../../../../../platform/huawei_secure_c/src/secureinput_a.o \
+ ../../../../../../platform/huawei_secure_c/src/secureprintoutput_a.o \
+ ../../../../../../platform/huawei_secure_c/src/memset_s.o \
+ ../../../../../../platform/huawei_secure_c/src/memcpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strncpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strncat_s.o \
+ ../../../../../../platform/huawei_secure_c/src/sprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsnprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/snprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/sscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/memmove_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strcpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strcat_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strtok_s.o \
+ ./1588/hinic5_ptp.o \
+ ./ctrl/hinic5_main.o \
+ ./ctrl/hinic5_irq.o \
+ ./ethtool/hinic5_rss.o \
+ ./ethtool/hinic5_ntuple.o \
+ ./ethtool/hinic5_ethtool.o \
+ ./ethtool/hinic5_ethtool_coalesce.o \
+ ./ethtool/hinic5_ethtool_lb_test.o \
+ ./ethtool/hinic5_ethtool_priv_flags.o \
+ ./ethtool/hinic5_ethtool_port_stats.o \
+ ./ethtool/hinic5_ethtool_link_stats.o \
+ ./ethtool/hinic5_tc.o \
+ ./ioctl/hinic5_dcb.o \
+ ./ioctl/hinic5_dbg.o \
+ ./netdev/hinic5_netdev_ops.o \
+ ./netdev/hinic5_filter.o \
+ ./nicio/hinic5_tx.o \
+ ./nicio/hinic5_rx.o \
+ ./nicio/hinic5_xdp.o \
+ ./macsec/hinic5_macsec_dfx.o \
+ ./macsec/hinic5_macsec_main.o \
+ ./macsec/hinic5_macsec_mgmt.o \
+ ./macsec/hinic5_macsec_nictool.o \
+ ./macsec/hinic5_macsec_protocol.o \
+ ./macsec/hinic5_macsec_service.o \
+ ../comm/hinic5_nic_cfg.o \
+ ../comm/hinic5_mag_cfg.o \
+ ../comm/hinic5_nic_cfg_vf.o \
+ ../comm/hinic5_rss_cfg.o \
+ ../comm/hinic5_nic_event.o \
+ ../comm/hinic5_nic_io.o \
+ ../comm/hinic5_nic_dbg.o \
+ ../comm/hinic5_cmdq_adapt.o \
+ ../comm/182x_cmdq_adapt/182x_cmdq_ops.o \
+ ../comm/187x_cmdq_adapt/187x_cmdq_ops.o \
+ ../../../cfm/bond/hinic5_bond_event.o \
+ ../../../cfm/bond/hinic5_bond.o \
# Driver Extension
-ifneq ($(DPU_HISDK5_DRV_EXTEND_MK),)
-$(info Using hisdk5 extension $(DPU_HISDK5_DRV_EXTEND_MK))
-export DPU_DRV_MK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
-include $(DPU_HISDK5_DRV_EXTEND_MK)
-hisdk5-objs += $(DPU_DRV_HISDK5_EXTEND_OBJS)
-endif
ifneq ($(DPU_HINIC5_DRV_EXTEND_MK),)
$(info Using hinic5 extension $(DPU_HINIC5_DRV_EXTEND_MK))
# Dirctory of NIC makefile
@@ -218,9 +137,6 @@ include $(DPU_HINIC5_DRV_EXTEND_MK)
hinic5-objs += $(DPU_DRV_HINIC5_EXTEND_OBJS)
endif
-hinic5-objs += $(hisdk5-objs)
-obj-$(CONFIG_HINIC5) += hinic5.o
-
all:build_info default
build_info:
@@ -230,11 +146,14 @@ build_info:
echo $$(realpath $$obj) >> build/build_src.txt; \
done
-KERNEL_VER := $(shell uname -r 2>/dev/null)
+KERNEL_VER ?= $(shell uname -r 2>/dev/null)
+ifeq ($(CONFIG_UB_UNIFIED_UBUS), y)
+KERNEL_DIR := $(UBUS_BUILD_KERNEL_DIR)
+else
KERNEL_DIR := /lib/modules/$(KERNEL_VER)/build
+endif
default:
$(MAKE) -C $(KERNEL_DIR) M=$(shell pwd) -W modules
-
clean:
rm -rf *.o *.ko *.order .*.cmd *.mod.* .H* .tm* .tmp_versions Module.symvers *.ko.unsigned null
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.c
index 3de2d9203..23b3c9b28 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_irq.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
#include <linux/kernel.h>
@@ -51,7 +44,8 @@ static void qp_add_napi(struct hinic5_irq *irq_cfg)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- netif_napi_add(nic_dev->netdev, &irq_cfg->napi, hinic5_poll, nic_dev->poll_weight);
+ netif_napi_add(nic_dev->netdev, &irq_cfg->napi, hinic5_poll,
+ nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
}
@@ -66,7 +60,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic5_irq *irq_cfg = (struct hinic5_irq *)data;
struct hinic5_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic5_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic5_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -76,24 +71,27 @@ static irqreturn_t qp_irq(int irq, void *data)
static int hinic5_request_irq(struct hinic5_irq *irq_cfg, u16 q_id)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- struct interrupt_info info = {0};
+ struct interrupt_info info = { 0 };
int err;
qp_add_napi(irq_cfg);
info.msix_index = irq_cfg->msix_entry_idx;
/* bind the msix_entry to this function */
- err = hinic5_set_interrupt_cfg(nic_dev->hwdev, info, HINIC5_CHANNEL_NIC);
+ err = hinic5_set_interrupt_cfg(nic_dev->hwdev, info,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
- nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to set RX interrupt cfg.\n");
+ nicif_err(nic_dev, drv, irq_cfg->netdev,
+ "Failed to set RX interrupt cfg.\n");
qp_del_napi(irq_cfg);
return err;
}
nic_dev->rxqs[q_id].last_coalesc_timer_cfg =
- nic_dev->intr_coalesce[q_id].rx_coalesce_timer_cfg;
+ nic_dev->intr_coalesce[q_id].rx_coalesce_timer_cfg;
nic_dev->rxqs[q_id].last_pending_limt =
- nic_dev->intr_coalesce[q_id].rx_pending_limt;
- err = hinic5_set_sq_rq_coalesce_cfg(nic_dev->hwdev, q_id, HINIC5_SQ_RQ_COALESCE,
+ nic_dev->intr_coalesce[q_id].rx_pending_limt;
+ err = hinic5_set_sq_rq_coalesce_cfg(nic_dev->hwdev, q_id,
+ HINIC5_SQ_RQ_COALESCE,
&nic_dev->intr_coalesce[q_id]);
if (err != 0) {
nicif_err(nic_dev, drv, irq_cfg->netdev,
@@ -102,9 +100,11 @@ static int hinic5_request_irq(struct hinic5_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name,
+ irq_cfg);
if (err != 0) {
- nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
+ nicif_err(nic_dev, drv, irq_cfg->netdev,
+ "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
return err;
}
@@ -136,7 +136,9 @@ int hinic5_qps_irq_init(struct hinic5_nic_dev *nic_dev)
u32 local_cpu;
int err;
- for (q_id = 0; q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; q_id++) {
+ for (q_id = 0;
+ q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ q_id++) {
qp_irq_info = &nic_dev->qps_irq_info[q_id];
irq_cfg = &nic_dev->q_params.irq_cfg[q_id];
@@ -147,11 +149,13 @@ int hinic5_qps_irq_init(struct hinic5_nic_dev *nic_dev)
irq_cfg->rxq = &nic_dev->rxqs[q_id];
nic_dev->rxqs[q_id].irq_cfg = irq_cfg;
- local_cpu = cpumask_local_spread(q_id, dev_to_node(nic_dev->lld_dev->dev));
+ local_cpu = cpumask_local_spread(
+ q_id, dev_to_node(nic_dev->lld_dev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
+ err = snprintf_s(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ sizeof(irq_cfg->irq_name) - 1, "%s_qp%u",
+ nic_dev->netdev->name, q_id);
if (err < 0) {
err = -EINVAL;
goto req_tx_irq_err;
@@ -159,24 +163,30 @@ int hinic5_qps_irq_init(struct hinic5_nic_dev *nic_dev)
err = hinic5_request_irq(irq_cfg, q_id);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to request Rx irq\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to request Rx irq\n");
goto req_tx_irq_err;
}
- hinic5_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic5_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC5_SET_MSIX_AUTO_MASK);
- hinic5_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC5_MSIX_ENABLE);
+ hinic5_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC5_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic5_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic5_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic5_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC5_MSIX_DISABLE);
- hinic5_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic5_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC5_MSIX_DISABLE);
+ hinic5_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC5_CLR_MSIX_AUTO_MASK);
hinic5_release_irq(irq_cfg, nic_dev->state);
}
@@ -189,7 +199,9 @@ void hinic5_qps_irq_deinit(struct hinic5_nic_dev *nic_dev)
struct hinic5_irq *irq_cfg = NULL;
u16 q_id;
- for (q_id = 0; q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; q_id++) {
+ for (q_id = 0;
+ q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ q_id++) {
irq_cfg = &nic_dev->q_params.irq_cfg[q_id];
hinic5_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
HINIC5_MSIX_DISABLE);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.h
index 43a70c750..17cb422ee 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_irq.h
@@ -1,15 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_irq.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_IRQ_H
-#define HINIC5_IRQ_H
+#define HINIC5_IRQ_H
#include "hinic5_nic_dev.h"
@@ -17,4 +10,4 @@ int hinic5_qps_irq_init(struct hinic5_nic_dev *nic_dev);
void hinic5_qps_irq_deinit(struct hinic5_nic_dev *nic_dev);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.c
index c901865f9..f90788e9d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_main.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
#include <linux/kernel.h>
@@ -33,7 +26,7 @@
#include "hinic5_hw.h"
#include "hinic5_crm.h"
#include "hinic5_mt.h"
-#include "hinic5_hinic5_vram.h"
+#include "hinic5_vram.h"
#include "hinic5_nic_cfg.h"
#include "hinic5_srv_nic.h"
#include "hinic5_nic_io.h"
@@ -46,7 +39,7 @@
#include "hinic5_dcb.h"
#include "hinic5_ptp.h"
#include "hinic5_nic_event.h"
-#include "hinic5_hinic5_vram_api.h"
+#include "hinic5_vram_api.h"
#include "hinic5_macsec_api.h"
#include "hinic5_main.h"
@@ -56,58 +49,69 @@
#define CFM_BOND_FULL
-#define DEFAULT_POLL_WEIGHT 64
+#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
MODULE_PARM_DESC(poll_weight, "Number packets for NAPI budget (default=64)");
-#define HINIC5_DEAULT_TXRX_MSIX_PENDING_LIMIT 2
+#define HINIC5_DEAULT_TXRX_MSIX_PENDING_LIMIT 2
#define HINIC5_MAX_TXRX_MSIX_PENDING_LIMIT 255
-#define HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG 25
+#define HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG 25
#define HINIC5_MAX_TXRX_MSIX_COALESC_TIMER_CFG 255
static unsigned char qp_pending_limit = HINIC5_DEAULT_TXRX_MSIX_PENDING_LIMIT;
module_param(qp_pending_limit, byte, 0444);
-MODULE_PARM_DESC(qp_pending_limit, "QP MSI-X Interrupt coalescing parameter pending_limit, 0-255 (default=2, unit=8)");
+MODULE_PARM_DESC(
+ qp_pending_limit,
+ "QP MSI-X Interrupt coalescing parameter pending_limit, 0-255 (default=2, unit=8)");
static unsigned char qp_coalesc_timer_cfg =
- HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
+ HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
module_param(qp_coalesc_timer_cfg, byte, 0444);
-MODULE_PARM_DESC(qp_coalesc_timer_cfg, "QP MSI-X Interrupt coalescing parameter coalesc_timer_cfg, 0-255 (default=25, unit=5us)");
+MODULE_PARM_DESC(
+ qp_coalesc_timer_cfg,
+ "QP MSI-X Interrupt coalescing parameter coalesc_timer_cfg, 0-255 (default=25, unit=5us)");
-#define DEFAULT_RX_BUFF_LEN 2
-u16 hinic5_rx_buff = DEFAULT_RX_BUFF_LEN;
-module_param(hinic5_rx_buff, ushort, 0444);
-MODULE_PARM_DESC(hinic5_rx_buff, "Set hinic5_rx_buff size, 2,4,8 (unit: KB, default=2KB)");
+#define DEFAULT_RX_BUFF_LEN 2
+u16 rx_buff = DEFAULT_RX_BUFF_LEN;
+module_param(rx_buff, ushort, 0444);
+MODULE_PARM_DESC(rx_buff, "Set rx_buff size, 2,4,8 (unit: KB, default=2KB)");
static unsigned int lro_replenish_thld = 256;
module_param(lro_replenish_thld, uint, 0444);
-MODULE_PARM_DESC(lro_replenish_thld, "Number wqe for lro replenish buffer, 0-16384 (unit: wqebb, default=256)");
+MODULE_PARM_DESC(
+ lro_replenish_thld,
+ "Number wqe for lro replenish buffer, 0-16384 (unit: wqebb, default=256)");
static unsigned char set_link_status_follow = HINIC5_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
-MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status, 0: DEFAULT, 1: PORT, 2: SEPARATE, 3: UNSET (default=3)");
+MODULE_PARM_DESC(
+ set_link_status_follow,
+ "Set link status follow port status, 0: DEFAULT, 1: PORT, 2: SEPARATE, 3: UNSET (default=3)");
-static bool page_pool_enabled = true;
+static bool page_pool_enabled = false;
module_param(page_pool_enabled, bool, 0444);
-MODULE_PARM_DESC(page_pool_enabled, "Set page_pool feature state, 0: DISABLE, 1: ENABLE (default=1)");
+MODULE_PARM_DESC(
+ page_pool_enabled,
+ "Set page_pool feature state, 0: DISABLE, 1: ENABLE (default=0)");
-static bool macsec_enabled;
+static bool macsec_enabled = false;
module_param(macsec_enabled, bool, 0444);
-MODULE_PARM_DESC(macsec_enabled, "Set macsec module state, 0: DISABLE, 1: ENABLE (default=0)");
+MODULE_PARM_DESC(macsec_enabled,
+ "Set macsec module state, 0: DISABLE, 1: ENABLE (default=0)");
-#define HINIC5_MAX_POLL_WEIGHT 16384
+#define HINIC5_MAX_POLL_WEIGHT 16384
-#define HINIC5_MAX_LRO_REPLENISH_THLD 16384
-#define HINIC5_DEFAULT_LRO_REPLENISH_THLD 255
+#define HINIC5_MAX_LRO_REPLENISH_THLD 16384
+#define HINIC5_DEFAULT_LRO_REPLENISH_THLD 255
-#define HINIC5_MAX_RX_BUFF 8
-#define HINIC5_MIN_RX_BUFF 2
+#define HINIC5_MAX_RX_BUFF 8
+#define HINIC5_MIN_RX_BUFF 2
static inline void hinic5_main_param_validate(void)
{
- if (poll_weight == 0 || poll_weight > HINIC5_MAX_POLL_WEIGHT) {
+ if ((poll_weight == 0) || poll_weight > HINIC5_MAX_POLL_WEIGHT) {
poll_weight = DEFAULT_POLL_WEIGHT;
pr_warn("[NIC] poll_weight is out of range(0-%u), reset to default %u\n",
HINIC5_MAX_POLL_WEIGHT, DEFAULT_POLL_WEIGHT);
@@ -120,22 +124,24 @@ static inline void hinic5_main_param_validate(void)
}
if (qp_coalesc_timer_cfg > HINIC5_MAX_TXRX_MSIX_COALESC_TIMER_CFG) {
- qp_coalesc_timer_cfg = HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
+ qp_coalesc_timer_cfg =
+ HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG;
pr_warn("[NIC] qp_coalesc_timer_cfg is out of range(0-255), reset to default %u\n",
HINIC5_DEAULT_TXRX_MSIX_COALESC_TIMER_CFG);
}
- if (hinic5_rx_buff != RX_BUFF_VALID_2KB && hinic5_rx_buff != RX_BUFF_VALID_4KB &&
- hinic5_rx_buff != RX_BUFF_VALID_8KB) {
- hinic5_rx_buff = DEFAULT_RX_BUFF_LEN;
- pr_warn("[NIC] hinic5_rx_buff is invalid(%u), only 2/4/8KB supported, reset to default %uKB\n",
- hinic5_rx_buff, DEFAULT_RX_BUFF_LEN);
+ if (rx_buff != RX_BUFF_VALID_2KB && rx_buff != RX_BUFF_VALID_4KB &&
+ rx_buff != RX_BUFF_VALID_8KB) {
+ rx_buff = DEFAULT_RX_BUFF_LEN;
+ pr_warn("[NIC] rx_buff is invalid(%u), only 2/4/8KB supported, reset to default %uKB\n",
+ rx_buff, DEFAULT_RX_BUFF_LEN);
}
if (lro_replenish_thld > HINIC5_MAX_LRO_REPLENISH_THLD) {
lro_replenish_thld = HINIC5_DEFAULT_LRO_REPLENISH_THLD;
pr_warn("[NIC] lro_replenish_thld is out of range(0-%u), reset to default %u\n",
- HINIC5_MAX_LRO_REPLENISH_THLD, HINIC5_DEFAULT_LRO_REPLENISH_THLD);
+ HINIC5_MAX_LRO_REPLENISH_THLD,
+ HINIC5_DEFAULT_LRO_REPLENISH_THLD);
}
if (set_link_status_follow > HINIC5_LINK_FOLLOW_STATUS_MAX) {
@@ -146,12 +152,13 @@ static inline void hinic5_main_param_validate(void)
}
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic5_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic5_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
-#define HINIC5_ASIC_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 100
-#define HINIC5_FPGA_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
-#define HINIC5_EMU_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
-#define HINIC5_EDA_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
+#define HINIC5_ASIC_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 100
+#define HINIC5_FPGA_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
+#define HINIC5_EMU_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
+#define HINIC5_EDA_WAIT_FLUSH_QP_RESOURCE_TIMEOUT 2000
#define HINIC5_GET_TIMEOUT(board, type) HINIC5_##board##_##type##_TIMEOUT
@@ -164,12 +171,12 @@ static struct notifier_block hinic5_netdev_notifier = {
#ifdef HAVE_UDP_TUNNEL_NIC_INFO
static const struct udp_tunnel_nic_info hinic5_udp_tunnels = {
- .set_port = hinic5_udp_tunnel_set_port,
- .unset_port = hinic5_udp_tunnel_unset_port,
- .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
- .tables = {
- { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
- },
+ .set_port = hinic5_udp_tunnel_set_port,
+ .unset_port = hinic5_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
};
#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
@@ -182,8 +189,10 @@ static void hinic5_register_notifier(struct hinic5_nic_dev *nic_dev)
if (hinic5_netdev_notifiers_ref_cnt == 1) {
err = register_netdevice_notifier(&hinic5_netdev_notifier);
if (err != 0) {
- nic_info(nic_dev->lld_dev->dev, "Register netdevice notifier failed, err: %d\n",
- err);
+ nic_info(
+ nic_dev->lld_dev->dev,
+ "Register netdevice notifier failed, err: %d\n",
+ err);
hinic5_netdev_notifiers_ref_cnt--;
}
}
@@ -201,12 +210,13 @@ static void hinic5_unregister_notifier(struct hinic5_nic_dev *nic_dev)
mutex_unlock(&hinic5_netdev_notifiers_mutex);
}
-#define HINIC5_MAX_VLAN_DEPTH_OFFLOAD_SUPPORT 1
-#define HINIC5_VLAN_CLEAR_OFFLOAD (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
- NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
- NETIF_F_ALL_TSO)
+#define HINIC5_MAX_VLAN_DEPTH_OFFLOAD_SUPPORT 1
+#define HINIC5_VLAN_CLEAR_OFFLOAD \
+ (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SCTP_CRC | \
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
-static int hinic5_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic5_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -239,9 +249,9 @@ static int hinic5_netdev_event(struct notifier_block *notifier, unsigned long ev
} else if (vlan_depth > HINIC5_MAX_VLAN_DEPTH_OFFLOAD_SUPPORT) {
#ifdef HAVE_NDO_SET_FEATURES
#ifdef HAVE_NDO_SET_U32_FEATURES
- set_netdev_hw_features(ndev,
- get_netdev_hw_features(ndev) &
- (~HINIC5_VLAN_CLEAR_OFFLOAD));
+ set_netdev_hw_features(
+ ndev, get_netdev_hw_features(ndev) &
+ (~HINIC5_VLAN_CLEAR_OFFLOAD));
#else
ndev->hw_features &= (~HINIC5_VLAN_CLEAR_OFFLOAD);
#endif
@@ -288,7 +298,8 @@ void hinic5_link_status_change(struct hinic5_nic_dev *nic_dev, bool status)
}
}
-static void netdev_vlan_feature_init(struct hinic5_nic_dev *nic_dev, netdev_features_t *vlan_fts)
+static void netdev_vlan_feature_init(struct hinic5_nic_dev *nic_dev,
+ netdev_features_t *vlan_fts)
{
if (HINIC5_SUPPORT_VLAN_OFFLOAD(nic_dev->hwdev) != 0) {
#if defined(NETIF_F_HW_VLAN_CTAG_TX)
@@ -313,101 +324,127 @@ static void netdev_vlan_feature_init(struct hinic5_nic_dev *nic_dev, netdev_feat
}
}
-static void netdev_hw_feature_init(struct net_device *netdev,
- struct hinic5_nic_dev *nic_dev, netdev_features_t *hw_features)
+static void netdev_hw_feature_init(struct hinic5_nic_dev *nic_dev)
{
+ struct net_device *netdev = nic_dev->netdev;
+ netdev_features_t hw_features = 0;
+
/* LRO is disable in default, only set hw features */
if (HINIC5_SUPPORT_LRO(nic_dev->hwdev) != 0)
- *hw_features |= NETIF_F_LRO;
+ hw_features |= NETIF_F_LRO;
#if (KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE)
if (HINIC5_SUPPORT_UFO(nic_dev->hwdev) != 0) {
/* UFO is disable in default */
- *hw_features |= NETIF_F_UFO;
+ hw_features |= NETIF_F_UFO;
netdev->vlan_features |= NETIF_F_UFO;
}
#endif
+
+#ifdef HAVE_NDO_SET_U32_FEATURES
+ hw_features |= get_netdev_hw_features(netdev);
+#else
+ hw_features |= netdev->hw_features;
+#endif
+
+ hw_features |= netdev->features;
+
+#ifdef HAVE_NDO_SET_U32_FEATURES
+ set_netdev_hw_features(netdev, hw_features);
+#else
+ netdev->hw_features = hw_features;
+#endif
}
-static void netdev_tso_feature_init(struct hinic5_nic_dev *nic_dev, netdev_features_t *tso_fts)
+static void netdev_tso_feature_init(struct hinic5_nic_dev *nic_dev,
+ netdev_features_t *tso_fts)
{
+ if (HINIC5_SUPPORT_TSO(nic_dev->hwdev) != 0)
+ *tso_fts |= NETIF_F_TSO | NETIF_F_TSO6;
+
#ifdef HAVE_ENCAPSULATION_TSO
if (HINIC5_SUPPORT_VXLAN_OFFLOAD(nic_dev->hwdev) ||
HINIC5_SUPPORT_GENEVE_OFFLOAD(nic_dev->hwdev))
- *tso_fts |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM;
+ *tso_fts |= NETIF_F_GSO_UDP_TUNNEL |
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
if (HINIC5_SUPPORT_IPXIP_OFFLOAD(nic_dev->hwdev))
*tso_fts |= NETIF_F_GSO_IPXIP4 | NETIF_F_GSO_IPXIP6;
#endif /* HAVE_ENCAPSULATION_TSO */
}
+static void netdev_tc_flower_feature_init(struct hinic5_nic_dev *nic_dev,
+ netdev_features_t *tc_fts)
+{
+ if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD))
+ *tc_fts |= NETIF_F_HW_TC;
+}
+
+static void netdev_enc_feature_init(struct hinic5_nic_dev *nic_dev,
+ netdev_features_t dft_fts,
+ netdev_features_t cso_fts,
+ netdev_features_t tso_fts,
+ netdev_features_t *hw_enc_fts)
+{
+#ifdef HAVE_ENCAPSULATION_CSUM
+ *hw_enc_fts |= dft_fts;
+ if (HINIC5_SUPPORT_VXLAN_OFFLOAD(nic_dev->hwdev) ||
+ HINIC5_SUPPORT_GENEVE_OFFLOAD(nic_dev->hwdev)) {
+ *hw_enc_fts |= cso_fts & (~NETIF_F_SCTP_CRC);
+#ifdef HAVE_ENCAPSULATION_TSO
+ *hw_enc_fts |= tso_fts | NETIF_F_TSO_ECN;
+#endif /* HAVE_ENCAPSULATION_TSO */
+ }
+
+ /* When the chip does not support parsing IPinIP tunnel packets,
+ disable the checksum offloading for inner SCTP. */
+ if (HINIC5_SUPPORT_IPXIP_OFFLOAD(nic_dev->hwdev))
+ *hw_enc_fts |= NETIF_F_SCTP_CRC;
+#endif /* HAVE_ENCAPSULATION_CSUM */
+}
+
+static void netdev_cso_feature_init(struct hinic5_nic_dev *nic_dev,
+ netdev_features_t *cso_fts)
+{
+ if (HINIC5_SUPPORT_CSUM(nic_dev->hwdev) != 0)
+ *cso_fts |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_RXCSUM;
+ if (HINIC5_SUPPORT_SCTP_CRC(nic_dev->hwdev) != 0)
+ *cso_fts |= NETIF_F_SCTP_CRC;
+}
+
static void netdev_feature_init(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
netdev_features_t cso_fts = 0;
netdev_features_t vlan_fts = 0;
netdev_features_t tso_fts = 0;
- netdev_features_t hw_features = 0;
+ netdev_features_t tc_fts = 0;
+ netdev_features_t hw_enc_fts = 0;
netdev_features_t dft_fts = NETIF_F_SG | NETIF_F_HIGHDMA;
- if (HINIC5_SUPPORT_CSUM(nic_dev->hwdev) != 0)
- cso_fts |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
- if (HINIC5_SUPPORT_SCTP_CRC(nic_dev->hwdev) != 0)
- cso_fts |= NETIF_F_SCTP_CRC;
-
- if (HINIC5_SUPPORT_TSO(nic_dev->hwdev) != 0)
- tso_fts |= NETIF_F_TSO | NETIF_F_TSO6;
-
+ netdev_cso_feature_init(nic_dev, &cso_fts);
netdev_vlan_feature_init(nic_dev, &vlan_fts);
-
netdev_tso_feature_init(nic_dev, &tso_fts);
+ netdev_tc_flower_feature_init(nic_dev, &tc_fts);
+ netdev_enc_feature_init(nic_dev, dft_fts, cso_fts, tso_fts,
+ &hw_enc_fts);
- if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD)) {
- netdev->features |= NETIF_F_HW_TC;
- hw_features |= NETIF_F_HW_TC;
- }
- netdev_hw_feature_init(netdev, nic_dev, &hw_features);
-
- netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
- netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ netdev->features |= dft_fts | cso_fts | tso_fts | tc_fts | vlan_fts;
+ netdev->vlan_features |= dft_fts | cso_fts | tso_fts | tc_fts;
+ netdev_hw_feature_init(nic_dev);
-#ifdef HAVE_NDO_SET_U32_FEATURES
- hw_features |= get_netdev_hw_features(netdev);
-#else
- hw_features |= netdev->hw_features;
+#ifdef HAVE_ENCAPSULATION_CSUM
+ netdev->hw_enc_features |= hw_enc_fts | tc_fts;
#endif
- hw_features |= netdev->features;
-
-#ifdef HAVE_NDO_SET_U32_FEATURES
- set_netdev_hw_features(netdev, hw_features);
-#else
- netdev->hw_features = hw_features;
+#ifdef HAVE_NETDEV_XDP_ACT_NDO_XMIT
+ netdev->xdp_features = NETDEV_XDP_ACT_NDO_XMIT;
#endif
#ifdef IFF_UNICAST_FLT
netdev->priv_flags |= IFF_UNICAST_FLT;
#endif
-
-#ifdef HAVE_ENCAPSULATION_CSUM
- netdev->hw_enc_features |= dft_fts;
- if (HINIC5_SUPPORT_VXLAN_OFFLOAD(nic_dev->hwdev) ||
- HINIC5_SUPPORT_GENEVE_OFFLOAD(nic_dev->hwdev)) {
- netdev->hw_enc_features |= cso_fts & (~NETIF_F_SCTP_CRC);
-#ifdef HAVE_ENCAPSULATION_TSO
- netdev->hw_enc_features |= tso_fts | NETIF_F_TSO_ECN;
-#endif /* HAVE_ENCAPSULATION_TSO */
- }
-
- /* When the chip does not support parsing IPinIP tunnel packets,
- * disable the checksum offloading for inner SCTP.
- */
- if (HINIC5_SUPPORT_IPXIP_OFFLOAD(nic_dev->hwdev))
- netdev->hw_enc_features |= NETIF_F_SCTP_CRC;
-#endif /* HAVE_ENCAPSULATION_CSUM */
-#ifdef HAVE_NETDEV_XDP_ACT_NDO_XMIT
- netdev->xdp_features = NETDEV_XDP_ACT_NDO_XMIT;
-#endif /* HAVE_NETDEV_XDP_ACT_NDO_XMIT */
}
static void init_intr_coal_param(struct hinic5_nic_dev *nic_dev)
@@ -445,12 +482,16 @@ static int hinic5_init_intr_coalesce(struct hinic5_nic_dev *nic_dev)
size = sizeof(*nic_dev->intr_coalesce) * nic_dev->max_qps;
if (size == 0) {
- nic_err(nic_dev->lld_dev->dev, "Cannot allocate zero size intr coalesce\n");
+ nic_err(nic_dev->lld_dev->dev,
+ "Cannot allocate zero size intr coalesce\n");
return -EINVAL;
}
nic_dev->intr_coalesce = kzalloc(size, GFP_KERNEL);
- if (!nic_dev->intr_coalesce)
+ if (nic_dev->intr_coalesce == NULL) {
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to alloc intr coalesce\n");
return -ENOMEM;
+ }
init_intr_coal_param(nic_dev);
@@ -487,7 +528,8 @@ static int hinic5_alloc_txrxqs(struct hinic5_nic_dev *nic_dev)
err = hinic5_init_intr_coalesce(nic_dev);
if (err != 0) {
- nic_err(nic_dev->lld_dev->dev, "Failed to init_intr_coalesce\n");
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to init_intr_coalesce\n");
goto init_intr_err;
}
@@ -528,9 +570,11 @@ static void hinic5_sw_deinit(struct hinic5_nic_dev *nic_dev)
static inline int invalid_mac_address(struct hinic5_nic_dev *nic_dev)
{
if (!is_valid_ether_addr(nic_dev->netdev->dev_addr)) {
- if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
return -EIO;
- nic_info(nic_dev->lld_dev->dev, "Invalid MAC address %pM, using random\n",
+ }
+ nic_info(nic_dev->lld_dev->dev,
+ "Invalid MAC address %pM, using random\n",
nic_dev->netdev->dev_addr);
eth_hw_addr_random(nic_dev->netdev);
}
@@ -553,25 +597,30 @@ static void hinic5_sw_mtu_range_init(struct net_device *netdev)
static void hinic5_tx_rx_ops_init(struct hinic5_nic_dev *nic_dev)
{
- nic_dev->tx_wqe_compact_task = HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev->hwdev);
+ nic_dev->tx_wqe_compact_task =
+ HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev->hwdev);
if (HINIC5_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev->hwdev))
- nic_dev->tx_rx_ops.tx_set_wqe_offload = hinic5_tx_set_compact_task_offload;
+ nic_dev->tx_rx_ops.tx_set_wqe_offload =
+ hinic5_tx_set_compact_task_offload;
else
- nic_dev->tx_rx_ops.tx_set_wqe_offload = hinic5_tx_set_normal_task_offload;
+ nic_dev->tx_rx_ops.tx_set_wqe_offload =
+ hinic5_tx_set_normal_task_offload;
if (hinic5_get_rq_wqe_type(nic_dev->hwdev) == HINIC5_COMPACT_RQ_WQE) {
- /* 1825/1872 integrated CQE */
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic5_rx_get_compact_cqe_info;
+ /* 1825/1872合一cqe */
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic5_rx_get_compact_cqe_info;
nic_dev->cqe_mode = HINIC5_RQ_CQE_INTEGRATE;
nic_dev->tx_rx_ops.rx_cqe_done = hinic5_rx_integrated_cqe_done;
} else if (HINIC5_SUPPORT_RX_HW_COMPACT_CQE(nic_dev->hwdev)) {
- /* 1872 separate CQE */
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic5_rx_get_compact_cqe_info;
+ /* 1872分离cqe */
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic5_rx_get_compact_cqe_info;
nic_dev->cqe_mode = HINIC5_RQ_CQE_SEPARATE;
nic_dev->tx_rx_ops.rx_cqe_done = hinic5_rx_separate_cqe_done;
} else {
- /* 1823/1825 separate CQE */
+ /* 1823/1825分离cqe */
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic5_rx_get_cqe_info;
nic_dev->cqe_mode = HINIC5_RQ_CQE_SEPARATE;
nic_dev->tx_rx_ops.rx_cqe_done = hinic5_rx_separate_cqe_done;
@@ -598,7 +647,8 @@ static int hinic5_sw_init(struct hinic5_nic_dev *nic_dev)
/* You can update the features supported by the driver according to the
* scenario here
*/
- hinic5_update_nic_feature(nic_dev->hwdev, nic_features & NIC_DRV_DEFAULT_FEATURE);
+ hinic5_update_nic_feature(nic_dev->hwdev,
+ nic_features & NIC_DRV_DEFAULT_FEATURE);
sema_init(&nic_dev->port_state_sem, 1);
@@ -627,17 +677,19 @@ static int hinic5_sw_init(struct hinic5_nic_dev *nic_dev)
err = invalid_mac_address(nic_dev);
if (err != 0) {
- nic_err(nic_dev->lld_dev->dev, "Invalid MAC address %pM\n", netdev->dev_addr);
+ nic_err(nic_dev->lld_dev->dev, "Invalid MAC address %pM\n",
+ netdev->dev_addr);
goto err_mac;
}
err = hinic5_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic5_global_func_id(nic_dev->hwdev), HINIC5_CHANNEL_NIC);
+ hinic5_global_func_id(nic_dev->hwdev),
+ HINIC5_CHANNEL_NIC);
/* When this is VF driver, we must consider that PF has already set VF
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err != 0 && err != HINIC5_PF_SET_VF_ALREADY) {
+ if ((err != 0) && (err != HINIC5_PF_SET_VF_ALREADY)) {
nic_err(nic_dev->lld_dev->dev, "Failed to set default MAC\n");
goto err_mac;
}
@@ -657,7 +709,7 @@ static int hinic5_sw_init(struct hinic5_nic_dev *nic_dev)
alloc_qps_err:
hinic5_del_mac(nic_dev->hwdev, netdev->dev_addr, 0,
hinic5_global_func_id(nic_dev->hwdev),
- HINIC5_CHANNEL_NIC);
+ HINIC5_CHANNEL_NIC);
err_mac:
hinic5_clear_rss_config(nic_dev);
@@ -715,14 +767,15 @@ static int set_interrupt_moder(struct hinic5_nic_dev *nic_dev, u16 q_id,
q_id >= nic_dev->q_params.num_qps)
return 0;
- memset(&coalesce_info, 0, sizeof(coalesce_info));
+ (void)memset_s(&coalesce_info, sizeof(coalesce_info), 0,
+ sizeof(coalesce_info));
coalesce_info.rx_coalesce_timer_cfg = coalesc_timer_cfg;
coalesce_info.rx_pending_limt = pending_limt;
coalesce_info.tx_coalesce_timer_cfg = coalesc_timer_cfg;
coalesce_info.tx_pending_limt = pending_limt;
- err = hinic5_set_sq_rq_coalesce_cfg(nic_dev->hwdev, q_id, HINIC5_SQ_RQ_COALESCE,
- &coalesce_info);
+ err = hinic5_set_sq_rq_coalesce_cfg(
+ nic_dev->hwdev, q_id, HINIC5_SQ_RQ_COALESCE, &coalesce_info);
if (err != 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to modify moderation for Queue: %u\n", q_id);
@@ -745,17 +798,19 @@ static void calc_coal_para(struct hinic5_nic_dev *nic_dev,
*coalesc_timer_cfg = q_coal->rx_usecs_high;
*pending_limt = q_coal->rx_pending_limt_high;
} else {
- *coalesc_timer_cfg =
- (u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_usecs_high - q_coal->rx_usecs_low) /
- (q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
- q_coal->rx_usecs_low);
-
- *pending_limt =
- (u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
- (q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
- q_coal->rx_pending_limt_low);
+ *coalesc_timer_cfg = (u8)((rx_rate - q_coal->pkt_rate_low) *
+ (q_coal->rx_usecs_high -
+ q_coal->rx_usecs_low) /
+ (q_coal->pkt_rate_high -
+ q_coal->pkt_rate_low) +
+ q_coal->rx_usecs_low);
+
+ *pending_limt = (u8)((rx_rate - q_coal->pkt_rate_low) *
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
+ (q_coal->pkt_rate_high -
+ q_coal->pkt_rate_low) +
+ q_coal->rx_pending_limt_low);
}
}
@@ -767,8 +822,10 @@ static void update_queue_coal(struct hinic5_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC5_RX_RATE_THRESH && avg_pkt_size > HINIC5_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC5_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC5_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg,
+ &pending_limt);
} else {
coalesc_timer_cfg = HINIC5_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -780,11 +837,10 @@ static void update_queue_coal(struct hinic5_nic_dev *nic_dev, u16 qid,
void hinic5_auto_moderation_work(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_nic_dev *nic_dev = container_of(delay,
- struct hinic5_nic_dev,
- moderation_task);
- unsigned long period = (unsigned long)(jiffies -
- nic_dev->last_moder_jiffies);
+ struct hinic5_nic_dev *nic_dev =
+ container_of(delay, struct hinic5_nic_dev, moderation_task);
+ unsigned long period =
+ (unsigned long)(jiffies - nic_dev->last_moder_jiffies);
u64 rx_packets, rx_bytes, rx_pkt_diff, rx_rate, avg_pkt_size;
u64 tx_packets, tx_bytes, tx_pkt_diff, tx_rate;
u16 qid;
@@ -795,7 +851,7 @@ void hinic5_auto_moderation_work(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC5_MODERATONE_DELAY);
- if (nic_dev->adaptive_rx_coal == 0 || period == 0)
+ if ((nic_dev->adaptive_rx_coal == 0) || (period == 0))
return;
for (qid = 0; qid < nic_dev->q_params.num_qps; qid++) {
@@ -806,18 +862,20 @@ void hinic5_auto_moderation_work(struct work_struct *work)
rx_pkt_diff =
rx_packets - nic_dev->rxqs[qid].last_moder_packets;
- avg_pkt_size = (rx_pkt_diff != 0) ?
- ((unsigned long)(rx_bytes -
- nic_dev->rxqs[qid].last_moder_bytes)) /
- rx_pkt_diff : 0;
+ avg_pkt_size =
+ (rx_pkt_diff != 0) ?
+ ((unsigned long)(rx_bytes -
+ nic_dev->rxqs[qid]
+ .last_moder_bytes)) /
+ rx_pkt_diff :
+ 0;
rx_rate = rx_pkt_diff * HZ / period;
tx_pkt_diff =
tx_packets - nic_dev->txqs[qid].last_moder_packets;
tx_rate = tx_pkt_diff * HZ / period;
- update_queue_coal(nic_dev, qid, rx_rate, avg_pkt_size,
- tx_rate);
+ update_queue_coal(nic_dev, qid, rx_rate, avg_pkt_size, tx_rate);
nic_dev->rxqs[qid].last_moder_packets = rx_packets;
nic_dev->rxqs[qid].last_moder_bytes = rx_bytes;
@@ -831,10 +889,13 @@ void hinic5_auto_moderation_work(struct work_struct *work)
static void hinic5_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_nic_dev *nic_dev = container_of(delay, struct hinic5_nic_dev, periodic_work);
+ struct hinic5_nic_dev *nic_dev =
+ container_of(delay, struct hinic5_nic_dev, periodic_work);
- if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag) != 0)
- hinic5_fault_event_report(nic_dev->hwdev, HINIC5_FAULT_SRC_TX_TIMEOUT,
+ if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag) !=
+ 0)
+ hinic5_fault_event_report(nic_dev->hwdev,
+ HINIC5_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
@@ -844,9 +905,9 @@ void hinic5_arp_dual_work(struct work_struct *work)
{
int ret;
struct hinic5_nic_dev *nic_dev =
- container_of(work, struct hinic5_nic_dev, arp_dual_work);
+ container_of(work, struct hinic5_nic_dev, arp_dual_work);
struct sk_buff *skb = NULL;
- struct hinic5_arp_pkt_info info = {0};
+ struct hinic5_arp_pkt_info info = { 0 };
struct hinic5_txq *txq = NULL;
u16 q_id;
u32 pkt_len;
@@ -869,82 +930,92 @@ void hinic5_arp_dual_work(struct work_struct *work)
ret = skb_copy_bits(skb, 0, info.pkt_buf, (int)pkt_len);
if (ret < 0) {
kfree_skb(skb);
- nic_err(nic_dev->lld_dev->dev, "Copy skb failed, ret:%d.\n", ret);
+ nic_err(nic_dev->lld_dev->dev,
+ "Copy skb failed, ret:%d.\n", ret);
continue;
}
kfree_skb(skb);
- msleep(10);
ret = hinic5_send_arp_to_mpu(nic_dev->hwdev, &info);
- if (ret < 0)
- nic_err(nic_dev->lld_dev->dev, "Send ARP to mpu failed, ret:%d.\n", ret);
+ if (ret < 0) {
+ nic_err(nic_dev->lld_dev->dev,
+ "Send ARP to mpu failed, ret:%d.\n", ret);
+ }
}
+ return;
}
void hinic5_update_stats_work(struct work_struct *work)
{
int ret = 0;
struct hinic5_nic_dev *nic_dev =
- container_of(work, struct hinic5_nic_dev, update_stats_work);
+ container_of(work, struct hinic5_nic_dev, update_stats_work);
- ret = hinic5_get_vport_stats(nic_dev->hwdev, hinic5_global_func_id(nic_dev->hwdev),
+ ret = hinic5_get_vport_stats(nic_dev->hwdev,
+ hinic5_global_func_id(nic_dev->hwdev),
&nic_dev->vport_stats);
- if (ret != 0)
- nic_err(nic_dev->lld_dev->dev, "Failed to get function stats from fw, ret:%d.\n", ret);
+ if (ret != 0) {
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to get function stats from fw, ret:%d.\n", ret);
+ }
return;
}
-static int init_nic_dev_hinic5_vram(struct hinic5_nic_dev *nic_dev)
+static int init_nic_dev_vram(struct hinic5_nic_dev *nic_dev)
{
- int is_in_kexec = hinic5_vram_get_kexec_flag();
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
+ int is_in_kexec = vram5_get_kexec_flag();
+ int is_use_vram = get5_use_vram_flag();
u16 func_id;
int ret;
- if (is_use_hinic5_vram != 0) {
+ if (is_use_vram != 0) {
func_id = hinic5_global_func_id(nic_dev->hwdev);
- ret = snprintf(nic_dev->nic_hinic5_vram_name, HINIC5_VRAM_NAME_MAX_LEN,
- "%s%hu", HINIC5_VRAM_NIC_HINIC5_VRAM, func_id);
+ ret = snprintf_s(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ VRAM_NAME_MAX_LEN - 1, "%s%hu", VRAM_NIC_VRAM,
+ func_id);
if (ret < 0) {
nic_err(nic_dev->lld_dev->dev,
- "NIC hinic5_vram name snprintf_s failed, ret:%d.\n", ret);
+ "NIC vram name snprintf_s failed, ret:%d.\n",
+ ret);
return -EINVAL;
}
- nic_dev->nic_hinic5_vram =
- (struct hinic5_hinic5_vram *)
- hinic5_hinic5_vram_kalloc(nic_dev->nic_hinic5_vram_name,
- sizeof(struct hinic5_hinic5_vram));
- if (!nic_dev->nic_hinic5_vram) {
- nic_err(nic_dev->lld_dev->dev, "Failed to allocate nic hinic5_vram\n");
+ nic_dev->nic_vram = (struct hinic5_vram *)hi5_vram_kalloc(
+ nic_dev->nic_vram_name, sizeof(struct hinic5_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to allocate nic vram\n");
return -ENOMEM;
}
if (is_in_kexec == 0)
- nic_dev->nic_hinic5_vram->hinic5_vram_mtu = nic_dev->netdev->mtu;
+ nic_dev->nic_vram->vram_mtu = nic_dev->netdev->mtu;
else
- nic_dev->netdev->mtu = nic_dev->nic_hinic5_vram->hinic5_vram_mtu;
+ nic_dev->netdev->mtu = nic_dev->nic_vram->vram_mtu;
} else {
- nic_dev->nic_hinic5_vram = kzalloc(sizeof(struct hinic5_hinic5_vram), GFP_KERNEL);
- if (!nic_dev->nic_hinic5_vram)
+ nic_dev->nic_vram =
+ kzalloc(sizeof(struct hinic5_vram), GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to allocate nic vram\n");
return -ENOMEM;
- nic_dev->nic_hinic5_vram->hinic5_vram_mtu = nic_dev->netdev->mtu;
+ }
+ nic_dev->nic_vram->vram_mtu = nic_dev->netdev->mtu;
}
return 0;
}
-static void free_nic_dev_hinic5_vram(struct hinic5_nic_dev *nic_dev)
+static void free_nic_dev_vram(struct hinic5_nic_dev *nic_dev)
{
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
-
- if (is_use_hinic5_vram != 0)
- hinic5_hinic5_vram_kfree((void *)nic_dev->nic_hinic5_vram,
- nic_dev->nic_hinic5_vram_name,
- sizeof(struct hinic5_hinic5_vram));
+ int is_use_vram = get5_use_vram_flag();
+ if (is_use_vram != 0)
+ hi5_vram_kfree((void *)nic_dev->nic_vram,
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic5_vram));
else
- kfree(nic_dev->nic_hinic5_vram);
- nic_dev->nic_hinic5_vram = NULL;
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
}
static void free_nic_dev(struct hinic5_nic_dev *nic_dev)
@@ -952,10 +1023,11 @@ static void free_nic_dev(struct hinic5_nic_dev *nic_dev)
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
nic_dev->vlan_bitmap = NULL;
- free_nic_dev_hinic5_vram(nic_dev);
+ free_nic_dev_vram(nic_dev);
}
-static void nic_dev_init(struct hinic5_nic_dev *nic_dev, struct net_device *netdev,
+static void nic_dev_init(struct hinic5_nic_dev *nic_dev,
+ struct net_device *netdev,
struct hinic5_lld_dev *lld_dev)
{
u8 rx_buff_per_page = RX_BUFF_NUM_PER_PAGE;
@@ -973,7 +1045,7 @@ static void nic_dev_init(struct hinic5_nic_dev *nic_dev, struct net_device *netd
nic_dev->poll_weight = (int)poll_weight;
nic_dev->msg_enable = DEFAULT_MSG_ENABLE;
nic_dev->lro_replenish_thld = lro_replenish_thld;
- nic_dev->rx_buff_len = (u16)(hinic5_rx_buff * CONVERT_UNIT);
+ nic_dev->rx_buff_len = (u16)(rx_buff * CONVERT_UNIT);
nic_dev->dma_rx_buff_size = rx_buff_per_page * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = (page_num > 0) ? ilog2(page_num) : 0;
@@ -993,12 +1065,13 @@ static void init_list_head(struct hinic5_nic_dev *nic_dev)
static int setup_nic_dev(struct net_device *netdev,
struct hinic5_lld_dev *lld_dev)
{
- struct hinic5_nic_dev *nic_dev = (struct hinic5_nic_dev *)netdev_priv(netdev);
+ struct hinic5_nic_dev *nic_dev =
+ (struct hinic5_nic_dev *)netdev_priv(netdev);
int ret;
nic_dev_init(nic_dev, netdev, lld_dev);
- ret = init_nic_dev_hinic5_vram(nic_dev);
+ ret = init_nic_dev_vram(nic_dev);
if (ret != 0)
return ret;
@@ -1012,14 +1085,16 @@ static int setup_nic_dev(struct net_device *netdev,
}
nic_dev->workq = create_singlethread_workqueue(HINIC5_NIC_DEV_WQ_NAME);
- if (!nic_dev->workq) {
+ if (nic_dev->workq == NULL) {
nic_err(lld_dev->dev, "Failed to initialize nic workqueue\n");
ret = -ENOMEM;
goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic5_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic5_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic5_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic5_rxq_check_work_handler);
init_list_head(nic_dev);
skb_queue_head_init(&nic_dev->arp_queue);
INIT_WORK(&nic_dev->rx_mode_work, hinic5_set_rx_mode_work);
@@ -1032,7 +1107,7 @@ static int setup_nic_dev(struct net_device *netdev,
kfree(nic_dev->vlan_bitmap);
nic_dev->vlan_bitmap = NULL;
vlan_bitmap_error:
- free_nic_dev_hinic5_vram(nic_dev);
+ free_nic_dev_vram(nic_dev);
return ret;
}
@@ -1044,11 +1119,12 @@ static int hinic5_set_default_hw_feature(struct hinic5_nic_dev *nic_dev)
hinic5_dcb_reset_hw_config(nic_dev);
if (set_link_status_follow < HINIC5_LINK_FOLLOW_STATUS_MAX) {
- err = hinic5_set_link_status_follow(nic_dev->hwdev,
- set_link_status_follow);
+ err = hinic5_set_link_status_follow(
+ nic_dev->hwdev, set_link_status_follow);
if (err == HINIC5_MGMT_CMD_UNSUPPORTED)
- nic_warn(nic_dev->lld_dev->dev,
- "Current version of firmware doesn't support to set link status follow port status\n");
+ nic_warn(
+ nic_dev->lld_dev->dev,
+ "Current version of firmware doesn't support to set link status follow port status\n");
}
}
@@ -1072,40 +1148,45 @@ static int hinic5_set_default_hw_feature(struct hinic5_nic_dev *nic_dev)
return 0;
}
-static int nic_init_for_hotreplace(struct hinic5_lld_dev *lld_dev, struct hinic5_nic_dev *nic_dev)
+static int nic_init_for_hotreplace(struct hinic5_lld_dev *lld_dev,
+ struct hinic5_nic_dev *nic_dev)
{
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
- int is_in_kexec = hinic5_vram_get_kexec_flag();
+ int is_use_vram = get5_use_vram_flag();
+ int is_in_kexec = vram5_get_kexec_flag();
int err;
/* register netdev flush ops, required only in sdinanoos hotreplace */
- if (is_use_hinic5_vram != 0) {
+ if (is_use_vram != 0) {
err = hiudk5_register_flush_fn(lld_dev, hinic5_flush_nic_dev);
if (err != 0) {
- nic_err(lld_dev->dev, "Failed to register netdev flush ops, err:%d.\n",
+ nic_err(lld_dev->dev,
+ "Failed to register netdev flush ops, err:%d.\n",
err);
return err;
}
}
if (is_in_kexec != 0 &&
- test_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_hinic5_vram->flags) != 0) {
+ test_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_vram->flags) != 0) {
err = hinic5_configure_dcb_hw(nic_dev, 1);
if (err != 0) {
- nic_err(lld_dev->dev, "Failed to enable dcb during sdinanoos-hotreplace\n");
+ nic_err(lld_dev->dev,
+ "Failed to enable dcb during sdinanoos-hotreplace\n");
hiudk5_unregister_flush_fn(lld_dev);
return err;
}
- nic_info(lld_dev->dev, "Enable dcb success during sdinanoos-hotreplace\n");
+ nic_info(lld_dev->dev,
+ "Enable dcb success during sdinanoos-hotreplace\n");
}
return 0;
}
-#define hinic5_set_dpath_timeout(nic_dev, hw_type) { \
- (nic_dev)->timeout.wait_flush_qp_res_timeout = \
- HINIC5_GET_TIMEOUT(hw_type, WAIT_FLUSH_QP_RESOURCE); \
-}
+#define hinic5_set_dpath_timeout(nic_dev, hw_type) \
+ { \
+ (nic_dev)->timeout.wait_flush_qp_res_timeout = \
+ HINIC5_GET_TIMEOUT(hw_type, WAIT_FLUSH_QP_RESOURCE); \
+ }
static void hinic5_init_dpath_timeout(struct hinic5_nic_dev *nic_dev)
{
@@ -1125,13 +1206,14 @@ static void hinic5_init_dpath_timeout(struct hinic5_nic_dev *nic_dev)
}
}
-__weak int hinic5_probe_extend_hook(struct net_device *netdev)
+__attribute__((weak)) int hinic5_probe_extend_hook(struct net_device *netdev)
{
return 0;
}
-__weak void hinic5_remove_extend_hook(struct net_device *netdev)
+__attribute__((weak)) void hinic5_remove_extend_hook(struct net_device *netdev)
{
+ return;
}
static int nic_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
@@ -1150,18 +1232,21 @@ static int nic_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
nic_info(lld_dev->dev, "NIC service probe begin\n");
err = hinic5_validate_parameters(lld_dev);
- if (err != 0)
+ if (err != 0) {
goto err_out;
+ }
glb_func_id = hinic5_global_func_id(lld_dev->hwdev);
- err = hinic5_func_reset(lld_dev->hwdev, glb_func_id, HINIC5_NIC_RES, HINIC5_CHANNEL_NIC);
+ err = hinic5_func_reset(lld_dev->hwdev, glb_func_id, HINIC5_NIC_RES,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
nic_err(lld_dev->dev, "Failed to reset function\n");
goto err_out;
}
- netdev = alloc_etherdev_mq(sizeof(*nic_dev), hinic5_func_max_nic_qnum(lld_dev->hwdev));
- if (!netdev) {
+ netdev = alloc_etherdev_mq(sizeof(*nic_dev),
+ hinic5_func_max_nic_qnum(lld_dev->hwdev));
+ if (netdev == NULL) {
nic_err(lld_dev->dev, "Failed to allocate ETH device\n");
err = -ENOMEM;
goto err_out;
@@ -1179,7 +1264,8 @@ static int nic_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
/* get nic cap from hw */
hinic5_support_nic(lld_dev->hwdev, &nic_dev->nic_cap);
- err = hinic5_init_nic_hwdev(nic_dev->hwdev, lld_dev->dev, nic_dev->rx_buff_len);
+ err = hinic5_init_nic_hwdev(nic_dev->hwdev, lld_dev->dev,
+ nic_dev->rx_buff_len);
if (err != 0) {
nic_err(lld_dev->dev, "Failed to init nic hwdev\n");
goto init_nic_hwdev_err;
@@ -1224,10 +1310,12 @@ static int nic_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
}
#endif
- if (macsec_enabled && HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD)) {
+ if (macsec_enabled &&
+ HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD)) {
err = macsec_init_offload(nic_dev);
- if (err != 0)
+ if (err != 0) {
goto hinic5_init_macsec_err;
+ }
}
err = nic_init_for_hotreplace(lld_dev, nic_dev);
@@ -1242,24 +1330,28 @@ static int nic_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
return 0;
init_hotreplace_err:
- if (macsec_enabled && HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD))
+ if (macsec_enabled &&
+ HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD)) {
macsec_cleanup_offload(nic_dev);
+ }
hinic5_init_macsec_err:
#if (KERNEL_VERSION(5, 1, 1) <= LINUX_VERSION_CODE)
- if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD))
+ if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD)) {
hinic5_deinit_tc(nic_dev);
+ }
hinic5_init_tc_err:
#endif
hinic5_ptp_deinit(nic_dev);
-
+#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
+ hinic5_unregister_notifier(nic_dev);
+#endif
unregister_netdev(netdev);
+
netdev_err:
hinic5_remove_extend_hook(netdev);
+
probe_hook_err:
-#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
- hinic5_unregister_notifier(nic_dev);
-#endif
hinic5_update_nic_feature(nic_dev->hwdev, 0);
hinic5_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -1284,9 +1376,9 @@ static void nic_remove(struct hinic5_lld_dev *lld_dev, void *adapter)
{
struct hinic5_nic_dev *nic_dev = adapter;
struct net_device *netdev = NULL;
- int is_use_hinic5_vram = get_use_hinic5_vram_flag();
+ int is_use_vram = get5_use_vram_flag();
- if (!nic_dev || !hinic5_support_nic(lld_dev->hwdev, NULL))
+ if ((nic_dev == NULL) || !hinic5_support_nic(lld_dev->hwdev, NULL))
return;
nic_info(lld_dev->dev, "NIC service remove begin\n");
@@ -1295,20 +1387,21 @@ static void nic_remove(struct hinic5_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- if (macsec_enabled && HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD))
+ if (macsec_enabled &&
+ HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, MACSEC_OFFLOAD)) {
macsec_cleanup_offload(nic_dev);
+ }
#if (KERNEL_VERSION(5, 1, 1) <= LINUX_VERSION_CODE)
- if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD))
+ if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD)) {
hinic5_deinit_tc(nic_dev);
+ }
#endif
#ifdef HAVE_XDP_SUPPORT
nic_dev->remove_flag = true;
#endif
- /* Unregister the network device using kernel function,
- * and release queues, xdp programs and other related resources
- */
+ /* 内核函数注销该网络设备,并释放队列、挂载的xdp程序等相关资源 */
unregister_netdev(netdev);
#ifdef HAVE_XDP_SUPPORT
@@ -1341,16 +1434,16 @@ static void nic_remove(struct hinic5_lld_dev *lld_dev, void *adapter)
kfree(nic_dev->vlan_bitmap);
nic_dev->vlan_bitmap = NULL;
- if (is_use_hinic5_vram != 0)
- hinic5_hinic5_vram_kfree((void *)nic_dev->nic_hinic5_vram,
- nic_dev->nic_hinic5_vram_name,
- sizeof(struct hinic5_hinic5_vram));
+ if (is_use_vram != 0)
+ hi5_vram_kfree((void *)nic_dev->nic_vram,
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic5_vram));
else
- kfree(nic_dev->nic_hinic5_vram);
+ kfree(nic_dev->nic_vram);
free_netdev(netdev);
- if (is_use_hinic5_vram != 0)
+ if (is_use_vram != 0)
hiudk5_unregister_flush_fn(lld_dev);
nic_info(lld_dev->dev, "NIC service removed\n");
@@ -1359,18 +1452,21 @@ static void nic_remove(struct hinic5_lld_dev *lld_dev, void *adapter)
static void sriov_state_change(struct hinic5_nic_dev *nic_dev,
const struct hinic5_sriov_state_info *info)
{
- /* todo: ubus scenario support to disable a single VF,
- * nic_dev records the actual active VF count, PCIe and ubus logic should be unified
- */
- if (info->enable == 0)
- hinic5_clear_vfs_info(nic_dev->hwdev, info->vf_id, info->vf_id);
+ u32 max_vf_id = HW_VF_ID_TO_OS(hinic5_func_max_vf(nic_dev->hwdev));
+
+ /* todo: ubus场景支持单独disable某一个vf,nic_dev中记录真实active的vf数目,pcie和ubus逻辑归一 */
+ if ((info->enable == 0))
+ hinic5_clear_vfs_info(nic_dev->hwdev, 0, max_vf_id);
}
static void hinic5_port_module_event_handler(struct hinic5_nic_dev *nic_dev,
struct hinic5_event_info *event)
{
- const char *g_hinic5_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic5_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic5_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module"
+ };
+ struct hinic5_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1380,7 +1476,8 @@ static void hinic5_port_module_event_handler(struct hinic5_nic_dev *nic_dev,
nicif_info(nic_dev, link, nic_dev->netdev,
"Port module event: Cable %s\n",
type == HINIC5_PORT_MODULE_CABLE_PLUGGED ?
- "plugged" : "unplugged");
+ "plugged" :
+ "unplugged");
break;
case HINIC5_PORT_MODULE_LINK_ERR:
if (err_type >= LINK_ERR_NUM) {
@@ -1407,7 +1504,8 @@ static void nic_event(struct hinic5_lld_dev *lld_dev, void *adapter,
struct hinic5_nic_dev *nic_dev = adapter;
struct hinic5_fault_event *fault = NULL;
- if (!nic_dev || !event || !hinic5_support_nic(lld_dev->hwdev, NULL))
+ if ((nic_dev == NULL) || (event == NULL) ||
+ !hinic5_support_nic(lld_dev->hwdev, NULL))
return;
switch (HINIC5_SRV_EVENT_TYPE(event->service, event->type)) {
@@ -1420,13 +1518,15 @@ static void nic_event(struct hinic5_lld_dev *lld_dev, void *adapter,
case HINIC5_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic5_port_module_event_handler(nic_dev, event);
break;
- case HINIC5_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC5_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC5_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic5_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic5_global_func_id(lld_dev->hwdev))
hinic5_link_status_change(nic_dev, false);
break;
case HINIC5_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1443,11 +1543,11 @@ struct net_device *hinic5_get_netdev_by_lld(struct hinic5_lld_dev *lld_dev)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!lld_dev || !hinic5_support_nic(lld_dev->hwdev, NULL))
+ if ((lld_dev == NULL) || !hinic5_support_nic(lld_dev->hwdev, NULL))
return NULL;
nic_dev = hinic5_get_uld_dev_unsafe(lld_dev, SERVICE_T_NIC);
- if (!nic_dev) {
+ if (nic_dev == NULL) {
nic_err(lld_dev->dev,
"There's no net device attached on the pci device");
return NULL;
@@ -1461,26 +1561,38 @@ struct hinic5_lld_dev *hinic5_get_lld_dev_by_netdev(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!netdev || !hinic5_is_netdev_ops_match(netdev))
+ if ((netdev == NULL) || !hinic5_is_netdev_ops_match(netdev))
return NULL;
nic_dev = netdev_priv(netdev);
- if (!nic_dev)
+ if (nic_dev == NULL)
return NULL;
return nic_dev->lld_dev;
}
EXPORT_SYMBOL(hinic5_get_lld_dev_by_netdev);
-int hinic5_get_phy_port_id_by_netdev(struct net_device *netdev, uint8_t *phy_port_id)
+void *hinic5_get_hwdev_by_netdev(struct net_device *netdev)
{
struct hinic5_lld_dev *lld_dev = NULL;
- if (!netdev || !phy_port_id)
+ lld_dev = hinic5_get_lld_dev_by_netdev(netdev);
+ if (lld_dev == NULL)
+ return NULL;
+
+ return lld_dev->hwdev;
+}
+
+int hinic5_get_phy_port_id_by_netdev(struct net_device *netdev,
+ uint8_t *phy_port_id)
+{
+ struct hinic5_lld_dev *lld_dev = NULL;
+
+ if ((netdev == NULL) || (phy_port_id == NULL))
return -EINVAL;
lld_dev = hinic5_get_lld_dev_by_netdev(netdev);
- if (!lld_dev)
+ if (lld_dev == NULL)
return -ENXIO;
*phy_port_id = hinic5_physical_port_id(lld_dev->hwdev);
@@ -1492,7 +1604,7 @@ void *hinic5_netdev_priv_get(const struct net_device *dev)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!dev)
+ if (dev == NULL)
return NULL;
nic_dev = netdev_priv(dev);
@@ -1504,7 +1616,7 @@ int hinic5_netdev_priv_set(const struct net_device *dev, void *priv)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!dev || !priv)
+ if (dev == NULL)
return -EINVAL;
nic_dev = netdev_priv(dev);
@@ -1513,18 +1625,18 @@ int hinic5_netdev_priv_set(const struct net_device *dev, void *priv)
return 0;
}
-struct hinic5_uld_info hinic5_g_nic_uld_info = {
+struct hinic5_uld_info g_nic_uld_info = {
.probe = nic_probe,
.remove = nic_remove,
.suspend = NULL,
.resume = NULL,
.event = nic_event,
- .ioctl = hinic5_nic_ioctl,
+ .ioctl = nic_ioctl,
};
-struct hinic5_uld_info *hinic5_get_nic_uld_info(void)
+struct hinic5_uld_info *get_nic_uld_info(void)
{
- return &hinic5_g_nic_uld_info;
+ return &g_nic_uld_info;
}
#define HINIC5_NIC_DRV_DESC "Intelligent Network Interface Card Driver"
@@ -1536,19 +1648,13 @@ static __init int hinic5_nic_lld_init(void)
pr_info("%s - version %s\n", HINIC5_NIC_DRV_DESC,
HINIC5_NIC_DRV_VERSION);
- err = hinic5_lld_init();
- if (err) {
- pr_err("SDK failed.\n");
- return err;
- }
-
err = hinic5_module_pre_init();
if (err != 0) {
pr_err("hinic5_module_pre_init failed\n");
- goto hinic5_module_pre_init_fail;
+ return err;
}
- err = hinic5_register_uld(SERVICE_T_NIC, &hinic5_g_nic_uld_info);
+ err = hinic5_register_uld(SERVICE_T_NIC, &g_nic_uld_info);
if (err != 0) {
pr_err("Register hinic5 uld failed\n");
goto hinic5_register_uld_fail;
@@ -1574,8 +1680,6 @@ static __init int hinic5_nic_lld_init(void)
hinic5_unregister_uld(SERVICE_T_NIC);
hinic5_register_uld_fail:
hinic5_module_post_exit();
-hinic5_module_pre_init_fail:
- hinic5_lld_exit();
return err;
}
@@ -1586,7 +1690,6 @@ static __exit void hinic5_nic_lld_exit(void)
hinic5_bond_deinit();
hinic5_unregister_uld(SERVICE_T_NIC);
hinic5_module_post_exit();
- hinic5_lld_exit();
}
#ifndef _LLT_TEST_
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.h
index e8b15c679..53537fda3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ctrl/hinic5_main.h
@@ -1,35 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_main.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_MAIN_H
-#define HINIC5_MAIN_H
+#define HINIC5_MAIN_H
-#define HINIC5_NIC_DEV_WQ_NAME "hinic5_nic_dev_wq"
+#define HINIC5_NIC_DEV_WQ_NAME "hinic5_nic_dev_wq"
-#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_LINK)
+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_LINK)
-#define QID_MASKED(q_id, nic_dev) ((q_id) & ((nic_dev)->num_qps - 1))
-#define WATCHDOG_TIMEOUT 5
+#define QID_MASKED(q_id, nic_dev) ((q_id) & ((nic_dev)->num_qps - 1))
+#define WATCHDOG_TIMEOUT 5
-#define HINIC5_SQ_DEPTH 1024
-#define HINIC5_RQ_DEPTH 1024
+#define HINIC5_SQ_DEPTH 1024
+#define HINIC5_RQ_DEPTH 1024
-#define HW_DEFAULT_COS_IS_VALID(cos) ((cos) & BIT(3))
+#define HW_DEFAULT_COS_IS_VALID(cos) ((cos)&BIT(3))
#define HW_DEFAULT_COS_VALID_BIT 0x7
enum hinic5_rx_buff_len {
- RX_BUFF_VALID_2KB = 2,
- RX_BUFF_VALID_4KB = 4,
- RX_BUFF_VALID_8KB = 8,
+ RX_BUFF_VALID_2KB = 2,
+ RX_BUFF_VALID_4KB = 4,
+ RX_BUFF_VALID_8KB = 8,
};
-#define CONVERT_UNIT 1024
+#define CONVERT_UNIT 1024
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.c
index 5aa32f8d3..728bf0dd2 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -37,12 +30,13 @@ static void hinic5_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- u8 mgmt_ver[HINIC5_MGMT_VERSION_MAX_LEN] = {0};
+ u8 mgmt_ver[HINIC5_MGMT_VERSION_MAX_LEN] = { 0 };
int err;
- strscpy(info->driver, HINIC5_NIC_DRV_NAME, sizeof(info->driver));
- strscpy(info->version, HINIC5_NIC_DRV_VERSION, sizeof(info->version));
- strscpy(info->bus_info, dev_name(nic_dev->lld_dev->dev), sizeof(info->bus_info));
+ strlcpy(info->driver, HINIC5_NIC_DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, HINIC5_NIC_DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, dev_name(nic_dev->lld_dev->dev),
+ sizeof(info->bus_info));
err = hinic5_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC5_MGMT_VERSION_MAX_LEN,
@@ -52,9 +46,11 @@ static void hinic5_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
+ err = snprintf_s(info->fw_version, sizeof(info->fw_version),
+ sizeof(info->fw_version) - 1, "%s", mgmt_ver);
if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf_s fw version\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to snprintf_s fw version\n");
}
static u32 hinic5_get_msglevel(struct net_device *netdev)
@@ -76,13 +72,14 @@ static void hinic5_set_msglevel(struct net_device *netdev, u32 data)
static int hinic5_nway_reset(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
int err;
while (test_and_set_bit(HINIC5_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic5_get_port_info(nic_dev->hwdev, &port_info, HINIC5_CHANNEL_NIC);
+ err = hinic5_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -90,14 +87,17 @@ static int hinic5_nway_reset(struct net_device *netdev)
}
if (port_info.autoneg_state != PORT_CFG_AN_ON) {
- nicif_err(nic_dev, drv, netdev, "Autonegotiation is not on, don't support to restart it\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Autonegotiation is not on, don't support to restart it\n");
err = -EOPNOTSUPP;
goto reset_err;
}
err = hinic5_set_autoneg(nic_dev->hwdev, false);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Set autonegotiation off failed\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Set autonegotiation off failed\n");
err = -EFAULT;
goto reset_err;
}
@@ -106,13 +106,15 @@ static int hinic5_nway_reset(struct net_device *netdev)
err = hinic5_set_autoneg(nic_dev->hwdev, true);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Set autonegotiation on failed\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Set autonegotiation on failed\n");
err = -EFAULT;
goto reset_err;
}
msleep(200); /* sleep 200 ms, waiting for status polling finished */
- nicif_info(nic_dev, drv, netdev, "Restart autonegotiation successfully\n");
+ nicif_info(nic_dev, drv, netdev,
+ "Restart autonegotiation successfully\n");
reset_err:
clear_bit(HINIC5_AUTONEG_RESET, &nic_dev->flags);
@@ -137,8 +139,8 @@ static void hinic5_get_ringparam(struct net_device *netdev,
ring->tx_pending = nic_dev->txqs[0].q_depth;
}
-static void hinic5_update_qp_depth(struct hinic5_nic_dev *nic_dev,
- u32 sq_depth, u32 rq_depth)
+static void hinic5_update_qp_depth(struct hinic5_nic_dev *nic_dev, u32 sq_depth,
+ u32 rq_depth)
{
u16 i;
@@ -157,7 +159,7 @@ static int check_ringparam_valid(struct net_device *netdev,
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- if (ring->rx_jumbo_pending != 0 || ring->rx_mini_pending != 0) {
+ if ((ring->rx_jumbo_pending != 0) || (ring->rx_mini_pending != 0)) {
nicif_err(nic_dev, drv, netdev,
"Unsupported rx_jumbo_pending/rx_mini_pending\n");
return -EINVAL;
@@ -177,8 +179,9 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
-__weak int hinic5_set_ringparam_pre_hook(struct net_device *netdev,
- struct ethtool_ringparam *ring)
+__attribute__((weak)) int
+hinic5_set_ringparam_pre_hook(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
{
return 0;
}
@@ -194,12 +197,14 @@ static int hinic5_set_ringparam(struct net_device *netdev,
#endif
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic5_dyna_txrxq_params q_params = {0};
+ struct hinic5_dyna_txrxq_params q_params = { 0 };
u32 new_sq_depth, new_rq_depth;
int err;
if (nic_dev->flow_bifur_group_num > HINIC5_GROUP_NUMBER_MIN) {
- nicif_err(nic_dev, drv, netdev, "Cannot be modified after queue groups are configured.\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Cannot be modified after queue groups are configured.\n");
return -EOPNOTSUPP;
}
@@ -241,10 +246,11 @@ static int hinic5_set_ringparam(struct net_device *netdev,
#endif
nicif_info(nic_dev, drv, netdev, "Restarting channel\n");
- err = hinic5_change_channel_settings(nic_dev, &q_params,
- NULL, NULL);
+ err = hinic5_change_channel_settings(nic_dev, &q_params, NULL,
+ NULL);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to change channel settings\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to change channel settings\n");
return -EFAULT;
}
}
@@ -345,7 +351,7 @@ static void hinic5_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct nic_pause_config nic_pause = {0};
+ struct nic_pause_config nic_pause = { 0 };
int err;
err = hinic5_get_pause_info(nic_dev->hwdev, &nic_pause);
@@ -353,11 +359,7 @@ static void hinic5_get_pauseparam(struct net_device *netdev,
nicif_err(nic_dev, drv, netdev,
"Failed to get pauseparam from hw\n");
} else {
- /* For compatibility with 23v200,
- * the retrieved auto_neg is port rate autonegotiation (may be on),
- * but the actual auto_neg that should be retrieved is pause frame autonegotiation (off),
- * so it is directly set to off on the driver side
- */
+ /* 为了兼容23v200,其获取的auto_neg是端口速率自协商(可能为on),而实际应该获取的auto_neg是pause帧自协商(off),故直接在驱动侧统一置为off */
pause->autoneg = AUTONEG_DISABLE;
pause->rx_pause = nic_pause.rx_pause;
pause->tx_pause = nic_pause.tx_pause;
@@ -368,22 +370,25 @@ static int hinic5_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct nic_pause_config nic_pause = {0};
- struct mag_port_info port_info = {0};
+ struct nic_pause_config nic_pause = { 0 };
+ struct mag_port_info port_info = { 0 };
int err;
if (pause->autoneg != AUTONEG_DISABLE) {
- nicif_warn(nic_dev, drv, netdev,
- "The current version does not support enabling pause frame auto-negotiation.\n");
+ nicif_warn(
+ nic_dev, drv, netdev,
+ "The current version does not support enabling pause frame auto-negotiation.\n");
}
- err = hinic5_get_port_info(nic_dev->hwdev, &port_info, HINIC5_CHANNEL_NIC);
+ err = hinic5_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC5_CHANNEL_NIC);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to get auto-negotiation state\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to get auto-negotiation state\n");
return -EFAULT;
}
- /* For compatibility with old version, configure according to port rate autonegotiation state */
+ /* 兼容旧版本,按端口速率自协商状态配置 */
nic_pause.auto_neg = port_info.autoneg_state;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -394,8 +399,9 @@ static int hinic5_set_pauseparam(struct net_device *netdev,
return err;
}
- nicif_info(nic_dev, drv, netdev, "Set pause options, autoneg: %s, tx: %s, rx: %s\n",
- "off", (pause->tx_pause != 0) ? "on" : "off",
+ nicif_info(nic_dev, drv, netdev,
+ "Set pause options, autoneg: %s, tx: %s, rx: %s\n", "off",
+ (pause->tx_pause != 0) ? "on" : "off",
(pause->rx_pause != 0) ? "on" : "off");
return 0;
@@ -410,7 +416,8 @@ static int hinic5_get_module_info(struct net_device *netdev,
u8 sfp_type_ext = 0;
int err;
- err = hinic5_get_sfp_cmis_type(nic_dev->hwdev, &sfp_type, &sfp_type_ext);
+ err = hinic5_get_sfp_cmis_type(nic_dev->hwdev, &sfp_type,
+ &sfp_type_ext);
if (err != 0)
return err;
@@ -460,26 +467,29 @@ static int hinic5_get_module_eeprom(struct net_device *netdev,
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
int err;
- if (ee->len == 0 ||
- ((ee->len + ee->offset) > STD_SFP_INFO_MAX_SIZE) || ee->len > PAGE_SIZE)
+ if ((ee->len == 0) ||
+ ((ee->len + ee->offset) > STD_SFP_INFO_MAX_SIZE) ||
+ ee->len > PAGE_SIZE)
return -EINVAL;
- memset(data, 0, ee->len);
+ (void)memset_s(data, ee->len, 0, ee->len);
- err = hinic5_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len, ee->offset);
+ err = hinic5_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len,
+ ee->offset);
if (err != 0)
return err;
- memcpy(data, sfp_data, ee->len);
+ err = memcpy_s(data, ee->len, sfp_data, ee->len);
return err == 0 ? 0 : -ENOMEM;
}
#endif /* ETHTOOL_GMODULEEEPROM */
#ifdef HAVE_ETHTOOL_GET_MODULE_EEPROM_BY_PAGE
-static int hinic5_get_module_eeprom_by_page(struct net_device *dev,
- const struct ethtool_module_eeprom *page_data,
- struct netlink_ext_ack *extack)
+static int
+hinic5_get_module_eeprom_by_page(struct net_device *dev,
+ const struct ethtool_module_eeprom *page_data,
+ struct netlink_ext_ack *extack)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(dev);
u8 page_id;
@@ -488,7 +498,7 @@ static int hinic5_get_module_eeprom_by_page(struct net_device *dev,
u32 len;
int ret;
- if (!page_data || !page_data->data)
+ if (page_data == NULL || page_data->data == NULL)
return -EINVAL;
page_id = page_data->page;
@@ -496,15 +506,17 @@ static int hinic5_get_module_eeprom_by_page(struct net_device *dev,
len = page_data->length;
i2c_address = page_data->i2c_address;
- if (i2c_address == SFF8079_I2C_ADDRESS_HIGH)
+ if (i2c_address == SFF8079_I2C_ADDRESS_HIGH) {
page_id = HINIC5_ETHTOOL_PAGE_A2H;
- memset(page_data->data, 0, len);
+ }
+ (void)memset_s(page_data->data, len, 0, len);
ret = hinic5_eeprom_page_check(page_id, offset, len);
if (ret != 0)
return ret;
- ret = hinic5_get_cmis_eeprom_by_page(nic_dev->hwdev, page_id, offset, page_data->data, len);
+ ret = hinic5_get_cmis_eeprom_by_page(nic_dev->hwdev, page_id, offset,
+ page_data->data, len);
if (ret != 0)
return ret;
return len;
@@ -512,9 +524,11 @@ static int hinic5_get_module_eeprom_by_page(struct net_device *dev,
#endif /* HAVE_ETHTOOL_GET_MODULE_EEPROM_BY_PAGE */
#ifdef HAVE_DEVLINK_PARAM_SET_EXTACK
-static int hinic5_get_ts_info(struct net_device *netdev, struct kernel_ethtool_ts_info *info)
+static int hinic5_get_ts_info(struct net_device *netdev,
+ struct kernel_ethtool_ts_info *info)
#else
-static int hinic5_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info)
+static int hinic5_get_ts_info(struct net_device *netdev,
+ struct ethtool_ts_info *info)
#endif
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -526,12 +540,10 @@ static int hinic5_get_ts_info(struct net_device *netdev, struct ethtool_ts_info
return 0;
}
- info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
- SOF_TIMESTAMPING_RX_SOFTWARE |
- SOF_TIMESTAMPING_SOFTWARE |
- SOF_TIMESTAMPING_TX_HARDWARE |
- SOF_TIMESTAMPING_RX_HARDWARE |
- SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE;
if (nic_dev->ptp_ctrl.ptp_clock)
info->phc_index = ptp_clock_index(nic_dev->ptp_ctrl.ptp_clock);
@@ -539,18 +551,18 @@ static int hinic5_get_ts_info(struct net_device *netdev, struct ethtool_ts_info
info->phc_index = -1;
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
- info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+ BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
return 0;
}
static const struct ethtool_ops hinic5_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
- ETHTOOL_COALESCE_MAX_FRAMES |
- ETHTOOL_COALESCE_USECS_LOW_HIGH |
- ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
+ .supported_coalesce_params =
+ ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES | ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -634,7 +646,7 @@ static const struct ethtool_ops hinic5_ethtool_ops = {
#ifdef HAVE_ETHTOOL_OPS_EXT
static const struct ethtool_ops_ext hinic5_ethtool_ops_ext = {
- .size = sizeof(struct ethtool_ops_ext),
+ .size = sizeof(struct ethtool_ops_ext),
.set_phys_id = hinic5_set_phys_id,
.get_channels = hinic5_get_channels,
.set_channels = hinic5_set_channels,
@@ -664,11 +676,10 @@ static const struct ethtool_ops_ext hinic5_ethtool_ops_ext = {
static const struct ethtool_ops hinic5vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
- ETHTOOL_COALESCE_MAX_FRAMES |
- ETHTOOL_COALESCE_USECS_LOW_HIGH |
- ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
+ .supported_coalesce_params =
+ ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES | ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -727,7 +738,7 @@ static const struct ethtool_ops hinic5vf_ethtool_ops = {
#ifdef HAVE_ETHTOOL_OPS_EXT
static const struct ethtool_ops_ext hinic5vf_ethtool_ops_ext = {
- .size = sizeof(struct ethtool_ops_ext),
+ .size = sizeof(struct ethtool_ops_ext),
.get_channels = hinic5_get_channels,
.set_channels = hinic5_set_channels,
@@ -761,4 +772,4 @@ void hinic5vf_set_ethtool_ops(struct net_device *netdev)
#ifdef HAVE_ETHTOOL_OPS_EXT
set_ethtool_ops_ext(netdev, &hinic5vf_ethtool_ops_ext);
#endif /* HAVE_ETHTOOL_OPS_EXT */
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.h
index d975cd52f..0af4f4b73 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool.h
@@ -1,55 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_H
-#define HINIC5_ETHTOOL_H
+#define HINIC5_ETHTOOL_H
#include <linux/ethtool.h>
#include <linux/netdevice.h>
-#define COALESCE_ALL_QUEUE 0xFFFF
-#define COALESCE_PENDING_LIMIT_UNIT 8
-#define COALESCE_TIMER_CFG_UNIT 5
-#define COALESCE_MAX_PENDING_LIMIT (255 * COALESCE_PENDING_LIMIT_UNIT)
-#define COALESCE_MAX_TIMER_CFG (255 * COALESCE_TIMER_CFG_UNIT)
-#define HINIC5_WAIT_PKTS_TO_RX_BUFFER 200
-#define HINIC5_WAIT_CLEAR_LP_TEST 100
+#define COALESCE_ALL_QUEUE 0xFFFF
+#define COALESCE_PENDING_LIMIT_UNIT 8
+#define COALESCE_TIMER_CFG_UNIT 5
+#define COALESCE_MAX_PENDING_LIMIT (255 * COALESCE_PENDING_LIMIT_UNIT)
+#define COALESCE_MAX_TIMER_CFG (255 * COALESCE_TIMER_CFG_UNIT)
+#define HINIC5_WAIT_PKTS_TO_RX_BUFFER 200
+#define HINIC5_WAIT_CLEAR_LP_TEST 100
-#define SFF8079_I2C_ADDRESS_HIGH 0x51
-#define HINIC5_ETHTOOL_PAGE_A2H 0x2
+#define SFF8079_I2C_ADDRESS_HIGH 0x51
+#define HINIC5_ETHTOOL_PAGE_A2H 0x2
#ifndef SET_ETHTOOL_OPS
-#define SET_ETHTOOL_OPS(netdev, ops) \
- ((netdev)->ethtool_ops = (ops))
+#define SET_ETHTOOL_OPS(netdev, ops) ((netdev)->ethtool_ops = (ops))
#endif
#ifdef NEED_ETHTOOL_COALESCE_USECS_LOW_HIGH
-#define ETHTOOL_COALESCE_USECS_LOW_HIGH \
+#define ETHTOOL_COALESCE_USECS_LOW_HIGH \
(ETHTOOL_COALESCE_RX_USECS_LOW | ETHTOOL_COALESCE_TX_USECS_LOW | \
- ETHTOOL_COALESCE_RX_USECS_HIGH | ETHTOOL_COALESCE_TX_USECS_HIGH)
+ ETHTOOL_COALESCE_RX_USECS_HIGH | ETHTOOL_COALESCE_TX_USECS_HIGH)
#endif
#ifdef NEED_ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH
-#define ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH \
- (ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW | \
- ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW | \
- ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH | \
- ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH)
+#define ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH \
+ (ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW | \
+ ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW | \
+ ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH | \
+ ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH)
#endif
#ifdef NEED_ETHTOOL_COALESCE_PKT_RATE_RX_USECS
-#define ETHTOOL_COALESCE_PKT_RATE_RX_USECS \
- (ETHTOOL_COALESCE_USE_ADAPTIVE_RX | \
- ETHTOOL_COALESCE_RX_USECS_LOW | ETHTOOL_COALESCE_RX_USECS_HIGH | \
- ETHTOOL_COALESCE_PKT_RATE_LOW | ETHTOOL_COALESCE_PKT_RATE_HIGH | \
- ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL)
+#define ETHTOOL_COALESCE_PKT_RATE_RX_USECS \
+ (ETHTOOL_COALESCE_USE_ADAPTIVE_RX | ETHTOOL_COALESCE_RX_USECS_LOW | \
+ ETHTOOL_COALESCE_RX_USECS_HIGH | ETHTOOL_COALESCE_PKT_RATE_LOW | \
+ ETHTOOL_COALESCE_PKT_RATE_HIGH | \
+ ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL)
#endif
/* Include sub-module headers */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.c
index 83ba1abca..ce7556a7e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_coalesce.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -29,35 +22,35 @@
#include "hinic5_ethtool.h"
#include "hinic5_ethtool_coalesce.h"
-#define CHECK_COALESCE_ALIGN(coal, item, unit) \
-do { \
- if ((coal)->item % (unit) != 0) \
- nicif_warn(nic_dev, drv, netdev, \
- "%s in %d units, change to %u\n", \
- #item, (unit), ((coal)->item - \
- (coal)->item % (unit))); \
-} while (0)
-
-#define CHECK_COALESCE_CHANGED(coal, item, unit, ori_val, obj_str) \
-do { \
- if (((coal)->item / (unit)) != (ori_val)) \
- nicif_info(nic_dev, drv, netdev, \
- "Change %s from %d to %u %s\n", \
- #item, (ori_val) * (unit), \
- ((coal)->item - (coal)->item % (unit)), \
- (obj_str)); \
-} while (0)
-
-#define CHECK_PKT_RATE_CHANGED(coal, item, ori_val, obj_str) \
-do { \
- if ((coal)->item != (ori_val)) \
- nicif_info(nic_dev, drv, netdev, \
- "Change %s from %llu to %u %s\n", \
- #item, (ori_val), (coal)->item, (obj_str)); \
-} while (0)
-
-int get_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+#define CHECK_COALESCE_ALIGN(coal, item, unit) \
+ do { \
+ if ((coal)->item % (unit) != 0) \
+ nicif_warn(nic_dev, drv, netdev, \
+ "%s in %d units, change to %u\n", #item, \
+ (unit), \
+ ((coal)->item - (coal)->item % (unit))); \
+ } while (0)
+
+#define CHECK_COALESCE_CHANGED(coal, item, unit, ori_val, obj_str) \
+ do { \
+ if (((coal)->item / (unit)) != (ori_val)) \
+ nicif_info(nic_dev, drv, netdev, \
+ "Change %s from %d to %u %s\n", #item, \
+ (ori_val) * (unit), \
+ ((coal)->item - (coal)->item % (unit)), \
+ (obj_str)); \
+ } while (0)
+
+#define CHECK_PKT_RATE_CHANGED(coal, item, ori_val, obj_str) \
+ do { \
+ if ((coal)->item != (ori_val)) \
+ nicif_info(nic_dev, drv, netdev, \
+ "Change %s from %llu to %u %s\n", #item, \
+ (ori_val), (coal)->item, (obj_str)); \
+ } while (0)
+
+int get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal,
+ u16 queue)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic5_qp_coalesce_info *interrupt_info = NULL;
@@ -75,34 +68,34 @@ int get_coalesce(struct net_device *netdev,
}
/* coalescs_timer is in unit of 5us */
- coal->rx_coalesce_usecs = interrupt_info->rx_coalesce_timer_cfg *
- COALESCE_TIMER_CFG_UNIT;
+ coal->rx_coalesce_usecs =
+ interrupt_info->rx_coalesce_timer_cfg * COALESCE_TIMER_CFG_UNIT;
/* coalescs_frams is in unit of 8 */
- coal->rx_max_coalesced_frames = interrupt_info->rx_pending_limt *
- COALESCE_PENDING_LIMIT_UNIT;
+ coal->rx_max_coalesced_frames =
+ interrupt_info->rx_pending_limt * COALESCE_PENDING_LIMIT_UNIT;
/* tx/rx use the same interrupt */
/* coalescs_timer is in unit of 5us */
- coal->tx_coalesce_usecs = interrupt_info->tx_coalesce_timer_cfg *
- COALESCE_TIMER_CFG_UNIT;
+ coal->tx_coalesce_usecs =
+ interrupt_info->tx_coalesce_timer_cfg * COALESCE_TIMER_CFG_UNIT;
/* coalescs_frams is in unit of 8 */
- coal->tx_max_coalesced_frames = interrupt_info->tx_pending_limt *
- COALESCE_PENDING_LIMIT_UNIT;
+ coal->tx_max_coalesced_frames =
+ interrupt_info->tx_pending_limt * COALESCE_PENDING_LIMIT_UNIT;
coal->use_adaptive_rx_coalesce = nic_dev->adaptive_rx_coal;
coal->pkt_rate_high = (u32)interrupt_info->pkt_rate_high;
- coal->rx_coalesce_usecs_high = interrupt_info->rx_usecs_high *
- COALESCE_TIMER_CFG_UNIT;
+ coal->rx_coalesce_usecs_high =
+ interrupt_info->rx_usecs_high * COALESCE_TIMER_CFG_UNIT;
coal->rx_max_coalesced_frames_high =
- interrupt_info->rx_pending_limt_high *
- COALESCE_PENDING_LIMIT_UNIT;
+ interrupt_info->rx_pending_limt_high *
+ COALESCE_PENDING_LIMIT_UNIT;
coal->pkt_rate_low = (u32)interrupt_info->pkt_rate_low;
- coal->rx_coalesce_usecs_low = interrupt_info->rx_usecs_low *
- COALESCE_TIMER_CFG_UNIT;
+ coal->rx_coalesce_usecs_low =
+ interrupt_info->rx_usecs_low * COALESCE_TIMER_CFG_UNIT;
coal->rx_max_coalesced_frames_low =
- interrupt_info->rx_pending_limt_low *
- COALESCE_PENDING_LIMIT_UNIT;
+ interrupt_info->rx_pending_limt_low *
+ COALESCE_PENDING_LIMIT_UNIT;
return 0;
}
@@ -121,12 +114,15 @@ int set_queue_coalesce(struct hinic5_nic_dev *nic_dev, u16 q_id,
* don't need to set coalesce to hw
*/
if ((test_bit(HINIC5_INTF_UP, &nic_dev->flags) == 0) ||
- q_id >= nic_dev->q_params.num_qps || nic_dev->adaptive_rx_coal != 0)
+ q_id >= nic_dev->q_params.num_qps ||
+ (nic_dev->adaptive_rx_coal != 0))
return 0;
- nic_dev->rxqs[q_id].last_coalesc_timer_cfg = intr_coal->rx_coalesce_timer_cfg;
+ nic_dev->rxqs[q_id].last_coalesc_timer_cfg =
+ intr_coal->rx_coalesce_timer_cfg;
nic_dev->rxqs[q_id].last_pending_limt = intr_coal->rx_pending_limt;
- err = hinic5_set_sq_rq_coalesce_cfg(nic_dev->hwdev, q_id, HINIC5_SQ_RQ_COALESCE, intr_coal);
+ err = hinic5_set_sq_rq_coalesce_cfg(nic_dev->hwdev, q_id,
+ HINIC5_SQ_RQ_COALESCE, intr_coal);
if (err != 0)
nicif_warn(nic_dev, drv, netdev,
"Failed to set queue%u coalesce", q_id);
@@ -186,7 +182,8 @@ int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-void tmp_coal_init(struct ethtool_coalesce *tmp_coal, const struct ethtool_coalesce *coal)
+void tmp_coal_init(struct ethtool_coalesce *tmp_coal,
+ const struct ethtool_coalesce *coal)
{
tmp_coal->cmd = coal->cmd;
tmp_coal->rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -197,18 +194,20 @@ void tmp_coal_init(struct ethtool_coalesce *tmp_coal, const struct ethtool_coale
tmp_coal->pkt_rate_low = coal->pkt_rate_low;
tmp_coal->rx_coalesce_usecs_low = coal->rx_coalesce_usecs_low;
- tmp_coal->rx_max_coalesced_frames_low = coal->rx_max_coalesced_frames_low;
+ tmp_coal->rx_max_coalesced_frames_low =
+ coal->rx_max_coalesced_frames_low;
tmp_coal->pkt_rate_high = coal->pkt_rate_high;
tmp_coal->rx_coalesce_usecs_high = coal->rx_coalesce_usecs_high;
- tmp_coal->rx_max_coalesced_frames_high = coal->rx_max_coalesced_frames_high;
+ tmp_coal->rx_max_coalesced_frames_high =
+ coal->rx_max_coalesced_frames_high;
}
int is_coalesce_legal(struct net_device *netdev,
const struct ethtool_coalesce *coal)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct ethtool_coalesce tmp_coal = {0};
+ struct ethtool_coalesce tmp_coal = { 0 };
if (!HINIC5_SUPPORT_SQ_RQ_CI_COALESCE(nic_dev->hwdev)) {
if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
@@ -217,7 +216,8 @@ int is_coalesce_legal(struct net_device *netdev,
return -EINVAL;
}
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ if (coal->rx_max_coalesced_frames !=
+ coal->tx_max_coalesced_frames) {
nicif_err(nic_dev, drv, netdev,
"tx-frames must be equal to rx-frames\n");
return -EINVAL;
@@ -227,8 +227,9 @@ int is_coalesce_legal(struct net_device *netdev,
tmp_coal_init(&tmp_coal, coal);
if (memcmp(coal, &tmp_coal, sizeof(struct ethtool_coalesce)) != 0) {
- nicif_err(nic_dev, drv, netdev,
- "Only support to change rx/tx-usecs and rx/tx-frames\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Only support to change rx/tx-usecs and rx/tx-frames\n");
return -EOPNOTSUPP;
}
@@ -237,29 +238,29 @@ int is_coalesce_legal(struct net_device *netdev,
if (coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT >=
coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT) {
- nicif_err(nic_dev, drv, netdev,
- "coalesce_usecs_high(%u) must more than coalesce_usecs_low(%u), after dividing %d usecs unit\n",
- coal->rx_coalesce_usecs_high,
- coal->rx_coalesce_usecs_low,
- COALESCE_TIMER_CFG_UNIT);
+ nicif_err(
+ nic_dev, drv, netdev,
+ "coalesce_usecs_high(%u) must more than coalesce_usecs_low(%u), after dividing %d usecs unit\n",
+ coal->rx_coalesce_usecs_high,
+ coal->rx_coalesce_usecs_low, COALESCE_TIMER_CFG_UNIT);
return -EOPNOTSUPP;
}
if (coal->rx_max_coalesced_frames_low / COALESCE_PENDING_LIMIT_UNIT >=
coal->rx_max_coalesced_frames_high / COALESCE_PENDING_LIMIT_UNIT) {
- nicif_err(nic_dev, drv, netdev,
- "coalesced_frames_high(%u) must more than coalesced_frames_low(%u),after dividing %d frames unit\n",
- coal->rx_max_coalesced_frames_high,
- coal->rx_max_coalesced_frames_low,
- COALESCE_PENDING_LIMIT_UNIT);
+ nicif_err(
+ nic_dev, drv, netdev,
+ "coalesced_frames_high(%u) must more than coalesced_frames_low(%u),after dividing %d frames unit\n",
+ coal->rx_max_coalesced_frames_high,
+ coal->rx_max_coalesced_frames_low,
+ COALESCE_PENDING_LIMIT_UNIT);
return -EOPNOTSUPP;
}
if (coal->pkt_rate_low >= coal->pkt_rate_high) {
nicif_err(nic_dev, drv, netdev,
"pkt_rate_high(%u) must more than pkt_rate_low(%u)\n",
- coal->pkt_rate_high,
- coal->pkt_rate_low);
+ coal->pkt_rate_high, coal->pkt_rate_low);
return -EOPNOTSUPP;
}
@@ -304,26 +305,30 @@ void check_coalesce_align(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT);
}
-int check_coalesce_change(struct net_device *netdev,
- u16 queue, const struct ethtool_coalesce *coal)
+int check_coalesce_change(struct net_device *netdev, u16 queue,
+ const struct ethtool_coalesce *coal)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic5_qp_coalesce_info *ori_intr_coal = NULL;
- char obj_str[32] = {0};
+ char obj_str[32] = { 0 };
int ret;
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
- ret = snprintf(obj_str, sizeof(obj_str), "for netdev");
+ ret = snprintf_s(obj_str, sizeof(obj_str), sizeof(obj_str) - 1,
+ "for netdev");
if (ret < 0) {
- nicif_err(nic_dev, drv, netdev, "Copy intr coalesce failed.\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Copy intr coalesce failed.\n");
return -EINVAL;
}
} else {
ori_intr_coal = &nic_dev->intr_coalesce[queue];
- ret = snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
+ ret = snprintf_s(obj_str, sizeof(obj_str), sizeof(obj_str) - 1,
+ "for queue %u", queue);
if (ret < 0) {
- nicif_err(nic_dev, drv, netdev, "Copy intr coalesce failed.\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Copy intr coalesce failed.\n");
return -EINVAL;
}
}
@@ -340,8 +345,8 @@ int check_coalesce_change(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_high,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_high, obj_str);
- CHECK_PKT_RATE_CHANGED(coal, pkt_rate_low,
- ori_intr_coal->pkt_rate_low, obj_str);
+ CHECK_PKT_RATE_CHANGED(coal, pkt_rate_low, ori_intr_coal->pkt_rate_low,
+ obj_str);
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs_low,
COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->rx_usecs_low, obj_str);
@@ -380,8 +385,8 @@ void init_intr_coal_params(struct hinic5_qp_coalesce_info *intr_coal,
COALESCE_PENDING_LIMIT_UNIT);
}
-int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+int set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal,
+ u16 queue)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic5_qp_coalesce_info intr_coal;
@@ -398,15 +403,16 @@ int set_coalesce(struct net_device *netdev,
if (err != 0)
return err;
- memset(&intr_coal, 0, sizeof(intr_coal));
+ (void)memset_s(&intr_coal, sizeof(intr_coal), 0, sizeof(intr_coal));
init_intr_coal_params(&intr_coal, coal);
last_adaptive_rx = nic_dev->adaptive_rx_coal;
nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
- if (nic_dev->adaptive_rx_coal == 0 &&
- (intr_coal.coalesce_timer_cfg == 0 || intr_coal.pending_limt == 0))
+ if ((nic_dev->adaptive_rx_coal == 0) &&
+ ((intr_coal.coalesce_timer_cfg == 0) ||
+ (intr_coal.pending_limt == 0)))
nicif_warn(nic_dev, drv, netdev, "Coalesce will be disabled\n");
/* ensure coalesce paramester will not be changed in auto
@@ -416,9 +422,10 @@ int set_coalesce(struct net_device *netdev,
if (nic_dev->adaptive_rx_coal == 0)
cancel_delayed_work_sync(&nic_dev->moderation_task);
else if (last_adaptive_rx == 0)
- queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->moderation_task,
HINIC5_MODERATONE_DELAY);
}
return set_hw_coal_param(nic_dev, &intr_coal, queue);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.h
index 893e4de84..fd1b7dc60 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_coalesce.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_coalesce.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_COALESCE_H
#define HINIC5_ETHTOOL_COALESCE_H
@@ -19,20 +12,25 @@ struct hinic5_nic_dev;
struct hinic5_qp_coalesce_info;
/* Coalesce configuration functions */
-int get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal, u16 queue);
+int get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal,
+ u16 queue);
int set_queue_coalesce(struct hinic5_nic_dev *nic_dev, u16 q_id,
const struct hinic5_qp_coalesce_info *coal);
int is_coalesce_exceed_limit(struct net_device *netdev,
const struct ethtool_coalesce *coal);
-void tmp_coal_init(struct ethtool_coalesce *tmp_coal, const struct ethtool_coalesce *coal);
-int is_coalesce_legal(struct net_device *netdev, const struct ethtool_coalesce *coal);
+void tmp_coal_init(struct ethtool_coalesce *tmp_coal,
+ const struct ethtool_coalesce *coal);
+int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal);
int set_hw_coal_param(struct hinic5_nic_dev *nic_dev,
struct hinic5_qp_coalesce_info *intr_coal, u16 queue);
-void check_coalesce_align(struct net_device *netdev, const struct ethtool_coalesce *coal);
+void check_coalesce_align(struct net_device *netdev,
+ const struct ethtool_coalesce *coal);
int check_coalesce_change(struct net_device *netdev, u16 queue,
const struct ethtool_coalesce *coal);
void init_intr_coal_params(struct hinic5_qp_coalesce_info *intr_coal,
struct ethtool_coalesce *coal);
-int set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal, u16 queue);
+int set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coal,
+ u16 queue);
#endif /* HINIC5_ETHTOOL_COALESCE_H */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.c
index b2b268219..8f3a65172 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_lb_test.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -35,7 +28,6 @@ void hinic5_run_lp_init_data(struct ethhdr *eth_hdr, struct sk_buff *skb_tmp,
{
u32 i;
u8 *test_data = NULL;
-
eth_hdr = __skb_put(skb_tmp, ETH_HLEN);
eth_hdr->h_proto = htons(ETH_P_ARP);
ether_addr_copy(eth_hdr->h_dest, nic_dev->netdev->dev_addr);
@@ -51,6 +43,90 @@ void hinic5_run_lp_init_data(struct ethhdr *eth_hdr, struct sk_buff *skb_tmp,
skb_tmp->protocol = htons(ETH_P_ARP);
}
+static int hinic5_lp_send_packets(struct hinic5_nic_dev *nic_dev,
+ struct net_device *netdev,
+ struct sk_buff *skb_tmp)
+{
+ u8 j;
+ struct sk_buff *skb = NULL;
+
+ for (j = 0; j < LP_PKT_CNT; j++) {
+ skb = pskb_copy(skb_tmp, GFP_ATOMIC);
+ if (!skb) {
+ nicif_err(nic_dev, drv, netdev,
+ "Copy skb failed for loopback test\n");
+ return -ENOMEM;
+ }
+
+ /* mark index for every pkt */
+ skb->data[LP_PKT_LEN - 1] = j;
+
+ if (hinic5_lb_xmit_frame(skb, netdev) != NETDEV_TX_OK) {
+ dev_kfree_skb_any(skb);
+ nicif_err(nic_dev, drv, netdev,
+ "Xmit pkt failed for loopback test\n");
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic5_lp_verify_packets(struct hinic5_nic_dev *nic_dev,
+ u8 *lb_test_rx_buf, u8 *pkt_data,
+ u32 loop_idx)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 j;
+
+ for (j = 0; j < LP_PKT_CNT; j++) {
+ u8 *pkt_ptr = lb_test_rx_buf + (u16)(j * LP_PKT_LEN);
+
+ if ((memcmp(pkt_ptr, pkt_data, (LP_PKT_LEN - 1)) != 0) ||
+ (*(pkt_ptr + (LP_PKT_LEN - 1)) != j)) {
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Compare pkt failed in loopback test(index=0x%02x, data[%d]=0x%02x)\n",
+ (j + (loop_idx * LP_PKT_CNT)), (LP_PKT_LEN - 1),
+ *(pkt_ptr + (LP_PKT_LEN - 1)));
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic5_lp_run_test_loop(struct hinic5_nic_dev *nic_dev,
+ struct net_device *netdev,
+ struct sk_buff *skb_tmp, u8 *lb_test_rx_buf,
+ u32 cnt)
+{
+ u32 i;
+ int err;
+
+ for (i = 0; i < cnt; i++) {
+ nic_dev->lb_test_rx_idx = 0;
+ (void)memset_s(lb_test_rx_buf, LP_PKT_CNT * LP_PKT_LEN, 0,
+ LP_PKT_CNT * LP_PKT_LEN);
+
+ /* Send packets */
+ err = hinic5_lp_send_packets(nic_dev, netdev, skb_tmp);
+ if (err != 0)
+ return err;
+
+ /* Wait for packets to be received */
+ msleep(HINIC5_WAIT_PKTS_TO_RX_BUFFER);
+
+ /* Verify received packets */
+ err = hinic5_lp_verify_packets(nic_dev, lb_test_rx_buf,
+ skb_tmp->data, i);
+ if (err != 0)
+ return err;
+ }
+
+ return 0;
+}
+
int hinic5_run_lp_test(struct hinic5_nic_dev *nic_dev, u32 test_time)
{
u8 *lb_test_rx_buf = nic_dev->lb_test_rx_buf;
@@ -58,57 +134,23 @@ int hinic5_run_lp_test(struct hinic5_nic_dev *nic_dev, u32 test_time)
u32 cnt = test_time * TEST_TIME_MULTIPLE;
struct sk_buff *skb_tmp = NULL;
struct ethhdr *eth_hdr = NULL;
- struct sk_buff *skb = NULL;
- u32 i;
- u8 j;
+ int err;
skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ nicif_err(nic_dev, drv, netdev,
+ "Alloc xmit skb template failed for loopback test\n");
return -ENOMEM;
+ }
hinic5_run_lp_init_data(eth_hdr, skb_tmp, nic_dev);
- for (i = 0; i < cnt; i++) {
- nic_dev->lb_test_rx_idx = 0;
- memset(lb_test_rx_buf, 0, LP_PKT_CNT * LP_PKT_LEN);
-
- for (j = 0; j < LP_PKT_CNT; j++) {
- skb = pskb_copy(skb_tmp, GFP_ATOMIC);
- if (!skb) {
- dev_kfree_skb_any(skb_tmp);
- nicif_err(nic_dev, drv, netdev,
- "Copy skb failed for loopback test\n");
- return -ENOMEM;
- }
-
- /* mark index for every pkt */
- skb->data[LP_PKT_LEN - 1] = j;
-
- if (hinic5_lb_xmit_frame(skb, netdev) != NETDEV_TX_OK) {
- dev_kfree_skb_any(skb);
- dev_kfree_skb_any(skb_tmp);
- nicif_err(nic_dev, drv, netdev,
- "Xmit pkt failed for loopback test\n");
- return -EBUSY;
- }
- }
-
- /* wait till all pkts received to RX buffer */
- msleep(HINIC5_WAIT_PKTS_TO_RX_BUFFER);
-
- for (j = 0; j < LP_PKT_CNT; j++) {
- if ((memcmp((lb_test_rx_buf + (u16)(j * LP_PKT_LEN)),
- skb_tmp->data, (LP_PKT_LEN - 1)) != 0) ||
- (*(lb_test_rx_buf + (u16)((j * LP_PKT_LEN) + (LP_PKT_LEN - 1))) != j)) {
- dev_kfree_skb_any(skb_tmp);
- nicif_err(nic_dev, drv, netdev,
- "Compare pkt failed in loopback test(index=0x%02x, data[%d]=0x%02x)\n",
- (j + (i * LP_PKT_CNT)), (LP_PKT_LEN - 1),
- *((lb_test_rx_buf + ((u64)j * LP_PKT_LEN)) +
- (LP_PKT_LEN - 1)));
- return -EIO;
- }
- }
+ /* Run test for specified time */
+ err = hinic5_lp_run_test_loop(nic_dev, netdev, skb_tmp, lb_test_rx_buf,
+ cnt);
+ if (err != 0) {
+ dev_kfree_skb_any(skb_tmp);
+ return err;
}
dev_kfree_skb_any(skb_tmp);
@@ -116,80 +158,126 @@ int hinic5_run_lp_test(struct hinic5_nic_dev *nic_dev, u32 test_time)
return 0;
}
-int do_lp_test(struct hinic5_nic_dev *nic_dev, u32 *flags, u32 test_time,
- enum diag_test_index *test_index)
+static int hinic5_lp_save_veb_offload(struct hinic5_nic_dev *nic_dev,
+ u16 *cur_veb_offload)
+{
+ int err;
+
+ if (!HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, VEB_OFFLOAD))
+ return 0;
+
+ err = hinic5_get_veb_offload(nic_dev->hwdev, cur_veb_offload);
+ if (err != 0)
+ return err;
+
+ if (*cur_veb_offload != 0)
+ return hinic5_set_veb_offload(nic_dev->hwdev, 0);
+
+ return 0;
+}
+
+static int hinic5_lp_restore_veb_offload(struct hinic5_nic_dev *nic_dev,
+ u16 cur_veb_offload)
+{
+ if (cur_veb_offload != 0)
+ return hinic5_set_veb_offload(nic_dev->hwdev, cur_veb_offload);
+
+ return 0;
+}
+
+static int hinic5_lp_prepare_internal_test(struct hinic5_nic_dev *nic_dev,
+ enum diag_test_index *test_index)
{
- struct net_device *netdev = nic_dev->netdev;
- u8 *lb_test_rx_buf = NULL;
- u16 cur_veb_offload = 0;
- int err = 0;
u16 glb_func_id;
+ int err;
- if (HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, VEB_OFFLOAD)) {
- err = hinic5_get_veb_offload(nic_dev->hwdev, &cur_veb_offload);
- if (err != 0)
- goto err_out;
+ *test_index = INTERNAL_LP_TEST;
- if (cur_veb_offload != 0) {
- err = hinic5_set_veb_offload(nic_dev->hwdev, 0);
- if (err != 0)
- goto err_out;
- }
+ if (hinic5_set_loopback_mode(nic_dev->hwdev, HINIC5_INTERNAL_LP_MODE,
+ true)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to set port loopback mode before loopback test\n");
+ return -EFAULT;
}
- if ((*flags & ETH_TEST_FL_EXTERNAL_LB) == 0) {
- *test_index = INTERNAL_LP_TEST;
- if (hinic5_set_loopback_mode(nic_dev->hwdev,
- HINIC5_INTERNAL_LP_MODE, true)) {
- nicif_err(nic_dev, drv, netdev,
- "Failed to set port loopback mode before loopback test\n");
- err = -EFAULT;
- goto restore_veb_offload;
- }
+ glb_func_id = hinic5_global_func_id(nic_dev->hwdev);
- glb_func_id = hinic5_global_func_id(nic_dev->hwdev);
-
- err = hinic5_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
- HINIC5_CHANNEL_NIC);
- if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to disable vport\n");
- goto restore_veb_offload;
- }
+ err = hinic5_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
+ HINIC5_CHANNEL_NIC);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to disable vport\n");
+ return err;
+ }
- msleep(nic_dev->timeout.wait_flush_qp_res_timeout);
+ msleep(nic_dev->timeout.wait_flush_qp_res_timeout);
- err = hinic5_set_vport_enable(nic_dev->hwdev, glb_func_id, true,
- HINIC5_CHANNEL_NIC);
- if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to enable vport\n");
- goto restore_veb_offload;
- }
- } else {
- *test_index = EXTERNAL_LP_TEST;
+ err = hinic5_set_vport_enable(nic_dev->hwdev, glb_func_id, true,
+ HINIC5_CHANNEL_NIC);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to enable vport\n");
+ return err;
}
+ return 0;
+}
+
+static int hinic5_lp_alloc_and_run_test(struct hinic5_nic_dev *nic_dev,
+ u32 test_time)
+{
+ u8 *lb_test_rx_buf = NULL;
+ int err = 0;
+
lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
if (!lb_test_rx_buf) {
- err = -ENOMEM;
- } else {
- nic_dev->lb_test_rx_buf = lb_test_rx_buf;
- nic_dev->lb_pkt_len = LP_PKT_LEN;
- set_bit(HINIC5_LP_TEST, &nic_dev->flags);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc RX buffer for loopback test\n");
+ return -ENOMEM;
+ }
- if (hinic5_run_lp_test(nic_dev, test_time) != 0)
- err = -EFAULT;
+ nic_dev->lb_test_rx_buf = lb_test_rx_buf;
+ nic_dev->lb_pkt_len = LP_PKT_LEN;
+ set_bit(HINIC5_LP_TEST, &nic_dev->flags);
- clear_bit(HINIC5_LP_TEST, &nic_dev->flags);
- msleep(HINIC5_WAIT_CLEAR_LP_TEST);
- vfree(lb_test_rx_buf);
- nic_dev->lb_test_rx_buf = NULL;
+ err = hinic5_run_lp_test(nic_dev, test_time);
+
+ clear_bit(HINIC5_LP_TEST, &nic_dev->flags);
+ msleep(HINIC5_WAIT_CLEAR_LP_TEST);
+ vfree(lb_test_rx_buf);
+ nic_dev->lb_test_rx_buf = NULL;
+
+ return err;
+}
+
+int do_lp_test(struct hinic5_nic_dev *nic_dev, u32 *flags, u32 test_time,
+ enum diag_test_index *test_index)
+{
+ u16 cur_veb_offload = 0;
+ int err;
+
+ /* Save and disable VEB offload if supported */
+ err = hinic5_lp_save_veb_offload(nic_dev, &cur_veb_offload);
+ if (err != 0)
+ return err;
+
+ /* Prepare loopback test based on type */
+ if ((*flags & ETH_TEST_FL_EXTERNAL_LB) == 0) {
+ err = hinic5_lp_prepare_internal_test(nic_dev, test_index);
+ if (err != 0)
+ goto restore_veb_offload;
+ } else {
+ *test_index = EXTERNAL_LP_TEST;
}
+ /* Allocate buffer and run loopback test */
+ err = hinic5_lp_alloc_and_run_test(nic_dev, test_time);
+
+ /* Clean up after test */
if ((*flags & ETH_TEST_FL_EXTERNAL_LB) == 0) {
if (hinic5_set_loopback_mode(nic_dev->hwdev,
HINIC5_INTERNAL_LP_MODE, false)) {
- nicif_err(nic_dev, drv, netdev,
- "Failed to cancel port loopback mode after loopback test\n");
err = -EFAULT;
}
} else {
@@ -197,9 +285,10 @@ int do_lp_test(struct hinic5_nic_dev *nic_dev, u32 *flags, u32 test_time,
}
restore_veb_offload:
- if (cur_veb_offload != 0)
- err = hinic5_set_veb_offload(nic_dev->hwdev, cur_veb_offload);
-err_out:
+ if (hinic5_lp_restore_veb_offload(nic_dev, cur_veb_offload)) {
+ err = -EFAULT;
+ }
+
return err;
}
@@ -214,8 +303,9 @@ void hinic5_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
/* don't support loopback test when netdev is closed. */
if (test_bit(HINIC5_INTF_UP, &nic_dev->flags) == 0) {
- nicif_err(nic_dev, drv, netdev,
- "Do not support loopback test when netdev is closed\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Do not support loopback test when netdev is closed\n");
eth_test->flags |= ETH_TEST_FL_FAILED;
data[PORT_DOWN_ERR_IDX] = 1;
return;
@@ -226,7 +316,8 @@ void hinic5_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags, test_time_real,
+ &test_index);
if (err != 0) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -235,14 +326,15 @@ void hinic5_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
netif_tx_wake_all_queues(netdev);
err = hinic5_get_link_state(nic_dev->hwdev, &link_status);
- if (err == 0 && link_status != 0)
+ if ((err == 0) && (link_status != 0))
netif_carrier_on(netdev);
}
-void hinic5_diag_test(struct net_device *netdev,
- struct ethtool_test *eth_test, u64 *data)
+void hinic5_diag_test(struct net_device *netdev, struct ethtool_test *eth_test,
+ u64 *data)
{
- memset(data, 0, DIAG_TEST_MAX * sizeof(u64));
+ (void)memset_s(data, DIAG_TEST_MAX * sizeof(u64), 0,
+ DIAG_TEST_MAX * sizeof(u64));
hinic5_lp_test(netdev, eth_test, data, 0);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.h
index e204b5863..0ba0bcc5d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_lb_test.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_lb_test.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_LB_TEST_H
#define HINIC5_ETHTOOL_LB_TEST_H
@@ -15,9 +8,9 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#define PORT_DOWN_ERR_IDX 0
-#define LP_DEFAULT_TIME 5 /* seconds */
-#define TEST_TIME_MULTIPLE 5
+#define PORT_DOWN_ERR_IDX 0
+#define LP_DEFAULT_TIME 5 /* seconds */
+#define TEST_TIME_MULTIPLE 5
#define HINIC5_INTERNAL_LP_MODE 5
enum diag_test_index {
@@ -39,4 +32,4 @@ void hinic5_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
void hinic5_diag_test(struct net_device *netdev, struct ethtool_test *eth_test,
u64 *data);
-#endif /* HINIC5_ETHTOOL_LB_TEST_H */
+#endif /* HINIC5_ETHTOOL_LB_TEST_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.c
index de3aa1671..b39acd9c4 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_link_stats.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -31,9 +24,9 @@
#include "hinic5_rx.h"
#include "hinic5_ethtool_link_stats.h"
-#define HINIC_ETHTOOL_FEC_INFO_LEN 6
-#define HINIC_SUPPORTED_FEC_CMD 0
-#define HINIC_ADVERTISED_FEC_CMD 1
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
struct hinic5_ethtool_fec {
u8 hinic_fec_offset;
@@ -41,18 +34,15 @@ struct hinic5_ethtool_fec {
};
static struct hinic5_ethtool_fec hinic5_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
- {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the
- * corresponding enumeration variable
- */
- {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
- {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
- {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
- {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT:
- * Available only in later versions
- */
- {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the
- * corresponding enumeration variable
- */
+ { PORT_FEC_NOT_SET,
+ 0xFF }, /* The ethtool does not have the corresponding enumeration variable */
+ { PORT_FEC_RSFEC, 0x32 }, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ { PORT_FEC_BASEFEC, 0x33 }, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ { PORT_FEC_NOFEC, 0x31 }, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ { PORT_FEC_LLRSFEC,
+ 0x4A }, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ { PORT_FEC_AUTO,
+ 0XFF } /* The ethtool does not have the corresponding enumeration variable */
};
static const u32 hinic5_mag_link_mode_ge[] = {
@@ -207,28 +197,30 @@ static const struct hw2ethtool_link_mode
},
};
-static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
- u32 mode)
+static void
+ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
link_settings->supported);
}
}
-static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
- u32 mode)
+static void
+ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
link_settings->advertising);
@@ -237,9 +229,9 @@ static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *lin
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
- (u32)SPEED_UNKNOWN, SPEED_10, SPEED_100, SPEED_1000, SPEED_10000,
- SPEED_25000, SPEED_40000, SPEED_50000, SPEED_100000, SPEED_200000,
- SPEED_400000, SPEED_800000,
+ (u32)SPEED_UNKNOWN, SPEED_10, SPEED_100, SPEED_1000,
+ SPEED_10000, SPEED_25000, SPEED_40000, SPEED_50000,
+ SPEED_100000, SPEED_200000, SPEED_400000, SPEED_800000,
};
static int hinic5_ethtool_to_hw_speed_level(u32 speed)
@@ -254,17 +246,20 @@ static int hinic5_ethtool_to_hw_speed_level(u32 speed)
return i;
}
-static void hinic5_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
- u32 hw_link_mode, u32 name)
+static void
+hinic5_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
+ u32 hw_link_mode, u32 name)
{
u32 link_mode;
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if ((hw_link_mode & BIT(link_mode)) != 0) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_supported_speed_link_mode(link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ethtool_add_advertised_speed_link_mode(link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -286,11 +281,11 @@ static int hinic5_link_speed_set(struct hinic5_nic_dev *nic_dev,
GET_ADVERTISED_MODE);
err = hinic5_get_link_state(nic_dev->hwdev, &link_state);
- if (err == 0 && link_state != 0) {
+ if ((err == 0) && (link_state != 0)) {
link_settings->speed =
port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
link_settings->duplex = port_info->duplex;
} else {
@@ -340,7 +335,7 @@ static void hinic5_link_port_type(struct cmd_link_settings *link_settings,
static int get_link_pause_settings(struct hinic5_nic_dev *nic_dev,
struct cmd_link_settings *link_settings)
{
- struct nic_pause_config nic_pause = {0};
+ struct nic_pause_config nic_pause = { 0 };
int err;
err = hinic5_get_pause_info(nic_dev->hwdev, &nic_pause);
@@ -351,7 +346,7 @@ static int get_link_pause_settings(struct hinic5_nic_dev *nic_dev,
}
ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
- if (nic_pause.rx_pause != 0 && nic_pause.tx_pause != 0) {
+ if ((nic_pause.rx_pause != 0) && (nic_pause.tx_pause != 0)) {
ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause != 0) {
ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
@@ -370,22 +365,27 @@ static bool is_bit_offset_defined(u8 bit_offset)
return false;
}
-static void ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
- u32 fec, u8 cmd)
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
{
u8 i;
-
for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
- if ((fec & BIT(hinic5_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ if ((fec & BIT(hinic5_ethtool_fec_info[i].hinic_fec_offset)) ==
+ 0)
continue;
- if (is_bit_offset_defined(hinic5_ethtool_fec_info[i].ethtool_bit_offset) &&
- cmd == HINIC_ADVERTISED_FEC_CMD) {
+ if ((is_bit_offset_defined(
+ hinic5_ethtool_fec_info[i].ethtool_bit_offset) ==
+ true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
set_bit(hinic5_ethtool_fec_info[i].ethtool_bit_offset,
link_settings->advertising);
return; /* There can be only one advertised fec mode. */
}
- if (is_bit_offset_defined(hinic5_ethtool_fec_info[i].ethtool_bit_offset) &&
- cmd == HINIC_SUPPORTED_FEC_CMD)
+ if ((is_bit_offset_defined(
+ hinic5_ethtool_fec_info[i].ethtool_bit_offset) ==
+ true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
set_bit(hinic5_ethtool_fec_info[i].ethtool_bit_offset,
link_settings->supported);
}
@@ -394,20 +394,25 @@ static void ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_
static void hinic5_link_fec_type(struct cmd_link_settings *link_settings,
u32 fec, u32 supported_fec)
{
- ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
- ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
}
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
int err;
err = hinic5_get_port_info(nic_dev->hwdev, &port_info,
HINIC5_CHANNEL_NIC);
if (err != 0) {
+ if (err == -EOPNOTSUPP) {
+ return err;
+ }
nicif_err(nic_dev, drv, netdev, "Failed to get port info\n");
return err;
}
@@ -418,13 +423,13 @@ static int get_link_settings(struct net_device *netdev,
hinic5_link_port_type(link_settings, port_info.port_type);
- /* port_info.fec is bit offset, value is BIT(port_info.fec);
- * but port_info.supported_fec_mode is bit value
- */
- hinic5_link_fec_type(link_settings, BIT(port_info.fec), port_info.supported_fec_mode);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec); but port_info.supported_fec_mode is bit value */
+ hinic5_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
- AUTONEG_ENABLE : AUTONEG_DISABLE;
+ AUTONEG_ENABLE :
+ AUTONEG_DISABLE;
if (port_info.autoneg_cap != 0)
ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
@@ -490,31 +495,33 @@ static int hinic5_is_speed_legal(struct hinic5_nic_dev *nic_dev,
if (port_info->supported_mode == LINK_MODE_UNKNOWN ||
port_info->advertised_mode == LINK_MODE_UNKNOWN) {
- nicif_err(nic_dev, drv, netdev, "Unknown supported link modes\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Unknown supported link modes\n");
return -EAGAIN;
}
speed_level = hinic5_ethtool_to_hw_speed_level(speed);
if (speed_level >= PORT_SPEED_UNKNOWN ||
!hinic5_is_support_speed(port_info->supported_mode, speed)) {
- nicif_err(nic_dev, drv, netdev,
- "Not supported speed: %u\n", speed);
+ nicif_err(nic_dev, drv, netdev, "Not supported speed: %u\n",
+ speed);
return -EINVAL;
}
return 0;
}
-static int get_link_settings_type(struct hinic5_nic_dev *nic_dev,
- u8 autoneg, u32 speed, u32 *set_settings)
+static int get_link_settings_type(struct hinic5_nic_dev *nic_dev, u8 autoneg,
+ u32 speed, u32 *set_settings)
{
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
int err;
err = hinic5_get_port_info(nic_dev->hwdev, &port_info,
HINIC5_CHANNEL_NIC);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to get current settings\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to get current settings\n");
return -EAGAIN;
}
@@ -524,7 +531,8 @@ static int get_link_settings_type(struct hinic5_nic_dev *nic_dev,
if (autoneg == AUTONEG_ENABLE) {
if (port_info.autoneg_cap == 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Not support autoneg\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Not support autoneg\n");
return -EOPNOTSUPP;
}
} else if (speed != (u32)SPEED_UNKNOWN) {
@@ -535,7 +543,8 @@ static int get_link_settings_type(struct hinic5_nic_dev *nic_dev,
*set_settings |= HILINK_LINK_SET_SPEED;
} else {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Need to set speed when autoneg is off\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Need to set speed when autoneg is off\n");
return -EOPNOTSUPP;
}
@@ -546,22 +555,25 @@ static int hinic5_set_settings_to_hw(struct hinic5_nic_dev *nic_dev,
u32 set_settings, u8 autoneg, u32 speed)
{
struct net_device *netdev = nic_dev->netdev;
- struct hinic5_link_ksettings settings = {0};
+ struct hinic5_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = {0};
- char link_info[128] = {0};
+ char set_link_str[128] = { 0 };
+ char link_info[128] = { 0 };
int err = 0;
- err = snprintf(link_info, sizeof(link_info), "%s",
- (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
- ((bool)autoneg ? "autong enable " : "autong disable ") : "");
+ err = snprintf_s(
+ link_info, sizeof(link_info), sizeof(link_info) - 1, "%s",
+ (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
+ ((bool)autoneg ? "autong enable " : "autong disable ") :
+ "");
if (err < 0)
return -EINVAL;
if ((set_settings & HILINK_LINK_SET_SPEED) != 0) {
speed_level = hinic5_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str),
- "%s speed %u ", link_info, speed);
+ err = snprintf_s(set_link_str, sizeof(set_link_str),
+ sizeof(set_link_str) - 1, "%s speed %u ",
+ link_info, speed);
if (err < 0)
return -EINVAL;
}
@@ -592,10 +604,12 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
return err;
if (set_settings != 0)
- err = hinic5_set_settings_to_hw(nic_dev, set_settings,
- autoneg, speed);
+ err = hinic5_set_settings_to_hw(nic_dev, set_settings, autoneg,
+ speed);
else
- nicif_info(nic_dev, drv, netdev, "Nothing changed, exiting without setting anything\n");
+ nicif_info(
+ nic_dev, drv, netdev,
+ "Nothing changed, exiting without setting anything\n");
return err;
}
@@ -641,4 +655,4 @@ int hinic5_set_settings(struct net_device *netdev,
return set_link_settings(netdev, link_settings->autoneg,
ethtool_cmd_speed(link_settings));
}
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.h
index f7eadfe2f..759648403 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_link_stats.h
@@ -1,15 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_link_stats.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_LINK_STATS_H
-#define HINIC5_ETHTOOL_LINK_STATS_H
+#define HINIC5_ETHTOOL_LINK_STATS_H
#include <linux/types.h>
#include <linux/ethtool.h>
@@ -20,22 +13,22 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-#define GET_SUPPORTED_MODE 0
-#define GET_ADVERTISED_MODE 1
+#define GET_SUPPORTED_MODE 0
+#define GET_ADVERTISED_MODE 1
struct cmd_link_settings {
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
- u32 speed;
- u8 duplex;
- u8 port;
- u8 autoneg;
+ u32 speed;
+ u8 duplex;
+ u8 port;
+ u8 autoneg;
};
-#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
-#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
+#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
+#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.c
index 961f58176..53b6b9e1d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_port_stats.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -33,11 +26,12 @@
#include "hinic5_xdp.h"
#include "hinic5_ethtool_port_stats.h"
-#define HINIC5_NETDEV_STAT(_stat_item) { \
- .name = #_stat_item, \
- .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
- .offset = offsetof(struct rtnl_link_stats64, _stat_item) \
-}
+#define HINIC5_NETDEV_STAT(_stat_item) \
+ { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
+ .offset = offsetof(struct rtnl_link_stats64, _stat_item) \
+ }
static struct hinic5_stats hinic5_netdev_stats[] = {
HINIC5_NETDEV_STAT(rx_packets),
@@ -78,36 +72,27 @@ static struct hinic5_stats hinic5_nic_dev_stats_extern[] = {
};
static struct hinic5_stats hinic5_rx_queue_stats[] = {
- HINIC5_RXQ_STAT(packets),
- HINIC5_RXQ_STAT(bytes),
- HINIC5_RXQ_STAT(errors),
- HINIC5_RXQ_STAT(csum_errors),
- HINIC5_RXQ_STAT(other_errors),
- HINIC5_RXQ_STAT(dropped),
+ HINIC5_RXQ_STAT(packets), HINIC5_RXQ_STAT(bytes),
+ HINIC5_RXQ_STAT(errors), HINIC5_RXQ_STAT(csum_errors),
+ HINIC5_RXQ_STAT(other_errors), HINIC5_RXQ_STAT(dropped),
#ifdef HAVE_XDP_SUPPORT
- HINIC5_RXQ_STAT(xdp_dropped),
- HINIC5_RXQ_STAT(xdp_redirected),
+ HINIC5_RXQ_STAT(xdp_dropped), HINIC5_RXQ_STAT(xdp_redirected),
#endif
HINIC5_RXQ_STAT(rx_buf_empty),
};
static struct hinic5_stats hinic5_rx_queue_stats_extern[] = {
- HINIC5_RXQ_STAT(alloc_skb_err),
- HINIC5_RXQ_STAT(alloc_rx_buf_err),
+ HINIC5_RXQ_STAT(alloc_skb_err), HINIC5_RXQ_STAT(alloc_rx_buf_err),
#ifdef HAVE_XDP_SUPPORT
HINIC5_RXQ_STAT(xdp_large_pkt),
#endif
- HINIC5_RXQ_STAT(restore_drop_sge),
- HINIC5_RXQ_STAT(pkt_mc),
+ HINIC5_RXQ_STAT(restore_drop_sge), HINIC5_RXQ_STAT(pkt_mc),
};
static struct hinic5_stats hinic5_tx_queue_stats[] = {
- HINIC5_TXQ_STAT(packets),
- HINIC5_TXQ_STAT(bytes),
- HINIC5_TXQ_STAT(busy),
- HINIC5_TXQ_STAT(wake),
- HINIC5_TXQ_STAT(dropped),
- HINIC5_TXQ_STAT(unfinished),
+ HINIC5_TXQ_STAT(packets), HINIC5_TXQ_STAT(bytes),
+ HINIC5_TXQ_STAT(busy), HINIC5_TXQ_STAT(wake),
+ HINIC5_TXQ_STAT(dropped), HINIC5_TXQ_STAT(unfinished),
};
#ifdef HAVE_XDP_SUPPORT
@@ -250,33 +235,36 @@ u32 hinic5_get_io_stats_size(const struct hinic5_nic_dev *nic_dev)
u32 count;
count = (u32)(ARRAY_LEN(hinic5_nic_dev_stats) +
- ARRAY_LEN(hinic5_nic_dev_stats_extern) +
- (ARRAY_LEN(hinic5_tx_queue_stats) +
- ARRAY_LEN(hinic5_tx_queue_stats_extern) +
- ARRAY_LEN(hinic5_rx_queue_stats) +
- ARRAY_LEN(hinic5_rx_queue_stats_extern)) * nic_dev->max_qps);
+ ARRAY_LEN(hinic5_nic_dev_stats_extern) +
+ (ARRAY_LEN(hinic5_tx_queue_stats) +
+ ARRAY_LEN(hinic5_tx_queue_stats_extern) +
+ ARRAY_LEN(hinic5_rx_queue_stats) +
+ ARRAY_LEN(hinic5_rx_queue_stats_extern)) *
+ nic_dev->max_qps);
return count;
}
-#define GET_VALUE_OF_PTR(size, ptr) ( \
- (size) == sizeof(u64) ? *(u64 *)(ptr) : \
- (size) == sizeof(u32) ? *(u32 *)(ptr) : \
- (size) == sizeof(u16) ? *(u16 *)(ptr) : *(u8 *)(ptr) \
-)
-
-#define DEV_STATS_PACK(items, item_idx, array, stats_ptr) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC5_SHOW_ITEM_LEN); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+#define GET_VALUE_OF_PTR(size, ptr) \
+ ((size) == sizeof(u64) ? *(u64 *)(ptr) : \
+ (size) == sizeof(u32) ? *(u32 *)(ptr) : \
+ (size) == sizeof(u16) ? *(u16 *)(ptr) : \
+ *(u8 *)(ptr))
+
+#define DEV_STATS_PACK(items, item_idx, array, stats_ptr) \
+ do { \
+ int j; \
+ for (j = 0; j < ARRAY_LEN(array); j++) { \
+ (void)memcpy_s((items)[item_idx].name, \
+ HINIC5_SHOW_ITEM_LEN, (array)[j].name, \
+ HINIC5_SHOW_ITEM_LEN); \
+ (items)[item_idx].hexadecimal = 0; \
+ (items)[item_idx].value = GET_VALUE_OF_PTR( \
+ (array)[j].size, \
+ (char *)(stats_ptr) + (array)[j].offset); \
+ (item_idx)++; \
+ } \
+ } while (0)
int hinic5_rx_queue_stat_pack(struct hinic5_show_item *item,
struct hinic5_stats *stat,
@@ -284,12 +272,14 @@ int hinic5_rx_queue_stat_pack(struct hinic5_show_item *item,
{
int ret;
- ret = snprintf(item->name, HINIC5_SHOW_ITEM_LEN, stat->name, qid);
+ ret = snprintf_s(item->name, HINIC5_SHOW_ITEM_LEN,
+ HINIC5_SHOW_ITEM_LEN - 1, stat->name, qid);
if (ret < 0)
return -EINVAL;
item->hexadecimal = 0;
- item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+ item->value = GET_VALUE_OF_PTR(stat->size,
+ (char *)(rxq_stats) + stat->offset);
return 0;
}
@@ -300,12 +290,14 @@ int hinic5_tx_queue_stat_pack(struct hinic5_show_item *item,
{
int ret;
- ret = snprintf(item->name, HINIC5_SHOW_ITEM_LEN, stat->name, qid);
+ ret = snprintf_s(item->name, HINIC5_SHOW_ITEM_LEN,
+ HINIC5_SHOW_ITEM_LEN - 1, stat->name, qid);
if (ret < 0)
return -EINVAL;
item->hexadecimal = 0;
- item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+ item->value = GET_VALUE_OF_PTR(stat->size,
+ (char *)(txq_stats) + stat->offset);
return 0;
}
@@ -319,39 +311,44 @@ int hinic5_get_io_stats(const struct hinic5_nic_dev *nic_dev, void *stats)
int ret;
DEV_STATS_PACK(items, item_idx, hinic5_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic5_nic_dev_stats_extern, &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic5_nic_dev_stats_extern,
+ &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
for (idx = 0; idx < ARRAY_LEN(hinic5_tx_queue_stats); idx++) {
- ret = hinic5_tx_queue_stat_pack(&items[item_idx++],
- &hinic5_tx_queue_stats[idx],
- &nic_dev->txqs[qid].txq_stats, qid);
+ ret = hinic5_tx_queue_stat_pack(
+ &items[item_idx++], &hinic5_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
if (ret != 0)
return -EINVAL;
- }
+ }
- for (idx = 0; idx < ARRAY_LEN(hinic5_tx_queue_stats_extern); idx++) {
- ret = hinic5_tx_queue_stat_pack(&items[item_idx++],
- &hinic5_tx_queue_stats_extern[idx],
- &nic_dev->txqs[qid].txq_stats, qid);
- if (ret != 0)
- return -EINVAL;
+ for (idx = 0; idx < ARRAY_LEN(hinic5_tx_queue_stats_extern);
+ idx++) {
+ ret = hinic5_tx_queue_stat_pack(
+ &items[item_idx++],
+ &hinic5_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
for (idx = 0; idx < ARRAY_LEN(hinic5_rx_queue_stats); idx++) {
- ret = hinic5_rx_queue_stat_pack(&items[item_idx++],
- &hinic5_rx_queue_stats[idx],
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ ret = hinic5_rx_queue_stat_pack(
+ &items[item_idx++], &hinic5_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
if (ret != 0)
return -EINVAL;
}
- for (idx = 0; idx < ARRAY_LEN(hinic5_rx_queue_stats_extern); idx++) {
- ret = hinic5_rx_queue_stat_pack(&items[item_idx++],
- &hinic5_rx_queue_stats_extern[idx],
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic5_rx_queue_stats_extern);
+ idx++) {
+ ret = hinic5_rx_queue_stat_pack(
+ &items[item_idx++],
+ &hinic5_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
if (ret != 0)
return -EINVAL;
}
@@ -377,7 +374,7 @@ int hinic5_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
xdp_num = nic_dev->q_params.xdp_qps;
count = ARRAY_LEN(hinic5_netdev_stats) +
- ARRAY_LEN(hinic5_nic_dev_stats) +
+ ARRAY_LEN(hinic5_nic_dev_stats) +
ARRAY_LEN(hinic5_port_link_stat) +
ARRAY_LEN(hinic5_function_stats) +
ARRAY_LEN(hinic5_tx_queue_stats) * q_num +
@@ -387,8 +384,9 @@ int hinic5_get_sset_count(struct net_device *netdev, int sset)
count += ARRAY_LEN(hinic5_xdp_tx_queue_stats) * xdp_num;
#endif
- if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
count += ARRAY_LEN(hinic5_port_stats);
+ }
return count;
case ETH_SS_PRIV_FLAGS:
@@ -401,55 +399,61 @@ int hinic5_get_sset_count(struct net_device *netdev, int sset)
static void get_drv_queue_stats(struct hinic5_nic_dev *nic_dev, u64 *data)
{
struct hinic5_txq_stats txq_stats;
-#ifdef HAVE_XDP_SUPPORT
struct hinic5_xdptxq_stats xdptxq_stats;
-#endif
struct hinic5_rxq_stats rxq_stats;
u16 i = 0, j = 0, qid = 0;
char *p = NULL;
- /* 1. Count kernel TX queues (num_qps), display regular statistic fields */
+ /* 1. 统计内核 TX 队列 (num_qps 个),显示常规统计字段 */
for (qid = 0; qid < nic_dev->q_params.num_qps; qid++) {
- if (!nic_dev->txqs)
+ if (nic_dev->txqs == NULL)
break;
hinic5_txq_get_stats(&nic_dev->txqs[qid], &txq_stats);
for (j = 0; j < ARRAY_LEN(hinic5_tx_queue_stats); j++, i++) {
p = (char *)(&txq_stats) +
- hinic5_tx_queue_stats[j].offset;
- data[i] = (hinic5_tx_queue_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ hinic5_tx_queue_stats[j].offset;
+ data[i] =
+ (hinic5_tx_queue_stats[j].size == sizeof(u64)) ?
+ *(u64 *)p :
+ *(u32 *)p;
}
}
- /* 3. Count RX queues (num_qps) (kernel queues only) */
+ /* 3. 统计 RX 队列 (num_qps 个) (仅内核队列) */
for (qid = 0; qid < nic_dev->q_params.num_qps; qid++) {
- if (!nic_dev->rxqs)
+ if (nic_dev->rxqs == NULL)
break;
hinic5_rxq_get_stats(&nic_dev->rxqs[qid], &rxq_stats);
for (j = 0; j < ARRAY_LEN(hinic5_rx_queue_stats); j++, i++) {
p = (char *)(&rxq_stats) +
- hinic5_rx_queue_stats[j].offset;
- data[i] = (hinic5_rx_queue_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ hinic5_rx_queue_stats[j].offset;
+ data[i] =
+ (hinic5_rx_queue_stats[j].size == sizeof(u64)) ?
+ *(u64 *)p :
+ *(u32 *)p;
}
}
- /* 2. Count XDP TX queues (xdp_qps), display XDP-related statistic fields only */
+ /* 2. 统计 XDP TX 队列 (xdp_qps 个),只显示 XDP 相关统计字段 */
#ifdef HAVE_XDP_SUPPORT
for (qid = nic_dev->q_params.num_qps;
- qid < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; qid++) {
- if (!nic_dev->txqs)
+ qid < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ qid++) {
+ if (nic_dev->txqs == NULL)
break;
hinic5_xdptxq_get_stats(&nic_dev->txqs[qid], &xdptxq_stats);
- /* Only display xdp_dropped and xdp_xmits */
- for (j = 0; j < ARRAY_LEN(hinic5_xdp_tx_queue_stats); j++, i++) {
+ /* 只显示 xdp_dropped 和 xdp_xmits */
+ for (j = 0; j < ARRAY_LEN(hinic5_xdp_tx_queue_stats);
+ j++, i++) {
p = (char *)(&xdptxq_stats) +
- hinic5_xdp_tx_queue_stats[j].offset;
+ hinic5_xdp_tx_queue_stats[j].offset;
data[i] = (hinic5_xdp_tx_queue_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ sizeof(u64)) ?
+ *(u64 *)p :
+ *(u32 *)p;
}
}
#endif
@@ -463,9 +467,12 @@ static u16 get_ethtool_port_stats(struct hinic5_nic_dev *nic_dev, u64 *data)
int err;
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic5_port_stats) * sizeof(*data));
+ if (port_stats == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ (void)memset_s(&data[i],
+ ARRAY_LEN(hinic5_port_stats) * sizeof(*data), 0,
+ ARRAY_LEN(hinic5_port_stats) * sizeof(*data));
i += ARRAY_LEN(hinic5_port_stats);
return i;
}
@@ -477,8 +484,9 @@ static u16 get_ethtool_port_stats(struct hinic5_nic_dev *nic_dev, u64 *data)
for (j = 0; j < ARRAY_LEN(hinic5_port_stats); j++, i++) {
p = (char *)(port_stats) + hinic5_port_stats[j].offset;
- data[i] = (hinic5_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ data[i] = (hinic5_port_stats[j].size == sizeof(u64)) ?
+ *(u64 *)p :
+ *(u32 *)p;
}
kfree(port_stats);
@@ -498,11 +506,11 @@ void hinic5_get_ethtool_stats(struct net_device *netdev,
#endif
struct hinic5_nic_stats *nic_stats = NULL;
- struct hinic5_vport_stats vport_stats = {0};
+ struct hinic5_vport_stats vport_stats = { 0 };
u16 i = 0, j = 0;
char *p = NULL;
int err;
- struct hinic5_port_link_stats link_count = {0};
+ struct hinic5_port_link_stats link_count = { 0 };
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -520,7 +528,8 @@ void hinic5_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic5_nic_dev_stats[j].size, p);
}
- err = hinic5_get_link_down_cnt(nic_dev->hwdev, (int *)&link_count.link_down_events_phy);
+ err = hinic5_get_link_down_cnt(nic_dev->hwdev,
+ (int *)&link_count.link_down_events_phy);
if (err != 0)
nicif_err(nic_dev, drv, netdev,
"Failed to get link down counter from fw\n");
@@ -530,7 +539,8 @@ void hinic5_get_ethtool_stats(struct net_device *netdev,
data[i++] = GET_VALUE_OF_PTR(hinic5_port_link_stat[j].size, p);
}
- err = hinic5_get_vport_stats(nic_dev->hwdev, hinic5_global_func_id(nic_dev->hwdev),
+ err = hinic5_get_vport_stats(nic_dev->hwdev,
+ hinic5_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err != 0)
nicif_err(nic_dev, drv, netdev,
@@ -552,19 +562,22 @@ static u16 get_drv_dev_strings(struct hinic5_nic_dev *nic_dev, char *p)
u16 i, cnt = 0;
for (i = 0; i < ARRAY_LEN(hinic5_netdev_stats); i++) {
- memcpy(p, hinic5_netdev_stats[i].name, ETH_GSTRING_LEN);
+ (void)memcpy_s(p, ETH_GSTRING_LEN, hinic5_netdev_stats[i].name,
+ ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
cnt++;
}
for (i = 0; i < ARRAY_LEN(hinic5_nic_dev_stats); i++) {
- memcpy(p, hinic5_nic_dev_stats[i].name, ETH_GSTRING_LEN);
+ (void)memcpy_s(p, ETH_GSTRING_LEN, hinic5_nic_dev_stats[i].name,
+ ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
cnt++;
}
for (i = 0; i < ARRAY_LEN(hinic5_port_link_stat); i++) {
- memcpy(p, hinic5_port_link_stat[i].name, ETH_GSTRING_LEN);
+ (void)memcpy_s(p, ETH_GSTRING_LEN,
+ hinic5_port_link_stat[i].name, ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
cnt++;
}
@@ -577,14 +590,17 @@ static u16 get_hw_stats_strings(struct hinic5_nic_dev *nic_dev, char *p)
u16 i, cnt = 0;
for (i = 0; i < ARRAY_LEN(hinic5_function_stats); i++) {
- memcpy(p, hinic5_function_stats[i].name, ETH_GSTRING_LEN);
+ (void)memcpy_s(p, ETH_GSTRING_LEN,
+ hinic5_function_stats[i].name, ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
cnt++;
}
if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
for (i = 0; i < ARRAY_LEN(hinic5_port_stats); i++) {
- memcpy(p, hinic5_port_stats[i].name, ETH_GSTRING_LEN);
+ (void)memcpy_s(p, ETH_GSTRING_LEN,
+ hinic5_port_stats[i].name,
+ ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
cnt++;
}
@@ -598,41 +614,49 @@ static u16 get_qp_stats_strings(const struct hinic5_nic_dev *nic_dev, char *p)
u16 i = 0, j = 0, cnt = 0;
int err;
- /* 1. Kernel TX queue statistic names (num_qps) */
+ /* 1. 内核 TX 队列统计名称 (num_qps 个) */
for (i = 0; i < nic_dev->q_params.num_qps; i++) {
for (j = 0; j < ARRAY_LEN(hinic5_tx_queue_stats); j++) {
- err = sprintf(p, hinic5_tx_queue_stats[j].name, i);
+ err = sprintf_s(p,
+ sizeof(hinic5_tx_queue_stats[j].name),
+ hinic5_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
- i, j);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ i, j);
p += ETH_GSTRING_LEN;
cnt++;
}
}
- /* 2 RX queue statistic names (kernel queues only) */
+ /* 2 RX 队列统计名称 (仅内核队列) */
for (i = 0; i < nic_dev->q_params.num_qps; i++) {
for (j = 0; j < ARRAY_LEN(hinic5_rx_queue_stats); j++) {
- err = sprintf(p, hinic5_rx_queue_stats[j].name, i);
+ err = sprintf_s(p,
+ sizeof(hinic5_rx_queue_stats[j].name),
+ hinic5_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
- i, j);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ i, j);
p += ETH_GSTRING_LEN;
cnt++;
}
}
- /* 3 XDP TX queue statistic names (xdp_qps) */
+ /* 3 XDP TX 队列统计名称 (xdp_qps 个) */
#ifdef HAVE_XDP_SUPPORT
for (i = 0; i < nic_dev->q_params.xdp_qps; i++) {
for (j = 0; j < ARRAY_LEN(hinic5_xdp_tx_queue_stats); j++) {
- err = sprintf(p, hinic5_xdp_tx_queue_stats[j].name, i);
+ err = sprintf_s(p, ETH_GSTRING_LEN,
+ hinic5_xdp_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to sprintf xdp tx queue stats name, idx_qps: %u, idx_stats: %u\n",
- i, j);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf xdp tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ i, j);
p += ETH_GSTRING_LEN;
cnt++;
}
@@ -650,21 +674,26 @@ void hinic5_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
switch (stringset) {
case ETH_SS_TEST:
- memcpy(data, *g_hinic5_test_strings, sizeof(g_hinic5_test_strings));
+ (void)memcpy_s(data, sizeof(g_hinic5_test_strings),
+ *g_hinic5_test_strings,
+ sizeof(g_hinic5_test_strings));
return;
case ETH_SS_STATS:
offset = get_drv_dev_strings(nic_dev, p);
- offset += get_hw_stats_strings(nic_dev,
- p + (u32)(offset * ETH_GSTRING_LEN));
- get_qp_stats_strings(nic_dev, p + (u32)(offset * ETH_GSTRING_LEN));
+ offset += get_hw_stats_strings(
+ nic_dev, p + (u32)(offset * ETH_GSTRING_LEN));
+ get_qp_stats_strings(nic_dev,
+ p + (u32)(offset * ETH_GSTRING_LEN));
return;
case ETH_SS_PRIV_FLAGS:
- memcpy(data, g_hinic_priv_flags_strings, sizeof(g_hinic_priv_flags_strings));
+ (void)memcpy_s(data, sizeof(g_hinic_priv_flags_strings),
+ g_hinic_priv_flags_strings,
+ sizeof(g_hinic_priv_flags_strings));
return;
default:
- nicif_err(nic_dev, drv, netdev,
- "Invalid string set %u.", stringset);
+ nicif_err(nic_dev, drv, netdev, "Invalid string set %u.",
+ stringset);
return;
}
}
@@ -681,31 +710,36 @@ static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
u8 i;
u8 fec_value_table_lenth;
struct fecparam_value_map fec_value_table[] = {
- {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
- {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
- {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
- {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+ { PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE },
+ { PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS },
+ { PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER },
+ { PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF },
#ifdef ETHTOOL_FEC_LLRS
- {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+ { PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS },
#endif
- {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ { PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO }
};
*out_fec_param = 0;
- fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) /
+ sizeof(struct fecparam_value_map));
if (opcode == MAG_CMD_OPCODE_SET) {
for (i = 0; i < fec_value_table_lenth; i++) {
- if ((in_fec_param & fec_value_table[i].ethtool_fec_value) != 0)
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
/* The MPU uses the offset to determine the FEC mode. */
- *out_fec_param = fec_value_table[i].hinic5_fec_offset;
+ *out_fec_param =
+ fec_value_table[i].hinic5_fec_offset;
}
}
if (opcode == MAG_CMD_OPCODE_GET) {
for (i = 0; i < fec_value_table_lenth; i++) {
- if ((in_fec_param & fec_value_table[i].hinic5_fec_value) != 0)
- *out_fec_param |= fec_value_table[i].ethtool_fec_value;
+ if ((in_fec_param &
+ fec_value_table[i].hinic5_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
}
}
}
@@ -713,17 +747,20 @@ static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
/* When the ethtool is used to set the FEC mode */
static bool check_fecparam_is_valid(u8 fec_param)
{
- if (fec_param == ETHTOOL_FEC_RS ||
- fec_param == ETHTOOL_FEC_BASER ||
+ if (
#ifdef ETHTOOL_FEC_LLRS
- fec_param == ETHTOOL_FEC_LLRS ||
+ (fec_param == ETHTOOL_FEC_LLRS) ||
#endif
- fec_param == ETHTOOL_FEC_OFF)
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
return true;
+ }
return false;
}
-int hinic5_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+int hinic5_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
u8 advertised_fec = 0;
@@ -737,25 +774,29 @@ int hinic5_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecp
}
fecparam_convert(MAG_CMD_OPCODE_GET, BIT(advertised_fec),
- (u8 *)(&fecparam->active_fec));
- fecparam_convert(MAG_CMD_OPCODE_GET, supported_fec, (u8 *)(&fecparam->fec));
+ (u8 *)(&(fecparam->active_fec)));
+ fecparam_convert(MAG_CMD_OPCODE_GET, supported_fec,
+ (u8 *)(&(fecparam->fec)));
nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
return 0;
}
-int hinic5_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+int hinic5_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
int err;
u8 advertised_fec = 0;
if (check_fecparam_is_valid((u8)(fecparam->fec)) == false) {
- nicif_err(nic_dev, drv, netdev, "fec param is invalid, failed to set fec param\n");
+ nicif_err(nic_dev, drv, netdev,
+ "fec param is invalid, failed to set fec param\n");
return -EINVAL;
}
- fecparam_convert(MAG_CMD_OPCODE_SET, (u8)(fecparam->fec), &advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_SET, (u8)(fecparam->fec),
+ &advertised_fec);
err = hinic5_set_fec(nic_dev->hwdev, advertised_fec);
if (err != 0) {
@@ -767,4 +808,3 @@ int hinic5_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecp
return 0;
}
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.h
index 05f5da4bd..5bc349422 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_port_stats.h
@@ -1,15 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_port_stats.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_PORT_STATS_H
-#define HINIC5_ETHTOOL_PORT_STATS_H
+#define HINIC5_ETHTOOL_PORT_STATS_H
#include <linux/kernel.h>
#include <linux/ethtool.h>
@@ -21,7 +14,7 @@
#include "mag_mpu_cmd_defs.h"
#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
+#define EVB_PORT_COUNTER 1
struct hinic5_stats {
char name[ETH_GSTRING_LEN];
@@ -33,48 +26,56 @@ struct hinic5_port_link_stats {
u64 link_down_events_phy;
};
-#define HINIC5_NIC_STAT(_stat_item) { \
- .name = #_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_nic_stats, _stat_item), \
- .offset = offsetof(struct hinic5_nic_stats, _stat_item) \
-}
+#define HINIC5_NIC_STAT(_stat_item) \
+ { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_nic_stats, _stat_item), \
+ .offset = offsetof(struct hinic5_nic_stats, _stat_item) \
+ }
-#define HINIC5_RXQ_STAT(_stat_item) { \
- .name = "rxq%d_"#_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_rxq_stats, _stat_item), \
- .offset = offsetof(struct hinic5_rxq_stats, _stat_item) \
-}
+#define HINIC5_RXQ_STAT(_stat_item) \
+ { \
+ .name = "rxq%d_" #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_rxq_stats, _stat_item), \
+ .offset = offsetof(struct hinic5_rxq_stats, _stat_item) \
+ }
-#define HINIC5_TXQ_STAT(_stat_item) { \
- .name = "txq%d_"#_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_txq_stats, _stat_item), \
- .offset = offsetof(struct hinic5_txq_stats, _stat_item) \
-}
+#define HINIC5_TXQ_STAT(_stat_item) \
+ { \
+ .name = "txq%d_" #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_txq_stats, _stat_item), \
+ .offset = offsetof(struct hinic5_txq_stats, _stat_item) \
+ }
#ifdef HAVE_XDP_SUPPORT
-#define HINIC5_XDPTXQ_STAT(_stat_item) { \
- .name = "txq%d_"#_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_xdptxq_stats, _stat_item), \
- .offset = offsetof(struct hinic5_xdptxq_stats, _stat_item) \
-}
+#define HINIC5_XDPTXQ_STAT(_stat_item) \
+ { \
+ .name = "txq%d_" #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_xdptxq_stats, _stat_item), \
+ .offset = offsetof(struct hinic5_xdptxq_stats, _stat_item) \
+ }
#endif
-#define HINIC5_FUNC_STAT(_stat_item) { \
- .name = #_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_vport_stats, _stat_item), \
- .offset = offsetof(struct hinic5_vport_stats, _stat_item) \
-}
+#define HINIC5_FUNC_STAT(_stat_item) \
+ { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_vport_stats, _stat_item), \
+ .offset = offsetof(struct hinic5_vport_stats, _stat_item) \
+ }
-#define HINIC5_PORT_STAT(_stat_item) { \
- .name = #_stat_item, \
- .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
- .offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
-}
+#define HINIC5_PORT_STAT(_stat_item) \
+ { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
+ }
-#define HINIC5_PORT_LINK_STAT(_stat_item) { \
- .name = #_stat_item, \
- .size = FIELD_SIZEOF(struct hinic5_port_link_stats, _stat_item), \
- .offset = offsetof(struct hinic5_port_link_stats, _stat_item) \
-}
+#define HINIC5_PORT_LINK_STAT(_stat_item) \
+ { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic5_port_link_stats, \
+ _stat_item), \
+ .offset = offsetof(struct hinic5_port_link_stats, _stat_item) \
+ }
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.c
index 9493501d2..7830f4cd3 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_priv_flags.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -59,10 +52,12 @@ int hinic5_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC5_RXQ_RECOVERY, &nic_dev->flags) != 0)
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work,
+ HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
- if (test_and_clear_bit(HINIC5_RXQ_RECOVERY, &nic_dev->flags) == 0)
+ if (test_and_clear_bit(HINIC5_RXQ_RECOVERY, &nic_dev->flags) ==
+ 0)
return 0;
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
nicif_info(nic_dev, drv, netdev, "close rxq recovery\n");
@@ -77,14 +72,16 @@ static int hinic5_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if ((priv_flags & HINIC5_PRIV_FLAGS_SYMM_RSS) != 0) {
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) {
- nicif_err(nic_dev, drv, netdev,
- "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) == 0) {
- nicif_err(nic_dev, drv, netdev,
- "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -103,7 +100,8 @@ static int hinic5_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
int err;
if ((priv_flags & HINIC5_PRIV_FLAGS_LINK_UP) != 0) {
- if (test_and_set_bit(HINIC5_FORCE_LINK_UP, &nic_dev->flags) != 0)
+ if (test_and_set_bit(HINIC5_FORCE_LINK_UP, &nic_dev->flags) !=
+ 0)
return 0;
if (!HINIC5_CHANNEL_RES_VALID(nic_dev))
@@ -117,9 +115,11 @@ static int hinic5_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev))
- hinic5_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic5_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
} else {
- if (test_and_clear_bit(HINIC5_FORCE_LINK_UP, &nic_dev->flags) == 0)
+ if (test_and_clear_bit(HINIC5_FORCE_LINK_UP, &nic_dev->flags) ==
+ 0)
return 0;
if (!HINIC5_CHANNEL_RES_VALID(nic_dev))
@@ -145,11 +145,13 @@ static int hinic5_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
return 0;
netif_carrier_off(netdev);
- nicif_info(nic_dev, link, netdev, "Link state is down\n");
+ nicif_info(nic_dev, link, netdev,
+ "Link state is down\n");
}
if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev))
- hinic5_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic5_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
}
return 0;
@@ -168,4 +170,4 @@ int hinic5_set_priv_flags(struct net_device *netdev, u32 priv_flags)
return err;
return hinic5_set_force_link_flag(netdev, priv_flags);
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.h
index 16e096cc2..f4a614343 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ethtool_priv_flags.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ethtool_priv_flags.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_ETHTOOL_PRIV_FLAGS_H
#define HINIC5_ETHTOOL_PRIV_FLAGS_H
@@ -14,8 +7,8 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#define HINIC5_PRIV_FLAGS_SYMM_RSS BIT(0)
-#define HINIC5_PRIV_FLAGS_LINK_UP BIT(1)
+#define HINIC5_PRIV_FLAGS_SYMM_RSS BIT(0)
+#define HINIC5_PRIV_FLAGS_LINK_UP BIT(1)
#define HINIC5_PRIV_FLAGS_RXQ_RECOVERY BIT(2)
/* Private flags functions - exported for external use */
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.c
index 0e2f88efe..3b02ea0fd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ntuple.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -27,11 +20,13 @@
#include "hinic5_nic_dev.h"
#include "hinic5_ntuple.h"
-static bool flow_bifurcations;
+static bool flow_bifurcations = 0;
module_param(flow_bifurcations, bool, 0444);
-MODULE_PARM_DESC(flow_bifurcations, "flow_bifurcations, 0: UNSUPPORTED, 1: SUPPORTED (default=0)");
+MODULE_PARM_DESC(flow_bifurcations,
+ "flow_bifurcations, 0: UNSUPPORTED, 1: SUPPORTED (default=0)");
-static void tcam_translate_key_y(u8 *key_y, const u8 *src_input, const u8 *mask, u8 len)
+static void tcam_translate_key_y(u8 *key_y, const u8 *src_input, const u8 *mask,
+ u8 len)
{
u8 idx;
@@ -39,7 +34,8 @@ static void tcam_translate_key_y(u8 *key_y, const u8 *src_input, const u8 *mask,
key_y[idx] = src_input[idx] & mask[idx];
}
-static void tcam_translate_key_x(u8 *key_x, const u8 *key_y, const u8 *mask, u8 len)
+static void tcam_translate_key_x(u8 *key_x, const u8 *key_y, const u8 *mask,
+ u8 len)
{
u8 idx;
@@ -50,8 +46,7 @@ static void tcam_translate_key_x(u8 *key_x, const u8 *key_y, const u8 *mask, u8
static void tcam_key_calculate(struct tag_tcam_key *tcam_key,
struct nic_tcam_cfg_rule *fdir_tcam_rule)
{
- tcam_translate_key_y(fdir_tcam_rule->key.y,
- (u8 *)(&tcam_key->key_info),
+ tcam_translate_key_y(fdir_tcam_rule->key.y, (u8 *)(&tcam_key->key_info),
(u8 *)(&tcam_key->key_mask), TCAM_FLOW_KEY_SIZE);
tcam_translate_key_x(fdir_tcam_rule->key.x, fdir_tcam_rule->key.y,
(u8 *)(&tcam_key->key_mask), TCAM_FLOW_KEY_SIZE);
@@ -65,7 +60,7 @@ static int hinic5_base_ipv4_parse(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
u32 temp;
switch (mask->ip4src) {
@@ -81,7 +76,8 @@ static int hinic5_base_ipv4_parse(struct hinic5_nic_dev *nic_dev,
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid src_ip mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid src_ip mask\n");
return -EINVAL;
}
@@ -98,7 +94,8 @@ static int hinic5_base_ipv4_parse(struct hinic5_nic_dev *nic_dev,
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid src_ip mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid src_ip mask\n");
return -EINVAL;
}
@@ -116,7 +113,7 @@ static int hinic5_base_ipv4_htn_parse(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
u32 temp;
switch (mask->ip4src) {
@@ -133,7 +130,8 @@ static int hinic5_base_ipv4_htn_parse(struct hinic5_nic_dev *nic_dev,
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid ipv4_htn src_ip mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid ipv4_htn src_ip mask\n");
return -EINVAL;
}
@@ -150,7 +148,8 @@ static int hinic5_base_ipv4_htn_parse(struct hinic5_nic_dev *nic_dev,
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid ipv4_htn src_ip mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid ipv4_htn src_ip mask\n");
return -EINVAL;
}
@@ -165,17 +164,18 @@ static int hinic5_fdir_tcam_ipv4_l4_htn_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *val = &fs->h_u.tcp_ip4_spec;
int err;
err = hinic5_base_ipv4_htn_parse(nic_dev, fs, tcam_key);
if (err != 0)
return err;
- if (fs->flow_type == TCP_V4_FLOW)
+ if (fs->flow_type == TCP_V4_FLOW) {
tcam_key->key_info_htn.ip_proto = IPPROTO_TCP;
- else
+ } else {
tcam_key->key_info_htn.ip_proto = IPPROTO_UDP;
+ }
tcam_key->key_mask_htn.ip_proto = U8_MAX;
tcam_key->key_mask_htn.dport = mask->pdst;
@@ -192,7 +192,7 @@ static int hinic5_fdir_tcam_ipv4_htn_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_usrip4_spec *l3_mask = &fs->m_u.usr_ip4_spec;
- struct ethtool_usrip4_spec *l3_val = &fs->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *l3_val = &fs->h_u.usr_ip4_spec;
int err;
err = hinic5_base_ipv4_htn_parse(nic_dev, fs, tcam_key);
@@ -210,7 +210,7 @@ static int hinic5_fdir_tcam_ipv4_l4_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip4_spec *l4_mask = &fs->m_u.tcp_ip4_spec;
- struct ethtool_tcpip4_spec *l4_val = &fs->h_u.tcp_ip4_spec;
+ struct ethtool_tcpip4_spec *l4_val = &fs->h_u.tcp_ip4_spec;
int err;
err = hinic5_base_ipv4_parse(nic_dev, fs, tcam_key);
@@ -237,7 +237,7 @@ static int hinic5_fdir_tcam_ipv4_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_usrip4_spec *l3_mask = &fs->m_u.usr_ip4_spec;
- struct ethtool_usrip4_spec *l3_val = &fs->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *l3_val = &fs->h_u.usr_ip4_spec;
int err;
err = hinic5_base_ipv4_parse(nic_dev, fs, tcam_key);
@@ -395,14 +395,15 @@ static int hinic5_base_ipv6_htn_parse(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip6_spec *mask = &fs->m_u.tcp_ip6_spec;
- struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
+ struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
int parse_res;
parse_res = ipv6_mask_parse((u32 *)mask->ip6src);
if (parse_res == IPV6_MASK_ALL_MASK) {
hinic5_ipv6_tcam_key_htn_pares_src(tcam_key, val);
} else if (parse_res == IPV6_MASK_INVALID) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid src_ipv6 mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid src_ipv6 mask\n");
return -EINVAL;
}
@@ -410,7 +411,8 @@ static int hinic5_base_ipv6_htn_parse(struct hinic5_nic_dev *nic_dev,
if (parse_res == IPV6_MASK_ALL_MASK) {
hinic5_ipv6_tcam_key_htn_pares_dst(tcam_key, val);
} else if (parse_res == IPV6_MASK_INVALID) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid dst_ipv6 mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid dst_ipv6 mask\n");
return -EINVAL;
}
@@ -425,17 +427,18 @@ static int hinic5_fdir_tcam_ipv6_l4_htn_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip6_spec *mask = &fs->m_u.tcp_ip6_spec;
- struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
+ struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
int err;
err = hinic5_base_ipv6_htn_parse(nic_dev, fs, tcam_key);
if (err != 0)
return err;
- if (fs->flow_type == TCP_V6_FLOW)
+ if (fs->flow_type == TCP_V6_FLOW) {
tcam_key->key_info_htn.ip_proto = IPPROTO_TCP;
- else
+ } else {
tcam_key->key_info_htn.ip_proto = IPPROTO_UDP;
+ }
tcam_key->key_mask_htn.ip_proto = U8_MAX;
tcam_key->key_mask_htn.dport = mask->pdst;
@@ -452,7 +455,7 @@ static int hinic5_fdir_tcam_ipv6_htn_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_usrip6_spec *mask = &fs->m_u.usr_ip6_spec;
- struct ethtool_usrip6_spec *val = &fs->h_u.usr_ip6_spec;
+ struct ethtool_usrip6_spec *val = &fs->h_u.usr_ip6_spec;
int err;
err = hinic5_base_ipv6_htn_parse(nic_dev, fs, tcam_key);
@@ -470,14 +473,15 @@ static int hinic5_base_ipv6_parse(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_tcpip6_spec *mask = &fs->m_u.tcp_ip6_spec;
- struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
+ struct ethtool_tcpip6_spec *val = &fs->h_u.tcp_ip6_spec;
int parse_res;
parse_res = ipv6_mask_parse((u32 *)mask->ip6src);
if (parse_res == IPV6_MASK_ALL_MASK) {
hinic5_ipv6_tcam_key_pares_src(tcam_key, val);
} else if (parse_res == IPV6_MASK_INVALID) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid src_ipv6 mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid src_ipv6 mask\n");
return -EINVAL;
}
@@ -485,7 +489,8 @@ static int hinic5_base_ipv6_parse(struct hinic5_nic_dev *nic_dev,
if (parse_res == IPV6_MASK_ALL_MASK) {
hinic5_ipv6_tcam_key_pares_dst(tcam_key, val);
} else if (parse_res == IPV6_MASK_INVALID) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "invalid dst_ipv6 mask\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "invalid dst_ipv6 mask\n");
return -EINVAL;
}
@@ -531,7 +536,7 @@ static int hinic5_fdir_tcam_ipv6_init(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key *tcam_key)
{
struct ethtool_usrip6_spec *l3_mask = &fs->m_u.usr_ip6_spec;
- struct ethtool_usrip6_spec *l3_val = &fs->h_u.usr_ip6_spec;
+ struct ethtool_usrip6_spec *l3_val = &fs->h_u.usr_ip6_spec;
int err;
err = hinic5_base_ipv6_parse(nic_dev, fs, tcam_key);
@@ -578,7 +583,7 @@ static int hinic5_fdir_tcam_info_init(struct hinic5_nic_dev *nic_dev,
break;
#endif
default:
- return -EOPNOTSUPP;
+ return -ENOTSUPP;
}
tcam_key->key_info.tunnel_type = 0;
@@ -590,21 +595,22 @@ static int hinic5_fdir_tcam_info_init(struct hinic5_nic_dev *nic_dev,
return 0;
}
-static int hinic5_fdir_tcam_info_htn_init(struct hinic5_nic_dev *nic_dev,
- struct ethtool_rx_flow_spec *fs,
- struct tag_tcam_key *tcam_key,
- struct nic_tcam_cfg_rule *fdir_tcam_rule)
+static int hinic5_fdir_tcam_info_htn_init(
+ struct hinic5_nic_dev *nic_dev, struct ethtool_rx_flow_spec *fs,
+ struct tag_tcam_key *tcam_key, struct nic_tcam_cfg_rule *fdir_tcam_rule)
{
int err;
- if (flow_bifurcations)
+ if (flow_bifurcations == true)
fdir_tcam_rule->data.fdir_info.qid_htn.flag = flow_bifurcations;
tcam_key->key_mask_htn.function_id_h = UINT5_MAX;
tcam_key->key_mask_htn.function_id_l = UINT5_MAX;
- tcam_key->key_info_htn.function_id_l = hinic5_global_func_id(nic_dev->hwdev) & UINT5_MAX;
+ tcam_key->key_info_htn.function_id_l =
+ hinic5_global_func_id(nic_dev->hwdev) & UINT5_MAX;
tcam_key->key_info_htn.function_id_h =
- (hinic5_global_func_id(nic_dev->hwdev) >> UINT5_WIDTH) & UINT5_MAX;
+ (hinic5_global_func_id(nic_dev->hwdev) >> UINT5_WIDTH) &
+ UINT5_MAX;
tcam_key->key_info_htn.tunnel_type = 0;
tcam_key->key_mask_htn.tunnel_type = UINT3_MAX;
@@ -636,7 +642,7 @@ static int hinic5_fdir_tcam_info_htn_init(struct hinic5_nic_dev *nic_dev,
break;
#endif
default:
- return -EOPNOTSUPP;
+ return -ENOTSUPP;
}
fdir_tcam_rule->data.fdir_info.qid_htn.qid = (u32)fs->ring_cookie;
@@ -695,9 +701,11 @@ hinic5_alloc_dynamic_block_resource(struct hinic5_nic_dev *nic_dev,
struct hinic5_tcam_dynamic_block *dynamic_block_ptr = NULL;
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
- if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %u memory failed\n",
- dynamic_block_id);
+ if (dynamic_block_ptr == NULL) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %hu memory failed\n",
+ dynamic_block_id);
return NULL;
}
@@ -710,10 +718,11 @@ hinic5_alloc_dynamic_block_resource(struct hinic5_nic_dev *nic_dev,
return dynamic_block_ptr;
}
-static void hinic5_free_dynamic_block_resource(struct hinic5_tcam_info *tcam_info,
- struct hinic5_tcam_dynamic_block *block_ptr)
+static void
+hinic5_free_dynamic_block_resource(struct hinic5_tcam_info *tcam_info,
+ struct hinic5_tcam_dynamic_block *block_ptr)
{
- if (!block_ptr)
+ if (block_ptr == NULL)
return;
list_del(&block_ptr->block_list);
@@ -734,12 +743,15 @@ hinic5_dynamic_lookup_tcam_filter(struct hinic5_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
- block_list)
- if (!tmp || tmp->dynamic_index_cnt < HINIC5_TCAM_DYNAMIC_BLOCK_SIZE)
+ block_list)
+ if ((tmp == NULL) ||
+ tmp->dynamic_index_cnt < HINIC5_TCAM_DYNAMIC_BLOCK_SIZE)
break;
- if (!tmp || tmp->dynamic_index_cnt >= HINIC5_TCAM_DYNAMIC_BLOCK_SIZE) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Fdir filter dynamic lookup for index failed\n");
+ if ((tmp == NULL) ||
+ tmp->dynamic_index_cnt >= HINIC5_TCAM_DYNAMIC_BLOCK_SIZE) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Fdir filter dynamic lookup for index failed\n");
return NULL;
}
@@ -748,7 +760,8 @@ hinic5_dynamic_lookup_tcam_filter(struct hinic5_nic_dev *nic_dev,
break;
if (index == HINIC5_TCAM_DYNAMIC_BLOCK_SIZE) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "tcam block 0x%x supports filter rules is full\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "tcam block 0x%x supports filter rules is full\n",
tmp->dynamic_block_id);
return NULL;
}
@@ -757,41 +770,46 @@ hinic5_dynamic_lookup_tcam_filter(struct hinic5_nic_dev *nic_dev,
tcam_filter->index = index;
*tcam_index = index;
- fdir_tcam_rule->index = index +
- HINIC5_PKT_TCAM_DYNAMIC_INDEX_START(tmp->dynamic_block_id);
+ fdir_tcam_rule->index = index + HINIC5_PKT_TCAM_DYNAMIC_INDEX_START(
+ tmp->dynamic_block_id);
return tmp;
}
-static int hinic5_tcam_filter_alloc_block(struct hinic5_tcam_info *tcam_info,
- struct hinic5_nic_dev *nic_dev,
+static int hinic5_tcam_filter_alloc_block(
+ struct hinic5_tcam_info *tcam_info, struct hinic5_nic_dev *nic_dev,
u16 *tcam_block_index, int *block_alloc_flag,
- const struct hinic5_tcam_dynamic_block *dynamic_block_ptr)
+ struct hinic5_tcam_dynamic_block **dynamic_block_ptr)
{
int err;
u16 block_cnt = tcam_info->tcam_dynamic_info.dynamic_block_cnt;
-
- if (tcam_info->tcam_rule_nums >= block_cnt * HINIC5_TCAM_DYNAMIC_BLOCK_SIZE) {
- if (block_cnt >= (HINIC5_MAX_TCAM_FILTERS / HINIC5_TCAM_DYNAMIC_BLOCK_SIZE)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Dynamic tcam block is full, alloc failed\n");
+ if (tcam_info->tcam_rule_nums >=
+ block_cnt * HINIC5_TCAM_DYNAMIC_BLOCK_SIZE) {
+ if (block_cnt >= (HINIC5_MAX_TCAM_FILTERS /
+ HINIC5_TCAM_DYNAMIC_BLOCK_SIZE)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Dynamic tcam block is full, alloc failed\n");
return -EFAULT;
}
err = hinic5_alloc_tcam_block(nic_dev->hwdev, tcam_block_index);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Fdir filter dynamic tcam alloc block failed\n");
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Fdir filter dynamic tcam alloc block failed\n");
return -EFAULT;
}
*block_alloc_flag = 1;
- dynamic_block_ptr =
- hinic5_alloc_dynamic_block_resource(nic_dev, tcam_info, *tcam_block_index);
- if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Fdir filter dynamic alloc block memory failed\n");
- hinic5_free_tcam_block(nic_dev->hwdev, tcam_block_index);
+ *dynamic_block_ptr = hinic5_alloc_dynamic_block_resource(
+ nic_dev, tcam_info, *tcam_block_index);
+ if (*dynamic_block_ptr == NULL) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Fdir filter dynamic alloc block memory failed\n");
+ hinic5_free_tcam_block(nic_dev->hwdev,
+ tcam_block_index);
return -EFAULT;
}
}
@@ -810,29 +828,37 @@ static int hinic5_add_tcam_filter(struct hinic5_nic_dev *nic_dev,
u16 index = 0;
int err;
- err = hinic5_tcam_filter_alloc_block(tcam_info, nic_dev, &tcam_block_index,
- &block_alloc_flag, dynamic_block_ptr);
- if (err != 0)
+ err = hinic5_tcam_filter_alloc_block(tcam_info, nic_dev,
+ &tcam_block_index,
+ &block_alloc_flag,
+ &dynamic_block_ptr);
+ if (err != 0) {
return err;
+ }
tmp = hinic5_dynamic_lookup_tcam_filter(nic_dev, fdir_tcam_rule,
tcam_info, tcam_filter, &index);
- if (!tmp) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Dynamic lookup tcam filter failed\n");
+ if (tmp == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Dynamic lookup tcam filter failed\n");
goto lookup_tcam_index_failed;
}
err = hinic5_add_tcam_rule(nic_dev->hwdev, fdir_tcam_rule);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Fdir_tcam_rule add failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Fdir_tcam_rule add failed\n");
goto add_tcam_rules_failed;
}
- nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %hu, local_index: %hu, global_index: %u, queue: %u, tcam_rule_nums: %d succeed\n",
- hinic5_global_func_id(nic_dev->hwdev),
- tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
- fdir_tcam_rule->data.fdir_info.qid, tcam_info->tcam_rule_nums + 1);
+ nicif_info(
+ nic_dev, drv, nic_dev->netdev,
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %hu, local_index: %hu, \
+ global_index: %u, queue: %u, tcam_rule_nums: %d succeed\n",
+ hinic5_global_func_id(nic_dev->hwdev),
+ tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
+ fdir_tcam_rule->data.fdir_info.qid,
+ tcam_info->tcam_rule_nums + 1);
if (tcam_info->tcam_rule_nums == 0) {
err = hinic5_set_fdir_tcam_rule_filter(nic_dev->hwdev, true);
@@ -855,7 +881,8 @@ static int hinic5_add_tcam_filter(struct hinic5_nic_dev *nic_dev,
add_tcam_rules_failed:
lookup_tcam_index_failed:
if (block_alloc_flag == 1) {
- hinic5_free_dynamic_block_resource(tcam_info, dynamic_block_ptr);
+ hinic5_free_dynamic_block_resource(tcam_info,
+ dynamic_block_ptr);
hinic5_free_tcam_block(nic_dev->hwdev, &tcam_block_index);
}
@@ -877,25 +904,28 @@ static int hinic5_del_tcam_filter(struct hinic5_nic_dev *nic_dev,
if (tmp->dynamic_block_id == dynamic_block_id)
break;
}
- if (!tmp || tmp->dynamic_block_id != dynamic_block_id) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Fdir filter del dynamic lookup for block failed\n");
+ if ((tmp == NULL) || tmp->dynamic_block_id != dynamic_block_id) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Fdir filter del dynamic lookup for block failed\n");
return -EFAULT;
}
index = HINIC5_PKT_TCAM_DYNAMIC_INDEX_START(tmp->dynamic_block_id) +
- tcam_filter->index;
+ tcam_filter->index;
err = hinic5_del_tcam_rule(nic_dev->hwdev, index);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir_tcam_rule del failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir_tcam_rule del failed\n");
return -EFAULT;
}
- nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %hu, local_index: %hu, global_index: %u, local_rules_nums: %d, global_rule_nums: %d succeed\n",
- hinic5_global_func_id(nic_dev->hwdev), dynamic_block_id,
- tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
- tcam_info->tcam_rule_nums - 1);
+ nicif_info(
+ nic_dev, drv, nic_dev->netdev,
+ "Del tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %hu, local_index: %hu, global_index: %u, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ hinic5_global_func_id(nic_dev->hwdev), dynamic_block_id,
+ tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
+ tcam_info->tcam_rule_nums - 1);
tmp->dynamic_index_used[tcam_filter->index] = 0;
tmp->dynamic_index_cnt--;
@@ -920,8 +950,8 @@ hinic5_tcam_filter_lookup(const struct list_head *filter_list,
struct hinic5_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
- if (memcmp(key, &iter->tcam_key,
- sizeof(struct tag_tcam_key)) == 0) {
+ if (memcmp(key, &iter->tcam_key, sizeof(struct tag_tcam_key)) ==
+ 0) {
return iter;
}
}
@@ -947,38 +977,42 @@ static int hinic5_remove_one_rule(struct hinic5_nic_dev *nic_dev,
struct tag_tcam_key tcam_key;
int err;
- memset(&fdir_tcam_rule, 0, sizeof(fdir_tcam_rule));
- memset(&tcam_key, 0, sizeof(tcam_key));
+ (void)memset_s(&fdir_tcam_rule, sizeof(fdir_tcam_rule), 0,
+ sizeof(fdir_tcam_rule));
+ (void)memset_s(&tcam_key, sizeof(tcam_key), 0, sizeof(tcam_key));
if (hinic5_support_htn(nic_dev->hwdev)) {
- err = hinic5_fdir_tcam_info_htn_init(nic_dev, ð_rule->flow_spec, &tcam_key,
+ err = hinic5_fdir_tcam_info_htn_init(nic_dev,
+ ð_rule->flow_spec,
+ &tcam_key,
&fdir_tcam_rule);
} else {
- err = hinic5_fdir_tcam_info_init(nic_dev, ð_rule->flow_spec, &tcam_key,
- &fdir_tcam_rule);
+ err = hinic5_fdir_tcam_info_init(nic_dev, ð_rule->flow_spec,
+ &tcam_key, &fdir_tcam_rule);
}
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Init fdir info failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Init fdir info failed\n");
return err;
}
- tcam_filter = hinic5_tcam_filter_lookup(&tcam_info->tcam_list,
- &tcam_key);
- if (!tcam_filter) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Filter does not exists\n");
+ tcam_filter =
+ hinic5_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key);
+ if (tcam_filter == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Filter does not exists\n");
return -EEXIST;
}
err = hinic5_del_tcam_filter(nic_dev, tcam_filter);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Delete tcam filter failed\n");
- goto free_tcam_filter;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Delete tcam filter failed\n");
+ return err;
}
del_ethtool_rule(nic_dev, eth_rule);
-
-free_tcam_filter:
kfree(tcam_filter);
tcam_filter = NULL;
return err;
@@ -999,64 +1033,94 @@ static void add_rule_to_list(struct hinic5_nic_dev *nic_dev,
list_add(&rule->list, head);
}
+static int hinic5_fdir_tcam_rule_init(struct hinic5_nic_dev *nic_dev,
+ struct ethtool_rx_flow_spec *fs,
+ struct tag_tcam_key *tcam_key,
+ struct nic_tcam_cfg_rule *fdir_tcam_rule)
+{
+ if (hinic5_support_htn(nic_dev->hwdev))
+ return hinic5_fdir_tcam_info_htn_init(nic_dev, fs, tcam_key,
+ fdir_tcam_rule);
+
+ return hinic5_fdir_tcam_info_init(nic_dev, fs, tcam_key,
+ fdir_tcam_rule);
+}
+
+static int hinic5_eth_rule_create(struct hinic5_nic_dev *nic_dev,
+ struct ethtool_rx_flow_spec *fs)
+{
+ struct hinic5_ethtool_rx_flow_rule *eth_rule = NULL;
+
+ eth_rule = kzalloc(sizeof(*eth_rule), GFP_KERNEL);
+ if (eth_rule == NULL)
+ return -ENOMEM;
+
+ eth_rule->flow_spec = *fs;
+ add_rule_to_list(nic_dev, eth_rule);
+
+ return 0;
+}
+
static int hinic5_add_one_rule(struct hinic5_nic_dev *nic_dev,
struct ethtool_rx_flow_spec *fs)
{
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
- struct hinic5_ethtool_rx_flow_rule *eth_rule = NULL;
struct hinic5_tcam_filter *tcam_filter = NULL;
struct hinic5_tcam_info *tcam_info = &nic_dev->tcam;
int err;
- memset(&fdir_tcam_rule, 0, sizeof(fdir_tcam_rule));
- memset(&tcam_key, 0, sizeof(tcam_key));
-
- if (hinic5_support_htn(nic_dev->hwdev)) {
- err = hinic5_fdir_tcam_info_htn_init(nic_dev, fs, &tcam_key,
- &fdir_tcam_rule);
- } else {
- err = hinic5_fdir_tcam_info_init(nic_dev, fs, &tcam_key,
- &fdir_tcam_rule);
- }
+ (void)memset_s(&fdir_tcam_rule, sizeof(fdir_tcam_rule), 0,
+ sizeof(fdir_tcam_rule));
+ (void)memset_s(&tcam_key, sizeof(tcam_key), 0, sizeof(tcam_key));
+ /* Initialize TCAM rule based on device type */
+ err = hinic5_fdir_tcam_rule_init(nic_dev, fs, &tcam_key,
+ &fdir_tcam_rule);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Init fdir info failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Init fdir info failed\n");
return err;
}
- tcam_filter = hinic5_tcam_filter_lookup(&tcam_info->tcam_list,
- &tcam_key);
- if (tcam_filter) {
+ /* Check if filter already exists */
+ tcam_filter =
+ hinic5_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key);
+ if (tcam_filter != NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Filter exists\n");
return -EEXIST;
}
+ /* Create and add TCAM filter */
tcam_filter = kzalloc(sizeof(*tcam_filter), GFP_KERNEL);
- if (!tcam_filter)
+ if (tcam_filter == NULL)
return -ENOMEM;
- memcpy(&tcam_filter->tcam_key,
- &tcam_key, sizeof(struct tag_tcam_key));
+
+ if (memcpy_s(&tcam_filter->tcam_key, sizeof(struct tag_tcam_key),
+ &tcam_key, sizeof(struct tag_tcam_key)) != 0) {
+ err = -ENOMEM;
+ goto add_tcam_filter_fail;
+ }
tcam_filter->queue = (u16)fdir_tcam_rule.data.fdir_info.qid;
err = hinic5_add_tcam_filter(nic_dev, tcam_filter, &fdir_tcam_rule);
if (err != 0)
goto add_tcam_filter_fail;
- /* driver save new rule filter */
- eth_rule = kzalloc(sizeof(*eth_rule), GFP_KERNEL);
- if (!eth_rule) {
- err = -ENOMEM;
- goto alloc_eth_rule_fail;
- }
-
- eth_rule->flow_spec = *fs;
- add_rule_to_list(nic_dev, eth_rule);
+ /* Create eth rule and add to list */
+ if (hinic5_eth_rule_create(nic_dev, fs))
+ goto hinic5_create_eth_rule_fail;
return 0;
-alloc_eth_rule_fail:
- hinic5_del_tcam_filter(nic_dev, tcam_filter);
+hinic5_create_eth_rule_fail:
+ err = hinic5_del_tcam_filter(nic_dev, tcam_filter);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Delete tcam filter failed\n");
+ return err;
+ }
+
add_tcam_filter_fail:
kfree(tcam_filter);
tcam_filter = NULL;
@@ -1079,13 +1143,15 @@ static int validate_flow(struct hinic5_nic_dev *nic_dev,
const struct ethtool_rx_flow_spec *fs)
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "loc exceed limit[0,%lu]\n",
MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
return -EINVAL;
}
if (fs->ring_cookie >= nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "action is larger than queue number %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "action is larger than queue number %u\n",
nic_dev->q_params.num_qps);
return -EINVAL;
}
@@ -1101,8 +1167,9 @@ static int validate_flow(struct hinic5_nic_dev *nic_dev,
#endif
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "flow type is not supported\n");
- return -EOPNOTSUPP;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "flow type is not supported\n");
+ return -ENOTSUPP;
}
return 0;
@@ -1117,7 +1184,8 @@ int hinic5_ethtool_flow_replace(struct hinic5_nic_dev *nic_dev,
int err;
if (!HINIC5_SUPPORT_FDIR(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unsupported ntuple function\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unsupported ntuple function\n");
return -EOPNOTSUPP;
}
@@ -1130,9 +1198,10 @@ int hinic5_ethtool_flow_replace(struct hinic5_nic_dev *nic_dev,
eth_rule = find_ethtool_rule(nic_dev, fs->location);
/* when location is same, delete old location rule. */
- if (eth_rule) {
- memcpy(&flow_spec_temp, ð_rule->flow_spec,
- sizeof(struct ethtool_rx_flow_spec));
+ if (eth_rule != NULL) {
+ (void)memcpy_s(&flow_spec_temp, sizeof(flow_spec_temp),
+ ð_rule->flow_spec,
+ sizeof(struct ethtool_rx_flow_spec));
err = hinic5_remove_one_rule(nic_dev, eth_rule);
if (err != 0)
return err;
@@ -1143,7 +1212,8 @@ int hinic5_ethtool_flow_replace(struct hinic5_nic_dev *nic_dev,
/* add new rule filter */
err = hinic5_add_one_rule(nic_dev, fs);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Add new rule filter failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Add new rule filter failed\n");
if (loc_exit_flag != 0)
hinic5_add_one_rule(nic_dev, &flow_spec_temp);
@@ -1159,7 +1229,8 @@ int hinic5_ethtool_flow_remove(struct hinic5_nic_dev *nic_dev, u32 location)
int err;
if (!HINIC5_SUPPORT_FDIR(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unsupported ntuple function\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unsupported ntuple function\n");
return -EOPNOTSUPP;
}
@@ -1167,7 +1238,7 @@ int hinic5_ethtool_flow_remove(struct hinic5_nic_dev *nic_dev, u32 location)
return -ENOSPC;
eth_rule = find_ethtool_rule(nic_dev, location);
- if (!eth_rule)
+ if (eth_rule == NULL)
return -ENOENT;
err = hinic5_remove_one_rule(nic_dev, eth_rule);
@@ -1181,7 +1252,8 @@ int hinic5_ethtool_get_flow(const struct hinic5_nic_dev *nic_dev,
struct hinic5_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC5_SUPPORT_FDIR(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unsupported ntuple function\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unsupported ntuple function\n");
return -EOPNOTSUPP;
}
@@ -1205,7 +1277,8 @@ int hinic5_ethtool_get_all_flows(const struct hinic5_nic_dev *nic_dev,
struct hinic5_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC5_SUPPORT_FDIR(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unsupported ntuple function\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unsupported ntuple function\n");
return -EOPNOTSUPP;
}
@@ -1216,15 +1289,18 @@ int hinic5_ethtool_get_all_flows(const struct hinic5_nic_dev *nic_dev,
return info->rule_cnt == idx ? 0 : -ENOENT;
}
-bool hinic5_validate_channel_setting_in_ntuple(const struct hinic5_nic_dev *nic_dev, u32 q_num)
+bool hinic5_validate_channel_setting_in_ntuple(
+ const struct hinic5_nic_dev *nic_dev, u32 q_num)
{
struct hinic5_ethtool_rx_flow_rule *iter = NULL;
list_for_each_entry(iter, &nic_dev->rx_flow_rule.rules, list) {
if (iter->flow_spec.ring_cookie >= q_num) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "User defined filter %u assigns flow to queue %llu. Queue number %u is invalid\n",
- iter->flow_spec.location, iter->flow_spec.ring_cookie, q_num);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "User defined filter %u assigns flow to queue %llu. Queue number %u is invalid\n",
+ iter->flow_spec.location,
+ iter->flow_spec.ring_cookie, q_num);
return false;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.h
index 27cd6f4ed..d1e8474ca 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_ntuple.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_ntuple.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_NTUPLE_H
#define HINIC5_NTUPLE_H
@@ -16,16 +9,16 @@
#define MAX_NUM_OF_ETHTOOL_NTUPLE_RULES BIT(10)
struct hinic5_ethtool_rx_flow_rule {
- struct list_head list;
+ struct list_head list;
struct ethtool_rx_flow_spec flow_spec;
};
-#define UINT1_MAX 0x1
-#define UINT2_MAX 0x3
-#define UINT3_MAX 0x7
-#define UINT4_MAX 0xf
-#define UINT5_WIDTH 0x5
-#define UINT5_MAX 0x1f
-#define UINT15_MAX 0x7fff
+#define UINT1_MAX 0x1
+#define UINT2_MAX 0x3
+#define UINT3_MAX 0x7
+#define UINT4_MAX 0xf
+#define UINT5_WIDTH 0x5
+#define UINT5_MAX 0x1f
+#define UINT15_MAX 0x7fff
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.c
index ad46e1c17..f88350b2a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_rss.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -24,28 +17,30 @@
#include "ossl_knl.h"
#include "hinic5_crm.h"
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
#include "hinic5_nic_cfg.h"
#include "hinic5_nic_dev.h"
#include "hinic5_hw.h"
#include "hinic5_rss.h"
-static u16 num_qps;
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs, 0-65535 (default=0)");
-#define MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, out_qps) do { \
- if ((num_qps) > (nic_dev)->max_qps) \
- nic_warn((nic_dev)->lld_dev->dev, \
- "Module Parameter %s value %u is out of range, " \
- "Maximum value for the device: %u, using %u\n", \
- #num_qps, num_qps, (nic_dev)->max_qps, \
- (nic_dev)->max_qps); \
- if ((num_qps) > (nic_dev)->max_qps) \
- (out_qps) = (nic_dev)->max_qps; \
- else if ((num_qps) > 0) \
- (out_qps) = (num_qps); \
-} while (0)
+#define MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, out_qps) \
+ do { \
+ if ((num_qps) > (nic_dev)->max_qps) \
+ nic_warn( \
+ (nic_dev)->lld_dev->dev, \
+ "Module Parameter %s value %u is out of range, " \
+ "Maximum value for the device: %u, using %u\n", \
+ #num_qps, num_qps, (nic_dev)->max_qps, \
+ (nic_dev)->max_qps); \
+ if ((num_qps) > (nic_dev)->max_qps) \
+ (out_qps) = (nic_dev)->max_qps; \
+ else if ((num_qps) > 0) \
+ (out_qps) = (num_qps); \
+ } while (0)
/* In rx, iq means cos */
static u8 hinic5_get_iqmap_by_tc(const u8 *prio_tc, u8 num_iq, u8 tc)
@@ -73,13 +68,13 @@ static u8 hinic5_get_tcid_by_rq(const u32 *indir_tbl, u8 num_tcs, u16 rq_id)
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++) {
if (indir_tbl[i] == rq_id)
return (u8)(i / tc_group_size);
- }
+ }
return 0xFF; /* Invalid TC */
}
-static int hinic5_get_rq2iq_map(struct hinic5_nic_dev *nic_dev,
- u16 num_rq, u8 num_tcs, u8 *prio_tc, u8 cos_num,
+static int hinic5_get_rq2iq_map(struct hinic5_nic_dev *nic_dev, u16 num_rq,
+ u8 num_tcs, u8 *prio_tc, u8 cos_num,
u32 *indir_tbl, u8 *map, u32 map_size)
{
u16 qid;
@@ -90,14 +85,16 @@ static int hinic5_get_rq2iq_map(struct hinic5_nic_dev *nic_dev,
temp_num_tcs = 1;
if (num_rq > map_size) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rq number(%u) exceed max map qid(%u)\n",
- num_rq, map_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Rq number(%u) exceed max map qid(%u)\n", num_rq,
+ map_size);
return -EINVAL;
}
if (cos_num < HINIC_NUM_IQ_PER_FUNC) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Cos number(%u) less then map qid(%d)\n",
- cos_num, HINIC_NUM_IQ_PER_FUNC);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Cos number(%u) less then map qid(%d)\n", cos_num,
+ HINIC_NUM_IQ_PER_FUNC);
return -EINVAL;
}
@@ -120,24 +117,28 @@ static inline void set_default_cos(u8 *default_cos,
if (nic_dev->hw_default_cos_valid != 0)
*default_cos = nic_dev->hw_default_cos;
else
- *default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ *default_cos =
+ (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
}
}
-static void hinic5_fillout_indir_tbl(struct hinic5_nic_dev *nic_dev, u8 group_num, u32 *indir)
+static void hinic5_fillout_indir_tbl(struct hinic5_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
u8 valid_cos_map = hinic5_get_dev_valid_cos_map(nic_dev);
u16 k, group_size, start_qid = 0, qp_num = 0;
u8 j, cur_cos = 0, group = 0;
u32 i = 0;
- if (!nic_dev)
+ if (nic_dev == NULL) {
return;
+ }
if (nic_dev->flow_bifur_group_num > HINIC5_GROUP_NUMBER_MIN) {
group_size = NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
- for (i = 0; i < group_size; i++)
+ for (i = 0; i < group_size; i++) {
indir[i] = i % nic_dev->q_params.num_qps;
+ }
return;
}
@@ -165,11 +166,12 @@ static void hinic5_fillout_indir_tbl(struct hinic5_nic_dev *nic_dev, u8 group_nu
}
}
-int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
+int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size,
+ u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
u8 i, group_num, cos_bitmap, group = 0;
- u8 cos_group[NIC_DCB_UP_MAX] = {0};
+ u8 cos_group[NIC_DCB_UP_MAX] = { 0 };
int err;
if (nic_dev->flow_bifur_group_num > HINIC5_GROUP_NUMBER_MIN) {
@@ -179,25 +181,29 @@ int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size,
cos_group[i] = 0;
}
} else if (dcb_en != 0) {
- group_num = roundup_pow_of_two(hinic5_get_dev_user_cos_num(nic_dev));
+ group_num = roundup_pow_of_two(
+ hinic5_get_dev_user_cos_num(nic_dev));
cos_bitmap = hinic5_get_dev_valid_cos_map(nic_dev);
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
if ((BIT(i) & cos_bitmap) != 0)
cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
else
- cos_group[NIC_DCB_UP_MAX - i - 1] = group_num - 1;
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
}
} else {
group_num = 0;
}
- err = hinic5_set_hw_rss_parameters(netdev, 1, group_num, cos_group, dcb_en);
+ err = hinic5_set_hw_rss_parameters(netdev, 1, group_num, cos_group,
+ dcb_en);
if (err != 0)
return err;
- err = hinic5_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, group_num, cos_group,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic5_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err != 0)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
@@ -205,7 +211,7 @@ int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size,
void hinic5_rss_deinit(struct hinic5_nic_dev *nic_dev)
{
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
+ u8 cos_map[NIC_DCB_UP_MAX] = { 0 };
hinic5_rss_cfg(nic_dev->hwdev, 0, 0, cos_map, 1);
}
@@ -239,14 +245,14 @@ static void decide_num_qps(struct hinic5_nic_dev *nic_dev)
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
int i, node;
- int is_in_kexec = hinic5_vram_get_kexec_flag();
-
+ int is_in_kexec = vram5_get_kexec_flag();
if (is_in_kexec != 0) {
- nic_dev->q_params.num_qps = nic_dev->nic_hinic5_vram->hinic5_vram_num_qps;
- nicif_info(nic_dev, drv, nic_dev->netdev,
- "Os hotreplace use hinic5_vram to init num qps 1:%u 2:%u\n",
- nic_dev->q_params.num_qps,
- nic_dev->nic_hinic5_vram->hinic5_vram_num_qps);
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(
+ nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
return;
}
@@ -262,12 +268,13 @@ static void decide_num_qps(struct hinic5_nic_dev *nic_dev)
num_cpus++;
}
- pr_info("num_cpus is: %u, and num_online_cpus is: %u", num_cpus, num_online_cpus());
+ pr_info("num_cpus is: %u, and num_online_cpus is: %u", num_cpus,
+ num_online_cpus());
if (num_cpus == 0)
num_cpus = (u16)num_online_cpus();
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
- nic_dev->nic_hinic5_vram->hinic5_vram_num_qps = nic_dev->q_params.num_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
}
static void copy_value_to_rss_hkey(struct hinic5_nic_dev *nic_dev,
@@ -276,7 +283,9 @@ static void copy_value_to_rss_hkey(struct hinic5_nic_dev *nic_dev,
u32 i;
u32 *rss_hkey = (u32 *)nic_dev->rss_hkey;
- memcpy(nic_dev->rss_hkey, hkey, NIC_RSS_KEY_SIZE);
+ (void)memcpy_s(nic_dev->rss_hkey,
+ NIC_RSS_KEY_SIZE * HINIC5_RSS_KEY_RSV_NUM, hkey,
+ NIC_RSS_KEY_SIZE);
/* make a copy of the key, and convert it to Big Endian */
for (i = 0; i < NIC_RSS_KEY_SIZE / sizeof(u32); i++)
@@ -286,19 +295,18 @@ static void copy_value_to_rss_hkey(struct hinic5_nic_dev *nic_dev,
static int alloc_rss_resource(struct hinic5_nic_dev *nic_dev)
{
u8 default_rss_key[NIC_RSS_KEY_SIZE] = {
- 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
- 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
- 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
- 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
- 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa};
+ 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67,
+ 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb,
+ 0xae, 0x7b, 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30,
+ 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+ };
/* We request double spaces for the hash key,
* the second one holds the key of Big Edian
* format.
*/
nic_dev->rss_hkey =
- kzalloc(NIC_RSS_KEY_SIZE *
- HINIC5_RSS_KEY_RSV_NUM, GFP_KERNEL);
+ kzalloc(NIC_RSS_KEY_SIZE * HINIC5_RSS_KEY_RSV_NUM, GFP_KERNEL);
if (nic_dev->rss_hkey == 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc memory for rss_hkey\n");
@@ -306,11 +314,11 @@ static int alloc_rss_resource(struct hinic5_nic_dev *nic_dev)
}
/* The second space is for big edian hash key */
- nic_dev->rss_hkey_be = (u32 *)(nic_dev->rss_hkey +
- NIC_RSS_KEY_SIZE);
+ nic_dev->rss_hkey_be = (u32 *)(nic_dev->rss_hkey + NIC_RSS_KEY_SIZE);
copy_value_to_rss_hkey(nic_dev, (u8 *)default_rss_key);
- nic_dev->rss_indir = kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
+ nic_dev->rss_indir =
+ kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
if (nic_dev->rss_indir == 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc memory for rss_indir\n");
@@ -324,10 +332,10 @@ static int alloc_rss_resource(struct hinic5_nic_dev *nic_dev)
void hinic5_try_to_enable_rss(struct hinic5_nic_dev *nic_dev)
{
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
+ u8 cos_map[NIC_DCB_UP_MAX] = { 0 };
int err = 0;
- if (!nic_dev)
+ if (nic_dev == NULL)
return;
nic_dev->max_qps = hinic5_func_max_nic_qnum(nic_dev->hwdev);
@@ -349,13 +357,14 @@ void hinic5_try_to_enable_rss(struct hinic5_nic_dev *nic_dev)
hinic5_init_rss_parameters(nic_dev->netdev);
/* Attempt to deploy the RSS configuration; if deployment fails,
- * revert to a single queue mode and disable RSS
- * to ensure the functionality remains operational.
- */
- err = hinic5_set_hw_rss_parameters(nic_dev->netdev, 0, 0, cos_map,
- test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ revert to a single queue mode and disable RSS
+ to ensure the functionality remains operational. */
+ err = hinic5_set_hw_rss_parameters(
+ nic_dev->netdev, 0, 0, cos_map,
+ test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
if (err != 0) {
- nic_err(nic_dev->lld_dev->dev, "Failed to set hardware rss parameters\n");
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to set hardware rss parameters\n");
hinic5_clear_rss_config(nic_dev);
nic_dev->max_qps = 1;
@@ -366,7 +375,7 @@ void hinic5_try_to_enable_rss(struct hinic5_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC5_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
- nic_dev->nic_hinic5_vram->hinic5_vram_num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic5_config_rss_hw_resource(struct hinic5_nic_dev *nic_dev,
@@ -480,7 +489,8 @@ static int update_rss_hash_opts(struct hinic5_nic_dev *nic_dev,
return 0;
}
-static int hinic5_set_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethtool_rxnfc *cmd)
+static int hinic5_set_rss_hash_opts(struct hinic5_nic_dev *nic_dev,
+ struct ethtool_rxnfc *cmd)
{
struct nic_rss_type *rss_type = &nic_dev->rss_type;
int err;
@@ -495,8 +505,8 @@ static int hinic5_set_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethto
/* RSS does not support anything other than hashing
* to queues on src and dst IPs and ports
*/
- if ((cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 |
- RXH_L4_B_2_3)) != 0)
+ if ((cmd->data &
+ ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)) != 0)
return -EINVAL;
/* We need at least the IP SRC and DEST fields for hashing */
@@ -505,7 +515,8 @@ static int hinic5_set_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethto
err = hinic5_get_rss_type(nic_dev->hwdev, rss_type);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to get rss type\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to get rss type\n");
return -EFAULT;
}
@@ -520,7 +531,8 @@ static int hinic5_set_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethto
return -EFAULT;
}
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set rss hash options success\n");
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set rss hash options success\n");
return 0;
}
@@ -553,7 +565,8 @@ static int hinic5_convert_rss_type(struct hinic5_nic_dev *nic_dev,
case IPV6_FLOW:
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unsupported flow type\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unsupported flow type\n");
cmd->data = 0;
return -EINVAL;
}
@@ -561,9 +574,10 @@ static int hinic5_convert_rss_type(struct hinic5_nic_dev *nic_dev,
return 0;
}
-static int hinic5_get_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethtool_rxnfc *cmd)
+static int hinic5_get_rss_hash_opts(struct hinic5_nic_dev *nic_dev,
+ struct ethtool_rxnfc *cmd)
{
- struct nic_rss_type rss_type = {0};
+ struct nic_rss_type rss_type = { 0 };
int err;
cmd->data = 0;
@@ -582,11 +596,11 @@ static int hinic5_get_rss_hash_opts(struct hinic5_nic_dev *nic_dev, struct ethto
}
#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULELOCS
-int hinic5_get_rxnfc(struct net_device *netdev,
- struct ethtool_rxnfc *cmd, void *rule_locs)
+int hinic5_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+ void *rule_locs)
#else
-int hinic5_get_rxnfc(struct net_device *netdev,
- struct ethtool_rxnfc *cmd, u32 *rule_locs)
+int hinic5_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
#endif
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -649,12 +663,12 @@ static u16 hinic5_max_channels(struct hinic5_nic_dev *nic_dev)
static u16 hinic5_curr_channels(struct hinic5_nic_dev *nic_dev)
{
- if (netif_running(nic_dev->netdev)) {
+ if (netif_running(nic_dev->netdev))
return (nic_dev->q_params.num_qps != 0) ?
- nic_dev->q_params.num_qps : 1;
- } else {
+ nic_dev->q_params.num_qps :
+ 1;
+ else {
u16 hinic5_max_ch = hinic5_max_channels(nic_dev);
-
return (u16)min_t(u16, hinic5_max_ch,
nic_dev->q_params.num_qps);
}
@@ -677,8 +691,9 @@ void hinic5_get_channels(struct net_device *netdev,
channels->combined_count = hinic5_curr_channels(nic_dev);
}
-static int hinic5_validate_channel_parameter(struct net_device *netdev,
- const struct ethtool_channels *channels)
+static int
+hinic5_validate_channel_parameter(struct net_device *netdev,
+ const struct ethtool_channels *channels)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
u16 max_channel = hinic5_max_channels(nic_dev);
@@ -690,7 +705,8 @@ static int hinic5_validate_channel_parameter(struct net_device *netdev,
return -EINVAL;
}
- if ((channels->tx_count + channels->rx_count + channels->other_count) != 0) {
+ if ((channels->tx_count + channels->rx_count + channels->other_count) !=
+ 0) {
nicif_err(nic_dev, drv, netdev,
"Setting rx/tx/other count not supported\n");
return -EINVAL;
@@ -710,7 +726,7 @@ int hinic5_set_channels(struct net_device *netdev,
struct ethtool_channels *channels)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic5_dyna_txrxq_params q_params = {0};
+ struct hinic5_dyna_txrxq_params q_params = { 0 };
unsigned int count = channels->combined_count;
int err;
u8 user_cos_num = hinic5_get_dev_user_cos_num(nic_dev);
@@ -720,16 +736,18 @@ int hinic5_set_channels(struct net_device *netdev,
return -EINVAL;
if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) == 0) {
- nicif_err(nic_dev, drv, netdev,
- "This function don't support RSS, only support 1 queue pair\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "This function don't support RSS, only support 1 queue pair\n");
return -EOPNOTSUPP;
}
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) {
if (count < user_cos_num) {
- nicif_err(nic_dev, drv, netdev,
- "DCB is on, channels num should more than valid cos num:%u\n",
- user_cos_num);
+ nicif_err(
+ nic_dev, drv, netdev,
+ "DCB is on, channels num should more than valid cos num:%u\n",
+ user_cos_num);
return -EOPNOTSUPP;
}
@@ -739,7 +757,8 @@ int hinic5_set_channels(struct net_device *netdev,
!hinic5_validate_channel_setting_in_ntuple(nic_dev, count))
return -EOPNOTSUPP;
- nicif_info(nic_dev, drv, netdev, "Set max combined queue number from %u to %u\n",
+ nicif_info(nic_dev, drv, netdev,
+ "Set max combined queue number from %u to %u\n",
nic_dev->q_params.num_qps, count);
if (netif_running(netdev)) {
@@ -756,16 +775,18 @@ int hinic5_set_channels(struct net_device *netdev,
#endif
nicif_info(nic_dev, drv, netdev, "Restarting channel\n");
- err = hinic5_change_channel_settings(nic_dev, &q_params, NULL, NULL);
+ err = hinic5_change_channel_settings(nic_dev, &q_params, NULL,
+ NULL);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to change channel settings\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to change channel settings\n");
return -EFAULT;
}
} else {
nic_dev->q_params.num_qps = (u16)count;
}
- nic_dev->nic_hinic5_vram->hinic5_vram_num_qps = nic_dev->q_params.num_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -774,21 +795,23 @@ u32 hinic5_get_rxfh_indir_size(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- return (nic_dev->flow_bifur_group_num <= HINIC5_GROUP_NUMBER_MIN)
- ? NIC_RSS_INDIR_SIZE
- : NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
+ return (nic_dev->flow_bifur_group_num <= HINIC5_GROUP_NUMBER_MIN) ?
+ NIC_RSS_INDIR_SIZE :
+ NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
}
#endif
-static void cfg_indir(struct hinic5_nic_dev *nic_dev, u32 *dest_indir, const u32 *src_indir)
+static void cfg_indir(struct hinic5_nic_dev *nic_dev, u32 *dest_indir,
+ const u32 *src_indir)
{
u16 kernel_indir_len;
+ kernel_indir_len =
+ (nic_dev->flow_bifur_group_num <= HINIC5_GROUP_NUMBER_MIN) ?
+ NIC_RSS_INDIR_SIZE :
+ NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
- kernel_indir_len = (nic_dev->flow_bifur_group_num <= HINIC5_GROUP_NUMBER_MIN)
- ? NIC_RSS_INDIR_SIZE
- : NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
-
- memcpy(dest_indir, src_indir, sizeof(u32) * kernel_indir_len);
+ (void)memcpy_s(dest_indir, sizeof(u32) * kernel_indir_len, src_indir,
+ sizeof(u32) * kernel_indir_len);
}
static int set_rss_rxfh(struct net_device *netdev, const u32 *indir,
@@ -797,12 +820,15 @@ static int set_rss_rxfh(struct net_device *netdev, const u32 *indir,
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
int err;
- if (indir) {
+ if (indir != NULL) {
cfg_indir(nic_dev, nic_dev->rss_indir, indir);
- err = hinic5_rss_set_indir_tbl(nic_dev->hwdev, nic_dev->rss_indir);
- if (err != 0)
+ err = hinic5_rss_set_indir_tbl(nic_dev->hwdev,
+ nic_dev->rss_indir);
+ if (err != 0) {
return -EFAULT;
- err = hinic5_rss_set_indir_tbl(nic_dev->hwdev, nic_dev->rss_indir);
+ }
+ err = hinic5_rss_set_indir_tbl(nic_dev->hwdev,
+ nic_dev->rss_indir);
if (err != 0) {
nicif_err(nic_dev, drv, netdev,
"Failed to set rss indir table\n");
@@ -811,10 +837,11 @@ static int set_rss_rxfh(struct net_device *netdev, const u32 *indir,
nicif_info(nic_dev, drv, netdev, "Change rss indir success\n");
}
- if (key) {
+ if (key != NULL) {
err = hinic5_rss_set_hash_key(nic_dev->hwdev, key);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to set rss key\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to set rss key\n");
return -EFAULT;
}
@@ -832,7 +859,8 @@ u32 hinic5_get_rxfh_key_size(struct net_device *netdev)
}
#if defined HAVE_ETHTOOL_RXFH_PARAM
-int hinic5_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh_param)
+int hinic5_get_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh_param)
#elif defined HAVE_RXFH_HASHFUNC
int hinic5_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
#else
@@ -853,21 +881,23 @@ int hinic5_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
#ifdef HAVE_RXFH_HASHFUNC
if (hfunc)
- *hfunc = (nic_dev->rss_hash_engine != 0) ?
- ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR;
+ *hfunc = (nic_dev->rss_hash_engine != 0) ? ETH_RSS_HASH_TOP :
+ ETH_RSS_HASH_XOR;
#endif
- if (indir)
+ if (indir != NULL)
cfg_indir(nic_dev, indir, nic_dev->rss_indir);
- if (key)
- memcpy(key, nic_dev->rss_hkey, NIC_RSS_KEY_SIZE);
+ if (key != NULL)
+ (void)memcpy_s(key, NIC_RSS_KEY_SIZE, nic_dev->rss_hkey,
+ NIC_RSS_KEY_SIZE);
return 0;
}
#if defined HAVE_ETHTOOL_RXFH_PARAM
-int hinic5_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh_param,
+int hinic5_set_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh_param,
struct netlink_ext_ack *extack)
#elif defined HAVE_RXFH_HASHFUNC
int hinic5_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key,
@@ -888,12 +918,14 @@ int hinic5_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key)
int err = 0;
if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) == 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Not support to set rss parameters when rss is disable\n");
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Not support to set rss parameters when rss is disable\n");
return -EOPNOTSUPP;
}
- if ((test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) && indir) {
+ if ((test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) &&
+ (indir != NULL)) {
nicif_err(nic_dev, drv, netdev,
"Not support to set indir when DCB is enabled\n");
return -EOPNOTSUPP;
@@ -902,14 +934,16 @@ int hinic5_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key)
#ifdef HAVE_RXFH_HASHFUNC
if (hfunc != ETH_RSS_HASH_NO_CHANGE) {
if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR) {
- nicif_err(nic_dev, drv, netdev,
- "Not support to set hfunc type except TOP and XOR\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Not support to set hfunc type except TOP and XOR\n");
return -EOPNOTSUPP;
}
- nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ?
- HINIC5_RSS_HASH_ENGINE_TYPE_XOR :
- HINIC5_RSS_HASH_ENGINE_TYPE_TOEP;
+ nic_dev->rss_hash_engine =
+ (hfunc == ETH_RSS_HASH_XOR) ?
+ HINIC5_RSS_HASH_ENGINE_TYPE_XOR :
+ HINIC5_RSS_HASH_ENGINE_TYPE_TOEP;
err = hinic5_rss_set_hash_engine(nic_dev->hwdev,
nic_dev->rss_hash_engine);
if (err != 0)
@@ -948,9 +982,10 @@ int hinic5_get_rxfh_indir(struct net_device *netdev, u32 *indir)
}
if (indir1->size < NIC_RSS_INDIR_SIZE) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get rss indir, rss size(%d) is more than system rss size(%u).\n",
- NIC_RSS_INDIR_SIZE, indir1->size);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to get rss indir, rss size(%d) is more than system rss size(%u).\n",
+ NIC_RSS_INDIR_SIZE, indir1->size);
return -EINVAL;
}
@@ -961,7 +996,7 @@ int hinic5_get_rxfh_indir(struct net_device *netdev, u32 *indir)
return -EOPNOTSUPP;
}
- if (indir)
+ if (indir != NULL)
cfg_indir(nic_dev, indir, nic_dev->rss_indir);
return 0;
@@ -979,9 +1014,10 @@ int hinic5_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
const u32 *indir = NULL;
if (indir1->size != NIC_RSS_INDIR_SIZE) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to set rss indir, rss size(%d) is more than system rss size(%u).\n",
- NIC_RSS_INDIR_SIZE, indir1->size);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to set rss indir, rss size(%d) is more than system rss size(%u).\n",
+ NIC_RSS_INDIR_SIZE, indir1->size);
return -EINVAL;
}
@@ -994,7 +1030,8 @@ int hinic5_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
return -EOPNOTSUPP;
}
- if ((test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) && indir) {
+ if ((test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) &&
+ (indir != NULL)) {
nicif_err(nic_dev, drv, netdev,
"Not support to set indir when DCB is enabled\n");
return -EOPNOTSUPP;
@@ -1004,4 +1041,3 @@ int hinic5_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
}
#endif /* defined(ETHTOOL_GRSSH) && defined(ETHTOOL_SRSSH) */
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.h
index 68abacff4..30f058192 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_rss.h
@@ -1,22 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_rss.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_RSS_H
#define HINIC5_RSS_H
#include "hinic5_nic_dev.h"
-#define HINIC_NUM_IQ_PER_FUNC 8
+#define HINIC_NUM_IQ_PER_FUNC 8
-int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map,
- u32 map_size, u8 dcb_en);
+int hinic5_rss_init(struct hinic5_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size,
+ u8 dcb_en);
void hinic5_rss_deinit(struct hinic5_nic_dev *nic_dev);
@@ -41,15 +34,16 @@ int hinic5_ethtool_flow_remove(struct hinic5_nic_dev *nic_dev, u32 location);
int hinic5_ethtool_flow_replace(struct hinic5_nic_dev *nic_dev,
struct ethtool_rx_flow_spec *fs);
-bool hinic5_validate_channel_setting_in_ntuple(const struct hinic5_nic_dev *nic_dev, u32 q_num);
+bool hinic5_validate_channel_setting_in_ntuple(
+ const struct hinic5_nic_dev *nic_dev, u32 q_num);
/* for ethtool */
#ifdef HAVE_ETHTOOL_GET_RXNFC_VOID_RULELOCS
-int hinic5_get_rxnfc(struct net_device *netdev,
- struct ethtool_rxnfc *cmd, void *rule_locs);
+int hinic5_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+ void *rule_locs);
#else
-int hinic5_get_rxnfc(struct net_device *netdev,
- struct ethtool_rxnfc *cmd, u32 *rule_locs);
+int hinic5_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs);
#endif
int hinic5_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd);
@@ -68,7 +62,8 @@ u32 hinic5_get_rxfh_indir_size(struct net_device *netdev);
u32 hinic5_get_rxfh_key_size(struct net_device *netdev);
#ifdef HAVE_ETHTOOL_RXFH_PARAM
-int hinic5_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh_param);
+int hinic5_get_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh_param);
#elif defined HAVE_RXFH_HASHFUNC
int hinic5_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc);
#else /* HAVE_RXFH_HASHFUNC */
@@ -76,7 +71,8 @@ int hinic5_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key);
#endif /* HAVE_RXFH_HASHFUNC */
#ifdef HAVE_ETHTOOL_RXFH_PARAM
-int hinic5_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh_param,
+int hinic5_set_rxfh(struct net_device *netdev,
+ struct ethtool_rxfh_param *rxfh_param,
struct netlink_ext_ack *extack);
#elif defined HAVE_RXFH_HASHFUNC
int hinic5_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.c
index c3e0d2512..0851f5a6d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_tc.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -48,10 +41,7 @@
#define GET_MASK_VAL(val, shift, mask) (((val) >> (shift)) & (mask))
-enum parse_type {
- KEY_TYPE,
- MASK_TYPE
-};
+enum parse_type { KEY_TYPE, MASK_TYPE };
static const struct rhashtable_params tc_flow_ht_params = {
.head_offset = offsetof(struct hinic5_tc_flow_node, node),
@@ -62,8 +52,9 @@ static const struct rhashtable_params tc_flow_ht_params = {
static int hinic5_tc_info_init_from_reg(struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
- struct hinic5_tc_pfe_cfg_reg_info cfg_info = {0};
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_pfe_cfg_reg_info cfg_info = { 0 };
int ret;
ret = hinic5_get_pfe_cfg(nic_dev->hwdev, &cfg_info);
@@ -71,12 +62,10 @@ static int hinic5_tc_info_init_from_reg(struct hinic5_nic_dev *nic_dev)
return ret;
mutex_lock(&tc_info->tc_lock);
- tc_info->tunnel_opt = GET_MASK_VAL(cfg_info.reg_value,
- PFE_TUNNEL_OPT_SHIFT,
- PFE_TUNNEL_OPT_MASK);
- tc_info->ipv6_shift_value = GET_MASK_VAL(cfg_info.reg_value,
- PFE_IPV6_SIP_SHIFT,
- PFE_IPV6_SIP_MASK);
+ tc_info->tunnel_opt = GET_MASK_VAL(
+ cfg_info.reg_value, PFE_TUNNEL_OPT_SHIFT, PFE_TUNNEL_OPT_MASK);
+ tc_info->ipv6_shift_value = GET_MASK_VAL(
+ cfg_info.reg_value, PFE_IPV6_SIP_SHIFT, PFE_IPV6_SIP_MASK);
tc_info->ipv6_shift_value2 = GET_MASK_VAL(cfg_info.reg_value2,
PFE_IPV6_SIP_DIP_SHIFT,
PFE_IPV6_SIP_DIP_MASK);
@@ -88,7 +77,8 @@ static int hinic5_tc_info_init_from_reg(struct hinic5_nic_dev *nic_dev)
static int hinic5_tc_del_flow_handler(struct hinic5_nic_dev *nic_dev,
struct hinic5_tc_flow_node *flow_node)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
/* send del cmd to mpu */
(void)hinic5_del_tc_flow_rule(nic_dev->hwdev, flow_node->rule_id);
@@ -101,7 +91,8 @@ static int hinic5_tc_del_flow_handler(struct hinic5_nic_dev *nic_dev,
clear_bit(flow_node->rule_id, tc_info->tcam_bitmap);
mutex_unlock(&tc_info->tc_lock);
- hinic5_info(nic_dev, drv, "flow with cookie:%lx is deleted\n", flow_node->cookie);
+ hinic5_info(nic_dev, drv, "flow with cookie:%lx is deleted\n",
+ flow_node->cookie);
kfree(flow_node);
return 0;
@@ -114,9 +105,11 @@ static void hinic5_tc_free_node(void *ptr, void *arg)
void hinic5_deinit_tc(struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
- rhashtable_free_and_destroy(&tc_info->flow_table, hinic5_tc_free_node, NULL);
+ rhashtable_free_and_destroy(&tc_info->flow_table, hinic5_tc_free_node,
+ NULL);
hinic5_flush_tc_flow_rule(nic_dev->hwdev, tc_info->tcam_bitmap);
@@ -124,13 +117,14 @@ void hinic5_deinit_tc(struct hinic5_nic_dev *nic_dev)
nic_dev->tc_info = NULL;
}
-static void hinic5_tc_match_basic(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_basic(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
struct flow_match_basic match;
flow_rule_match_basic(rule, &match);
- if (match.key->n_proto != 0 && match.mask->n_proto != 0) {
+ if ((match.key->n_proto != 0) && (match.mask->n_proto != 0)) {
flow->l2_key.ether_type = match.key->n_proto;
flow->l2_mask.ether_type = match.mask->n_proto;
flow->key_flags |= BIT(HINIC5_TC_KEY_ETH_TYPE);
@@ -145,19 +139,22 @@ static void hinic5_tc_match_basic(struct flow_rule *rule, struct hinic5_tc_flow
}
}
-static void hinic5_tc_match_eth_addrs(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_eth_addrs(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
struct flow_match_eth_addrs match;
flow_rule_match_eth_addrs(rule, &match);
- if (!is_zero_ether_addr(match.key->dst) && !is_zero_ether_addr(match.mask->dst)) {
+ if (!is_zero_ether_addr(match.key->dst) &&
+ !is_zero_ether_addr(match.mask->dst)) {
ether_addr_copy(flow->l2_key.dmac, match.key->dst);
ether_addr_copy(flow->l2_mask.dmac, match.mask->dst);
flow->key_flags |= BIT(HINIC5_TC_KEY_DST_MAC);
}
- if (!is_zero_ether_addr(match.key->src) && !is_zero_ether_addr(match.mask->src)) {
+ if (!is_zero_ether_addr(match.key->src) &&
+ !is_zero_ether_addr(match.mask->src)) {
ether_addr_copy(flow->l2_key.smac, match.key->src);
ether_addr_copy(flow->l2_mask.smac, match.mask->src);
flow->key_flags |= BIT(HINIC5_TC_KEY_SRC_MAC);
@@ -165,36 +162,41 @@ static void hinic5_tc_match_eth_addrs(struct flow_rule *rule, struct hinic5_tc_f
}
}
-static void hinic5_tc_match_vlan(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_vlan(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
struct flow_match_vlan match;
flow_rule_match_vlan(rule, &match);
- flow->l2_key.vlan_tag = cpu_to_be16(match.key->vlan_id |
- (match.key->vlan_priority << VLAN_PRIO_SHIFT));
- flow->l2_mask.vlan_tag = cpu_to_be16(match.mask->vlan_id |
- (match.mask->vlan_priority << VLAN_PRIO_SHIFT));
+ flow->l2_key.vlan_tag = cpu_to_be16(
+ match.key->vlan_id |
+ (match.key->vlan_priority << VLAN_PRIO_SHIFT));
+ flow->l2_mask.vlan_tag = cpu_to_be16(
+ match.mask->vlan_id |
+ (match.mask->vlan_priority << VLAN_PRIO_SHIFT));
flow->key_flags |= BIT(HINIC5_TC_KEY_VLAN_TAG);
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN)) {
flow_rule_match_cvlan(rule, &match);
- flow->l2_key.cvlan_tag = cpu_to_be16(match.key->vlan_id |
- (match.key->vlan_priority << VLAN_PRIO_SHIFT));
- flow->l2_mask.cvlan_tag = cpu_to_be16(match.mask->vlan_id |
- (match.mask->vlan_priority << VLAN_PRIO_SHIFT));
+ flow->l2_key.cvlan_tag = cpu_to_be16(
+ match.key->vlan_id |
+ (match.key->vlan_priority << VLAN_PRIO_SHIFT));
+ flow->l2_mask.cvlan_tag = cpu_to_be16(
+ match.mask->vlan_id |
+ (match.mask->vlan_priority << VLAN_PRIO_SHIFT));
flow->key_flags |= BIT(HINIC5_TC_KEY_CVLAN);
}
} else {
flow->l2_key.vlan_tag = 0;
- flow->l2_mask.vlan_tag = 0; /* For ipv4 non-vlan packets */
+ flow->l2_mask.vlan_tag = 0; // 适配ipv4非vlan报文
}
}
-static void hinic5_tc_match_ip_addrs(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_ip_addrs(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
struct flow_match_control ctrl_match;
-
flow_rule_match_control(rule, &ctrl_match);
if (ctrl_match.key->addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
@@ -209,7 +211,7 @@ static void hinic5_tc_match_ip_addrs(struct flow_rule *rule, struct hinic5_tc_fl
flow->key_flags |= BIT(HINIC5_TC_KEY_IPV4);
} else if (ctrl_match.key->addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS &&
- flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
struct flow_match_ipv6_addrs match;
flow_rule_match_ipv6_addrs(rule, &match);
@@ -222,7 +224,8 @@ static void hinic5_tc_match_ip_addrs(struct flow_rule *rule, struct hinic5_tc_fl
}
}
-static void hinic5_tc_match_enc_ip_addrs(struct flow_rule *rule, struct hinic5_tc_flow *flow,
+static void hinic5_tc_match_enc_ip_addrs(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow,
struct hinic5_tc_info *tc_info)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
@@ -235,7 +238,8 @@ static void hinic5_tc_match_enc_ip_addrs(struct flow_rule *rule, struct hinic5_t
flow->l3_mask.enc_ipv4.saddr.s_addr = match.mask->src;
flow->key_flags |= BIT(HINIC5_TC_KEY_ENC_IP);
tc_info->enc_ip_type = ENC_IPV4_TYPE;
- } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
+ } else if (flow_rule_match_key(rule,
+ FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
struct flow_match_ipv6_addrs match;
flow_rule_match_enc_ipv6_addrs(rule, &match);
@@ -248,7 +252,8 @@ static void hinic5_tc_match_enc_ip_addrs(struct flow_rule *rule, struct hinic5_t
}
}
-static void hinic5_tc_match_ports(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_ports(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
struct flow_match_ports match;
@@ -263,7 +268,8 @@ static void hinic5_tc_match_ports(struct flow_rule *rule, struct hinic5_tc_flow
}
}
-static void hinic5_tc_match_vni(struct flow_rule *rule, struct hinic5_tc_flow *flow)
+static void hinic5_tc_match_vni(struct flow_rule *rule,
+ struct hinic5_tc_flow *flow)
{
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
struct flow_match_enc_keyid match;
@@ -275,9 +281,12 @@ static void hinic5_tc_match_vni(struct flow_rule *rule, struct hinic5_tc_flow *f
}
}
-typedef void (*hinic5_tc_key_func)(const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem);
+typedef void (*hinic5_tc_key_func)(const u8 *attr[],
+ const struct hinic5_tc_info *tc_info,
+ u8 *mem);
-static void hinic5_tc_parse_key_field(struct hinic5_tc_flow *flow, const u8 *attr[])
+static void hinic5_tc_parse_key_field(struct hinic5_tc_flow *flow,
+ const u8 *attr[])
{
attr[HINIC5_TC_FIELD_ETH_TYPE] = (const u8 *)&flow->l2_key.ether_type;
attr[HINIC5_TC_FIELD_VNI] = (const u8 *)&flow->l2_key.vni;
@@ -287,16 +296,19 @@ static void hinic5_tc_parse_key_field(struct hinic5_tc_flow *flow, const u8 *att
attr[HINIC5_TC_FIELD_DST_MAC] = (const u8 *)&flow->l2_key.dmac[0];
attr[HINIC5_TC_FIELD_SRC_IP] = (const u8 *)&flow->l3_key.ipv4.saddr;
attr[HINIC5_TC_FIELD_DST_IP] = (const u8 *)&flow->l3_key.ipv4.daddr;
- attr[HINIC5_TC_FIELD_ENC_DST_IP] = (const u8 *)&flow->l3_key.enc_ipv4.daddr;
+ attr[HINIC5_TC_FIELD_ENC_DST_IP] =
+ (const u8 *)&flow->l3_key.enc_ipv4.daddr;
attr[HINIC5_TC_FIELD_SRC_IPV6] = (const u8 *)&flow->l3_key.ipv6.saddr;
attr[HINIC5_TC_FIELD_DST_IPV6] = (const u8 *)&flow->l3_key.ipv6.daddr;
- attr[HINIC5_TC_FIELD_ENC_DST_IPV6] = (const u8 *)&flow->l3_key.enc_ipv6.daddr;
+ attr[HINIC5_TC_FIELD_ENC_DST_IPV6] =
+ (const u8 *)&flow->l3_key.enc_ipv6.daddr;
attr[HINIC5_TC_FIELD_SRC_PORT] = (const u8 *)&flow->l4_key.ports.sport;
attr[HINIC5_TC_FIELD_DST_PORT] = (const u8 *)&flow->l4_key.ports.dport;
attr[HINIC5_TC_FIELD_PROTOCOL] = (const u8 *)&flow->l4_key.ip_proto;
}
-static void hinic5_tc_parse_mask_field(struct hinic5_tc_flow *flow, const u8 *attr[])
+static void hinic5_tc_parse_mask_field(struct hinic5_tc_flow *flow,
+ const u8 *attr[])
{
attr[HINIC5_TC_FIELD_ETH_TYPE] = (const u8 *)&flow->l2_mask.ether_type;
attr[HINIC5_TC_FIELD_VNI] = (const u8 *)&flow->l2_mask.vni;
@@ -306,10 +318,12 @@ static void hinic5_tc_parse_mask_field(struct hinic5_tc_flow *flow, const u8 *at
attr[HINIC5_TC_FIELD_DST_MAC] = (const u8 *)&flow->l2_mask.dmac[0];
attr[HINIC5_TC_FIELD_SRC_IP] = (const u8 *)&flow->l3_mask.ipv4.saddr;
attr[HINIC5_TC_FIELD_DST_IP] = (const u8 *)&flow->l3_mask.ipv4.daddr;
- attr[HINIC5_TC_FIELD_ENC_DST_IP] = (const u8 *)&flow->l3_mask.enc_ipv4.daddr;
+ attr[HINIC5_TC_FIELD_ENC_DST_IP] =
+ (const u8 *)&flow->l3_mask.enc_ipv4.daddr;
attr[HINIC5_TC_FIELD_SRC_IPV6] = (const u8 *)&flow->l3_mask.ipv6.saddr;
attr[HINIC5_TC_FIELD_DST_IPV6] = (const u8 *)&flow->l3_mask.ipv6.daddr;
- attr[HINIC5_TC_FIELD_ENC_DST_IPV6] = (const u8 *)&flow->l3_mask.enc_ipv6.daddr;
+ attr[HINIC5_TC_FIELD_ENC_DST_IPV6] =
+ (const u8 *)&flow->l3_mask.enc_ipv6.daddr;
attr[HINIC5_TC_FIELD_SRC_PORT] = (const u8 *)&flow->l4_mask.ports.sport;
attr[HINIC5_TC_FIELD_DST_PORT] = (const u8 *)&flow->l4_mask.ports.dport;
attr[HINIC5_TC_FIELD_PROTOCOL] = (const u8 *)&flow->l4_mask.ip_proto;
@@ -317,101 +331,88 @@ static void hinic5_tc_parse_mask_field(struct hinic5_tc_flow *flow, const u8 *at
static u16 hinic5_tc_get_key_flags(u16 profile_id, u16 tunnel_opt)
{
- u16 key_flags[HINIC5_TC_PROFILE_MAX] = {0};
-
- key_flags[HINIC5_TC_PROFILE_TUN_ETH] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE);
-
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_VLAN] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_VLAN_TAG);
-
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_QINQ] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_VLAN_TAG) |
- BIT(HINIC5_TC_KEY_CVLAN);
-
- key_flags[HINIC5_TC_PROFILE_ETH] = BIT(HINIC5_TC_KEY_SRC_MAC) | BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE);
-
- key_flags[HINIC5_TC_PROFILE_ETH_VLAN] = BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_VLAN_TAG);
-
- key_flags[HINIC5_TC_PROFILE_ETH_QINQ] = BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_VLAN_TAG) |
- BIT(HINIC5_TC_KEY_CVLAN);
-
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP4] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_IPV4) |
- BIT(HINIC5_TC_KEY_PROTOCOL);
-
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP4_TCPORUDP] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_IPV4) |
- BIT(HINIC5_TC_KEY_PROTOCOL) |
- BIT(HINIC5_TC_KEY_PORTS);
+ u16 key_flags[HINIC5_TC_PROFILE_MAX] = { 0 };
+
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) | BIT(HINIC5_TC_KEY_ETH_TYPE);
+
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_VLAN] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) | BIT(HINIC5_TC_KEY_ETH_TYPE) |
+ BIT(HINIC5_TC_KEY_VLAN_TAG);
+
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_QINQ] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) | BIT(HINIC5_TC_KEY_ETH_TYPE) |
+ BIT(HINIC5_TC_KEY_VLAN_TAG) | BIT(HINIC5_TC_KEY_CVLAN);
+
+ key_flags[HINIC5_TC_PROFILE_ETH] = BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE);
+
+ key_flags[HINIC5_TC_PROFILE_ETH_VLAN] =
+ BIT(HINIC5_TC_KEY_SRC_MAC) | BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_VLAN_TAG);
+
+ key_flags[HINIC5_TC_PROFILE_ETH_QINQ] =
+ BIT(HINIC5_TC_KEY_SRC_MAC) | BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_VLAN_TAG) |
+ BIT(HINIC5_TC_KEY_CVLAN);
+
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP4] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_IPV4) |
+ BIT(HINIC5_TC_KEY_PROTOCOL);
+
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP4_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_IPV4) |
+ BIT(HINIC5_TC_KEY_PROTOCOL) | BIT(HINIC5_TC_KEY_PORTS);
key_flags[HINIC5_TC_PROFILE_ETH_IP4] = BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_IPV4) |
- BIT(HINIC5_TC_KEY_PROTOCOL);
+ BIT(HINIC5_TC_KEY_IPV4) |
+ BIT(HINIC5_TC_KEY_PROTOCOL);
- key_flags[HINIC5_TC_PROFILE_ETH_IP4_TCPORUDP] = BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_IPV4) |
- BIT(HINIC5_TC_KEY_PROTOCOL) |
- BIT(HINIC5_TC_KEY_PORTS);
+ key_flags[HINIC5_TC_PROFILE_ETH_IP4_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_DST_MAC) | BIT(HINIC5_TC_KEY_IPV4) |
+ BIT(HINIC5_TC_KEY_PROTOCOL) | BIT(HINIC5_TC_KEY_PORTS);
if (tunnel_opt == TUNNEL_OPT_OFF) {
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL);
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL) |
- BIT(HINIC5_TC_KEY_PORTS);
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL);
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL) | BIT(HINIC5_TC_KEY_PORTS);
} else {
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL);
- key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP] = BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_SRC_MAC) |
- BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_ETH_TYPE) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL) |
- BIT(HINIC5_TC_KEY_PORTS);
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL);
+ key_flags[HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_SRC_MAC) |
+ BIT(HINIC5_TC_KEY_DST_MAC) |
+ BIT(HINIC5_TC_KEY_ETH_TYPE) | BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL) | BIT(HINIC5_TC_KEY_PORTS);
}
key_flags[HINIC5_TC_PROFILE_ETH_IP6] = BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL);
+ BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL);
- key_flags[HINIC5_TC_PROFILE_ETH_IP6_TCPORUDP] = BIT(HINIC5_TC_KEY_DST_MAC) |
- BIT(HINIC5_TC_KEY_IPV6) |
- BIT(HINIC5_TC_KEY_PROTOCOL) |
- BIT(HINIC5_TC_KEY_PORTS);
+ key_flags[HINIC5_TC_PROFILE_ETH_IP6_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_DST_MAC) | BIT(HINIC5_TC_KEY_IPV6) |
+ BIT(HINIC5_TC_KEY_PROTOCOL) | BIT(HINIC5_TC_KEY_PORTS);
- key_flags[HINIC5_TC_PROFILE_OUTER_IP_INNER_IP] = BIT(HINIC5_TC_KEY_ENC_IP) |
- BIT(HINIC5_TC_KEY_VNI) | BIT(HINIC5_TC_KEY_IPV4);
+ key_flags[HINIC5_TC_PROFILE_OUTER_IP_INNER_IP] =
+ BIT(HINIC5_TC_KEY_ENC_IP) | BIT(HINIC5_TC_KEY_VNI) |
+ BIT(HINIC5_TC_KEY_IPV4);
- key_flags[HINIC5_TC_PROFILE_OUTER_IP_INNER_IP_TCPORUDP] = BIT(HINIC5_TC_KEY_ENC_IP) |
- BIT(HINIC5_TC_KEY_VNI) |
- BIT(HINIC5_TC_KEY_IPV4) | BIT(HINIC5_TC_KEY_PORTS);
+ key_flags[HINIC5_TC_PROFILE_OUTER_IP_INNER_IP_TCPORUDP] =
+ BIT(HINIC5_TC_KEY_ENC_IP) | BIT(HINIC5_TC_KEY_VNI) |
+ BIT(HINIC5_TC_KEY_IPV4) | BIT(HINIC5_TC_KEY_PORTS);
return key_flags[profile_id];
}
@@ -420,7 +421,8 @@ static void hinic5_tc_get_key_tun_eth(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_tun_eth *rule_st = (struct hinic5_tc_rule_tun_eth *)mem;
+ struct hinic5_tc_rule_tun_eth *rule_st =
+ (struct hinic5_tc_rule_tun_eth *)mem;
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
@@ -432,30 +434,35 @@ static void hinic5_tc_get_key_tun_eth_vlan(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_tun_eth_vlan *rule_st = (struct hinic5_tc_rule_tun_eth_vlan *)mem;
+ struct hinic5_tc_rule_tun_eth_vlan *rule_st =
+ (struct hinic5_tc_rule_tun_eth_vlan *)mem;
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
WRITE_FIELD_U16(rule_st, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
- WRITE_FIELD_SPLIT_U16(rule_st, vlan_tag, attr[HINIC5_TC_FIELD_VLAN_TAG]);
+ WRITE_FIELD_SPLIT_U16(rule_st, vlan_tag,
+ attr[HINIC5_TC_FIELD_VLAN_TAG]);
}
static void hinic5_tc_get_key_tun_eth_qinq(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_tun_eth_qinq *rule_st = (struct hinic5_tc_rule_tun_eth_qinq *)mem;
+ struct hinic5_tc_rule_tun_eth_qinq *rule_st =
+ (struct hinic5_tc_rule_tun_eth_qinq *)mem;
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
WRITE_FIELD_U16(rule_st, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
- WRITE_FIELD_SPLIT_U16(rule_st, vlan_tag, attr[HINIC5_TC_FIELD_VLAN_TAG]);
+ WRITE_FIELD_SPLIT_U16(rule_st, vlan_tag,
+ attr[HINIC5_TC_FIELD_VLAN_TAG]);
WRITE_FIELD_U16(rule_st, cvlan_tag, attr[HINIC5_TC_FIELD_CVLAN_TAG]);
}
-static void hinic5_tc_get_key_eth(const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
+static void hinic5_tc_get_key_eth(const u8 *attr[],
+ const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_eth *rule_st = (struct hinic5_tc_rule_eth *)mem;
@@ -468,7 +475,8 @@ static void hinic5_tc_get_key_eth_vlan(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_eth_vlan *rule_st = (struct hinic5_tc_rule_eth_vlan *)mem;
+ struct hinic5_tc_rule_eth_vlan *rule_st =
+ (struct hinic5_tc_rule_eth_vlan *)mem;
WRITE_MAC(rule_st, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
@@ -480,7 +488,8 @@ static void hinic5_tc_get_key_eth_qinq(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_eth_qinq *rule_st = (struct hinic5_tc_rule_eth_qinq *)mem;
+ struct hinic5_tc_rule_eth_qinq *rule_st =
+ (struct hinic5_tc_rule_eth_qinq *)mem;
WRITE_MAC(rule_st, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
@@ -493,26 +502,28 @@ static void hinic5_tc_get_key_tun_eth_ip4(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_tun_eth_ip4 *rule_st = (struct hinic5_tc_rule_tun_eth_ip4 *)mem;
+ struct hinic5_tc_rule_tun_eth_ip4 *rule_st =
+ (struct hinic5_tc_rule_tun_eth_ip4 *)mem;
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
- WRITE_FIELD_SPLIT_U16(rule_st, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
+ WRITE_FIELD_SPLIT_U16(rule_st, ether_type,
+ attr[HINIC5_TC_FIELD_ETH_TYPE]);
WRITE_IP4(rule_st, sip, attr[HINIC5_TC_FIELD_SRC_IP]);
WRITE_IP4(rule_st, dip, attr[HINIC5_TC_FIELD_DST_IP]);
WRITE_FIELD_U8(rule_st, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
}
-static void hinic5_tc_get_key_tun_eth_ip4_tcporudp(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_tun_eth_ip4_tcporudp(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_tun_eth_ip4_tcporudp *rule_st =
- (struct hinic5_tc_rule_tun_eth_ip4_tcporudp *)mem;
+ (struct hinic5_tc_rule_tun_eth_ip4_tcporudp *)mem;
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
- WRITE_FIELD_SPLIT_U16(rule_st, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
+ WRITE_FIELD_SPLIT_U16(rule_st, ether_type,
+ attr[HINIC5_TC_FIELD_ETH_TYPE]);
WRITE_IP4(rule_st, sip, attr[HINIC5_TC_FIELD_SRC_IP]);
WRITE_IP4(rule_st, dip, attr[HINIC5_TC_FIELD_DST_IP]);
WRITE_FIELD_U8(rule_st, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
@@ -524,7 +535,8 @@ static void hinic5_tc_get_key_eth_ip4(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_eth_ip4 *rule_st = (struct hinic5_tc_rule_eth_ip4 *)mem;
+ struct hinic5_tc_rule_eth_ip4 *rule_st =
+ (struct hinic5_tc_rule_eth_ip4 *)mem;
WRITE_FIELD_U16(rule_st, vlan_tag, attr[HINIC5_TC_FIELD_VLAN_TAG]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
@@ -533,12 +545,11 @@ static void hinic5_tc_get_key_eth_ip4(const u8 *attr[],
WRITE_FIELD_U8(rule_st, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
}
-static void hinic5_tc_get_key_eth_ip4_tcporudp(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_eth_ip4_tcporudp(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_eth_ip4_tcporudp *rule_st =
- (struct hinic5_tc_rule_eth_ip4_tcporudp *)mem;
+ (struct hinic5_tc_rule_eth_ip4_tcporudp *)mem;
WRITE_FIELD_U16(rule_st, vlan_tag, attr[HINIC5_TC_FIELD_VLAN_TAG]);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
@@ -549,7 +560,8 @@ static void hinic5_tc_get_key_eth_ip4_tcporudp(const u8 *attr[],
WRITE_FIELD_U16(rule_st, dport, attr[HINIC5_TC_FIELD_DST_PORT]);
}
-static void hinic5_tc_get_ip6_trunc(const u8 *ip6, u8 *trunc_mem, u16 ip6_bit_len, u16 shift)
+static void hinic5_tc_get_ip6_trunc(const u8 *ip6, u8 *trunc_mem,
+ u16 ip6_bit_len, u16 shift)
{
/* keep ip6 bits[shift+ip6_bit_len:shift] */
u16 i, trunc_byte_idx, trunc_bit_idx;
@@ -559,27 +571,33 @@ static void hinic5_tc_get_ip6_trunc(const u8 *ip6, u8 *trunc_mem, u16 ip6_bit_le
for (i = start_bit; i < start_bit + ip6_bit_len; i++) {
trunc_byte_idx = (i - start_bit) / BYTE8_SIZE;
trunc_bit_idx = BYTE8_SIZE - 1 - (i - start_bit) % BYTE8_SIZE;
- bit_val = (ip6[i / BYTE8_SIZE] >> (BYTE8_SIZE - 1 - i % BYTE8_SIZE)) & 1;
+ bit_val = (ip6[i / BYTE8_SIZE] >>
+ (BYTE8_SIZE - 1 - i % BYTE8_SIZE)) &
+ 1;
trunc_mem[trunc_byte_idx] |= bit_val << trunc_bit_idx;
}
}
-static void hinic5_tc_set_ip6_trunc(const u8 *attr[], const struct hinic5_tc_info *tc_info,
+static void hinic5_tc_set_ip6_trunc(const u8 *attr[],
+ const struct hinic5_tc_info *tc_info,
struct hinic5_tc_ip6_trunc *ip6_trunc)
{
switch (tc_info->profile_id) {
case HINIC5_TC_PROFILE_TUN_ETH_IP6:
case HINIC5_TC_PROFILE_TUN_ETH_IP6_TCPORUDP:
- hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_SRC_IPV6], ip6_trunc->sip6,
- IP6_ADDR_TRUNC_72BITS, tc_info->ipv6_shift_value2);
+ hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_SRC_IPV6],
+ ip6_trunc->sip6, IP6_ADDR_TRUNC_72BITS,
+ tc_info->ipv6_shift_value2);
attr[HINIC5_TC_FIELD_SRC_IPV6] = ip6_trunc->sip6;
- hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_DST_IPV6], ip6_trunc->dip6,
- IP6_ADDR_TRUNC_72BITS, tc_info->ipv6_shift_value2);
+ hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_DST_IPV6],
+ ip6_trunc->dip6, IP6_ADDR_TRUNC_72BITS,
+ tc_info->ipv6_shift_value2);
attr[HINIC5_TC_FIELD_DST_IPV6] = ip6_trunc->dip6;
break;
case HINIC5_TC_PROFILE_ETH_IP6_TCPORUDP:
- hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_SRC_IPV6], ip6_trunc->sip6,
- IP6_ADDR_TRUNC_96BITS, tc_info->ipv6_shift_value);
+ hinic5_tc_get_ip6_trunc(attr[HINIC5_TC_FIELD_SRC_IPV6],
+ ip6_trunc->sip6, IP6_ADDR_TRUNC_96BITS,
+ tc_info->ipv6_shift_value);
attr[HINIC5_TC_FIELD_SRC_IPV6] = ip6_trunc->sip6;
break;
default:
@@ -592,56 +610,73 @@ static void hinic5_tc_get_key_tun_eth_ip6(const u8 *attr[],
u8 *mem)
{
struct hinic5_tc_rule_tun_eth_ip6_off *rule_st_off =
- (struct hinic5_tc_rule_tun_eth_ip6_off *)mem;
+ (struct hinic5_tc_rule_tun_eth_ip6_off *)mem;
struct hinic5_tc_rule_tun_eth_ip6_on *rule_st_on =
- (struct hinic5_tc_rule_tun_eth_ip6_on *)mem;
- struct hinic5_tc_ip6_trunc ip6_trunc = {0};
+ (struct hinic5_tc_rule_tun_eth_ip6_on *)mem;
+ struct hinic5_tc_ip6_trunc ip6_trunc = { 0 };
if (tc_info->tunnel_opt == TUNNEL_OPT_OFF) {
WRITE_VNI(rule_st_off, attr[HINIC5_TC_FIELD_VNI]);
- WRITE_IP6_128BITS_OPT_OFF(rule_st_off, sip6, attr[HINIC5_TC_FIELD_SRC_IPV6]);
- WRITE_IP6_128BITS_OPT_OFF(rule_st_off, dip6, attr[HINIC5_TC_FIELD_DST_IPV6]);
- WRITE_FIELD_U8(rule_st_off, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
+ WRITE_IP6_128BITS_OPT_OFF(rule_st_off, sip6,
+ attr[HINIC5_TC_FIELD_SRC_IPV6]);
+ WRITE_IP6_128BITS_OPT_OFF(rule_st_off, dip6,
+ attr[HINIC5_TC_FIELD_DST_IPV6]);
+ WRITE_FIELD_U8(rule_st_off, proto,
+ attr[HINIC5_TC_FIELD_PROTOCOL]);
} else {
hinic5_tc_set_ip6_trunc(attr, tc_info, &ip6_trunc);
WRITE_VNI(rule_st_on, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st_on, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st_on, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
- WRITE_FIELD_U16(rule_st_on, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
- WRITE_SIP6_72BITS_OPT_ON(rule_st_on, attr[HINIC5_TC_FIELD_SRC_IPV6]);
- WRITE_DIP6_72BITS_OPT_ON(rule_st_on, attr[HINIC5_TC_FIELD_DST_IPV6]);
- WRITE_FIELD_U8(rule_st_on, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
+ WRITE_FIELD_U16(rule_st_on, ether_type,
+ attr[HINIC5_TC_FIELD_ETH_TYPE]);
+ WRITE_SIP6_72BITS_OPT_ON(rule_st_on,
+ attr[HINIC5_TC_FIELD_SRC_IPV6]);
+ WRITE_DIP6_72BITS_OPT_ON(rule_st_on,
+ attr[HINIC5_TC_FIELD_DST_IPV6]);
+ WRITE_FIELD_U8(rule_st_on, proto,
+ attr[HINIC5_TC_FIELD_PROTOCOL]);
}
}
-static void hinic5_tc_get_key_tun_eth_ip6_tcporudp(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_tun_eth_ip6_tcporudp(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_tun_eth_ip6_tcporudp_off *rule_st_off =
- (struct hinic5_tc_rule_tun_eth_ip6_tcporudp_off *)mem;
+ (struct hinic5_tc_rule_tun_eth_ip6_tcporudp_off *)mem;
struct hinic5_tc_rule_tun_eth_ip6_tcporudp_on *rule_st_on =
- (struct hinic5_tc_rule_tun_eth_ip6_tcporudp_on *)mem;
- struct hinic5_tc_ip6_trunc ip6_trunc = {0};
+ (struct hinic5_tc_rule_tun_eth_ip6_tcporudp_on *)mem;
+ struct hinic5_tc_ip6_trunc ip6_trunc = { 0 };
if (tc_info->tunnel_opt == TUNNEL_OPT_OFF) {
WRITE_VNI(rule_st_off, attr[HINIC5_TC_FIELD_VNI]);
- WRITE_IP6_128BITS_OPT_OFF(rule_st_off, sip6, attr[HINIC5_TC_FIELD_SRC_IPV6]);
- WRITE_IP6_128BITS_OPT_OFF(rule_st_off, dip6, attr[HINIC5_TC_FIELD_DST_IPV6]);
- WRITE_FIELD_U8(rule_st_off, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
- WRITE_FIELD_U16(rule_st_off, sport, attr[HINIC5_TC_FIELD_SRC_PORT]);
- WRITE_FIELD_U16(rule_st_off, dport, attr[HINIC5_TC_FIELD_DST_PORT]);
+ WRITE_IP6_128BITS_OPT_OFF(rule_st_off, sip6,
+ attr[HINIC5_TC_FIELD_SRC_IPV6]);
+ WRITE_IP6_128BITS_OPT_OFF(rule_st_off, dip6,
+ attr[HINIC5_TC_FIELD_DST_IPV6]);
+ WRITE_FIELD_U8(rule_st_off, proto,
+ attr[HINIC5_TC_FIELD_PROTOCOL]);
+ WRITE_FIELD_U16(rule_st_off, sport,
+ attr[HINIC5_TC_FIELD_SRC_PORT]);
+ WRITE_FIELD_U16(rule_st_off, dport,
+ attr[HINIC5_TC_FIELD_DST_PORT]);
} else {
hinic5_tc_set_ip6_trunc(attr, tc_info, &ip6_trunc);
WRITE_VNI(rule_st_on, attr[HINIC5_TC_FIELD_VNI]);
WRITE_MAC(rule_st_on, smac, attr[HINIC5_TC_FIELD_SRC_MAC]);
WRITE_MAC(rule_st_on, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
- WRITE_FIELD_U16(rule_st_on, ether_type, attr[HINIC5_TC_FIELD_ETH_TYPE]);
- WRITE_SIP6_72BITS_OPT_ON(rule_st_on, attr[HINIC5_TC_FIELD_SRC_IPV6]);
- WRITE_DIP6_72BITS_OPT_ON(rule_st_on, attr[HINIC5_TC_FIELD_DST_IPV6]);
- WRITE_FIELD_U8(rule_st_on, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
- WRITE_FIELD_U16(rule_st_on, sport, attr[HINIC5_TC_FIELD_SRC_PORT]);
- WRITE_FIELD_U16(rule_st_on, dport, attr[HINIC5_TC_FIELD_DST_PORT]);
+ WRITE_FIELD_U16(rule_st_on, ether_type,
+ attr[HINIC5_TC_FIELD_ETH_TYPE]);
+ WRITE_SIP6_72BITS_OPT_ON(rule_st_on,
+ attr[HINIC5_TC_FIELD_SRC_IPV6]);
+ WRITE_DIP6_72BITS_OPT_ON(rule_st_on,
+ attr[HINIC5_TC_FIELD_DST_IPV6]);
+ WRITE_FIELD_U8(rule_st_on, proto,
+ attr[HINIC5_TC_FIELD_PROTOCOL]);
+ WRITE_FIELD_U16(rule_st_on, sport,
+ attr[HINIC5_TC_FIELD_SRC_PORT]);
+ WRITE_FIELD_U16(rule_st_on, dport,
+ attr[HINIC5_TC_FIELD_DST_PORT]);
}
}
@@ -649,7 +684,8 @@ static void hinic5_tc_get_key_eth_ip6(const u8 *attr[],
const struct hinic5_tc_info *tc_info,
u8 *mem)
{
- struct hinic5_tc_rule_eth_ip6 *rule_st = (struct hinic5_tc_rule_eth_ip6 *)mem;
+ struct hinic5_tc_rule_eth_ip6 *rule_st =
+ (struct hinic5_tc_rule_eth_ip6 *)mem;
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
WRITE_IP6_128BITS(rule_st, sip6, attr[HINIC5_TC_FIELD_SRC_IPV6]);
@@ -657,13 +693,12 @@ static void hinic5_tc_get_key_eth_ip6(const u8 *attr[],
WRITE_FIELD_U8(rule_st, proto, attr[HINIC5_TC_FIELD_PROTOCOL]);
}
-static void hinic5_tc_get_key_eth_ip6_tcporudp(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_eth_ip6_tcporudp(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_eth_ip6_tcporudp *rule_st =
- (struct hinic5_tc_rule_eth_ip6_tcporudp *)mem;
- struct hinic5_tc_ip6_trunc ip6_trunc = {0};
+ (struct hinic5_tc_rule_eth_ip6_tcporudp *)mem;
+ struct hinic5_tc_ip6_trunc ip6_trunc = { 0 };
hinic5_tc_set_ip6_trunc(attr, tc_info, &ip6_trunc);
WRITE_MAC(rule_st, dmac, attr[HINIC5_TC_FIELD_DST_MAC]);
@@ -674,19 +709,21 @@ static void hinic5_tc_get_key_eth_ip6_tcporudp(const u8 *attr[],
WRITE_FIELD_SPLIT_U16(rule_st, dport, attr[HINIC5_TC_FIELD_DST_PORT]);
}
-static void hinic5_tc_get_key_outer_ip_inner_ip(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_outer_ip_inner_ip(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_outer_ip_inner_ip *rule_st =
- (struct hinic5_tc_rule_outer_ip_inner_ip *)mem;
+ (struct hinic5_tc_rule_outer_ip_inner_ip *)mem;
if (tc_info->enc_ip_type == ENC_IPV4_TYPE) {
- WRITE_FIELD_U16(rule_st, outer_dip_6, attr[HINIC5_TC_FIELD_ENC_DST_IP]);
+ WRITE_FIELD_U16(rule_st, outer_dip_6,
+ attr[HINIC5_TC_FIELD_ENC_DST_IP]);
WRITE_FIELD_U16(rule_st, outer_dip_7,
- attr[HINIC5_TC_FIELD_ENC_DST_IP] + OFFSET_2BYTE);
+ attr[HINIC5_TC_FIELD_ENC_DST_IP] +
+ OFFSET_2BYTE);
} else {
- WRITE_IP6_128BITS(rule_st, outer_dip, attr[HINIC5_TC_FIELD_ENC_DST_IPV6]);
+ WRITE_IP6_128BITS(rule_st, outer_dip,
+ attr[HINIC5_TC_FIELD_ENC_DST_IPV6]);
}
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
@@ -694,19 +731,21 @@ static void hinic5_tc_get_key_outer_ip_inner_ip(const u8 *attr[],
WRITE_IP4(rule_st, dip, attr[HINIC5_TC_FIELD_DST_IP]);
}
-static void hinic5_tc_get_key_outer_ip_inner_ip_tcporudp(const u8 *attr[],
- const struct hinic5_tc_info *tc_info,
- u8 *mem)
+static void hinic5_tc_get_key_outer_ip_inner_ip_tcporudp(
+ const u8 *attr[], const struct hinic5_tc_info *tc_info, u8 *mem)
{
struct hinic5_tc_rule_outer_ip_inner_ip_tcporudp *rule_st =
- (struct hinic5_tc_rule_outer_ip_inner_ip_tcporudp *)mem;
+ (struct hinic5_tc_rule_outer_ip_inner_ip_tcporudp *)mem;
if (tc_info->enc_ip_type == ENC_IPV4_TYPE) {
- WRITE_FIELD_U16(rule_st, outer_dip_6, attr[HINIC5_TC_FIELD_ENC_DST_IP]);
+ WRITE_FIELD_U16(rule_st, outer_dip_6,
+ attr[HINIC5_TC_FIELD_ENC_DST_IP]);
WRITE_FIELD_U16(rule_st, outer_dip_7,
- attr[HINIC5_TC_FIELD_ENC_DST_IP] + OFFSET_2BYTE);
+ attr[HINIC5_TC_FIELD_ENC_DST_IP] +
+ OFFSET_2BYTE);
} else {
- WRITE_IP6_128BITS(rule_st, outer_dip, attr[HINIC5_TC_FIELD_ENC_DST_IPV6]);
+ WRITE_IP6_128BITS(rule_st, outer_dip,
+ attr[HINIC5_TC_FIELD_ENC_DST_IPV6]);
}
WRITE_VNI(rule_st, attr[HINIC5_TC_FIELD_VNI]);
@@ -740,13 +779,13 @@ static hinic5_tc_key_func hinic5_tc_get_key_func(u16 profile_id)
return g_hinic5_tc_key_funcs[profile_id];
}
-static int hinic5_tc_parse_key(struct hinic5_tc_flow *flow,
- u8 *mem,
+static int hinic5_tc_parse_key(struct hinic5_tc_flow *flow, u8 *mem,
struct hinic5_nic_dev *nic_dev,
enum parse_type type)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
- const u8 *attr[HINIC5_TC_FIELD_TYPE_MAX] = {NULL};
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
+ const u8 *attr[HINIC5_TC_FIELD_TYPE_MAX] = { NULL };
u16 profile_id, tunnel_opt;
hinic5_tc_key_func key_func = NULL;
u16 flags;
@@ -758,7 +797,9 @@ static int hinic5_tc_parse_key(struct hinic5_tc_flow *flow,
/* verify profile_id */
if (profile_id >= HINIC5_TC_PROFILE_MAX) {
- hinic5_err(nic_dev, drv, "profile_id exceed limit: profile_id = %u\n", profile_id);
+ hinic5_err(nic_dev, drv,
+ "profile_id exceed limit: profile_id = %u\n",
+ profile_id);
return -EINVAL;
}
@@ -766,8 +807,10 @@ static int hinic5_tc_parse_key(struct hinic5_tc_flow *flow,
flags = hinic5_tc_get_key_flags(profile_id, tunnel_opt);
if ((flow->key_flags & flags) != flags) {
- hinic5_err(nic_dev, drv, "flow key flags not match, flow_flags(%u) key_flags(%u)\n",
- flow->key_flags, flags);
+ hinic5_err(
+ nic_dev, drv,
+ "flow key flags not match, flow_flags(%u) key_flags(%u)\n",
+ flow->key_flags, flags);
return -EINVAL;
}
@@ -782,11 +825,12 @@ static int hinic5_tc_parse_key(struct hinic5_tc_flow *flow,
return 0;
}
-#define ACT_VXLAN_TBL_INDEX_BITS 8
-#define ACT_FLOW_MARK_BITS 24
-#define ACT_VLAN_SEL_BITS 3
-#define ACT_COUNT_ID_BITS 9
-#define ACT_CHECK_VLD(field_val, field_bits) ((field_val) < (1ULL << (field_bits)))
+#define ACT_VXLAN_TBL_INDEX_BITS 8
+#define ACT_FLOW_MARK_BITS 24
+#define ACT_VLAN_SEL_BITS 3
+#define ACT_COUNT_ID_BITS 9
+#define ACT_CHECK_VLD(field_val, field_bits) \
+ ((field_val) < (1ULL << (field_bits)))
static int hinic5_tc_parse_action_tunnel(struct hinic5_tc_action_info *action,
const struct flow_action_entry *act)
@@ -810,11 +854,11 @@ static int hinic5_tc_parse_action_tunnel(struct hinic5_tc_action_info *action,
static void hinic5_tc_parse_action_output(struct hinic5_tc_action_info *action,
const struct flow_action_entry *act)
{
- // action queue + action output temporary stub solution
+ // action queue + action output 临时打桩方案
/* output, chain_index[15:0]
- * queue index, chain_index[23:16]
- *queue flag, chain_index[31:24]
- */
+ queue index, chain_index[23:16]
+ queue flag, chain_index[31:24]
+ */
action->output = act->chain_index & U16_MAX;
action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_OUTPUT);
if ((act->chain_index >> SHIFT_24BITS) > 0) {
@@ -823,7 +867,8 @@ static void hinic5_tc_parse_action_output(struct hinic5_tc_action_info *action,
}
}
-static int hinic5_tc_parse_action(struct flow_action *flow_action, struct hinic5_nic_dev *nic_dev,
+static int hinic5_tc_parse_action(struct flow_action *flow_action,
+ struct hinic5_nic_dev *nic_dev,
struct hinic5_tc_action_info *action)
{
struct flow_action_entry *act = NULL;
@@ -839,12 +884,14 @@ static int hinic5_tc_parse_action(struct flow_action *flow_action, struct hinic5
case FLOW_ACTION_DROP:
action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_DROP);
break;
- case FLOW_ACTION_ACCEPT: // action upcall function stub
- action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_UPCALL);
+ case FLOW_ACTION_ACCEPT: // action upcall功能打桩
+ action->action_flag |=
+ BIT(HINIC5_TC_ACTION_FLOW_UPCALL);
break;
case FLOW_ACTION_MARK:
action->flow_mark = act->mark;
- if (!ACT_CHECK_VLD(action->flow_mark, ACT_FLOW_MARK_BITS))
+ if (!ACT_CHECK_VLD(action->flow_mark,
+ ACT_FLOW_MARK_BITS))
return -EINVAL;
action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_MARK);
break;
@@ -852,7 +899,7 @@ static int hinic5_tc_parse_action(struct flow_action *flow_action, struct hinic5
hinic5_tc_parse_action_output(action, act);
break;
#ifdef HAVE_FLOW_ACTION_PRIORITY
- case FLOW_ACTION_PRIORITY: // action count function stub
+ case FLOW_ACTION_PRIORITY: // action count功能打桩
action->count_id = (u16)act->priority;
if (!ACT_CHECK_VLD(action->count_id, ACT_COUNT_ID_BITS))
return -EINVAL;
@@ -864,20 +911,24 @@ static int hinic5_tc_parse_action(struct flow_action *flow_action, struct hinic5
action->vlan_sel = act->vlan.prio;
if (!ACT_CHECK_VLD(action->vlan_sel, ACT_VLAN_SEL_BITS))
return -EINVAL;
- action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_VLAN_PUSH);
+ action->action_flag |=
+ BIT(HINIC5_TC_ACTION_FLOW_VLAN_PUSH);
break;
case FLOW_ACTION_VLAN_POP:
- action->action_flag |= BIT(HINIC5_TC_ACTION_FLOW_VLAN_POP);
+ action->action_flag |=
+ BIT(HINIC5_TC_ACTION_FLOW_VLAN_POP);
break;
case FLOW_ACTION_TUNNEL_ENCAP:
if (hinic5_tc_parse_action_tunnel(action, act) != 0)
return -EOPNOTSUPP;
break;
case FLOW_ACTION_TUNNEL_DECAP:
- action->action_flag |= BIT(HINIC5_TC_ACTION_VXLAN_DECAP);
+ action->action_flag |=
+ BIT(HINIC5_TC_ACTION_VXLAN_DECAP);
break;
default:
- hinic5_err(nic_dev, drv, "act(%u) not support offload\n", act->id);
+ hinic5_err(nic_dev, drv,
+ "act(%u) not support offload\n", act->id);
break;
}
}
@@ -886,7 +937,8 @@ static int hinic5_tc_parse_action(struct flow_action *flow_action, struct hinic5
int hinic5_tc_set_profile_id(struct hinic5_nic_dev *nic_dev, u16 profile_id)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
if (profile_id >= HINIC5_TC_PROFILE_MAX) {
hinic5_err(nic_dev, drv, "profile_id exceed limit\n");
@@ -913,8 +965,10 @@ static int hinic5_tc_set_flow_info(struct hinic5_nic_dev *nic_dev,
}
/* parse mask, unassigned data set all f */
- memset(info->mask_tcam_mem, 0xFF, TC_ACL_KEY_BYTE);
- ret = hinic5_tc_parse_key(flow, info->mask_tcam_mem, nic_dev, MASK_TYPE);
+ (void)memset_s(info->mask_tcam_mem, TC_ACL_KEY_BYTE, 0xFF,
+ TC_ACL_KEY_BYTE);
+ ret = hinic5_tc_parse_key(flow, info->mask_tcam_mem, nic_dev,
+ MASK_TYPE);
if (ret != 0) {
hinic5_err(nic_dev, drv, "parse mask failed\n");
return -EINVAL;
@@ -937,7 +991,8 @@ static int hinic5_tc_parse_flow(struct flow_cls_offload *tc_flow_cmd,
/* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
(dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
- hinic5_err(nic_dev, drv, "cannot form TC key: used_keys = 0x%x\n",
+ hinic5_err(nic_dev, drv,
+ "cannot form TC key: used_keys = 0x%x\n",
(unsigned int)dissector->used_keys);
return -EOPNOTSUPP;
}
@@ -961,12 +1016,69 @@ static int hinic5_tc_parse_flow(struct flow_cls_offload *tc_flow_cmd,
return 0;
}
+static struct hinic5_tc_flow_node *
+hinic5_tc_create_flow_node(struct flow_cls_offload *cls_flower)
+{
+ struct hinic5_tc_flow_node *new_node = NULL;
+
+ new_node = kzalloc(sizeof(*new_node), GFP_KERNEL);
+ if (!new_node)
+ return NULL;
+
+ new_node->cookie = cls_flower->cookie;
+ return new_node;
+}
+
+static int hinic5_tc_convert_to_cfg(struct hinic5_nic_dev *nic_dev,
+ struct flow_cls_offload *cls_flower,
+ struct hinic5_tc_flow *flow,
+ struct hinic5_tc_cfg_info *info)
+{
+ int ret;
+
+ ret = hinic5_tc_set_flow_info(nic_dev, flow, info);
+ if (ret != 0)
+ return ret;
+
+ info->group_id = cls_flower->common.chain_index & PFE_GROUP_ID_MASK;
+ if (info->group_id < PFE_GROUP_CNT_MAX) {
+ info->group_vld = (cls_flower->common.chain_index >>
+ PFE_GROUP_VLD_SHIFT) &
+ 0x1;
+ } else {
+ hinic5_err(nic_dev, drv, "invalid group id:0x%x\n",
+ info->group_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hinic5_tc_insert_flow_node(struct hinic5_tc_info *tc_info,
+ struct hinic5_tc_flow_node *new_node,
+ u16 rule_id)
+{
+ int ret;
+
+ ret = rhashtable_insert_fast(&tc_info->flow_table, &new_node->node,
+ tc_info->flow_ht_params);
+ if (ret != 0)
+ return ret;
+
+ mutex_lock(&tc_info->tc_lock);
+ set_bit(rule_id, tc_info->tcam_bitmap);
+ mutex_unlock(&tc_info->tc_lock);
+
+ return 0;
+}
+
static int hinic5_add_cls_flower(struct flow_cls_offload *cls_flower,
struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
struct hinic5_tc_flow_node *new_node = NULL, *old_node = NULL;
- struct hinic5_tc_cfg_info info = {0};
+ struct hinic5_tc_cfg_info info = { 0 };
struct hinic5_tc_flow *flow = NULL;
int ret;
@@ -976,75 +1088,66 @@ static int hinic5_add_cls_flower(struct flow_cls_offload *cls_flower,
return -EOPNOTSUPP;
}
- new_node = kzalloc(sizeof(*new_node), GFP_KERNEL);
+ /* Create new flow node */
+ new_node = hinic5_tc_create_flow_node(cls_flower);
if (!new_node)
return -ENOMEM;
- new_node->cookie = cls_flower->cookie;
flow = &new_node->flow;
- /* If a flow exists with the same cookie, delete it */
- old_node = rhashtable_lookup_fast(&tc_info->flow_table, &cls_flower->cookie,
+ /* Check and delete existing flow with same cookie */
+ old_node = rhashtable_lookup_fast(&tc_info->flow_table,
+ &cls_flower->cookie,
tc_info->flow_ht_params);
if (old_node)
hinic5_tc_del_flow_handler(nic_dev, old_node);
+ /* Parse flow specification */
ret = hinic5_tc_parse_flow(cls_flower, nic_dev, flow, tc_info);
if (ret != 0)
goto fail;
- /* trans flow to tc_cfg_info */
- ret = hinic5_tc_set_flow_info(nic_dev, flow, &info);
+ /* Convert flow to TC configuration */
+ ret = hinic5_tc_convert_to_cfg(nic_dev, cls_flower, flow, &info);
if (ret != 0)
goto fail;
- info.group_id = cls_flower->common.chain_index & PFE_GROUP_ID_MASK;
- if (info.group_id < PFE_GROUP_CNT_MAX) {
- info.group_vld = (cls_flower->common.chain_index >> PFE_GROUP_VLD_SHIFT) & 0x1;
- } else {
- hinic5_err(nic_dev, drv, "invalid group id:0x%x\n", info.group_id);
- goto fail;
- }
-
- /* send rule to mpu */
+ /* Add flow rule to hardware */
ret = hinic5_add_tc_flow_rule(nic_dev->hwdev, &info, false);
if (ret != 0)
goto fail;
new_node->rule_id = info.index;
- /* save rule in hashmap */
- ret = rhashtable_insert_fast(&tc_info->flow_table, &new_node->node,
- tc_info->flow_ht_params);
+ /* Insert into hash table and update bitmap */
+ ret = hinic5_tc_insert_flow_node(tc_info, new_node, info.index);
if (ret != 0) {
hinic5_del_tc_flow_rule(nic_dev->hwdev, info.index);
goto fail;
}
- mutex_lock(&tc_info->tc_lock);
- set_bit(info.index, tc_info->tcam_bitmap);
- mutex_unlock(&tc_info->tc_lock);
-
hinic5_info(nic_dev, drv, "Add tc rule cookie=0x%lx, index = %u\n",
cls_flower->cookie, info.index);
return 0;
fail:
kfree(new_node);
- hinic5_err(nic_dev, drv, "cookie=0x%lx error=%d\n",
- cls_flower->cookie, ret);
+ hinic5_err(nic_dev, drv, "cookie=0x%lx error=%d\n", cls_flower->cookie,
+ ret);
return ret;
}
static int hinic5_del_cls_flower(const struct flow_cls_offload *cls_flower,
struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
struct hinic5_tc_flow_node *flow_node = NULL;
- if (!tc_info)
+ if (tc_info == NULL)
return 0;
- flow_node = rhashtable_lookup_fast(&tc_info->flow_table, &cls_flower->cookie,
+ flow_node = rhashtable_lookup_fast(&tc_info->flow_table,
+ &cls_flower->cookie,
tc_info->flow_ht_params);
if (!flow_node) {
hinic5_err(nic_dev, drv, "flow with cookie=0x%lx not exist\n",
@@ -1073,10 +1176,12 @@ int hinic5_setup_cls_flower(struct flow_cls_offload *cls_flower,
}
}
-static int hinic5_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+static int hinic5_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+ void *cb_priv)
{
struct hinic5_nic_dev *nic_dev = cb_priv;
- struct flow_cls_offload *cls_flower = (struct flow_cls_offload *)type_data;
+ struct flow_cls_offload *cls_flower =
+ (struct flow_cls_offload *)type_data;
switch (type) {
case TC_SETUP_CLSFLOWER:
@@ -1088,27 +1193,31 @@ static int hinic5_setup_tc_block_cb(enum tc_setup_type type, void *type_data, vo
static LIST_HEAD(hinic5_block_cb_list);
-int hinic5_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data)
+int hinic5_setup_tc(struct net_device *netdev, enum tc_setup_type type,
+ void *type_data)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
switch (type) {
case TC_SETUP_BLOCK:
- return flow_block_cb_setup_simple(type_data, &hinic5_block_cb_list,
- hinic5_setup_tc_block_cb, nic_dev, nic_dev, true);
+ return flow_block_cb_setup_simple(type_data,
+ &hinic5_block_cb_list,
+ hinic5_setup_tc_block_cb,
+ nic_dev, nic_dev, true);
default:
return -EOPNOTSUPP;
}
}
-/* PFE default rule for LACP negotiation packets */
+/* PFE设置lacp协商报文的默认规则 */
static int hinic5_set_default_rule_of_pfe_lcam(struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
- struct hinic5_tc_cfg_info info = {0};
- struct hinic5_tc_flow flow = {0};
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_cfg_info info = { 0 };
+ struct hinic5_tc_flow flow = { 0 };
u8 *mac = (u8 *)nic_dev->netdev->dev_addr;
- u8 lacp_dmac[ETH_ALEN] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x02};
+ u8 lacp_dmac[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02 };
if (hinic5_func_type(nic_dev->hwdev) == TYPE_VF)
return 0;
@@ -1116,12 +1225,13 @@ static int hinic5_set_default_rule_of_pfe_lcam(struct hinic5_nic_dev *nic_dev)
tc_info->profile_id = HINIC5_TC_PROFILE_ETH_QINQ;
flow.key_flags = TC_LACP_KEY_FLAG;
flow.actions.action_flag = PFE_ACTION_TO_PORT;
- memset(flow.l2_mask.dmac, 0xff, ETH_ALEN);
- memset(flow.l2_mask.smac, 0xff, ETH_ALEN);
- memset(&flow.l2_mask.ether_type, 0xff, sizeof(flow.l2_mask.ether_type));
- memcpy(flow.l2_key.dmac, lacp_dmac, ETH_ALEN);
+ memset_s(flow.l2_mask.dmac, ETH_ALEN, 0xff, ETH_ALEN);
+ memset_s(flow.l2_mask.smac, ETH_ALEN, 0xff, ETH_ALEN);
+ memset_s(&flow.l2_mask.ether_type, sizeof(flow.l2_mask.ether_type),
+ 0xff, sizeof(flow.l2_mask.ether_type));
+ memcpy_s(flow.l2_key.dmac, ETH_ALEN, lacp_dmac, ETH_ALEN);
flow.l2_key.ether_type = cpu_to_be16(TYPE_OF_LACP);
- memcpy(flow.l2_key.smac, mac, ETH_ALEN);
+ memcpy_s(flow.l2_key.smac, ETH_ALEN, mac, ETH_ALEN);
/* trans flow to tc_cfg_info */
(void)hinic5_tc_set_flow_info(nic_dev, &flow, &info);
@@ -1144,7 +1254,7 @@ int hinic5_init_tc(struct hinic5_nic_dev *nic_dev)
int ret;
nic_dev->tc_info = kmalloc(sizeof(struct hinic5_tc_info), GFP_KERNEL);
- if (!nic_dev->tc_info)
+ if (nic_dev->tc_info == NULL)
return -ENOMEM;
tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
@@ -1155,7 +1265,8 @@ int hinic5_init_tc(struct hinic5_nic_dev *nic_dev)
tc_info->profile_id = 0;
mutex_init(&tc_info->tc_lock);
- memset(tc_info->tcam_bitmap, 0, sizeof(tc_info->tcam_bitmap));
+ memset_s(tc_info->tcam_bitmap, sizeof(tc_info->tcam_bitmap), 0,
+ sizeof(tc_info->tcam_bitmap));
(void)hinic5_set_default_rule_of_pfe_lcam(nic_dev);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.h
index e2d6f2ad7..d1bc45b52 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ethtool/hinic5_tc.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_tc.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_TC_H
#define HINIC5_TC_H
@@ -58,11 +51,11 @@ enum hinic5_tc_field_type {
};
struct hinic5_tc_l2_key {
- u8 dmac[ETH_ALEN];
- u8 smac[ETH_ALEN];
- __be16 vlan_tag;
- __be16 cvlan_tag;
- __be16 ether_type;
+ u8 dmac[ETH_ALEN];
+ u8 smac[ETH_ALEN];
+ __be16 vlan_tag;
+ __be16 cvlan_tag;
+ __be16 ether_type;
u32 vni;
};
@@ -90,7 +83,7 @@ struct hinic5_tc_l3_key {
};
struct hinic5_tc_l4_key {
- u8 ip_proto;
+ u8 ip_proto;
struct {
__be16 sport;
__be16 dport;
@@ -99,13 +92,13 @@ struct hinic5_tc_l4_key {
struct hinic5_tc_flow {
u16 key_flags;
- struct hinic5_tc_l2_key l2_key;
- struct hinic5_tc_l2_key l2_mask;
- struct hinic5_tc_l3_key l3_key;
- struct hinic5_tc_l3_key l3_mask;
- struct hinic5_tc_l4_key l4_key;
- struct hinic5_tc_l4_key l4_mask;
- struct hinic5_tc_action_info actions;
+ struct hinic5_tc_l2_key l2_key;
+ struct hinic5_tc_l2_key l2_mask;
+ struct hinic5_tc_l3_key l3_key;
+ struct hinic5_tc_l3_key l3_mask;
+ struct hinic5_tc_l4_key l4_key;
+ struct hinic5_tc_l4_key l4_mask;
+ struct hinic5_tc_action_info actions;
};
#define SHIFT_8BITS 8
@@ -129,93 +122,126 @@ struct hinic5_tc_flow {
#define FIELD_BYTE_14 14
#define FIELD_BYTE_15 15
-#define FIELD_U16(data, hi, lo) \
- (((data)[hi] << SHIFT_8BITS) | (data)[lo])
+#define FIELD_U16(data, hi, lo) (((data)[hi] << SHIFT_8BITS) | (data)[lo])
-#define WRITE_MAC(rule_st, field, data) do { \
- (rule_st)->field##_0 = (data)[FIELD_BYTE_0]; \
- (rule_st)->field##_1 = (data)[FIELD_BYTE_1]; \
- (rule_st)->field##_2 = (data)[FIELD_BYTE_2]; \
- (rule_st)->field##_3 = (data)[FIELD_BYTE_3]; \
- (rule_st)->field##_4 = (data)[FIELD_BYTE_4]; \
- (rule_st)->field##_5 = (data)[FIELD_BYTE_5]; \
-} while (0)
+#define WRITE_MAC(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_0 = (data)[FIELD_BYTE_0]; \
+ (rule_st)->field##_1 = (data)[FIELD_BYTE_1]; \
+ (rule_st)->field##_2 = (data)[FIELD_BYTE_2]; \
+ (rule_st)->field##_3 = (data)[FIELD_BYTE_3]; \
+ (rule_st)->field##_4 = (data)[FIELD_BYTE_4]; \
+ (rule_st)->field##_5 = (data)[FIELD_BYTE_5]; \
+ } while (0)
-#define WRITE_VNI(rule_st, data) do { \
- (rule_st)->vni_h = FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_1); \
- (rule_st)->vni_l = (data)[FIELD_BYTE_0]; \
-} while (0)
+#define WRITE_VNI(rule_st, data) \
+ do { \
+ (rule_st)->vni_h = \
+ FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_1); \
+ (rule_st)->vni_l = (data)[FIELD_BYTE_0]; \
+ } while (0)
-#define WRITE_FIELD_U8(rule_st, field, data) \
- ((rule_st)->field = (data)[FIELD_BYTE_0])
+#define WRITE_FIELD_U8(rule_st, field, data) \
+ (rule_st)->field = (data)[FIELD_BYTE_0]
#define WRITE_FIELD_U16(rule_st, field, data) \
- ((rule_st)->field = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1))
-
-#define WRITE_FIELD_SPLIT_U16(rule_st, field, data) do { \
- (rule_st)->field##_l = (data)[FIELD_BYTE_1]; \
- (rule_st)->field##_h = (data)[FIELD_BYTE_0]; \
-} while (0)
-
-#define WRITE_IP4(rule_st, field, data) do { \
- (rule_st)->field##_0 = (data)[FIELD_BYTE_0]; \
- (rule_st)->field##_1 = (data)[FIELD_BYTE_1]; \
- (rule_st)->field##_2 = (data)[FIELD_BYTE_2]; \
- (rule_st)->field##_3 = (data)[FIELD_BYTE_3]; \
-} while (0)
-
-#define WRITE_IP6_128BITS(rule_st, field, data) do { \
- (rule_st)->field##_0 = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
- (rule_st)->field##_1 = FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
- (rule_st)->field##_2 = FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
- (rule_st)->field##_3 = FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
- (rule_st)->field##_4 = FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
- (rule_st)->field##_5 = FIELD_U16(data, FIELD_BYTE_10, FIELD_BYTE_11); \
- (rule_st)->field##_6 = FIELD_U16(data, FIELD_BYTE_12, FIELD_BYTE_13); \
- (rule_st)->field##_7 = FIELD_U16(data, FIELD_BYTE_14, FIELD_BYTE_15); \
-} while (0)
-
-#define WRITE_IP6_96BITS(rule_st, field, data) do { \
- (rule_st)->field##_0 = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
- (rule_st)->field##_1 = FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
- (rule_st)->field##_2 = FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
- (rule_st)->field##_3 = FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
- (rule_st)->field##_4 = FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
- (rule_st)->field##_5 = FIELD_U16(data, FIELD_BYTE_10, FIELD_BYTE_11); \
-} while (0)
-
-#define WRITE_IP6_128BITS_OPT_OFF(rule_st, field, data) do { \
- (rule_st)->field##_0 = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
- (rule_st)->field##_1_h = (data)[FIELD_BYTE_2]; \
- (rule_st)->field##_1_l = (data)[FIELD_BYTE_3]; \
- (rule_st)->field##_2 = FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
- (rule_st)->field##_3_h = (data)[FIELD_BYTE_6]; \
- (rule_st)->field##_3_l = (data)[FIELD_BYTE_7]; \
- (rule_st)->field##_4 = FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
- (rule_st)->field##_5_h = (data)[FIELD_BYTE_10]; \
- (rule_st)->field##_5_l = (data)[FIELD_BYTE_11]; \
- (rule_st)->field##_6 = FIELD_U16(data, FIELD_BYTE_12, FIELD_BYTE_13); \
- (rule_st)->field##_7_h = (data)[FIELD_BYTE_14]; \
- (rule_st)->field##_7_l = (data)[FIELD_BYTE_15]; \
-} while (0)
-
-#define WRITE_SIP6_72BITS_OPT_ON(rule_st, data) do { \
- (rule_st)->sip6_0_h = (data)[FIELD_BYTE_0]; \
- (rule_st)->sip6_0_l = (data)[FIELD_BYTE_1]; \
- (rule_st)->sip6_1 = FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
- (rule_st)->sip6_2_h = (data)[FIELD_BYTE_4]; \
- (rule_st)->sip6_2_l = (data)[FIELD_BYTE_5]; \
- (rule_st)->sip6_3 = FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
- (rule_st)->sip6_4_h = (data)[FIELD_BYTE_8]; \
-} while (0)
-
-#define WRITE_DIP6_72BITS_OPT_ON(rule_st, data) do { \
- (rule_st)->dip6_0 = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
- (rule_st)->dip6_1 = FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
- (rule_st)->dip6_2 = FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
- (rule_st)->dip6_3 = FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
- (rule_st)->dip6_4_h = (data)[FIELD_BYTE_8]; \
-} while (0)
+ (rule_st)->field = FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1)
+
+#define WRITE_FIELD_SPLIT_U16(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_l = (data)[FIELD_BYTE_1]; \
+ (rule_st)->field##_h = (data)[FIELD_BYTE_0]; \
+ } while (0)
+
+#define WRITE_IP4(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_0 = (data)[FIELD_BYTE_0]; \
+ (rule_st)->field##_1 = (data)[FIELD_BYTE_1]; \
+ (rule_st)->field##_2 = (data)[FIELD_BYTE_2]; \
+ (rule_st)->field##_3 = (data)[FIELD_BYTE_3]; \
+ } while (0)
+
+#define WRITE_IP6_128BITS(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_0 = \
+ FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
+ (rule_st)->field##_1 = \
+ FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
+ (rule_st)->field##_2 = \
+ FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
+ (rule_st)->field##_3 = \
+ FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
+ (rule_st)->field##_4 = \
+ FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
+ (rule_st)->field##_5 = \
+ FIELD_U16(data, FIELD_BYTE_10, FIELD_BYTE_11); \
+ (rule_st)->field##_6 = \
+ FIELD_U16(data, FIELD_BYTE_12, FIELD_BYTE_13); \
+ (rule_st)->field##_7 = \
+ FIELD_U16(data, FIELD_BYTE_14, FIELD_BYTE_15); \
+ } while (0)
+
+#define WRITE_IP6_96BITS(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_0 = \
+ FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
+ (rule_st)->field##_1 = \
+ FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
+ (rule_st)->field##_2 = \
+ FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
+ (rule_st)->field##_3 = \
+ FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
+ (rule_st)->field##_4 = \
+ FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
+ (rule_st)->field##_5 = \
+ FIELD_U16(data, FIELD_BYTE_10, FIELD_BYTE_11); \
+ } while (0)
+
+#define WRITE_IP6_128BITS_OPT_OFF(rule_st, field, data) \
+ do { \
+ (rule_st)->field##_0 = \
+ FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
+ (rule_st)->field##_1_h = (data)[FIELD_BYTE_2]; \
+ (rule_st)->field##_1_l = (data)[FIELD_BYTE_3]; \
+ (rule_st)->field##_2 = \
+ FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
+ (rule_st)->field##_3_h = (data)[FIELD_BYTE_6]; \
+ (rule_st)->field##_3_l = (data)[FIELD_BYTE_7]; \
+ (rule_st)->field##_4 = \
+ FIELD_U16(data, FIELD_BYTE_8, FIELD_BYTE_9); \
+ (rule_st)->field##_5_h = (data)[FIELD_BYTE_10]; \
+ (rule_st)->field##_5_l = (data)[FIELD_BYTE_11]; \
+ (rule_st)->field##_6 = \
+ FIELD_U16(data, FIELD_BYTE_12, FIELD_BYTE_13); \
+ (rule_st)->field##_7_h = (data)[FIELD_BYTE_14]; \
+ (rule_st)->field##_7_l = (data)[FIELD_BYTE_15]; \
+ } while (0)
+
+#define WRITE_SIP6_72BITS_OPT_ON(rule_st, data) \
+ do { \
+ (rule_st)->sip6_0_h = (data)[FIELD_BYTE_0]; \
+ (rule_st)->sip6_0_l = (data)[FIELD_BYTE_1]; \
+ (rule_st)->sip6_1 = \
+ FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
+ (rule_st)->sip6_2_h = (data)[FIELD_BYTE_4]; \
+ (rule_st)->sip6_2_l = (data)[FIELD_BYTE_5]; \
+ (rule_st)->sip6_3 = \
+ FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
+ (rule_st)->sip6_4_h = (data)[FIELD_BYTE_8]; \
+ } while (0)
+
+#define WRITE_DIP6_72BITS_OPT_ON(rule_st, data) \
+ do { \
+ (rule_st)->dip6_0 = \
+ FIELD_U16(data, FIELD_BYTE_0, FIELD_BYTE_1); \
+ (rule_st)->dip6_1 = \
+ FIELD_U16(data, FIELD_BYTE_2, FIELD_BYTE_3); \
+ (rule_st)->dip6_2 = \
+ FIELD_U16(data, FIELD_BYTE_4, FIELD_BYTE_5); \
+ (rule_st)->dip6_3 = \
+ FIELD_U16(data, FIELD_BYTE_6, FIELD_BYTE_7); \
+ (rule_st)->dip6_4_h = (data)[FIELD_BYTE_8]; \
+ } while (0)
#define BYTE8_SIZE 8
#define IP6_ADDR_TRUNC_72BITS 72
@@ -240,24 +266,18 @@ struct hinic5_tc_flow_node {
/* PFE tc info */
struct hinic5_tc_info {
u16 profile_id;
- /* PFE group key template 3-1 used: 1'b0: use template 3-1-1, 1'b1: use template 3-1-2 */
- u16 tunnel_opt;
- /* PFE group key template 3-2 IPV6 sip truncation offset value N,
- * truncate [N+len:N], maximum value is 32
- */
- u16 ipv6_shift_value;
- /* PFE group key template 3-1 IPV6 sip and dip truncation offset value N,
- * truncate [N+len:N], maximum value is 56
- */
- u16 ipv6_shift_value2;
- u16 enc_ip_type; /* Tunnel packet outer IP type: 0-ipv4, 1-ipv6 */
+ u16 tunnel_opt; /* PFE组key使用的模板3-1:1'b0:使用模板3-1-1,1'b1:使用模板3-1-2 */
+ u16 ipv6_shift_value; /* PFE组key模板3-2 IPV6 sip截断使用时的偏移值N,截取[N+len:N],最大值为32 */
+ u16 ipv6_shift_value2; /* PFE组key模板3-1 IPV6 sip和dip截断使用时的偏移值N,截取[N+len:N],最大值为56 */
+ u16 enc_ip_type; /* 隧道报文外层ip类型: 0-ipv4, 1-ipv6 */
ulong tcam_bitmap[HINIC5_TC_TCAM_BITMAP_LEN];
struct rhashtable flow_table;
struct rhashtable_params flow_ht_params;
- struct mutex tc_lock; /* Mutex to protect this structure from concurrent access */
+ struct mutex tc_lock;
};
-int hinic5_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data);
+int hinic5_setup_tc(struct net_device *netdev, enum tc_setup_type type,
+ void *type_data);
int hinic5_init_tc(struct hinic5_nic_dev *nic_dev);
void hinic5_deinit_tc(struct hinic5_nic_dev *nic_dev);
int hinic5_tc_set_profile_id(struct hinic5_nic_dev *nic_dev, u16 profile_id);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.c
index 40004ceec..ef2e70d80 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dbg.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -16,22 +9,23 @@
#include <linux/rhashtable.h>
#include <linux/netdevice.h>
+#include "bond_pub_cmd.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_structs.h"
#include "nic_pub_cmd.h"
#include "hinic5_crm.h"
#include "hinic5_hw.h"
#include "hinic5_nic_dev.h"
-#include "hinic5_nic_dbg.h"
-#include "hinic5_nic_sq.h"
#include "hinic5_nic_rq.h"
-#include "hinic5_rx.h"
-#include "hinic5_tx.h"
+#include "hinic5_nic_sq.h"
#include "hinic5_dcb.h"
-#include "hinic5_bond.h"
-#include "nic_cfg_comm.h"
-#include "bond_pub_cmd.h"
#include "hinic5_macsec_api.h"
+#include "hinic5_rx.h"
#include "hinic5_tc.h"
+#include "hinic5_tx.h"
+#include "drv_bond_api.h"
#include "drv_nic_api.h"
+#include "hinic5_nic_dbg.h"
#include "hinic5_dbg.h"
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
@@ -39,7 +33,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
struct drv_version_info *ver_info = buf_out;
int err;
- if (!buf_out) {
+ if (buf_out == NULL) {
pr_err("Buf_out is NULL.\n");
return -EINVAL;
}
@@ -50,8 +44,9 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC5_NIC_DRV_VERSION, "2026-05-20_00:00:00");
+ err = snprintf_s(ver_info->ver, sizeof(ver_info->ver),
+ sizeof(ver_info->ver) - 1, "%s %s",
+ HINIC5_NIC_DRV_VERSION, __TIME_STR__);
if (err < 0)
return -EINVAL;
@@ -71,13 +66,13 @@ static int get_tx_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if ((buf_in == NULL) || (buf_out == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || in_size != sizeof(u32)) {
+ if ((out_size == NULL) || in_size != sizeof(u32)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect in buf size from user :%u, expect: %lu\n",
in_size, sizeof(u32));
@@ -98,9 +93,8 @@ static int get_tx_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_q_num(struct hinic5_nic_dev *nic_dev,
- const void *buf_in, u32 in_size,
- void *buf_out, const u32 *out_size)
+static int get_q_num(struct hinic5_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
{
if (!HINIC5_CHANNEL_RES_VALID(nic_dev)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
@@ -108,7 +102,7 @@ static int get_q_num(struct hinic5_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out || !out_size) {
+ if ((buf_out == NULL) || (out_size == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Param buf_out or out_size is NULL.\n");
return -EINVAL;
@@ -126,9 +120,8 @@ static int get_q_num(struct hinic5_nic_dev *nic_dev,
return 0;
}
-static int get_tx_wqe_info(struct hinic5_nic_dev *nic_dev,
- const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+static int get_tx_wqe_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
const struct wqe_info *info = buf_in;
u16 wqebb_cnt = 1;
@@ -139,21 +132,23 @@ static int get_tx_wqe_info(struct hinic5_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ if ((buf_in == NULL) || (buf_out == NULL)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || in_size != sizeof(struct wqe_info)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, expect: %lu\n",
- in_size, sizeof(struct wqe_info));
+ if ((out_size == NULL) || in_size != sizeof(struct wqe_info)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ in_size, sizeof(struct wqe_info));
return -EINVAL;
}
return hinic5_dbg_get_wqe_info(nic_dev->hwdev, (u16)info->q_id,
- (u16)info->wqe_id, wqebb_cnt,
- buf_out, (u16 *)(u8 *)out_size, HINIC5_SQ);
+ (u16)info->wqe_id, wqebb_cnt, buf_out,
+ (u16 *)(u8 *)out_size, HINIC5_SQ);
}
static int get_rx_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
@@ -169,16 +164,17 @@ static int get_rx_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if ((buf_in == NULL) || (buf_out == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || in_size != sizeof(u32)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, expect: %lu\n",
- in_size, sizeof(u32));
+ if ((out_size == NULL) || in_size != sizeof(u32)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ in_size, sizeof(u32));
return -EINVAL;
}
@@ -192,7 +188,8 @@ static int get_rx_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -214,21 +211,23 @@ static int get_rx_wqe_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ if ((buf_in == NULL) || (buf_out == NULL)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || in_size != sizeof(struct wqe_info)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, expect: %lu\n",
- in_size, sizeof(struct wqe_info));
+ if ((out_size == NULL) || in_size != sizeof(struct wqe_info)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ in_size, sizeof(struct wqe_info));
return -EINVAL;
}
return hinic5_dbg_get_wqe_info(nic_dev->hwdev, (u16)info->q_id,
- (u16)info->wqe_id, wqebb_cnt,
- buf_out, (u16 *)(u8 *)out_size, HINIC5_RQ);
+ (u16)info->wqe_id, wqebb_cnt, buf_out,
+ (u16 *)(u8 *)out_size, HINIC5_RQ);
}
static int get_rx_cqe_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
@@ -244,16 +243,17 @@ static int get_rx_cqe_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out || !out_size) {
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in, buf_out or out_size is NULL.\n");
return -EINVAL;
}
if (in_size != sizeof(struct wqe_info)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, expect: %lu\n",
- in_size, sizeof(struct wqe_info));
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ in_size, sizeof(struct wqe_info));
return -EINVAL;
}
@@ -268,16 +268,21 @@ static int get_rx_cqe_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
if (q_id >= nic_dev->q_params.num_qps) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u.\n", q_id, nic_dev->q_params.num_qps);
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
return -EFAULT;
}
if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid wqe idx[%u] >= %u.\n", idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
- memcpy(buf_out, nic_dev->rxqs[q_id].rx_info[idx].cqe_info, sizeof(struct hinic5_cqe_info));
+ if (memcpy_s(buf_out, *out_size,
+ nic_dev->rxqs[q_id].rx_info[idx].cqe_info,
+ sizeof(struct hinic5_cqe_info)) != 0)
+ return -ENOMEM;
return 0;
}
@@ -300,7 +305,8 @@ static int clear_func_static(struct hinic5_nic_dev *nic_dev, const void *buf_in,
*out_size = 0;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- memset(&nic_dev->net_stats, 0, sizeof(nic_dev->net_stats));
+ (void)memset_s(&nic_dev->net_stats, sizeof(nic_dev->net_stats), 0,
+ sizeof(nic_dev->net_stats));
#endif
clean_nicdev_stats(nic_dev);
for (i = 0; i < nic_dev->max_qps; i++) {
@@ -316,7 +322,7 @@ static int get_loopback_mode(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
struct hinic5_nic_loop_mode *mode = buf_out;
- if (!out_size || !mode)
+ if ((out_size == NULL) || (mode == NULL))
return -EINVAL;
if (*out_size != sizeof(*mode)) {
@@ -342,7 +348,7 @@ static int set_loopback_mode(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!mode || !out_size || in_size != sizeof(*mode))
+ if ((mode == NULL) || (out_size == NULL) || in_size != sizeof(*mode))
return -EINVAL;
if (*out_size != sizeof(*mode)) {
@@ -355,7 +361,8 @@ static int set_loopback_mode(struct hinic5_nic_dev *nic_dev, const void *buf_in,
err = hinic5_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -378,7 +385,7 @@ static int set_link_mode_param_valid(struct hinic5_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_in || !out_size ||
+ if (buf_in == NULL || (out_size == NULL) ||
in_size != sizeof(enum hinic5_nic_link_mode))
return -EINVAL;
@@ -423,7 +430,7 @@ static int set_link_mode(struct hinic5_nic_dev *nic_dev, const void *buf_in,
default:
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid link mode %d to set\n", *link);
- return -EINVAL;
+ return -EINVAL;
}
return 0;
@@ -436,19 +443,21 @@ static int set_pf_bw_limit(struct hinic5_nic_dev *nic_dev, const void *buf_in,
int err;
if (HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
- if (!buf_in || !buf_out || in_size != sizeof(u32) ||
- !out_size || *out_size != sizeof(u8))
+ if ((buf_in == NULL) || (buf_out == NULL) || in_size != sizeof(u32) ||
+ (out_size == NULL) || *out_size != sizeof(u8))
return -EINVAL;
pf_bw_limit = *((u32 *)buf_in);
err = hinic5_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %u%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -465,11 +474,12 @@ static int get_pf_bw_limit(struct hinic5_nic_dev *nic_dev, const void *buf_in,
int err;
if (HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
- if (!buf_out || !out_size)
+ if ((buf_out == NULL) || (out_size == NULL))
return -EINVAL;
if (*out_size != sizeof(u32)) {
@@ -494,10 +504,10 @@ static int get_sset_count(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
u32 count;
- if (!buf_in || in_size != sizeof(u32) || !out_size ||
- *out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ if ((buf_in == NULL) || in_size != sizeof(u32) || (out_size == NULL) ||
+ *out_size != sizeof(u32) || (buf_out == NULL)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -522,17 +532,18 @@ static int get_sset_stats(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 sset, count, size;
int err;
- if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ if ((buf_in == NULL) || in_size != sizeof(u32) || (out_size == NULL) ||
+ (buf_out == NULL)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -552,8 +563,8 @@ static int get_sset_stats(struct hinic5_nic_dev *nic_dev, const void *buf_in,
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -570,10 +581,13 @@ static int update_pcp_dscp_cfg(struct hinic5_nic_dev *nic_dev,
if ((qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) != 0) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if ((nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i])) == 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ if ((nic_dev->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i])) == 0) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Invalid cos=%u, func cos valid map is %u",
+ qos_in->pcp2cos[i],
+ nic_dev->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -583,8 +597,10 @@ static int update_pcp_dscp_cfg(struct hinic5_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos,
- qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ if (memcpy_s(wanted_dcb_cfg->pcp2cos,
+ sizeof(wanted_dcb_cfg->pcp2cos), qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos)) != 0)
+ return -ENOMEM;
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -594,13 +610,15 @@ static int update_pcp_dscp_cfg(struct hinic5_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ nic_dev->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
if (cos >= NIC_DCB_UP_MAX ||
((nic_dev->func_dft_cos_bitmap & BIT(cos)) == 0)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Invalid cos=%u, func cos valid map is %u",
+ cos, nic_dev->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -611,8 +629,10 @@ static int update_pcp_dscp_cfg(struct hinic5_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ nic_dev->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -638,7 +658,8 @@ static int update_wanted_qos_cfg(struct hinic5_nic_dev *nic_dev,
}
if ((qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) != 0) {
- if ((BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap) == 0) {
+ if ((BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap) ==
+ 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -661,16 +682,19 @@ static int update_wanted_qos_cfg(struct hinic5_nic_dev *nic_dev,
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) {
if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "DCB is on, cos num should not more than channel num:%u\n",
+ nic_dev->q_params.num_qps);
return -EOPNOTSUPP;
}
}
if ((BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap) == 0) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %d\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %d\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -682,25 +706,29 @@ static int dcb_mt_qos_map(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
const struct hinic5_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic5_mt_qos_dev_cfg *qos_out = buf_out;
- struct hinic5_dcb_config wanted_dcb_cfg = {0};
+ struct hinic5_dcb_config wanted_dcb_cfg = { 0 };
u8 i;
int err;
- if (!buf_out || !out_size || !buf_in)
+ if ((buf_out == NULL) || (out_size == NULL) || (buf_in == NULL))
return -EINVAL;
if (*out_size != sizeof(*qos_out) || in_size != sizeof(*qos_in)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*qos_in));
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*qos_in));
return -EINVAL;
}
- memcpy(qos_out, qos_in, sizeof(*qos_in));
+ if (memcpy_s(qos_out, sizeof(*qos_out), qos_in, sizeof(*qos_in)) != 0)
+ return -ENOMEM;
qos_out->head.status = 0;
if ((qos_in->op_code & MT_DCB_OPCODE_WR) != 0) {
- memcpy(&wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
- sizeof(struct hinic5_dcb_config));
+ (void)memcpy_s(&wanted_dcb_cfg,
+ sizeof(struct hinic5_dcb_config),
+ &nic_dev->hw_dcb_cfg,
+ sizeof(struct hinic5_dcb_config));
err = update_wanted_qos_cfg(nic_dev, &wanted_dcb_cfg, qos_in);
if (err != 0) {
qos_out->head.status = MT_EINVAL;
@@ -722,39 +750,62 @@ static int dcb_mt_qos_map(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int dcb_mt_dcb_state(struct hinic5_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, const u32 *out_size)
+static int dcb_mt_dcb_state_validate(struct hinic5_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, const u32 *out_size)
{
const struct hinic5_mt_dcb_state *dcb_in = buf_in;
struct hinic5_mt_dcb_state *dcb_out = buf_out;
- int err;
- u8 user_cos_num;
- u8 netif_run = 0;
- if (!buf_in || !buf_out || !out_size)
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
return -EINVAL;
if (*out_size != sizeof(*dcb_out) || in_size != sizeof(*dcb_in)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "buf size err, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*dcb_in));
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "buf size err, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*dcb_in));
return -EINVAL;
}
+ return 0;
+}
+
+static int dcb_mt_dcb_state(struct hinic5_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, const u32 *out_size)
+{
+ const struct hinic5_mt_dcb_state *dcb_in = buf_in;
+ struct hinic5_mt_dcb_state *dcb_out = buf_out;
+ int err;
+ u8 user_cos_num;
+ u8 netif_run = 0;
+
+ err = dcb_mt_dcb_state_validate(nic_dev, buf_in, in_size, buf_out,
+ out_size);
+ if (err != 0)
+ return err;
+
user_cos_num = hinic5_get_dev_user_cos_num(nic_dev);
- memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
+ if (memcpy_s(dcb_out, sizeof(*dcb_out), dcb_in, sizeof(*dcb_in)) != 0)
+ return -ENOMEM;
dcb_out->head.status = 0;
if ((dcb_in->op_code & MT_DCB_OPCODE_WR) != 0) {
- if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state != 0 && (netif_is_rxfh_configured(nic_dev->netdev))) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Cannot enable dcb when user has configured rss indirect table.\n");
+ if ((dcb_in->state != 0) &&
+ (netif_is_rxfh_configured(nic_dev->netdev))) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Cannot enable dcb when user has configured rss indirect table.\n");
return -EOPNOTSUPP;
}
- if (dcb_in->state != 0 && user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "cos num %u is big than qps num %u\n",
+ if ((dcb_in->state != 0) &&
+ (user_cos_num > nic_dev->q_params.num_qps)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "cos num %u is big than qps num %u\n",
user_cos_num, nic_dev->q_params.num_qps);
return -EOPNOTSUPP;
}
@@ -765,7 +816,8 @@ static int dcb_mt_dcb_state(struct hinic5_nic_dev *nic_dev, const void *buf_in,
}
err = hinic5_setup_cos(nic_dev->netdev,
- (dcb_in->state != 0) ? user_cos_num : 0, netif_run);
+ (dcb_in->state != 0) ? user_cos_num : 0,
+ netif_run);
if (err != 0)
goto setup_cos_fail;
@@ -781,7 +833,8 @@ static int dcb_mt_dcb_state(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic5_setup_cos(nic_dev->netdev, (dcb_in->state != 0) ? 0 : user_cos_num, netif_run);
+ hinic5_setup_cos(nic_dev->netdev,
+ (dcb_in->state != 0) ? 0 : user_cos_num, netif_run);
setup_cos_fail:
if (netif_run != 0)
@@ -796,17 +849,21 @@ static int dcb_mt_hw_qos_get(struct hinic5_nic_dev *nic_dev, const void *buf_in,
const struct hinic5_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic5_mt_qos_cos_cfg *cos_cfg_out = buf_out;
- if (!buf_in || !buf_out || !out_size)
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*cos_cfg_in));
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*cos_cfg_in));
return -EINVAL;
}
- memcpy(cos_cfg_out, cos_cfg_in, sizeof(*cos_cfg_in));
+ if (memcpy_s(cos_cfg_out, *out_size, cos_cfg_in, sizeof(*cos_cfg_in)) !=
+ 0)
+ return -ENOMEM;
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic5_physical_port_id(nic_dev->hwdev);
@@ -824,7 +881,7 @@ static int get_inter_num(struct hinic5_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic5_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size) {
+ if ((buf_out == NULL) || (out_size == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_out or out_size is NULL.\n");
return -EINVAL;
@@ -844,7 +901,7 @@ static int get_inter_num(struct hinic5_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, const u32 *out_size)
{
- if (!buf_out || !out_size) {
+ if ((buf_out == NULL) || (out_size == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_out or out_size is NULL.\n");
return -EINVAL;
@@ -857,23 +914,26 @@ static int get_netdev_name(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic5_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, const u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic5_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ const u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
- if (!buf_out || !out_size)
+ if ((buf_out == NULL) || (out_size == NULL))
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
- *out_size, sizeof(int));
+ nicif_err(
+ nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ *out_size, sizeof(int));
return -EINVAL;
}
@@ -882,23 +942,27 @@ static int get_netdev_tx_timeout(struct hinic5_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic5_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic5_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
- if (!buf_in)
+ if (buf_in == NULL)
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
- in_size, sizeof(int));
+ nicif_err(
+ nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -908,13 +972,14 @@ static int get_xsfp_present(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
struct mag_cmd_get_xsfp_present *sfp_abs = buf_out;
- if (!buf_in || !buf_out || !out_size)
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
return -EINVAL;
if (*out_size != sizeof(*sfp_abs) || in_size != sizeof(*sfp_abs)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*sfp_abs));
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_abs));
return -EINVAL;
}
@@ -930,13 +995,14 @@ static int get_xsfp_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
struct mag_cmd_get_xsfp_info *sfp_info = buf_out;
int err;
- if (!buf_in || !buf_out || !out_size)
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
return -EINVAL;
if (*out_size != sizeof(*sfp_info) || in_size != sizeof(*sfp_info)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*sfp_info));
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_info));
return -EINVAL;
}
@@ -956,17 +1022,28 @@ static int get_xsfp_tlv_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
int err;
- if (!buf_in || !buf_out || !out_size)
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
return -EINVAL;
- if (*out_size != sizeof(*sfp_tlv_info) || in_size != sizeof(*sfp_tlv_info_req)) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
- in_size, *out_size, sizeof(*sfp_tlv_info));
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
return -EINVAL;
}
- err = hinic5_get_sfp_tlv_info(nic_dev->hwdev, sfp_tlv_info, sfp_tlv_info_req);
+ err = hinic5_get_sfp_tlv_info(nic_dev->hwdev, sfp_tlv_info,
+ sfp_tlv_info_req);
+
+ if (sfp_tlv_info->head.status ==
+ HINIC5_LOGICAL_OPTICAL_UNSUPPORTED) { /* hinicadm xsfp 或 sfp,保持status为ERR_PERM */
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Not support get logical optical module tlv info\n");
+ return 0;
+ }
+
if (err != 0) {
sfp_tlv_info->head.status = MT_EIO;
return 0;
@@ -978,14 +1055,15 @@ static int get_xsfp_tlv_info(struct hinic5_nic_dev *nic_dev, const void *buf_in,
static int get_profile_id(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, const u32 *out_size)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
if (!HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD)) {
hinic5_err(nic_dev, drv, "dev is not enable PFE\n");
return -EINVAL;
}
- if (!out_size || !buf_out) {
+ if ((out_size == NULL) || (buf_out == NULL)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Param buf_out or out_size is NULL.\n");
return -EINVAL;
@@ -1006,7 +1084,8 @@ static int get_profile_id(struct hinic5_nic_dev *nic_dev, const void *buf_in,
static int set_profile_id(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, const u32 *out_size)
{
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
const u16 *profile_id = buf_in;
if (!HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD)) {
@@ -1014,7 +1093,7 @@ static int set_profile_id(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!buf_in) {
+ if (buf_in == NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Param buf_in is NULL.\n");
return -EINVAL;
@@ -1037,11 +1116,14 @@ static int set_profile_id(struct hinic5_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int hinic5_move_tcam_table(struct hinic5_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, const u32 *out_size)
+static int hinic5_move_tcam_table(struct hinic5_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, const u32 *out_size)
{
- struct hinic5_tc_move_info *acl_move_info = (struct hinic5_tc_move_info *)buf_in;
- struct hinic5_tc_info *tc_info = (struct hinic5_tc_info *)nic_dev->tc_info;
+ struct hinic5_tc_move_info *acl_move_info =
+ (struct hinic5_tc_move_info *)buf_in;
+ struct hinic5_tc_info *tc_info =
+ (struct hinic5_tc_info *)nic_dev->tc_info;
struct hinic5_tc_flow_node *flow_node = NULL;
struct rhashtable_iter iter;
int ret;
@@ -1052,7 +1134,7 @@ static int hinic5_move_tcam_table(struct hinic5_nic_dev *nic_dev, const void *bu
return -EINVAL;
}
- if (!buf_in) {
+ if (buf_in == NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Param buf_in is NULL.\n");
return -EINVAL;
@@ -1077,9 +1159,11 @@ static int hinic5_move_tcam_table(struct hinic5_nic_dev *nic_dev, const void *bu
rhashtable_walk_enter(&tc_info->flow_table, &iter);
rhashtable_walk_start(&iter);
- while ((flow_node = (struct hinic5_tc_flow_node *)rhashtable_walk_next(&iter)) != NULL &&
+ while ((flow_node = (struct hinic5_tc_flow_node *)rhashtable_walk_next(
+ &iter)) != NULL &&
!IS_ERR(flow_node)) {
- if (flow_node->rule_id >= old_index && flow_node->rule_id < old_index + len)
+ if (flow_node->rule_id >= old_index &&
+ flow_node->rule_id < old_index + len)
flow_node->rule_id += (u16)(new_index - old_index);
}
rhashtable_walk_stop(&iter);
@@ -1088,146 +1172,146 @@ static int hinic5_move_tcam_table(struct hinic5_nic_dev *nic_dev, const void *bu
return ret;
}
-static int g_bond_event_err;
-
-void hinic_bond_dfx_active_event(const char *bond_name, struct bond_attr *attr, int err)
+bool bond_dfx_can_do_attach(struct bonding *bond)
{
- if (err != 0)
- g_bond_event_err = 1;
+ return true;
}
int hinic_bond_dfx_ops(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, const u32 *out_size)
{
- u16 bond_id;
- int err = 0;
+ int err = EOK;
struct bond_dfx_ops_info *info = (struct bond_dfx_ops_info *)buf_in;
struct bond_srv_func srv_func = {
.before_active = NULL,
- .after_active = hinic_bond_dfx_active_event,
+ .after_active = NULL,
.before_modify = NULL,
.after_modify = NULL,
.before_deactive = NULL,
.after_deactive = NULL,
- .can_attach = NULL,
+ .can_attach = bond_dfx_can_do_attach,
};
- if (!buf_in) {
+ if (buf_in == NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev, "buf_in is NULL.\n");
return -EINVAL;
}
if (in_size != sizeof(struct bond_dfx_ops_info)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unexpect in buf size from user :%u, expect: %lu\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect in buf size from user :%u, expect: %lu\n",
in_size, sizeof(struct bond_dfx_ops_info));
return -EINVAL;
}
if (info->ops == BOND_DFX_OP_ADD) {
- (void)hinic5_bond_register_service_func(info->user, &srv_func);
- err = hinic5_bond_attach(info->bond_name, info->user, &bond_id);
- if (g_bond_event_err != 0) {
- hinic5_bond_detach(bond_id, info->user);
- g_bond_event_err = 0;
+ err = hinic5_bond_register(info->user, &srv_func);
+ if (err != 0) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to register hinic5 bond, user: %u, ret: %d\n",
+ info->user, err);
}
} else if (info->ops == BOND_DFX_OP_DEL) {
- err = hinic5_bond_get_id_by_name(info->bond_name, &bond_id);
- if (err == 0) {
- hinic5_bond_detach(bond_id, info->user);
- hinic5_bond_unregister_service_func(info->user);
+ err = hinic5_bond_unregister(info->user);
+ if (err != 0) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to unregister hinic5 bond, user: %u, ret: %d\n",
+ info->user, err);
}
}
-
info->head.status = (u8)err;
-
return err;
}
static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
- /* Get sq info */
- {TX_INFO, (nic_driv_module)get_tx_info},
- /* Get queue number */
- {Q_NUM, (nic_driv_module)get_q_num},
- /* Get tx wqe info */
- {TX_WQE_INFO, get_tx_wqe_info},
- /* Get rx info */
- {RX_INFO, (nic_driv_module)get_rx_info},
- /* Get rx wqe info */
- {RX_WQE_INFO, get_rx_wqe_info},
- /* Get rx cqe info */
- {RX_CQE_INFO, (nic_driv_module)get_rx_cqe_info},
- /* Get interrupt number */
- {GET_INTER_NUM, (nic_driv_module)get_inter_num},
- /* Clear func statistics */
- {CLEAR_FUNC_STASTIC, clear_func_static},
- /* Get current loopback mode */
- {GET_LOOPBACK_MODE, (nic_driv_module)get_loopback_mode},
- /* Set loopback mode */
- {SET_LOOPBACK_MODE, (nic_driv_module)set_loopback_mode},
- /* Set link mode */
- {SET_LINK_MODE, set_link_mode},
- /* Set pxe bandwidth limit */
- {SET_PF_BW_LIMIT, (nic_driv_module)set_pf_bw_limit},
- /* Get pxe bandwidth limit */
- {GET_PF_BW_LIMIT, (nic_driv_module)get_pf_bw_limit},
- /* Get current IO statistics count */
- {GET_SSET_COUNT, (nic_driv_module)get_sset_count},
- /* Get current IO statistics status */
- {GET_SSET_ITEMS, (nic_driv_module)get_sset_stats},
- /* Manage DCB state */
- {DCB_STATE, (nic_driv_module)dcb_mt_dcb_state},
- /* Manage qos mapping relationship */
- {QOS_DEV, (nic_driv_module)dcb_mt_qos_map},
- /* Get hardware qos configuration */
- {GET_QOS_COS, (nic_driv_module)dcb_mt_hw_qos_get},
- /* Get network device name */
- {GET_ULD_DEV_NAME, (nic_driv_module)get_netdev_name},
- /* Get tx timeout value */
- {GET_TX_TIMEOUT, (nic_driv_module)get_netdev_tx_timeout},
- /* Configure tx timeout value */
- {SET_TX_TIMEOUT, set_netdev_tx_timeout},
- /* Get optical module presence information */
- {GET_XSFP_PRESENT, (nic_driv_module)get_xsfp_present},
- /* Get optical module information */
- {GET_XSFP_INFO, (nic_driv_module)get_xsfp_info},
- /* Get optical module information in TLV format */
- {GET_XSFP_INFO_COMP_CMIS, (nic_driv_module)get_xsfp_tlv_info},
- /* Get profile id */
- {CMD_GET_PROFILE_ID, (nic_driv_module)get_profile_id},
- /* Configure profile id */
- {CMD_SET_PROFILE_ID, (nic_driv_module)set_profile_id},
- /* Configure tcam table */
- {CMD_MOVE_TCAM_TABLE, (nic_driv_module)hinic5_move_tcam_table},
- /* bond bind/unbind dfx */
- {BOND_DFX_OPS, (nic_driv_module)hinic_bond_dfx_ops},
- /* Query driver-side MACsec table entries */
- {MACSEC_TOOL_OP_LIST, (nic_driv_module)macsec_cmd_list},
- /* Query chip-side MACsec table entries */
- {MACSEC_TOOL_OP_DUMP, (nic_driv_module)macsec_cmd_list},
- /* Get chip-side SC MIB information or PORT MIB information */
- {MACSEC_TOOL_OP_MIB, (nic_driv_module)macsec_cmd_mib},
- /* Add SC or SA configuration */
- {MACSEC_TOOL_OP_ADD, (nic_driv_module)macsec_cmd_add},
- /* Delete SC or SA configuration */
- {MACSEC_TOOL_OP_DEL, (nic_driv_module)macsec_cmd_del},
- /* Modify SC configuration */
- {MACSEC_TOOL_OP_SET, (nic_driv_module)macsec_cmd_set},
- /* Clear MACsec configuration managed by a device */
- {MACSEC_TOOL_OP_FLUSH, (nic_driv_module)macsec_cmd_flush}
+ /* 获取sq ifo */
+ { TX_INFO, (nic_driv_module)get_tx_info },
+ /* 获取队列数目 */
+ { Q_NUM, (nic_driv_module)get_q_num },
+ /* 获取tx wqe信息 */
+ { TX_WQE_INFO, get_tx_wqe_info },
+ /* 获取rx info */
+ { RX_INFO, (nic_driv_module)get_rx_info },
+ /* 获取rx wqe信息 */
+ { RX_WQE_INFO, get_rx_wqe_info },
+ /* 获取rx cqe信息 */
+ { RX_CQE_INFO, (nic_driv_module)get_rx_cqe_info },
+ /* 获取中断数目 */
+ { GET_INTER_NUM, (nic_driv_module)get_inter_num },
+ /* 清楚func的统计信息 */
+ { CLEAR_FUNC_STASTIC, clear_func_static },
+ /* 获取当前的环回模式 */
+ { GET_LOOPBACK_MODE, (nic_driv_module)get_loopback_mode },
+ /* 设置环回模式 */
+ { SET_LOOPBACK_MODE, (nic_driv_module)set_loopback_mode },
+ /* 设置link模式 */
+ { SET_LINK_MODE, set_link_mode },
+ /* 设置pxe带宽上限 */
+ { SET_PF_BW_LIMIT, (nic_driv_module)set_pf_bw_limit },
+ /* 获取pxe带宽上限 */
+ { GET_PF_BW_LIMIT, (nic_driv_module)get_pf_bw_limit },
+ /* 获取当前IO统计项的个数 */
+ { GET_SSET_COUNT, (nic_driv_module)get_sset_count },
+ /* 获取当前IO统计状态 */
+ { GET_SSET_ITEMS, (nic_driv_module)get_sset_stats },
+ /* 管理DCB状态 */
+ { DCB_STATE, (nic_driv_module)dcb_mt_dcb_state },
+ /* 管理qos的映射关系 */
+ { QOS_DEV, (nic_driv_module)dcb_mt_qos_map },
+ /* 获取硬件qos配置 */
+ { GET_QOS_COS, (nic_driv_module)dcb_mt_hw_qos_get },
+ /* 获取网络设备名称 */
+ { GET_ULD_DEV_NAME, (nic_driv_module)get_netdev_name },
+ /* 获取tx timeout的时间 */
+ { GET_TX_TIMEOUT, (nic_driv_module)get_netdev_tx_timeout },
+ /* 配置tx timeout的时间 */
+ { SET_TX_TIMEOUT, set_netdev_tx_timeout },
+ /* 获取光模块的在位信息 */
+ { GET_XSFP_PRESENT, (nic_driv_module)get_xsfp_present },
+ /* 获取光模块的信息 */
+ { GET_XSFP_INFO, (nic_driv_module)get_xsfp_info },
+ /* 以tlv格式获取光模块的信息 */
+ { GET_XSFP_INFO_COMP_CMIS, (nic_driv_module)get_xsfp_tlv_info },
+ /* 获取profile id */
+ { CMD_GET_PROFILE_ID, (nic_driv_module)get_profile_id },
+ /* 配置profile id */
+ { CMD_SET_PROFILE_ID, (nic_driv_module)set_profile_id },
+ /* 配置tcam表 */
+ { CMD_MOVE_TCAM_TABLE, (nic_driv_module)hinic5_move_tcam_table },
+ /* bond 绑定/解绑 dfx */
+ { BOND_DFX_OPS, (nic_driv_module)hinic_bond_dfx_ops },
+ /* 查询驱动侧MACsec表项 */
+ { MACSEC_TOOL_OP_LIST, (nic_driv_module)macsec_cmd_list },
+ /* 查询芯片侧MACsec表项 */
+ { MACSEC_TOOL_OP_DUMP, (nic_driv_module)macsec_cmd_list },
+ /* 获取芯片侧 SC MIB 信息或者 PORT MIB 信息 */
+ { MACSEC_TOOL_OP_MIB, (nic_driv_module)macsec_cmd_mib },
+ /* 新增 SC 或 SA 配置 */
+ { MACSEC_TOOL_OP_ADD, (nic_driv_module)macsec_cmd_add },
+ /* 删除 SC 或 SA 配置 */
+ { MACSEC_TOOL_OP_DEL, (nic_driv_module)macsec_cmd_del },
+ /* 修改 SC 配置 */
+ { MACSEC_TOOL_OP_SET, (nic_driv_module)macsec_cmd_set },
+ /* 清除某个设备管理的 MACsec 配置 */
+ { MACSEC_TOOL_OP_FLUSH, (nic_driv_module)macsec_cmd_flush }
};
-__weak int hinic5_tool_cmd_extend_handle(struct net_device *netdev, u32 cmd,
- struct hinic5_nt_msg *nt_msg, bool *support)
+__attribute__((weak)) int
+hinic5_tool_cmd_extend_handle(struct net_device *netdev, u32 cmd,
+ struct hinic5_nt_msg *nt_msg, bool *support)
{
*support = false;
return 0;
}
-static int send_to_nic_driver(struct hinic5_nic_dev *nic_dev, u32 cmd, struct hinic5_nt_msg *nt_msg)
+static int send_to_nic_driver(struct hinic5_nic_dev *nic_dev, u32 cmd,
+ struct hinic5_nt_msg *nt_msg)
{
int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]));
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
bool support = false;
int err = 0;
@@ -1238,15 +1322,16 @@ static int send_to_nic_driver(struct hinic5_nic_dev *nic_dev, u32 cmd, struct hi
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
- nic_driv_module_cmd_handle[index].driv_cmd_name) {
- err = nic_driv_module_cmd_handle[index].driv_func
- (nic_dev, nt_msg->buf_in,
- nt_msg->in_size, nt_msg->buf_out, &nt_msg->out_size);
+ nic_driv_module_cmd_handle[index].driv_cmd_name) {
+ err = nic_driv_module_cmd_handle[index].driv_func(
+ nic_dev, nt_msg->buf_in, nt_msg->in_size,
+ nt_msg->buf_out, &(nt_msg->out_size));
goto cmd_out;
}
}
- err = hinic5_tool_cmd_extend_handle(nic_dev->netdev, cmd_type, nt_msg, &support);
+ err = hinic5_tool_cmd_extend_handle(nic_dev->netdev, cmd_type, nt_msg,
+ &support);
if (!support) {
pr_err("Can't find callback for %d\n", cmd_type);
err = -EINVAL;
@@ -1261,21 +1346,21 @@ static int send_to_nic_driver(struct hinic5_nic_dev *nic_dev, u32 cmd, struct hi
return err;
}
-int hinic5_nic_ioctl(void *uld_dev, u32 cmd, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+int nic_ioctl(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
int err;
- struct hinic5_nt_msg nt_msg = {0};
+ struct hinic5_nt_msg nt_msg = { 0 };
if (cmd == GET_DRV_VERSION)
return get_nic_drv_version(buf_out, out_size);
- else if (!uld_dev)
+ else if (uld_dev == NULL)
return -EINVAL;
nt_msg.buf_in = (void *)buf_in;
- nt_msg.in_size = in_size;
+ nt_msg.in_size = in_size;
nt_msg.buf_out = buf_out;
- nt_msg.out_size = *out_size;
+ nt_msg.out_size = *out_size;
err = send_to_nic_driver(uld_dev, cmd, &nt_msg);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.h
index 31dd445fe..2a5f66fdd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dbg.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dbg.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_DBG_H
#define HINIC5_DBG_H
@@ -17,12 +10,12 @@
#define HINIC5_CAR_INFO_INDEX (0x4)
typedef int (*nic_driv_module)(struct hinic5_nic_dev *nic_dev,
- const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size);
struct nic_drv_module_handle {
- u32 driv_cmd_name;
- nic_driv_module driv_func;
+ u32 driv_cmd_name;
+ nic_driv_module driv_func;
};
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.c
index 2845e6496..a90b691a0 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dcb.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -26,7 +19,7 @@
#include "hinic5_nic_dev.h"
#include "hinic5_dcb.h"
-#define MAX_BW_PERCENT 100
+#define MAX_BW_PERCENT 100
u8 hinic5_get_dev_user_cos_num(struct hinic5_nic_dev *nic_dev)
{
@@ -39,7 +32,7 @@ u8 hinic5_get_dev_user_cos_num(struct hinic5_nic_dev *nic_dev)
u8 hinic5_get_dev_valid_cos_map(struct hinic5_nic_dev *nic_dev)
{
- if (!nic_dev)
+ if (nic_dev == NULL)
return 0;
if (nic_dev->hw_dcb_cfg.trust == 0)
return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
@@ -62,16 +55,20 @@ void hinic5_update_qp_cos_cfg(struct hinic5_nic_dev *nic_dev)
num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ (void)memset_s(dcb_cfg->cos_qp_offset, sizeof(dcb_cfg->cos_qp_offset),
+ 0, sizeof(dcb_cfg->cos_qp_offset));
+ (void)memset_s(dcb_cfg->cos_qp_num, sizeof(dcb_cfg->cos_qp_num), 0,
+ sizeof(dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if ((BIT(i) & valid_cos_map) != 0) {
- cos_qp_num = num_qp_per_cos + ((remainder > 0) ? (remainder--, 1) : 0);
+ cos_qp_num = num_qp_per_cos +
+ ((remainder > 0) ? (remainder--, 1) : 0);
dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
dcb_cfg->cos_qp_num[i] = cos_qp_num;
- hinic5_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
+ hinic5_info(nic_dev, drv,
+ "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
cos_qp_offset += cos_qp_num;
@@ -96,8 +93,10 @@ void hinic5_update_tx_db_cos(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
hinic5_set_txq_cos(nic_dev, start_qid, q_num, i);
- hinic5_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
- start_qid, q_num, i);
+ hinic5_info(
+ nic_dev, drv,
+ "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
+ start_qid, q_num, i);
}
}
}
@@ -105,7 +104,7 @@ void hinic5_update_tx_db_cos(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
static int hinic5_set_tx_cos_state(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
{
struct hinic5_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- struct hinic5_dcb_state dcb_state = {0};
+ struct hinic5_dcb_state dcb_state = { 0 };
u8 i;
int err;
@@ -119,8 +118,11 @@ static int hinic5_set_tx_cos_state(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ (void)memset_s(dcb_state.pcp2cos, sizeof(dcb_state.pcp2cos),
+ dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
+ (void)memset_s(dcb_state.dscp2cos, sizeof(dcb_state.dscp2cos),
+ dcb_cfg->default_cos,
+ sizeof(dcb_state.dscp2cos));
}
err = hinic5_set_dcb_state(nic_dev->hwdev, &dcb_state);
if (err != 0) {
@@ -128,10 +130,12 @@ static int hinic5_set_tx_cos_state(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
return err;
}
- err = hinic5_dcb_state_op(nic_dev->hwdev, HISDK5_DCB_STATE_SET,
- (struct hisdk5_dcb_state *)(void *)&dcb_state);
+ err = hinic5_dcb_state_op(
+ nic_dev->hwdev, HISDK5_DCB_STATE_SET,
+ (struct hisdk5_dcb_state *)(void *)&dcb_state);
if (err != 0) {
- hinic5_err(nic_dev, drv, "Failed to sync nic dcb state to the sdk.\n");
+ hinic5_err(nic_dev, drv,
+ "Failed to sync nic dcb state to the sdk.\n");
return err;
}
return 0;
@@ -164,10 +168,10 @@ int hinic5_configure_dcb_hw(struct hinic5_nic_dev *nic_dev, u8 dcb_en)
if (dcb_en != 0) {
set_bit(HINIC5_DCB_ENABLE, &nic_dev->flags);
- set_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_hinic5_vram->flags);
+ set_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_vram->flags);
} else {
clear_bit(HINIC5_DCB_ENABLE, &nic_dev->flags);
- clear_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_hinic5_vram->flags);
+ clear_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_vram->flags);
}
return 0;
@@ -186,14 +190,17 @@ int hinic5_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
int err;
- if (cos != 0 && (test_bit(HINIC5_SAME_RXTX, &nic_dev->flags) != 0)) {
- nicif_err(nic_dev, drv, netdev, "Failed to enable DCB while Symmetric RSS is enabled\n");
+ if ((cos != 0) && (test_bit(HINIC5_SAME_RXTX, &nic_dev->flags) != 0)) {
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Failed to enable DCB while Symmetric RSS is enabled\n");
return -EOPNOTSUPP;
}
if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n", cos,
+ nic_dev->cos_config_num_max);
return -EINVAL;
}
@@ -216,18 +223,18 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
return support_cos;
}
-static void hinic5_dcb_save(struct hinic5_hinic5_vram *nic_hinic5_vram,
+static void hinic5_dcb_save(struct hinic5_vram *nic_vram,
struct hinic5_dcb_config *hw_cfg)
{
- nic_hinic5_vram->default_cos = hw_cfg->default_cos;
- nic_hinic5_vram->trust = hw_cfg->trust;
+ nic_vram->default_cos = hw_cfg->default_cos;
+ nic_vram->trust = hw_cfg->trust;
}
static void hinic5_dcb_restore(struct hinic5_dcb_config *hw_cfg,
- struct hinic5_hinic5_vram *nic_hinic5_vram)
+ struct hinic5_vram *nic_vram)
{
- hw_cfg->default_cos = nic_hinic5_vram->default_cos;
- hw_cfg->trust = nic_hinic5_vram->trust;
+ hw_cfg->default_cos = nic_vram->default_cos;
+ hw_cfg->trust = nic_vram->trust;
}
static void hinic5_sync_dcb_cfg(struct hinic5_nic_dev *nic_dev,
@@ -235,8 +242,9 @@ static void hinic5_sync_dcb_cfg(struct hinic5_nic_dev *nic_dev,
{
struct hinic5_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic5_dcb_config));
- hinic5_dcb_save(nic_dev->nic_hinic5_vram, hw_cfg);
+ (void)memcpy_s(hw_cfg, sizeof(struct hinic5_dcb_config), dcb_cfg,
+ sizeof(struct hinic5_dcb_config));
+ hinic5_dcb_save(nic_dev->nic_vram, hw_cfg);
}
static int init_default_dcb_cfg(struct hinic5_nic_dev *nic_dev,
@@ -246,13 +254,14 @@ static int init_default_dcb_cfg(struct hinic5_nic_dev *nic_dev,
int err;
int is_in_kexec;
- err = hinic5_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic5_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map,
+ &port_cos_bitmap);
if (err != 0) {
hinic5_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- is_in_kexec = hinic5_vram_get_kexec_flag();
+ is_in_kexec = vram5_get_kexec_flag();
nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
@@ -264,11 +273,11 @@ static int init_default_dcb_cfg(struct hinic5_nic_dev *nic_dev,
if (nic_dev->hw_default_cos_valid != 0)
dcb_cfg->default_cos = nic_dev->hw_default_cos;
else
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
- hinic5_dcb_save(nic_dev->nic_hinic5_vram, dcb_cfg);
- } else {
- hinic5_dcb_restore(dcb_cfg, nic_dev->nic_hinic5_vram);
- }
+ dcb_cfg->default_cos =
+ (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ hinic5_dcb_save(nic_dev->nic_vram, dcb_cfg);
+ } else
+ hinic5_dcb_restore(dcb_cfg, nic_dev->nic_vram);
dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
@@ -276,9 +285,12 @@ static int init_default_dcb_cfg(struct hinic5_nic_dev *nic_dev,
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = ((hw_dft_cos_map & BIT(i)) != 0) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = ((hw_dft_cos_map & BIT(i)) != 0) ?
+ i :
+ dcb_cfg->default_cos;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
- dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
+ dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] =
+ dcb_cfg->pcp2cos[i];
}
return 0;
@@ -286,7 +298,7 @@ static int init_default_dcb_cfg(struct hinic5_nic_dev *nic_dev,
void hinic5_dcb_reset_hw_config(struct hinic5_nic_dev *nic_dev)
{
- struct hinic5_dcb_config dft_cfg = {0};
+ struct hinic5_dcb_config dft_cfg = { 0 };
init_default_dcb_cfg(nic_dev, &dft_cfg);
hinic5_sync_dcb_cfg(nic_dev, &dft_cfg);
@@ -299,8 +311,9 @@ int hinic5_configure_dcb(struct net_device *netdev)
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
int err;
- err = hinic5_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic5_sync_dcb_state(
+ nic_dev->hwdev, 1,
+ test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
if (err != 0) {
hinic5_err(nic_dev, drv, "Set dcb state failed\n");
return err;
@@ -320,7 +333,8 @@ int hinic5_dcb_init(struct hinic5_nic_dev *nic_dev)
err = init_default_dcb_cfg(nic_dev, dcb_cfg);
if (err != 0) {
- hinic5_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic5_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
return err;
}
@@ -336,14 +350,16 @@ int hinic5_dcb_init(struct hinic5_nic_dev *nic_dev)
return 0;
}
-static int change_qos_cfg(struct hinic5_nic_dev *nic_dev, const struct hinic5_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic5_nic_dev *nic_dev,
+ const struct hinic5_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
int err = 0;
if (test_and_set_bit(HINIC5_DCB_UP_COS_SETTING, &nic_dev->flags)) {
- nicif_warn(nic_dev, drv, netdev,
- "Cos_up map setting in inprocess, please try again later\n");
+ nicif_warn(
+ nic_dev, drv, netdev,
+ "Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
}
@@ -364,12 +380,14 @@ int hinic5_dcbcfg_set_up_bitmap(struct hinic5_nic_dev *nic_dev,
struct hinic5_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic5_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg,
- &nic_dev->hw_dcb_cfg, sizeof(struct hinic5_dcb_config));
+ (void)memcpy_s(&old_dcb_cfg, sizeof(struct hinic5_dcb_config),
+ &nic_dev->hw_dcb_cfg, sizeof(struct hinic5_dcb_config));
- if (memcmp(wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic5_dcb_config)) == 0) {
- nicif_info(nic_dev, drv, nic_dev->netdev,
- "Same valid up bitmap, don't need to change anything\n");
+ if (memcmp(wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic5_dcb_config)) == 0) {
+ nicif_info(
+ nic_dev, drv, nic_dev->netdev,
+ "Same valid up bitmap, don't need to change anything\n");
return 0;
}
@@ -380,12 +398,14 @@ int hinic5_dcbcfg_set_up_bitmap(struct hinic5_nic_dev *nic_dev,
err = change_qos_cfg(nic_dev, wanted_dcb_cfg);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic5_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic5_setup_cos(nic_dev->netdev, user_cos_num,
+ netif_run);
if (err != 0)
goto set_err;
}
@@ -401,7 +421,8 @@ int hinic5_dcbcfg_set_up_bitmap(struct hinic5_nic_dev *nic_dev,
vport_up_fail:
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags))
hinic5_setup_cos(nic_dev->netdev,
- (user_cos_num != 0) ? 0 : user_cos_num, netif_run);
+ (user_cos_num != 0) ? 0 : user_cos_num,
+ netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.h
index 9021c3220..af9ce722a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/ioctl/hinic5_dcb.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_dcb.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#ifndef HINIC5_DCB_H
#define HINIC5_DCB_H
@@ -14,16 +7,16 @@
#include "ossl_knl.h"
struct hinic5_cos_cfg {
- u8 up;
- u8 bw_pct;
- u8 tc_id;
- u8 prio_sp; /* 0 - DWRR, 1 - SP */
+ u8 up;
+ u8 bw_pct;
+ u8 tc_id;
+ u8 prio_sp; /* 0 - DWRR, 1 - SP */
};
struct hinic5_tc_cfg {
- u8 bw_pct;
- u8 prio_sp; /* 0 - DWRR, 1 - SP */
- u16 rsvd;
+ u8 bw_pct;
+ u8 prio_sp; /* 0 - DWRR, 1 - SP */
+ u16 rsvd;
};
enum HINIC5_DCB_TRUST {
@@ -33,20 +26,20 @@ enum HINIC5_DCB_TRUST {
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
-#define DBG_DFLT_DSCP_VAL 0xFF
+#define DBG_DFLT_DSCP_VAL 0xFF
struct hinic5_dcb_config {
- u8 trust; /* pcp, dscp */
- u8 default_cos;
- u8 pcp_user_cos_num;
- u8 pcp_valid_cos_map;
- u8 dscp_user_cos_num;
- u8 dscp_valid_cos_map;
- u8 pcp2cos[PCP_MAX_UP];
- u8 dscp2cos[DSCP_MAC_UP];
+ u8 trust; /* pcp, dscp */
+ u8 default_cos;
+ u8 pcp_user_cos_num;
+ u8 pcp_valid_cos_map;
+ u8 dscp_user_cos_num;
+ u8 dscp_valid_cos_map;
+ u8 pcp2cos[PCP_MAX_UP];
+ u8 dscp2cos[DSCP_MAC_UP];
- u8 cos_qp_offset[NIC_DCB_COS_MAX];
- u8 cos_qp_num[NIC_DCB_COS_MAX];
+ u8 cos_qp_offset[NIC_DCB_COS_MAX];
+ u8 cos_qp_num[NIC_DCB_COS_MAX];
};
struct hinic5_nic_dev;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_api.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_api.h
index 9ca9c4b8e..0c049185d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_api.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_api.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_api.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : MACsec api header file
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: MACsec api header file
+ * Create: 2025/11/04
*/
#ifndef HINIC5_MACSEC_API_H
@@ -14,11 +10,11 @@
#include <linux/types.h>
#include "hinic5_nic_dev.h"
-/* MACsec initialization */
+/* MACsec初始化 */
int macsec_init_offload(struct hinic5_nic_dev *nic_dev);
void macsec_cleanup_offload(struct hinic5_nic_dev *nic_dev);
-/* MACsec ioctl interface */
+/* MACsec ioctl接口 */
int macsec_cmd_list(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size);
int macsec_cmd_mib(struct hinic5_nic_dev *nic_dev, const void *buf_in,
@@ -32,4 +28,4 @@ int macsec_cmd_set(struct hinic5_nic_dev *nic_dev, const void *buf_in,
int macsec_cmd_flush(struct hinic5_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size);
-#endif // HINIC5_MACSEC_API_H
+#endif // HINIC5_MACSEC_API_H
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_common.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_common.h
index 1e7988152..5043b343f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_common.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_common.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_common.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : common define
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: common define
+ * Create: 2024/03/06
*/
#ifndef HINIC5_MACSEC_COMMON_H
@@ -19,11 +15,13 @@
#include "hinic5_nic_dev.h"
#include "hinic5_macsec_dev.h"
-#define PORT_MSK_IN_SCI 0x00FF /* Generalized port, currently represents sc_index */
+#define PORT_MSK_IN_SCI 0x00FF // 广义 port,实际现阶段表示 sc_index
#define MACSEC_SC_STATUS_VALID(status) \
((((status) == SC_STATUS_MAX) || ((status) == SC_STATUS_NONE)) ? 0 : 1)
-#define MACSEC_SA_STATUS_VALID(status) \
- ((((status) >= SA_STATUS_EXPIRED) || ((status) == SA_STATUS_NONE)) ? 0 : 1)
+#define MACSEC_SA_STATUS_VALID(status) \
+ ((((status) >= SA_STATUS_EXPIRED) || ((status) == SA_STATUS_NONE)) ? \
+ 0 : \
+ 1)
#define HIMACSEC_CONFIDENTIALITY_OFFSET_0 0
#define HIMACSEC_CONFIDENTIALITY_OFFSET_30 1
#define HIMACSEC_CONFIDENTIALITY_OFFSET_50 2
@@ -34,8 +32,8 @@ typedef enum {
HIMACSEC_SC_MODE_MAX
} himacsec_sc_mode_e;
-/* Used to determine if MACsec global switch is on, which affects NIC service if enabled */
-#define MACSEC_GLOBAL_SWITCH_IS_DISABLE 0
+#define MACSEC_GLOBAL_SWITCH_IS_DISABLE \
+ 0 /* 用于判断MACsec全局开关是否打开,若打开会影响NIC业务 */
#define MACSEC_GLOBAL_SWITCH_IS_ENABLE 1
/* MACsec offload adapt */
@@ -49,30 +47,38 @@ int himacsec_destroy_sa(struct hinic5_nic_dev *nic_dev, u64 sci, u8 assoc_num,
crypt_direction_e direct);
int himacsec_create_sc(struct hinic5_nic_dev *nic_dev,
macsec_sc_info_s *sc_info, crypt_direction_e direct);
-int himacsec_destroy_sc(struct hinic5_nic_dev *nic_dev, u64 sci, crypt_direction_e direct);
+int himacsec_destroy_sc(struct hinic5_nic_dev *nic_dev, u64 sci,
+ crypt_direction_e direct);
int himacsec_set_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *sc_info,
crypt_direction_e direct);
struct himacsec_sc *himacsec_get_valid_dev_sc(struct hinic5_nic_dev *nic_dev,
- u64 sci, crypt_direction_e direct);
+ u64 sci,
+ crypt_direction_e direct);
struct himacsec_sa *himacsec_get_valid_dev_sa(struct hinic5_nic_dev *nic_dev,
- u64 sci, u8 an, crypt_direction_e direct);
+ u64 sci, u8 an,
+ crypt_direction_e direct);
struct himacsec_sc *get_g_macsec_port_res(u32 mode, u32 port_id);
-struct himacsec_sc *himacsec_get_dev_sc(struct hinic5_nic_dev *nic_dev, crypt_direction_e direct);
+struct himacsec_sc *himacsec_get_dev_sc(struct hinic5_nic_dev *nic_dev,
+ crypt_direction_e direct);
/* mailbox msg function */
int himacsec_cmd_exec_get_spec(void *hwdev, struct himacsec_spec *spec);
int himacsec_cmd_exec_macsec_enable(struct hinic5_lld_dev *lld_dev,
- macsec_mbox_service_op_cmd_e op_code, u8 *macsec_flag);
+ macsec_mbox_service_op_cmd_e op_code,
+ u8 *macsec_flag);
int himacsec_cmd_exec_sc_op(struct hinic5_lld_dev *lld_dev,
- macsec_sc_info_s *sc_info, macsec_mbox_sc_op_cmd_e opcode);
+ macsec_sc_info_s *sc_info,
+ macsec_mbox_sc_op_cmd_e opcode);
int himacsec_cmd_exec_sa_op(struct hinic5_lld_dev *lld_dev,
- macsec_sa_info_s *sa_info, macsec_mbox_sa_op_cmd_e opcode);
+ macsec_sa_info_s *sa_info,
+ macsec_mbox_sa_op_cmd_e opcode);
int himacsec_cmd_exec_mib_port(struct hinic5_lld_dev *lld_dev,
struct himacsec_cmd_mib_out *cmd_out);
int himacsec_cmd_exec_mib_sc(struct hinic5_lld_dev *lld_dev,
struct himacsec_cmd_mib_out *out_buf, u64 sci);
int himacsec_cmd_exec_get_feature_nego(struct hinic5_lld_dev *lld_dev,
u64 *feature_bitmap, u32 feature_size);
-int himacsec_cmd_exec_flush(struct hinic5_lld_dev *lld_dev, tag_macsec_flush_cmd_s *flush_info);
+int himacsec_cmd_exec_flush(struct hinic5_lld_dev *lld_dev,
+ tag_macsec_flush_cmd_s *flush_info);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dev.h
index 55695b267..596aaac43 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dev.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dev.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_dev.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Device entities storage
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: 存放实体
+ * Create: 2024/03/01
*/
#ifndef HINIC5_MACSEC_DEV_H
@@ -16,10 +12,10 @@
#include "ossl_knl.h"
typedef struct himacsec_spec {
- u8 macsec_support; /* Whether hardware supports MACsec */
- u8 max_port; /* Maximum number of ports on the chip */
- u8 max_port_sc; /* Maximum number of SCs per port */
- u8 max_sa; /* Maximum number of SA stored per SC */
+ u8 macsec_support; /* 硬件是否支持MACsec */
+ u8 max_port; /* Maximum number of ports on the chip */
+ u8 max_port_sc; /* Maximum number of SCs per port */
+ u8 max_sa; /* Maximum number of SA stored per SC */
} himacsec_spec_s;
typedef struct himacsec_stats {
@@ -38,18 +34,16 @@ typedef struct macsec_resource {
struct himacsec_spec spec;
u64 himacsec_feature[MACSEC_MAX_FEATURE_QWORD];
u32 num_of_device;
- himacsec_stats_s *stats; /* Driver internal counter */
+ himacsec_stats_s *stats; // 驱动内部计数
struct notifier_block nb;
u8 function_port;
- /* macsec sub-device ifindex,
- * ifindex of offloaded macsec device will be stored in this array
- */
- u32 offload_child_dev_idx[MACSEC_SC_NUM];
- u32 offload_dev_num; /* Number of valid elements in offload_child_dev_idx array */
+ u32 offload_child_dev_idx
+ [MACSEC_SC_NUM]; // macsec子设备 的ifindex,卸载的macsec设备的ifindex会存到此数组里
+ u32 offload_dev_num; // offload_child_dev_idx数组中有效的元素个数
} macsec_resource_s;
struct macsec_port_res {
- struct himacsec_sc enc_sc; /* Array head pointer */
+ struct himacsec_sc enc_sc; // 数组头指针
struct himacsec_sc dec_sc;
};
@@ -71,4 +65,4 @@ enum param_bit {
PARAM_BIT_MAX,
};
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.c
index df7afffde..bb7165fd7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.c
@@ -1,16 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_dfx.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : macsec dfx related code
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: macsec dfx 相关代码
+ * Create: 2024/05/23
*/
#include <linux/printk.h>
#include <linux/types.h>
#include <linux/semaphore.h>
+#include "securec.h"
#include "hinic5_mt.h"
#include "hinic5_crm.h"
#include "hinic5_nic_dev.h"
@@ -22,79 +19,98 @@
void himacsec_dfx_convert_key_length(u32 *key_length, u32 chip_key_len_val)
{
- if (chip_key_len_val == HIMACSEC_REG_KEY_LENGTH_128)
+ if (chip_key_len_val == HIMACSEC_REG_KEY_LENGTH_128) {
*key_length = CRYPT_KEY_LENGTH_128;
- else if (chip_key_len_val == HIMACSEC_REG_KEY_LENGTH_256)
+ } else if (chip_key_len_val == HIMACSEC_REG_KEY_LENGTH_256) {
*key_length = CRYPT_KEY_LENGTH_256;
- else
+ } else {
*key_length = chip_key_len_val;
+ }
}
-void himacsec_dfx_show_enc_sa(struct hinic5_nic_dev *nic_dev, macsec_sa_info_s *enc_sa)
+void himacsec_dfx_show_enc_sa(struct hinic5_nic_dev *nic_dev,
+ macsec_sa_info_s *enc_sa)
{
u32 key_len;
himacsec_dfx_convert_key_length(&key_len, enc_sa->current_key_length);
- macsec_info(nic_dev->lld_dev->dev,
- "%s: encryption sa: sci=%llx, an=%d, algorithm=%d[0: AES, 1:SM4], offset=0x%x, key length=%d[0: 128, 1: 256], xpn enable=%d, ssci=0x%x",
- nic_dev->netdev->name, enc_sa->sci, enc_sa->an,
- enc_sa->current_crypto_algo, enc_sa->confidentiality_offset,
- enc_sa->current_key_length, enc_sa->extended_pn_enable,
- enc_sa->ssci);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: encryption sa: sci=%llx, an=%d, algorithm=%d[0: AES, 1:SM4], "
+ "offset=0x%x, key length=%d[0: 128, 1: 256], xpn enable=%d, ssci=0x%x",
+ nic_dev->netdev->name, enc_sa->sci, enc_sa->an,
+ enc_sa->current_crypto_algo, enc_sa->confidentiality_offset,
+ enc_sa->current_key_length, enc_sa->extended_pn_enable,
+ enc_sa->ssci);
// encrytion info
- macsec_info(nic_dev->lld_dev->dev, "%s: encryption sa: sci=%llx, an=%d, pn threshold=0x%llx, next pn=0x%llx, enable transmit=%d",
- nic_dev->netdev->name, enc_sa->sci, enc_sa->an,
- enc_sa->pn_th, enc_sa->next_pn, enc_sa->enable_transmit);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: encryption sa: sci=%llx, an=%d, pn threshold=0x%llx, next pn=0x%llx, enable transmit=%d",
+ nic_dev->netdev->name, enc_sa->sci, enc_sa->an, enc_sa->pn_th,
+ enc_sa->next_pn, enc_sa->enable_transmit);
}
-void himacsec_dfx_show_dec_sa(struct hinic5_nic_dev *nic_dev, macsec_sa_info_s *dec_sa)
+void himacsec_dfx_show_dec_sa(struct hinic5_nic_dev *nic_dev,
+ macsec_sa_info_s *dec_sa)
{
u32 key_len;
himacsec_dfx_convert_key_length(&key_len, dec_sa->current_key_length);
- macsec_info(nic_dev->lld_dev->dev,
- "%s: decryption sa: sci=%llx, an=%d, algorithm=%d[0: AES, 1:SM4], offset=0x%x, key length=%d[0: 128, 1: 256], xpn enable=%d, ssci=0x%x",
- nic_dev->netdev->name, dec_sa->sci, dec_sa->an,
- dec_sa->current_crypto_algo, dec_sa->confidentiality_offset,
- dec_sa->current_key_length, dec_sa->extended_pn_enable,
- dec_sa->ssci);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: decryption sa: sci=%llx, an=%d, algorithm=%d[0: AES, 1:SM4], "
+ "offset=0x%x, key length=%d[0: 128, 1: 256], xpn enable=%d, ssci=0x%x",
+ nic_dev->netdev->name, dec_sa->sci, dec_sa->an,
+ dec_sa->current_crypto_algo, dec_sa->confidentiality_offset,
+ dec_sa->current_key_length, dec_sa->extended_pn_enable,
+ dec_sa->ssci);
// decrytion info
- macsec_info(nic_dev->lld_dev->dev, "%s: decryption sa: sci=%llx, an=%d, replay=%d, windows=0x%x, enable receive=%d, lowest pn=0x%llx",
- nic_dev->netdev->name, dec_sa->sci, dec_sa->an,
- dec_sa->replay_protect, dec_sa->replay_window,
- dec_sa->enable_receive, dec_sa->lowest_pn);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: decryption sa: sci=%llx, an=%d, replay=%d, windows=0x%x, enable receive=%d, lowest pn=0x%llx",
+ nic_dev->netdev->name, dec_sa->sci, dec_sa->an,
+ dec_sa->replay_protect, dec_sa->replay_window,
+ dec_sa->enable_receive, dec_sa->lowest_pn);
}
void himacsec_dfx_show_sa(struct hinic5_nic_dev *nic_dev,
macsec_sa_info_s *sa_info, crypt_direction_e direct)
{
- if (direct == MACSEC_OUTBOUND)
+ if (direct == MACSEC_OUTBOUND) {
himacsec_dfx_show_enc_sa(nic_dev, sa_info);
- else
+ } else {
himacsec_dfx_show_dec_sa(nic_dev, sa_info);
+ }
}
-void himacsec_dfx_show_enc_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *enc_sc)
+void himacsec_dfx_show_enc_sc(struct hinic5_nic_dev *nic_dev,
+ macsec_sc_info_s *enc_sc)
{
- macsec_info(nic_dev->lld_dev->dev,
- "%s: encryption sc: sci=%llx, protect_frames=%d, protection_mode=%d, include_sci=%d, use_scb=%d, use_es=%d, encodingsa=%d",
- nic_dev->netdev->name, enc_sc->sci,
- enc_sc->protect_frames, enc_sc->protection_mode,
- enc_sc->include_sci_enable, enc_sc->use_scb_enable,
- enc_sc->use_es_enable, enc_sc->encoding_sa);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: encryption sc: sci=%llx, protect_frames=%d, protection_mode=%d, include_sci=%d, use_scb=%d, "
+ "use_es=%d, encodingsa=%d",
+ nic_dev->netdev->name, enc_sc->sci, enc_sc->protect_frames,
+ enc_sc->protection_mode, enc_sc->include_sci_enable,
+ enc_sc->use_scb_enable, enc_sc->use_es_enable,
+ enc_sc->encoding_sa);
}
-void himacsec_dfx_show_dec_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *dec_sc)
+void himacsec_dfx_show_dec_sc(struct hinic5_nic_dev *nic_dev,
+ macsec_sc_info_s *dec_sc)
{
- macsec_info(nic_dev->lld_dev->dev, "%s: decryption sc: sci=%llx, validate_frames=%d",
- nic_dev->netdev->name, dec_sc->sci, dec_sc->validate_frames);
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: decryption sc: sci=%llx, validate_frames=%d",
+ nic_dev->netdev->name, dec_sc->sci,
+ dec_sc->validate_frames);
}
void himacsec_dfx_show_sc(struct hinic5_nic_dev *nic_dev,
macsec_sc_info_s *sc_info, crypt_direction_e direct)
{
- if (direct == MACSEC_OUTBOUND)
+ if (direct == MACSEC_OUTBOUND) {
himacsec_dfx_show_enc_sc(nic_dev, sc_info);
- else
+ } else {
himacsec_dfx_show_dec_sc(nic_dev, sc_info);
-}
+ }
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.h
index 96be3b08f..528d8c212 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_dfx.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_dfx.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Device entities storage
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: 存放实体
+ * Create: 2024/03/01
*/
#ifndef HINIC5_MACSEC_DFX_H
@@ -18,12 +14,20 @@
#include "macsec_mpu_cmd_defs.h"
#include "macsec_pub_cmd.h"
-#define HIMACSEC_DRV_VER "100.0.1.102"
+#ifdef GLOBAL_VERSION_STR
+#define HIMACSEC_DRV_VER GLOBAL_VERSION_STR
+#else
+#define HIMACSEC_DRV_VER ""
+#endif
-#define macsec_err(dev, format, ...) dev_err(dev, "[MACsec]" format, ##__VA_ARGS__)
-#define macsec_warning(dev, format, ...) dev_warn(dev, "[MACsec]" format, ##__VA_ARGS__)
-#define macsec_notice(dev, format, ...) dev_notice(dev, "[MACsec]" format, ##__VA_ARGS__)
-#define macsec_info(dev, format, ...) dev_info(dev, "[MACsec]" format, ##__VA_ARGS__)
+#define macsec_err(dev, format, ...) \
+ dev_err(dev, "[MACsec]" format, ##__VA_ARGS__)
+#define macsec_warning(dev, format, ...) \
+ dev_warn(dev, "[MACsec]" format, ##__VA_ARGS__)
+#define macsec_notice(dev, format, ...) \
+ dev_notice(dev, "[MACsec]" format, ##__VA_ARGS__)
+#define macsec_info(dev, format, ...) \
+ dev_info(dev, "[MACsec]" format, ##__VA_ARGS__)
void himacsec_dfx_convert_key_length(u32 *key_length, u32 chip_key_len_val);
void himacsec_dfx_show_sa(struct hinic5_nic_dev *nic_dev,
@@ -31,4 +35,4 @@ void himacsec_dfx_show_sa(struct hinic5_nic_dev *nic_dev,
void himacsec_dfx_show_sc(struct hinic5_nic_dev *nic_dev,
macsec_sc_info_s *sc_info, crypt_direction_e direct);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_main.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_main.c
index 0cea7aa63..e1211e7df 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_main.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_main.c
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_main.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : macsec main
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: macsec main
+ * Create: 2025/11/05
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [MACsec]" fmt
@@ -25,15 +21,16 @@
#include "hinic5_macsec_common.h"
#include "hinic5_macsec_dev.h"
-// TODO: This parameter is for 4SA mode adaptation, to be removed after config file is ready
+// TODO 该参数适配支持4sa模式, 配置文件ready后删除
static u8 macsec_sc_mode = HIMACSEC_SC_MODE_FOUR_SA;
module_param(macsec_sc_mode, byte, 0444);
MODULE_PARM_DESC(macsec_sc_mode, "MACsec SC mode, 0: 2SA, 1: 4SA (default=1)");
-struct macsec_port_res g_macsec_port_res[MACSEC_PORT_NUM] = {0};
+struct macsec_port_res g_macsec_port_res[MACSEC_PORT_NUM] = { 0 };
-#define HIMACSEC_DRV_DESC "Huawei(R) Intelligent Network Interface Card, MACsec driver"
-#define HIMACSEC_AUTHOR "Huawei Technologies CO., Ltd"
+#define HIMACSEC_DRV_DESC \
+ "Huawei(R) Intelligent Network Interface Card, MACsec driver"
+#define HIMACSEC_AUTHOR "Huawei Technologies CO., Ltd"
struct himacsec_sc *get_g_macsec_port_res(u32 mode, u32 port_id)
{
@@ -41,33 +38,38 @@ struct himacsec_sc *get_g_macsec_port_res(u32 mode, u32 port_id)
pr_err("MACsec param port_id(0x%x) invalid", port_id);
return NULL;
}
- if (mode == MACSEC_OUTBOUND)
+ if (mode == MACSEC_OUTBOUND) {
return &g_macsec_port_res[port_id].enc_sc;
- else
+ } else {
return &g_macsec_port_res[port_id].dec_sc;
+ }
}
int himacsec_init_dev_spec(struct macsec_resource *macsec_res,
- struct hinic5_lld_dev *lld_dev, struct himacsec_spec *spec)
+ struct hinic5_lld_dev *lld_dev,
+ struct himacsec_spec *spec)
{
macsec_res->spec.macsec_support = spec->macsec_support;
macsec_res->spec.max_port = spec->max_port;
if (macsec_sc_mode >= HIMACSEC_SC_MODE_MAX) {
- macsec_err(lld_dev->dev, "MACsec param macsec_sc_mode(0x%x) invalid",
+ macsec_err(lld_dev->dev,
+ "MACsec param macsec_sc_mode(0x%x) invalid",
macsec_sc_mode);
return -EINVAL;
}
- macsec_res->spec.max_sa = (macsec_sc_mode + 1) << 0x1; // macsec_sc_mode=0: 2SA mode
- // macsec_sc_mode=1: 4SA mode
- macsec_res->spec.max_port_sc = spec->max_port_sc; // Port SC count: 2SA mode - 8 SCs
- // 4SA mode - 4 SCs
+ macsec_res->spec.max_sa =
+ (macsec_sc_mode + 1)
+ << 0x1; // macsec_sc_mod=0: 2SA模式 macsec_sc_mode=1: 4SA模式
+ macsec_res->spec.max_port_sc =
+ spec->max_port_sc; // 端口SC数量:2SA模式-8个SC 4SA模式-4个SC
return 0;
}
-int himacsec_init_resource(struct hinic5_nic_dev *nic_dev, struct hinic5_lld_dev *lld_dev,
+int himacsec_init_resource(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_lld_dev *lld_dev,
struct himacsec_spec *spec, u64 feature_bitmap)
{
struct macsec_resource *macsec_res = NULL;
@@ -76,24 +78,28 @@ int himacsec_init_resource(struct hinic5_nic_dev *nic_dev, struct hinic5_lld_dev
u8 port = hinic5_physical_port_id(lld_dev->hwdev);
macsec_res = kzalloc(sizeof(struct macsec_resource), GFP_KERNEL);
- if (!macsec_res)
+ if (macsec_res == NULL) {
+ macsec_err(lld_dev->dev, "Alloc MACsec resource memory failed");
return -ENOMEM;
+ }
- /* 1. Initialize spec */
+ /* 1、初始化 spec */
ret = himacsec_init_dev_spec(macsec_res, lld_dev, spec);
if (ret != 0) {
kfree(macsec_res);
return ret;
}
- /* 3. Private data callback */
+ /* 3、私有数据回挂 */
macsec_res->function_port = port;
macsec_res->offload_dev_num = 0;
macsec_res->himacsec_feature[0] = feature_bitmap;
- nic_dev->macsec_res = macsec_res; // Callback to nic_dev
+ nic_dev->macsec_res = macsec_res; // 回挂到nic_dev
- macsec_info(lld_dev->dev, "Func 0x%x macsec capability: sc_mode(0:2sa, 1:4sa): %u, func_port: %u, feature: 0x%llx",
- func_id, macsec_sc_mode, port, feature_bitmap);
+ macsec_info(
+ lld_dev->dev,
+ "Func 0x%x macsec capability: sc_mode(0:2sa, 1:4sa): %u, func_port: %u, feature: 0x%llx",
+ func_id, macsec_sc_mode, port, feature_bitmap);
return ret;
}
@@ -102,14 +108,16 @@ void himacsec_release_resource(struct hinic5_nic_dev *nic_dev)
{
struct macsec_resource *macsec_res = NULL;
- if (!nic_dev)
+ if (nic_dev == NULL) {
return;
+ }
macsec_res = nic_dev->macsec_res;
- if (!macsec_res)
+ if (macsec_res == NULL) {
return;
+ }
- // 2. Clean up MACsec resources
+ // 2、清理 MACsec 资源
kfree(macsec_res);
nic_dev->macsec_res = NULL;
}
@@ -118,48 +126,51 @@ int macsec_init_offload(struct hinic5_nic_dev *nic_dev)
{
u64 feature_bitmap = 0;
int ret;
- struct himacsec_spec spec = {0};
+ struct himacsec_spec spec = { 0 };
struct hinic5_lld_dev *lld_dev = NULL;
u8 macsec_flag = MACSEC_GLOBAL_SWITCH_IS_DISABLE;
- if (!nic_dev || !nic_dev->lld_dev || !nic_dev->netdev) {
+ if (nic_dev == NULL || nic_dev->lld_dev == NULL ||
+ nic_dev->netdev == NULL) {
pr_err("lld device is NULL, MACsec init failed");
return -ENODEV;
}
lld_dev = nic_dev->lld_dev;
- /* 1. Confirm MACsec enable status */
+ /* 1、确认MACsec使能情况 */
if (!hinic5_support_macsec(lld_dev->hwdev)) {
macsec_info(lld_dev->dev, "HW don't support macsec");
return 0;
}
- /* 2. Feature negotiation */
- if (himacsec_cmd_exec_get_feature_nego(lld_dev, &feature_bitmap, 1) != 0) {
+ /* 2、特性协商 */
+ if (himacsec_cmd_exec_get_feature_nego(lld_dev, &feature_bitmap, 1) !=
+ 0) {
macsec_err(lld_dev->dev, "Feature negotiation failed");
return -EBUSY;
}
- /* 3. Global configuration fetch */
+ /* 3、全局配置获取 */
if (himacsec_cmd_exec_get_spec(lld_dev->hwdev, &spec) != 0) {
macsec_err(lld_dev->dev, "Get chip spec failed");
return -EBUSY;
}
- /* 4. Initialize MACsec private data in nic_dev */
+ /* 4、nic_dev中初始化MACsec私有数据 */
ret = himacsec_init_resource(nic_dev, lld_dev, &spec, feature_bitmap);
if (ret != 0) {
- macsec_err(lld_dev->dev, "Init MACsec private data failed, ret:%d", ret);
+ macsec_err(lld_dev->dev,
+ "Init MACsec private data failed, ret:%d", ret);
return ret;
}
- /* 5. Initialize MACsec function offload in kernel protocol stack */
+ /* 5、内核协议栈 macsec 功能卸载初始化 */
himacsec_offload_init(nic_dev);
- /* 6. Enable MACsec, initialization operation required (only once) */
- ret = himacsec_cmd_exec_macsec_enable(lld_dev, MACSEC_CMD_SERVICE_OP_MACSEC_ENABLE,
- &macsec_flag);
+ /* 6、使能 macsec,需要进行初始化操作(只需要一次) */
+ ret = himacsec_cmd_exec_macsec_enable(
+ lld_dev, MACSEC_CMD_SERVICE_OP_MACSEC_ENABLE, &macsec_flag);
if (ret != 0) {
macsec_err(lld_dev->dev, "Enable macsec failed, ret:%d", ret);
goto enable_macsec_fail;
@@ -171,8 +182,9 @@ int macsec_init_offload(struct hinic5_nic_dev *nic_dev)
enable_macsec_fail:
himacsec_offload_deinit(nic_dev);
himacsec_release_resource(nic_dev);
- if (macsec_flag == MACSEC_GLOBAL_SWITCH_IS_DISABLE)
+ if (macsec_flag == MACSEC_GLOBAL_SWITCH_IS_DISABLE) {
return 0;
+ }
return ret;
}
@@ -182,7 +194,8 @@ void macsec_cleanup_offload(struct hinic5_nic_dev *nic_dev)
struct hinic5_lld_dev *lld_dev = NULL;
int ret;
- if (!nic_dev || !nic_dev->lld_dev || !nic_dev->netdev) {
+ if (nic_dev == NULL || nic_dev->lld_dev == NULL ||
+ nic_dev->netdev == NULL) {
pr_err("lld device is NULL, MACsec resource release failed");
return;
}
@@ -190,15 +203,18 @@ void macsec_cleanup_offload(struct hinic5_nic_dev *nic_dev)
lld_dev = nic_dev->lld_dev;
macsec_res = nic_dev->macsec_res;
- if (!macsec_res || macsec_res->spec.macsec_support == 0)
+ if ((macsec_res == NULL) || (macsec_res->spec.macsec_support == 0)) {
return;
+ }
- ret = himacsec_cmd_exec_macsec_enable(lld_dev, MACSEC_CMD_SERVICE_OP_MACSEC_DISABLE, NULL);
- if (ret != 0)
+ ret = himacsec_cmd_exec_macsec_enable(
+ lld_dev, MACSEC_CMD_SERVICE_OP_MACSEC_DISABLE, NULL);
+ if (ret != 0) {
macsec_err(lld_dev->dev, "Disable macsec failed, ret:%d", ret);
+ }
himacsec_offload_deinit(nic_dev);
himacsec_release_resource(nic_dev);
macsec_info(lld_dev->dev, "Macsec resource release successfully");
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_mgmt.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_mgmt.c
index 77adc6d74..741a580da 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_mgmt.c
@@ -1,16 +1,13 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_mgmt.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : macsec configuration distribution
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: macsec 配置下发
+ * Create: 2024/03/07
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [MACsec]" fmt
#include <linux/types.h>
+#include "securec.h"
#include "macsec_mpu_cmd.h"
#include "macsec_mpu_cmd_defs.h"
#include "hinic5_hw.h"
@@ -25,16 +22,20 @@ int himacsec_cmd_exec_get_feature_nego(struct hinic5_lld_dev *lld_dev,
{
int ret;
u16 out_size = sizeof(macsec_feature_nego_cmd_s);
- macsec_feature_nego_cmd_s feature_nego = {0};
+ macsec_feature_nego_cmd_s feature_nego = { 0 };
- if (!feature_bitmap) {
- macsec_err(lld_dev->dev, "MACsec get feature nego invalid param, feature bitmap is NULL");
+ if (feature_bitmap == NULL) {
+ macsec_err(
+ lld_dev->dev,
+ "MACsec get feature nego invalid param, feature bitmap is NULL");
return -EINVAL;
}
if (feature_size > MACSEC_MAX_FEATURE_QWORD) {
- macsec_err(lld_dev->dev, "MACsec get feature nego invalid param, feature_size(0x%x) is greater than 0x%x",
- feature_size, MACSEC_MAX_FEATURE_QWORD);
+ macsec_err(
+ lld_dev->dev,
+ "MACsec get feature nego invalid param, feature_size(0x%x) is greater than 0x%x",
+ feature_size, MACSEC_MAX_FEATURE_QWORD);
return -EINVAL;
}
@@ -44,21 +45,23 @@ int himacsec_cmd_exec_get_feature_nego(struct hinic5_lld_dev *lld_dev,
sizeof(macsec_feature_nego_cmd_s),
&feature_nego, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || feature_nego.head.status != 0 ||
- out_size != (u32)sizeof(feature_nego)) {
- macsec_err(lld_dev->dev, "MACsec get feature nego status(0x%x) incorrect, out size(0x%x) not equals 0x%x",
- feature_nego.head.status, out_size, (u32)sizeof(feature_nego));
+ if ((ret != 0) || (feature_nego.head.status != 0) ||
+ (out_size != (u32)sizeof(feature_nego))) {
+ macsec_err(
+ lld_dev->dev,
+ "MACsec get feature nego status(0x%x) incorrect, out size(0x%x) not equals 0x%x",
+ feature_nego.head.status, out_size,
+ (u32)sizeof(feature_nego));
return -EINVAL;
}
- memcpy(feature_bitmap, feature_nego.s_feature, feature_size * sizeof(u64));
+ (void)memcpy_s(feature_bitmap, feature_size * sizeof(u64),
+ feature_nego.s_feature, feature_size * sizeof(u64));
return 0;
}
-/* TODO(B998): Get chip specifications, port number, max supported SC count per port,
- * AT&Productization consider getting from config file, currently FT solidified
- */
+/* TODO(B998):获得芯片规格,port数、最大支持SC数/port,AT&产品化考虑是否从配置文件获取,当前FT固化 */
int himacsec_cmd_exec_get_spec(void *hwdev, struct himacsec_spec *spec)
{
spec->macsec_support = 1;
@@ -69,16 +72,18 @@ int himacsec_cmd_exec_get_spec(void *hwdev, struct himacsec_spec *spec)
}
int himacsec_cmd_exec_macsec_enable(struct hinic5_lld_dev *lld_dev,
- macsec_mbox_service_op_cmd_e op_code, u8 *macsec_flag)
+ macsec_mbox_service_op_cmd_e op_code,
+ u8 *macsec_flag)
{
- macsec_cmd_service_operation_s macsec_cfg = {0};
+ macsec_cmd_service_operation_s macsec_cfg = { 0 };
u16 out_size = sizeof(macsec_cmd_service_operation_s);
int ret;
- /* MACsec global switch is only configured on PPF device */
+ /* MACsec全局开关仅在PPF设备配置时配置 */
if (hinic5_func_type(lld_dev->hwdev) != TYPE_PPF) {
- if (macsec_flag)
+ if (macsec_flag != NULL) {
*macsec_flag = MACSEC_GLOBAL_SWITCH_IS_ENABLE;
+ }
return 0;
}
@@ -89,60 +94,72 @@ int himacsec_cmd_exec_macsec_enable(struct hinic5_lld_dev *lld_dev,
sizeof(macsec_cmd_service_operation_s),
&macsec_cfg, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || out_size != sizeof(macsec_cmd_service_operation_s) ||
- macsec_cfg.head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec service init cmd, err=0x%x, status=0x%x, out size:0x%x, enable:0x%x",
- ret, macsec_cfg.head.status, out_size, macsec_cfg.op_code);
+ if ((ret != 0) ||
+ (out_size != sizeof(macsec_cmd_service_operation_s)) ||
+ (macsec_cfg.head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec service init cmd, err=0x%x, status=0x%x, out size:0x%x, enable:0x%x",
+ ret, macsec_cfg.head.status, out_size,
+ macsec_cfg.op_code);
return -EINVAL;
}
- if (macsec_flag)
+ if (macsec_flag != NULL) {
*macsec_flag = MACSEC_GLOBAL_SWITCH_IS_ENABLE;
+ }
return 0;
}
-int himacsec_cmd_exec_sc_op(struct hinic5_lld_dev *lld_dev, macsec_sc_info_s *sc_info,
+int himacsec_cmd_exec_sc_op(struct hinic5_lld_dev *lld_dev,
+ macsec_sc_info_s *sc_info,
macsec_mbox_sc_op_cmd_e opcode)
{
u16 out_size = sizeof(macsec_cmd_sc_operation_s);
- macsec_cmd_sc_operation_s macsec_cfg = {0};
+ macsec_cmd_sc_operation_s macsec_cfg = { 0 };
int ret;
- memcpy(&macsec_cfg.sc_info, sc_info, sizeof(macsec_sc_info_s));
+ (void)memcpy_s(&macsec_cfg.sc_info, sizeof(macsec_sc_info_s), sc_info,
+ sizeof(macsec_sc_info_s));
macsec_cfg.op_code = opcode;
- // HINIC5_CHANNEL_MACSEC scenario:
- // Need to intercept all features using this channel to MPU requests
+ // HINIC5_CHANNEL_MACSEC 作用于场景:需要拦截所有使用该通道的特性发往 MPU 的请求
ret = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_MACSEC,
MACSEC_CMD_SC_OP, &macsec_cfg,
sizeof(macsec_cmd_sc_operation_s),
&macsec_cfg, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || out_size != sizeof(macsec_cmd_sc_operation_s) ||
- macsec_cfg.head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec sc cmd, err=0x%x, status=0x%x, out size:0x%x",
- ret, macsec_cfg.head.status, out_size);
+ if ((ret != 0) || (out_size != sizeof(macsec_cmd_sc_operation_s)) ||
+ (macsec_cfg.head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec sc cmd, err=0x%x, status=0x%x, out size:0x%x",
+ ret, macsec_cfg.head.status, out_size);
return -EINVAL;
}
- // buf result
- if (opcode == MACSEC_CMD_ENC_SC_GET_INFO || opcode == MACSEC_CMD_DEC_SC_GET_INFO)
- memcpy(sc_info, &macsec_cfg.sc_info, sizeof(macsec_sc_info_s));
+ // buf 结果拷贝
+ if ((opcode == MACSEC_CMD_ENC_SC_GET_INFO) ||
+ (opcode == MACSEC_CMD_DEC_SC_GET_INFO)) {
+ (void)memcpy_s(sc_info, sizeof(macsec_sc_info_s),
+ &macsec_cfg.sc_info, sizeof(macsec_sc_info_s));
+ }
return 0;
}
-int himacsec_cmd_exec_sa_op(struct hinic5_lld_dev *lld_dev, macsec_sa_info_s *sa_info,
+int himacsec_cmd_exec_sa_op(struct hinic5_lld_dev *lld_dev,
+ macsec_sa_info_s *sa_info,
macsec_mbox_sa_op_cmd_e opcode)
{
- /* out_size in driver->mpu flow represents the buf size for receiving mailbox return message
- * out_size in mpu->driver flow represents the actual size of mailbox return message,
- * copied by sdk to out_buf
- */
+ /* out_size 在 driver->mpu 流程中表示用于接收 mailbox 返回消息的 buf 大小
+ * out_size 在 mpu->driver 流程中表示 mailbox 返回消息实际的大小,由 sdk 拷贝到 out_buf 中
+ */
u16 out_size = sizeof(macsec_cmd_sa_operation_s);
- macsec_cmd_sa_operation_s macsec_cfg = {0};
+ macsec_cmd_sa_operation_s macsec_cfg = { 0 };
int ret;
- memcpy(&macsec_cfg.sa_info, sa_info, sizeof(macsec_sa_info_s));
+ (void)memcpy_s(&macsec_cfg.sa_info, sizeof(macsec_sa_info_s), sa_info,
+ sizeof(macsec_sa_info_s));
macsec_cfg.op_code = opcode;
ret = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_MACSEC,
@@ -150,23 +167,30 @@ int himacsec_cmd_exec_sa_op(struct hinic5_lld_dev *lld_dev, macsec_sa_info_s *sa
sizeof(macsec_cmd_sa_operation_s),
&macsec_cfg, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- memset(macsec_cfg.sa_info.sak, 0, HIMACSEC_MAX_SAK_KEY_LEN);
- if (ret != 0 || out_size != sizeof(macsec_cmd_sa_operation_s) ||
- macsec_cfg.head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec sa cmd, err=0x%x, status=0x%x, out size:0x%x",
- ret, macsec_cfg.head.status, out_size);
+ (void)memset_s(macsec_cfg.sa_info.sak, HIMACSEC_MAX_SAK_KEY_LEN, 0,
+ HIMACSEC_MAX_SAK_KEY_LEN);
+ if ((ret != 0) || (out_size != sizeof(macsec_cmd_sa_operation_s)) ||
+ (macsec_cfg.head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec sa cmd, err=0x%x, status=0x%x, out size:0x%x",
+ ret, macsec_cfg.head.status, out_size);
return -EINVAL;
}
- // buf result
- if (opcode == MACSEC_CMD_ENC_SA_GET_INFO || opcode == MACSEC_CMD_DEC_SA_GET_INFO)
- memcpy(sa_info, &macsec_cfg.sa_info, sizeof(macsec_sa_info_s));
+ // buf 结果拷贝
+ if ((opcode == MACSEC_CMD_ENC_SA_GET_INFO) ||
+ (opcode == MACSEC_CMD_DEC_SA_GET_INFO)) {
+ (void)memcpy_s(sa_info, sizeof(macsec_sa_info_s),
+ &macsec_cfg.sa_info, sizeof(macsec_sa_info_s));
+ }
return 0;
}
-int himacsec_cmd_exec_mib_port(struct hinic5_lld_dev *lld_dev, struct himacsec_cmd_mib_out *cmd_out)
+int himacsec_cmd_exec_mib_port(struct hinic5_lld_dev *lld_dev,
+ struct himacsec_cmd_mib_out *cmd_out)
{
- macsec_cmd_port_mib_operation_s macsec_cfg = {0};
+ macsec_cmd_port_mib_operation_s macsec_cfg = { 0 };
u16 out_size = sizeof(macsec_cmd_port_mib_operation_s);
int ret;
@@ -175,15 +199,24 @@ int himacsec_cmd_exec_mib_port(struct hinic5_lld_dev *lld_dev, struct himacsec_c
sizeof(macsec_cmd_port_mib_operation_s),
&macsec_cfg, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || out_size != sizeof(macsec_cmd_port_mib_operation_s) ||
- macsec_cfg.head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec port mib cmd, err=0x%x, status=0x%x, out size:0x%x",
- ret, macsec_cfg.head.status, out_size);
+ if ((ret != 0) ||
+ (out_size != sizeof(macsec_cmd_port_mib_operation_s)) ||
+ (macsec_cfg.head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec port mib cmd, err=0x%x, status=0x%x, out size:0x%x",
+ ret, macsec_cfg.head.status, out_size);
return -EINVAL;
}
- // Copy result to out_buf
- memcpy(cmd_out->mib_buf, &macsec_cfg.port_mib, sizeof(macsec_cfg.port_mib));
+ // 复制结果到 out_buf
+ ret = memcpy_s(cmd_out->mib_buf, HIMACSEC_MIB_OUT_BUF_MAX,
+ &macsec_cfg.port_mib, sizeof(macsec_cfg.port_mib));
+ if (ret != 0) {
+ macsec_err(lld_dev->dev,
+ "Copy port mib information failed, ret=%d", ret);
+ return ret;
+ }
return 0;
}
@@ -191,7 +224,7 @@ int himacsec_cmd_exec_mib_port(struct hinic5_lld_dev *lld_dev, struct himacsec_c
int himacsec_cmd_exec_mib_sc(struct hinic5_lld_dev *lld_dev,
struct himacsec_cmd_mib_out *out_buf, u64 sci)
{
- macsec_cmd_sc_mib_operation_s macsec_cfg = {0};
+ macsec_cmd_sc_mib_operation_s macsec_cfg = { 0 };
u16 out_size = sizeof(macsec_cmd_sc_mib_operation_s);
int ret;
@@ -201,32 +234,45 @@ int himacsec_cmd_exec_mib_sc(struct hinic5_lld_dev *lld_dev,
sizeof(macsec_cmd_sc_mib_operation_s),
&macsec_cfg, &out_size, 0,
HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || out_size != sizeof(macsec_cmd_sc_mib_operation_s) ||
- macsec_cfg.head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec sc mib cmd, err=0x%x, status=0x%x, out size:0x%x",
- ret, macsec_cfg.head.status, out_size);
+ if ((ret != 0) || (out_size != sizeof(macsec_cmd_sc_mib_operation_s)) ||
+ (macsec_cfg.head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec sc mib cmd, err=0x%x, status=0x%x, out size:0x%x",
+ ret, macsec_cfg.head.status, out_size);
return -EINVAL;
}
out_buf->num = 1;
- memcpy(out_buf->mib_buf, &macsec_cfg.sc_mib, sizeof(macsec_sc_mib_info_s));
+ ret = memcpy_s(out_buf->mib_buf, HIMACSEC_MIB_OUT_BUF_MAX,
+ &macsec_cfg.sc_mib, sizeof(macsec_sc_mib_info_s));
+ if (ret != 0) {
+ macsec_err(lld_dev->dev,
+ "Copy sc mib information failed, sci=%llx, ret=%d",
+ sci, ret);
+ return ret;
+ }
return 0;
}
-int himacsec_cmd_exec_flush(struct hinic5_lld_dev *lld_dev, tag_macsec_flush_cmd_s *flush_info)
+int himacsec_cmd_exec_flush(struct hinic5_lld_dev *lld_dev,
+ tag_macsec_flush_cmd_s *flush_info)
{
u16 out_size = sizeof(tag_macsec_flush_cmd_s);
int ret;
ret = hinic5_msg_to_mgmt_sync(lld_dev->hwdev, HINIC5_MOD_MACSEC,
MACSEC_CMD_FLUSH_OP, flush_info,
- sizeof(tag_macsec_flush_cmd_s), flush_info,
- &out_size, 0, HINIC5_CHANNEL_MACSEC);
- if (ret != 0 || out_size != sizeof(tag_macsec_flush_cmd_s) ||
- flush_info->head.status != 0) {
- macsec_err(lld_dev->dev, "Failed to exec flush cmd, err=0x%x, status=0x%x, out size:0x%x",
- ret, flush_info->head.status, out_size);
+ sizeof(tag_macsec_flush_cmd_s),
+ flush_info, &out_size, 0,
+ HINIC5_CHANNEL_MACSEC);
+ if ((ret != 0) || (out_size != sizeof(tag_macsec_flush_cmd_s)) ||
+ (flush_info->head.status != 0)) {
+ macsec_err(
+ lld_dev->dev,
+ "Failed to exec flush cmd, err=0x%x, status=0x%x, out size:0x%x",
+ ret, flush_info->head.status, out_size);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_nictool.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_nictool.c
index 7da02d6a3..28938eceb 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_nictool.c
@@ -1,16 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_nictool.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : macsec nictool interface
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: macsec nictool intaface
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [MACsec]" fmt
#include <linux/semaphore.h>
+#include "securec.h"
#include "hinic5_lld.h"
#include "hinic5_mt.h"
@@ -20,9 +16,10 @@
#include "hinic5_macsec_common.h"
#include "hinic5_macsec_dfx.h"
-static int himacsec_cmd_check_param_buf(const void *buf, u32 buf_size, u32 exp_buf_size)
+static int himacsec_cmd_check_param_buf(const void *buf, u32 buf_size,
+ u32 exp_buf_size)
{
- if (!buf || buf_size != exp_buf_size) {
+ if ((buf == NULL) || (buf_size != exp_buf_size)) {
pr_err("Buffer in or out can not be NULL when exec macsec cmd, buf size=%d, exp size=%d",
buf_size, exp_buf_size);
return -EINVAL;
@@ -30,10 +27,11 @@ static int himacsec_cmd_check_param_buf(const void *buf, u32 buf_size, u32 exp_b
return 0;
}
-int himacsec_fill_enc_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *enc_sc,
- struct himacsec_sa *tar_sa, u8 *sa_cnt, u32 cmd_type)
+int himacsec_fill_enc_sa(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_sc *enc_sc, struct himacsec_sa *tar_sa,
+ u8 *sa_cnt, u32 cmd_type)
{
- struct himacsec_sa enc_sa = {0};
+ struct himacsec_sa enc_sa = { 0 };
u8 sa_index = 0;
u8 an = 0; // There is no an in the sa table, it needs to be rewritten back
int index;
@@ -42,15 +40,18 @@ int himacsec_fill_enc_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *enc
for (index = 0; index < nic_dev->macsec_res->spec.max_sa; index++) {
enc_sa = enc_sc->sa[index];
an = enc_sa.info.an;
- if (MACSEC_SA_STATUS_VALID(enc_sa.status.status.sa) == 0)
+ if (MACSEC_SA_STATUS_VALID(enc_sa.status.status.sa) == 0) {
continue;
+ }
if (cmd_type == MACSEC_TOOL_OP_DUMP) {
- ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev,
- &enc_sa.info,
- MACSEC_CMD_ENC_SA_GET_INFO);
+ ret = himacsec_cmd_exec_sa_op(
+ nic_dev->lld_dev, &enc_sa.info,
+ MACSEC_CMD_ENC_SA_GET_INFO);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd dump encryption sa config failed, ret=%d",
- nic_dev->netdev->name, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Exec cmd dump encryption sa config failed, ret=%d",
+ nic_dev->netdev->name, ret);
return ret;
}
enc_sa.info.an = an;
@@ -61,10 +62,11 @@ int himacsec_fill_enc_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *enc
return ret;
}
-int himacsec_fill_dec_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *dec_sc,
- struct himacsec_sa *tar_sa, u8 *sa_cnt, u32 cmd_type)
+int himacsec_fill_dec_sa(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_sc *dec_sc, struct himacsec_sa *tar_sa,
+ u8 *sa_cnt, u32 cmd_type)
{
- struct himacsec_sa dec_sa = {0};
+ struct himacsec_sa dec_sa = { 0 };
u8 an = 0; // There is no an in the sa table, it needs to be rewritten back
u8 sa_index = 0;
int index;
@@ -73,15 +75,18 @@ int himacsec_fill_dec_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *dec
for (index = 0; index < nic_dev->macsec_res->spec.max_sa; index++) {
dec_sa = dec_sc->sa[index];
an = dec_sa.info.an;
- if (MACSEC_SA_STATUS_VALID(dec_sa.status.status.sa) == 0)
+ if (MACSEC_SA_STATUS_VALID(dec_sa.status.status.sa) == 0) {
continue;
+ }
if (cmd_type == MACSEC_TOOL_OP_DUMP) {
- ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev,
- &dec_sa.info,
- MACSEC_CMD_DEC_SA_GET_INFO);
+ ret = himacsec_cmd_exec_sa_op(
+ nic_dev->lld_dev, &dec_sa.info,
+ MACSEC_CMD_DEC_SA_GET_INFO);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd dump decryption sa config failed, ret=%d",
- nic_dev->netdev->name, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Exec cmd dump decryption sa config failed, ret=%d",
+ nic_dev->netdev->name, ret);
return ret;
}
dec_sa.info.an = an;
@@ -92,8 +97,10 @@ int himacsec_fill_dec_sa(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *dec
return ret;
}
-int macsec_get_enc_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *temp_sc,
- struct himacsec_cmd_list_sc_buf *cur_sc_buf, u32 cmd_type)
+int macsec_get_enc_sc_info(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_sc *temp_sc,
+ struct himacsec_cmd_list_sc_buf *cur_sc_buf,
+ u32 cmd_type)
{
int ret = 0;
@@ -101,15 +108,18 @@ int macsec_get_enc_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *t
ret = himacsec_cmd_exec_sc_op(nic_dev->lld_dev, &temp_sc->info,
MACSEC_CMD_ENC_SC_GET_INFO);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, fetch tx sc info fail.",
- ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, fetch tx sc info fail.",
+ ret);
return ret;
}
}
ret = himacsec_fill_enc_sa(nic_dev, temp_sc, cur_sc_buf->sc.sa,
&cur_sc_buf->sa_cnt, cmd_type);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, fetch tx sa info fail.",
+ macsec_err(nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, fetch tx sa info fail.",
ret);
return ret;
}
@@ -118,8 +128,10 @@ int macsec_get_enc_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *t
return 0;
}
-int macsec_get_dec_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *temp_sc,
- struct himacsec_cmd_list_sc_buf *cur_sc_buf, u32 cmd_type)
+int macsec_get_dec_sc_info(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_sc *temp_sc,
+ struct himacsec_cmd_list_sc_buf *cur_sc_buf,
+ u32 cmd_type)
{
int ret = 0;
@@ -127,15 +139,18 @@ int macsec_get_dec_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *t
ret = himacsec_cmd_exec_sc_op(nic_dev->lld_dev, &temp_sc->info,
MACSEC_CMD_DEC_SC_GET_INFO);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, fetch rx sc info fail.",
- ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, fetch rx sc info fail.",
+ ret);
return ret;
}
}
ret = himacsec_fill_dec_sa(nic_dev, temp_sc, cur_sc_buf->sc.sa,
&cur_sc_buf->sa_cnt, cmd_type);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, fetch rx sa info fail.",
+ macsec_err(nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, fetch rx sa info fail.",
ret);
return ret;
}
@@ -144,13 +159,13 @@ int macsec_get_dec_sc_info(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *t
return 0;
}
-int himacsec_fill_config(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_list_out *cmd_out,
- u32 cmd_type)
+int himacsec_fill_config(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_cmd_list_out *cmd_out, u32 cmd_type)
{
struct himacsec_cmd_list_sc_buf *enc_sc_buf =
- (struct himacsec_cmd_list_sc_buf *)cmd_out->enc_sc_buf;
+ (struct himacsec_cmd_list_sc_buf *)cmd_out->enc_sc_buf;
struct himacsec_cmd_list_sc_buf *dec_sc_buf =
- (struct himacsec_cmd_list_sc_buf *)cmd_out->dec_sc_buf;
+ (struct himacsec_cmd_list_sc_buf *)cmd_out->dec_sc_buf;
struct himacsec_cmd_list_sc_buf *cur_sc_buf = NULL;
struct himacsec_sc *temp_sc = NULL;
u32 enc_sc_cnt = 0;
@@ -159,30 +174,39 @@ int himacsec_fill_config(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_lis
u32 port_id = nic_dev->macsec_res->function_port;
int ret = 0;
- for (index = 0; index < nic_dev->macsec_res->spec.max_port_sc; index++) {
- // Get encryption direction macsec config
+ for (index = 0; index < nic_dev->macsec_res->spec.max_port_sc;
+ index++) {
+ // 获取加密方向 macsec 配置
temp_sc = get_g_macsec_port_res(MACSEC_OUTBOUND, port_id);
- if (!temp_sc && (MACSEC_SC_STATUS_VALID(temp_sc->status.status.sc) != 0)) {
- /* Calculate the next address to receive sc parameters */
+ if ((temp_sc != NULL) &&
+ (MACSEC_SC_STATUS_VALID(temp_sc->status.status.sc) != 0)) {
+ /* 计算下一个接收sc参数的地址 */
cur_sc_buf = enc_sc_buf + enc_sc_cnt;
- ret = macsec_get_enc_sc_info(nic_dev, temp_sc, cur_sc_buf, cmd_type);
+ ret = macsec_get_enc_sc_info(nic_dev, temp_sc,
+ cur_sc_buf, cmd_type);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, get tx macsec info fail.",
- ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, get tx macsec info fail.",
+ ret);
return ret;
}
enc_sc_cnt++;
}
- // Get decryption direction macsec config
+ // 获取解密方向 macsec 配置
temp_sc = get_g_macsec_port_res(MACSEC_INBOUND, port_id);
- if (temp_sc && (MACSEC_SC_STATUS_VALID(temp_sc->status.status.sc) != 0)) {
- /* Calculate the next address to receive sc parameters */
+ if ((temp_sc != NULL) &&
+ (MACSEC_SC_STATUS_VALID(temp_sc->status.status.sc) != 0)) {
+ /* 计算下一个接收sc参数的地址 */
cur_sc_buf = dec_sc_buf + dec_sc_cnt;
- ret = macsec_get_dec_sc_info(nic_dev, temp_sc, cur_sc_buf, cmd_type);
+ ret = macsec_get_dec_sc_info(nic_dev, temp_sc,
+ cur_sc_buf, cmd_type);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Dump cmd failed ret=%d, get rx macsec info fail.",
- ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Dump cmd failed ret=%d, get rx macsec info fail.",
+ ret);
return ret;
}
dec_sc_cnt++;
@@ -194,41 +218,48 @@ int himacsec_fill_config(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_lis
return 0;
}
-int himacsec_fill_mib_sc(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_mib_out *cmd_out,
- u64 sci)
+int himacsec_fill_mib_sc(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_cmd_mib_out *cmd_out, u64 sci)
{
struct himacsec_sc *enc_sc = NULL;
struct himacsec_sc *dec_sc = NULL;
int ret;
- // 1. Parameter validation
+ // 1. 参数校验
enc_sc = himacsec_get_valid_dev_sc(nic_dev, sci, MACSEC_OUTBOUND);
dec_sc = himacsec_get_valid_dev_sc(nic_dev, sci, MACSEC_INBOUND);
- if (!enc_sc && !dec_sc) { // SCI does not exist
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd querying sc mib failed, sci=%llx not found",
- nic_dev->netdev->name, sci);
+ if ((enc_sc == NULL) && (dec_sc == NULL)) { // SCI 不存在
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Exec cmd querying sc mib failed, sci=%llx not found",
+ nic_dev->netdev->name, sci);
return -EINVAL;
}
- // 2. Send query request
+ // 2. 发送查询请求
ret = himacsec_cmd_exec_mib_sc(nic_dev->lld_dev, cmd_out, sci);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd querying sc mib failed, sci=%llx, ret=%d",
- nic_dev->netdev->name, sci, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Exec cmd querying sc mib failed, sci=%llx, ret=%d",
+ nic_dev->netdev->name, sci, ret);
return ret;
}
return ret;
}
-int himacsec_fill_mib_port(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_mib_out *cmd_out)
+int himacsec_fill_mib_port(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_cmd_mib_out *cmd_out)
{
int ret;
ret = himacsec_cmd_exec_mib_port(nic_dev->lld_dev, cmd_out);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd query port mib failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd query port mib failed, ret=%d",
nic_dev->netdev->name, ret);
+ }
return ret;
}
@@ -241,25 +272,30 @@ int macsec_cmd_list(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
int ret = -EINVAL;
struct himacsec_cmd_in *cmd_in = (struct himacsec_cmd_in *)buf_in;
- struct himacsec_cmd_list_out *cmd_out = (struct himacsec_cmd_list_out *)buf_out;
+ struct himacsec_cmd_list_out *cmd_out =
+ (struct himacsec_cmd_list_out *)buf_out;
- // 1. Parameter validation
- if (!nic_dev->macsec_res) {
+ // 1. 参数校验
+ if (nic_dev->macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "Macsec resource is NULL");
return -EINVAL;
}
- if ((himacsec_cmd_check_param_buf(buf_in, in_size, sizeof(struct himacsec_cmd_hdr)) != 0) ||
- (himacsec_cmd_check_param_buf(buf_out, *out_size,
- sizeof(struct himacsec_cmd_list_out)) != 0)) {
+ if ((himacsec_cmd_check_param_buf(
+ buf_in, in_size, sizeof(struct himacsec_cmd_hdr)) != 0) ||
+ (himacsec_cmd_check_param_buf(
+ buf_out, *out_size,
+ sizeof(struct himacsec_cmd_list_out)) != 0)) {
return -EINVAL;
}
- // 2. Parameter assignment
+ // 2. 参数赋值
ret = himacsec_fill_config(nic_dev, cmd_out, cmd_in->hdr.cmd_type);
- if (ret != 0)
+ if (ret != 0) {
macsec_err(nic_dev->lld_dev->dev,
- "Cmd list/dump macsec config exec failed, ret=%d", ret);
+ "Cmd list/dump macsec config exec failed, ret=%d",
+ ret);
+ }
return ret;
}
@@ -273,34 +309,40 @@ int macsec_cmd_mib(struct hinic5_nic_dev *nic_dev, const void *buf_in,
int ret = -EINVAL;
struct himacsec_cmd_in *cmd_in = (struct himacsec_cmd_in *)buf_in;
struct himacsec_cmd_mib_in *mib_in = NULL;
- struct himacsec_cmd_mib_out *cmd_out = (struct himacsec_cmd_mib_out *)buf_out;
- u32 exp_in_size = sizeof(struct himacsec_cmd_hdr) + sizeof(struct himacsec_cmd_mib_in);
+ struct himacsec_cmd_mib_out *cmd_out =
+ (struct himacsec_cmd_mib_out *)buf_out;
+ u32 exp_in_size = sizeof(struct himacsec_cmd_hdr) +
+ sizeof(struct himacsec_cmd_mib_in);
- // 1. Parameter validation
- if (!nic_dev->macsec_res) {
+ // 1. 参数校验
+ if (nic_dev->macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "Macsec resource is NULL");
return -EINVAL;
}
if ((himacsec_cmd_check_param_buf(buf_in, in_size, exp_in_size) != 0) ||
- (himacsec_cmd_check_param_buf(buf_out, *out_size,
- sizeof(struct himacsec_cmd_mib_out)) != 0)) {
+ (himacsec_cmd_check_param_buf(
+ buf_out, *out_size, sizeof(struct himacsec_cmd_mib_out)) !=
+ 0)) {
return -EINVAL;
}
- // 2. Parse input parameters
+ // 2. 解析入参
mib_in = (struct himacsec_cmd_mib_in *)cmd_in->buf;
if (mib_in->mib_type == HIMACSEC_TOOL_MIB_TYPE_PORT) {
ret = himacsec_fill_mib_port(nic_dev, cmd_out);
} else if (mib_in->mib_type == HIMACSEC_TOOL_MIB_TYPE_SC) {
ret = himacsec_fill_mib_sc(nic_dev, cmd_out, mib_in->sci);
} else {
- macsec_err(nic_dev->lld_dev->dev, "Unknown mib type %d", mib_in->mib_type);
+ macsec_err(nic_dev->lld_dev->dev, "Unknown mib type %d",
+ mib_in->mib_type);
return -EINVAL;
}
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "Cmd querying macsec mib failed, ret=%d", ret);
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Cmd querying macsec mib failed, ret=%d", ret);
+ }
return ret;
}
@@ -309,84 +351,104 @@ int macsec_cmd_flush(struct hinic5_nic_dev *nic_dev, const void *buf_in,
{
int ret, index;
struct himacsec_cmd_in *cmd_in = (struct himacsec_cmd_in *)buf_in;
- tag_macsec_flush_cmd_s flush_cmd = {0};
+ tag_macsec_flush_cmd_s flush_cmd = { 0 };
struct macsec_resource *macsec_res = nic_dev->macsec_res;
struct himacsec_sc *enc_sc = NULL;
struct himacsec_sc *dec_sc = NULL;
- if (!macsec_res) {
+ if (macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
return -EINVAL;
}
- // 1. Parameter validation
- if (himacsec_cmd_check_param_buf(buf_in, in_size, sizeof(struct himacsec_cmd_hdr)) != 0)
+ // 1. 参数校验
+ if (himacsec_cmd_check_param_buf(
+ buf_in, in_size, sizeof(struct himacsec_cmd_hdr)) != 0) {
return -EINVAL;
+ }
- macsec_info(nic_dev->lld_dev->dev, "MACsec flush process, obj_type=0x%x",
+ macsec_info(nic_dev->lld_dev->dev,
+ "MACsec flush process, obj_type=0x%x",
cmd_in->hdr.obj_type);
flush_cmd.op_code = MACSEC_CMD_FLUSH_SC_OP;
ret = himacsec_cmd_exec_flush(nic_dev->lld_dev, &flush_cmd);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "MACsec flush failed, ret=0x%x", ret);
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "MACsec flush failed, ret=0x%x", ret);
+ }
enc_sc = himacsec_get_dev_sc(nic_dev, MACSEC_OUTBOUND);
dec_sc = himacsec_get_dev_sc(nic_dev, MACSEC_INBOUND);
- /* Clear driver internal data */
+ /* 清除驱动内数据 */
for (index = 0; index < macsec_res->spec.max_port_sc; index++) {
- memset(enc_sc, 0, sizeof(struct himacsec_sc));
- memset(dec_sc, 0, sizeof(struct himacsec_sc));
+ (void)memset_s(enc_sc, sizeof(struct himacsec_sc), 0,
+ sizeof(struct himacsec_sc));
+ (void)memset_s(dec_sc, sizeof(struct himacsec_sc), 0,
+ sizeof(struct himacsec_sc));
}
return ret;
}
-int himacsec_nictool_add_sc(struct hinic5_nic_dev *nic_dev, const struct himacsec_cmd_in *cmd_in,
- u32 in_size, crypt_direction_e direct)
+int himacsec_nictool_add_sc(struct hinic5_nic_dev *nic_dev,
+ const struct himacsec_cmd_in *cmd_in, u32 in_size,
+ crypt_direction_e direct)
{
int ret = 0;
macsec_sc_info_s *sc = (macsec_sc_info_s *)cmd_in->buf;
- u32 exp_in_size = sizeof(struct himacsec_cmd_hdr) + sizeof(macsec_sc_info_s);
-
+ u32 exp_in_size =
+ sizeof(struct himacsec_cmd_hdr) + sizeof(macsec_sc_info_s);
if (in_size != exp_in_size) {
- macsec_err(nic_dev->lld_dev->dev, "Add encryption cmd buffer invalid, in size=0x%x, exp_size=0x%x",
- in_size, exp_in_size);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Add encryption cmd buffer invalid, in size=0x%x, exp_size=0x%x",
+ in_size, exp_in_size);
return -EINVAL;
}
ret = himacsec_create_sc(nic_dev, sc, direct);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "Add encryption cmd fail, ret=%d", ret);
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Add encryption cmd fail, ret=%d", ret);
+ }
return ret;
}
-int himacsec_nictool_add_sa(struct hinic5_nic_dev *nic_dev, const struct himacsec_cmd_in *cmd_in,
- u32 in_size, crypt_direction_e direct)
+int himacsec_nictool_add_sa(struct hinic5_nic_dev *nic_dev,
+ const struct himacsec_cmd_in *cmd_in, u32 in_size,
+ crypt_direction_e direct)
{
macsec_sa_info_s *sa = (macsec_sa_info_s *)cmd_in->buf;
- u32 exp_in_size = sizeof(struct himacsec_cmd_hdr) + sizeof(macsec_sa_info_s);
+ u32 exp_in_size =
+ sizeof(struct himacsec_cmd_hdr) + sizeof(macsec_sa_info_s);
struct macsec_resource *macsec_res = nic_dev->macsec_res;
if (in_size != exp_in_size) {
- macsec_err(nic_dev->lld_dev->dev, "Add sa failed, size error, in size=0x%x, exp_size=0x%x",
- in_size, exp_in_size);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Add sa failed, size error, in size=0x%x, exp_size=0x%x",
+ in_size, exp_in_size);
return -EINVAL;
}
- // SM4 algorithm needs to validate whether feature negotiation result is supported
- if (sa->current_crypto_algo == HIMACSEC_CRYPTO_ALGO_SM4 &&
- (macsec_res->himacsec_feature[0] & (u64)MACSEC_F_SUPPORT_SM4) == 0) {
- macsec_err(nic_dev->lld_dev->dev, "Add sa failed, unsupported algorithm(0x%x)",
+ // SM4 算法需要校验特性协商结果是否支持
+ if ((sa->current_crypto_algo == HIMACSEC_CRYPTO_ALGO_SM4) &&
+ (macsec_res->himacsec_feature[0] & (u64)MACSEC_F_SUPPORT_SM4) ==
+ 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Add sa failed, unsupported algorithm(0x%x)",
sa->current_crypto_algo);
return -EINVAL;
}
- // Need to display configuration of RX side next_pn table
+ // 需要显示配置RX侧的next_pn表
if (sa->next_pn < sa->replay_window) {
- macsec_err(nic_dev->lld_dev->dev, "Add sa failed, replay window(0x%x) is over next pn(0x%llx)",
- sa->replay_window, sa->next_pn);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Add sa failed, replay window(0x%x) is over next pn(0x%llx)",
+ sa->replay_window, sa->next_pn);
return -EINVAL;
}
sa->lowest_pn = sa->next_pn - sa->replay_window;
@@ -394,58 +456,68 @@ int himacsec_nictool_add_sa(struct hinic5_nic_dev *nic_dev, const struct himacse
return himacsec_create_sa(nic_dev, sa, direct);
}
-int macsec_cmd_add(struct hinic5_nic_dev *nic_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+int macsec_cmd_add(struct hinic5_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct himacsec_cmd_in *cmd_in = (struct himacsec_cmd_in *)buf_in;
himacsec_tool_obj_e obj = HIMACSEC_TOOL_OBJ_MAX;
int ret;
- // 1. Parameter validation
- if (!nic_dev->macsec_res) {
+ // 1. 参数校验
+ if (nic_dev->macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "Macsec resource is NULL");
return -EINVAL;
}
- if (!buf_in) {
- macsec_err(nic_dev->lld_dev->dev, "Buffer in can not be NULL when exec macsec add cmd");
+ if (buf_in == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Buffer in can not be NULL when exec macsec add cmd");
return -EINVAL;
}
- obj = cmd_in->hdr.obj_type; // Type to be added
+ obj = cmd_in->hdr.obj_type; // 需要添加的类型
switch (obj) {
case HIMACSEC_TOOL_OBJ_ENC_SC:
- ret = himacsec_nictool_add_sc(nic_dev, cmd_in, in_size, MACSEC_OUTBOUND);
+ ret = himacsec_nictool_add_sc(nic_dev, cmd_in, in_size,
+ MACSEC_OUTBOUND);
break;
case HIMACSEC_TOOL_OBJ_DEC_SC:
- ret = himacsec_nictool_add_sc(nic_dev, cmd_in, in_size, MACSEC_INBOUND);
+ ret = himacsec_nictool_add_sc(nic_dev, cmd_in, in_size,
+ MACSEC_INBOUND);
break;
case HIMACSEC_TOOL_OBJ_ENC_SA:
- ret = himacsec_nictool_add_sa(nic_dev, cmd_in, in_size, MACSEC_OUTBOUND);
+ ret = himacsec_nictool_add_sa(nic_dev, cmd_in, in_size,
+ MACSEC_OUTBOUND);
break;
case HIMACSEC_TOOL_OBJ_DEC_SA:
- ret = himacsec_nictool_add_sa(nic_dev, cmd_in, in_size, MACSEC_INBOUND);
+ ret = himacsec_nictool_add_sa(nic_dev, cmd_in, in_size,
+ MACSEC_INBOUND);
break;
default:
- macsec_err(nic_dev->lld_dev->dev, "Unknown macsec object type:%d ", obj);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Unknown macsec object type:%d ", obj);
ret = -EINVAL;
break;
}
return ret;
}
-int macsec_cmd_del(struct hinic5_nic_dev *nic_dev, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size)
+int macsec_cmd_del(struct hinic5_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
{
struct himacsec_cmd_in *cmd_in = (struct himacsec_cmd_in *)buf_in;
- u32 exp_in_size = sizeof(struct himacsec_cmd_del_in) + sizeof(struct himacsec_cmd_hdr);
+ u32 exp_in_size = sizeof(struct himacsec_cmd_del_in) +
+ sizeof(struct himacsec_cmd_hdr);
himacsec_tool_obj_e obj = HIMACSEC_TOOL_OBJ_MAX;
struct himacsec_cmd_del_in *param = NULL;
int ret = 0;
- if (!buf_in || exp_in_size != in_size) {
- macsec_err(nic_dev->lld_dev->dev, "Buffer in invalid when exec macsec del cmd, in_size=%d, exp_size=%d",
- in_size, exp_in_size);
+ if ((buf_in == NULL) || (exp_in_size != in_size)) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Buffer in invalid when exec macsec del cmd, in_size=%d, exp_size=%d",
+ in_size, exp_in_size);
return -EINVAL;
}
@@ -460,96 +532,122 @@ int macsec_cmd_del(struct hinic5_nic_dev *nic_dev, const void *buf_in, u32 in_si
ret = himacsec_destroy_sc(nic_dev, param->sci, MACSEC_INBOUND);
break;
case HIMACSEC_TOOL_OBJ_ENC_SA:
- ret = himacsec_destroy_sa(nic_dev, param->sci, param->an, MACSEC_OUTBOUND);
+ ret = himacsec_destroy_sa(nic_dev, param->sci, param->an,
+ MACSEC_OUTBOUND);
break;
case HIMACSEC_TOOL_OBJ_DEC_SA:
- ret = himacsec_destroy_sa(nic_dev, param->sci, param->an, MACSEC_INBOUND);
+ ret = himacsec_destroy_sa(nic_dev, param->sci, param->an,
+ MACSEC_INBOUND);
break;
default:
- macsec_err(nic_dev->lld_dev->dev, "Unknown macsec object type:%d ", obj);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Unknown macsec object type:%d ", obj);
ret = -EINVAL;
break;
}
return ret;
}
-int himacsec_cmd_set_enc_sc(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_in *cmd_in,
- u32 in_size)
+int himacsec_cmd_set_enc_sc(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_cmd_in *cmd_in, u32 in_size)
{
struct himacsec_sc *priv_sc_ptr = NULL;
struct himacsec_cmd_set_sc_in *param = NULL;
- u32 exp_in_size = sizeof(struct himacsec_cmd_set_sc_in) + sizeof(struct himacsec_cmd_hdr);
- macsec_sc_info_s enc_sc = {0};
+ u32 exp_in_size = sizeof(struct himacsec_cmd_set_sc_in) +
+ sizeof(struct himacsec_cmd_hdr);
+ macsec_sc_info_s enc_sc = { 0 };
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (!macsec_res) {
+ if (macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
return -EINVAL;
}
param = (struct himacsec_cmd_set_sc_in *)cmd_in->buf;
- if (!param || exp_in_size != in_size) {
- macsec_err(nic_dev->lld_dev->dev, "Buffer in invalid when exec macsec set cmd, in_size=%d, exp_size=%d",
- in_size, exp_in_size);
+ if ((param == NULL) || (exp_in_size != in_size)) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Buffer in invalid when exec macsec set cmd, in_size=%d, exp_size=%d",
+ in_size, exp_in_size);
return -EINVAL;
}
- priv_sc_ptr = himacsec_get_valid_dev_sc(nic_dev, param->sci, MACSEC_OUTBOUND);
- if (!priv_sc_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Set encryption sc failed, sc not found",
+ priv_sc_ptr =
+ himacsec_get_valid_dev_sc(nic_dev, param->sci, MACSEC_OUTBOUND);
+ if (priv_sc_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Set encryption sc failed, sc not found",
nic_dev->netdev->name);
return -EINVAL;
}
- memcpy(&enc_sc, &priv_sc_ptr->info, sizeof(macsec_sc_info_s));
- // Use sc copy data, driver internal data will be automatically updated after update
- if ((param->set_flag_bitmap & HIMACSEC_SET_SC_ENCODING_SA_BIT_VAL) != 0) {
- // sa validation
- if (!himacsec_get_valid_dev_sa(nic_dev, param->sci,
- param->sc.encoding_sa, MACSEC_OUTBOUND)) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Update encodingsa failed, sa '%d' invalid",
- nic_dev->netdev->name, param->sc.encoding_sa);
+ (void)memcpy_s(&enc_sc, sizeof(macsec_sc_info_s), &priv_sc_ptr->info,
+ sizeof(macsec_sc_info_s));
+ // 使用sc副本数据,更新完成后自动更新驱动内部数据
+ if ((param->set_flag_bitmap & HIMACSEC_SET_SC_ENCODING_SA_BIT_VAL) !=
+ 0) {
+ // sa 合法性校验
+ if (himacsec_get_valid_dev_sa(nic_dev, param->sci,
+ param->sc.encoding_sa,
+ MACSEC_OUTBOUND) == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Update encodingsa failed, sa '%d' invalid",
+ nic_dev->netdev->name, param->sc.encoding_sa);
return -EINVAL;
}
- // Convert an to sa_index
- enc_sc.encoding_sa = param->sc.encoding_sa % macsec_res->spec.max_sa;
+ enc_sc.encoding_sa =
+ param->sc.encoding_sa %
+ macsec_res->spec.max_sa; // an 转换为 sa_index
}
- if ((param->set_flag_bitmap & HIMACSEC_SET_SC_PROTECT_FRAMES_BIT_VAL) != 0)
+ if ((param->set_flag_bitmap & HIMACSEC_SET_SC_PROTECT_FRAMES_BIT_VAL) !=
+ 0) {
enc_sc.protect_frames = param->sc.protect_frames;
+ }
- if ((param->set_flag_bitmap & HIMACSEC_SET_SC_PROTECTION_MODE_BIT_VAL) != 0)
+ if ((param->set_flag_bitmap &
+ HIMACSEC_SET_SC_PROTECTION_MODE_BIT_VAL) != 0) {
enc_sc.protection_mode = param->sc.protection_mode;
+ }
return himacsec_set_sc(nic_dev, &enc_sc, MACSEC_OUTBOUND);
}
-int himacsec_cmd_set_dec_sc(struct hinic5_nic_dev *nic_dev, struct himacsec_cmd_in *cmd_in,
- u32 in_size)
+int himacsec_cmd_set_dec_sc(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_cmd_in *cmd_in, u32 in_size)
{
struct himacsec_sc *priv_sc_ptr = NULL;
struct himacsec_cmd_set_sc_in *param = NULL;
- u32 exp_in_size = sizeof(struct himacsec_cmd_set_sc_in) + sizeof(struct himacsec_cmd_hdr);
- macsec_sc_info_s dec_sc = {0};
+ u32 exp_in_size = sizeof(struct himacsec_cmd_set_sc_in) +
+ sizeof(struct himacsec_cmd_hdr);
+ macsec_sc_info_s dec_sc = { 0 };
param = (struct himacsec_cmd_set_sc_in *)cmd_in->buf;
- if (!param || exp_in_size != in_size) {
- macsec_err(nic_dev->lld_dev->dev, "Buffer in invalid when exec macsec set cmd, in_size=%d, exp_size=%d",
- in_size, exp_in_size);
+ if ((param == NULL) || (exp_in_size != in_size)) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Buffer in invalid when exec macsec set cmd, in_size=%d, exp_size=%d",
+ in_size, exp_in_size);
return -EINVAL;
}
- priv_sc_ptr = himacsec_get_valid_dev_sc(nic_dev, param->sci, MACSEC_INBOUND);
- if (!priv_sc_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Set decryption sc failed, sc not found",
+ priv_sc_ptr =
+ himacsec_get_valid_dev_sc(nic_dev, param->sci, MACSEC_INBOUND);
+ if (priv_sc_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Set decryption sc failed, sc not found",
nic_dev->netdev->name);
return -EINVAL;
}
- memcpy(&dec_sc, &priv_sc_ptr->info, sizeof(macsec_sc_info_s));
+ (void)memcpy_s(&dec_sc, sizeof(macsec_sc_info_s), &priv_sc_ptr->info,
+ sizeof(macsec_sc_info_s));
- if ((param->set_flag_bitmap & HIMACSEC_SET_SC_VALIDATE_FRAMES_BIT_VAL) != 0)
+ if ((param->set_flag_bitmap &
+ HIMACSEC_SET_SC_VALIDATE_FRAMES_BIT_VAL) != 0) {
dec_sc.validate_frames = param->sc.validate_frames;
+ }
return himacsec_set_sc(nic_dev, &dec_sc, MACSEC_INBOUND);
}
@@ -560,8 +658,9 @@ int macsec_cmd_set(struct hinic5_nic_dev *nic_dev, const void *buf_in,
himacsec_tool_obj_e obj = HIMACSEC_TOOL_OBJ_MAX;
int ret;
- if (!buf_in) {
- macsec_err(nic_dev->lld_dev->dev, "Buffer in is NULL when exec macsec set cmd");
+ if (buf_in == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Buffer in is NULL when exec macsec set cmd");
return -EINVAL;
}
@@ -571,9 +670,10 @@ int macsec_cmd_set(struct hinic5_nic_dev *nic_dev, const void *buf_in,
} else if (obj == HIMACSEC_TOOL_OBJ_DEC_SC) {
ret = himacsec_cmd_set_dec_sc(nic_dev, cmd_in, in_size);
} else {
- macsec_err(nic_dev->lld_dev->dev, "Unknown macsec object type:%d ", obj);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Unknown macsec object type:%d ", obj);
ret = -EINVAL;
}
return ret;
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_protocol.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_protocol.c
index 77ab83e58..cf9cb279b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_protocol.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_protocol.c
@@ -1,15 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_protocol.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Adapt to Linux standard kernel macsec
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: 对接 Linux 标准内核 macsec 适配
+ * Create: 2024/03/01
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [MACsec]" fmt
#include <linux/netdevice.h>
+#include "securec.h"
#include "ossl_knl.h"
#include "hinic5_srv_nic.h"
@@ -20,17 +17,18 @@
#include "hinic5_macsec_dev.h"
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)) && \
- IS_ENABLED(CONFIG_MACSEC) && \
- defined(HAVE_NETDEVICE_MACSEC_OPS))
+ IS_ENABLED(CONFIG_MACSEC) && defined(HAVE_NETDEVICE_MACSEC_OPS))
#include <net/macsec.h>
-#define htonll(x) (htonl(1) == 1 ? (x) : \
- ((((uint64_t)htonl((x) & 0xFFFFFFFF)) << 32) | \
- htonl((x) >> 32)))
-#define ntohll(x) (ntohl(1) == 1 ? (x) : \
- ((((uint64_t)ntohl((x) & 0xFFFFFFFF)) << 32) | \
- ntohl((x) >> 32)))
+#define htonll(x) \
+ ((1 == htonl(1)) ? \
+ (x) : \
+ ((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32))
+#define ntohll(x) \
+ ((1 == ntohl(1)) ? \
+ (x) : \
+ ((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#define VALIDATE_RET_OK 0x5a5aa5a5
#define HIMACSEC_DEV_LINK_KIND "macsec"
@@ -38,52 +36,60 @@ struct hinic5_nic_dev *macsec_get_nic_dev_by_netdev(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!netdev) {
+ if (netdev == NULL) {
pr_err("Get nic dev fail, netdev is NULL");
return NULL;
}
nic_dev = netdev_priv(netdev);
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Get nic dev fail, nic_dev is NULL");
return NULL;
}
return nic_dev;
}
-int macsec_base_validate(struct hinic5_nic_dev *nic_dev, struct macsec_context *ctx)
+int macsec_base_validate(struct hinic5_nic_dev *nic_dev,
+ struct macsec_context *ctx)
{
- if (!nic_dev || !nic_dev->macsec_res) {
+ if (nic_dev == NULL || nic_dev->macsec_res == NULL) {
pr_err("NIC device is NULL");
return -ENODEV;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
return VALIDATE_RET_OK;
}
-int macsec_sa_update_validate(struct hinic5_nic_dev *nic_dev, struct macsec_context *ctx,
- struct himacsec_sa **priv_sa, crypt_direction_e direct, u64 sci)
+int macsec_sa_update_validate(struct hinic5_nic_dev *nic_dev,
+ struct macsec_context *ctx,
+ struct himacsec_sa **priv_sa,
+ crypt_direction_e direct, u64 sci)
{
int ret = macsec_base_validate(nic_dev, ctx);
u8 assoc_num = ctx->sa.assoc_num;
- if (ret != VALIDATE_RET_OK)
+ if (ret != VALIDATE_RET_OK) {
return ret;
+ }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 8)
if (ctx->sa.update_pn) {
- macsec_err(nic_dev->lld_dev->dev, "Update sa failed, not support pn update");
+ macsec_err(nic_dev->lld_dev->dev,
+ "Update sa failed, not support pn update");
return -EINVAL;
}
#endif
*priv_sa = himacsec_get_valid_dev_sa(nic_dev, sci, assoc_num, direct);
- if (!*priv_sa) {
- macsec_err(nic_dev->lld_dev->dev, "Update sa failed, sa does not exist, sci=%llx, an=0x%x",
- sci, assoc_num);
+ if (*priv_sa == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Update sa failed, sa does not exist, sci=%llx, an=0x%x",
+ sci, assoc_num);
return -EINVAL;
}
@@ -96,17 +102,20 @@ int himacsec_sa_active_update(struct hinic5_nic_dev *nic_dev,
int ret;
u8 temp_active_status;
- // 1. If sa active is the same before and after command, no processing
- if (macsec_sa->info.enable_receive == active)
+ // 1、命令前后,sa active 相同,不作处理
+ if (macsec_sa->info.enable_receive == active) {
return 0;
+ }
- // 2. Changed sa enable config
+ // 2、改变了 sa enable 配置
temp_active_status = macsec_sa->info.enable_receive;
macsec_sa->info.enable_receive = active;
- ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, &macsec_sa->info, MACSEC_CMD_DEC_SA_UPDATE);
+ ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, &macsec_sa->info,
+ MACSEC_CMD_DEC_SA_UPDATE);
if (ret != 0) {
macsec_sa->info.enable_receive = temp_active_status;
- macsec_err(nic_dev->lld_dev->dev, "Update sa failed, ret=%d", ret);
+ macsec_err(nic_dev->lld_dev->dev, "Update sa failed, ret=%d",
+ ret);
}
return ret;
@@ -116,10 +125,8 @@ void reverse_u8_array(u8 *array, u32 size)
{
u32 left = 0;
u32 right = size - 1;
-
while (left < right) {
u8 temp = array[left];
-
array[left] = array[right];
array[right] = temp;
left++;
@@ -138,8 +145,8 @@ int macsec_secy_features_validate(struct macsec_context *ctx)
return -EINVAL;
}
- if (secy->key_len != HIMACSEC_KEY_LENGTH_128 &&
- secy->key_len != HIMACSEC_KEY_LENGTH_256) {
+ if ((secy->key_len != HIMACSEC_KEY_LENGTH_128) &&
+ (secy->key_len != HIMACSEC_KEY_LENGTH_256)) {
pr_err("%s: MACsec offload is supported only when key_len is 128bit or 256bit",
netdev->name);
return -EINVAL;
@@ -154,10 +161,9 @@ int macsec_secy_features_validate(struct macsec_context *ctx)
return 0;
}
-/* direct:true macsec_key_length convert to reg_key_length;
- * false reg_key_length convert to macsec_key_length
- */
-void macsec_adapt_convert_key_length(u8 *reg_key_length, u16 *macsec_key_length, bool direct)
+/* direct:true macsec_key_length convert to reg_key_length; false reg_key_length convert to macsec_key_length */
+void macsec_adapt_convert_key_length(u8 *reg_key_length, u16 *macsec_key_length,
+ bool direct)
{
if (direct) {
// macsec_key_length convert to reg_key_length
@@ -167,7 +173,8 @@ void macsec_adapt_convert_key_length(u8 *reg_key_length, u16 *macsec_key_length,
*reg_key_length = HIMACSEC_REG_KEY_LENGTH_256;
} else {
// macsec_secy_features_validate has checked, macsec_key_length=128 or 256
- pr_err("Parse sa key length failed, macsec key length=%d", *reg_key_length);
+ pr_err("Parse sa key length failed, macsec key length=%d",
+ *reg_key_length);
}
} else {
// reg_key_length convert to macsec_key_length
@@ -176,17 +183,17 @@ void macsec_adapt_convert_key_length(u8 *reg_key_length, u16 *macsec_key_length,
} else if (*reg_key_length == HIMACSEC_REG_KEY_LENGTH_256) {
*macsec_key_length = HIMACSEC_KEY_LENGTH_256;
} else {
- // Read the exception value from the register,
- // request does not return failure, fill in the exception value
+ // Read the exception value from the register, request does not return failure, fill in the exception value
*macsec_key_length = 0;
- pr_err("Parse sa key length failed, reg key length=%d", *reg_key_length);
+ pr_err("Parse sa key length failed, reg key length=%d",
+ *reg_key_length);
}
}
}
-void macsec_adapt_convert_validate_type(u8 *reg_validate_val,
- enum macsec_validation_type *macsec_validation_val,
- bool direct)
+void macsec_adapt_convert_validate_type(
+ u8 *reg_validate_val,
+ enum macsec_validation_type *macsec_validation_val, bool direct)
{
if (direct) {
// macsec val to reg val
@@ -194,49 +201,60 @@ void macsec_adapt_convert_validate_type(u8 *reg_validate_val,
*reg_validate_val = (u8)(*macsec_validation_val) + 1;
return;
}
- pr_err("Parse validate type failed, macsec validate=%d", *macsec_validation_val);
+ pr_err("Parse validate type failed, macsec validate=%d",
+ *macsec_validation_val);
} else {
// reg val to macsec val
if (*reg_validate_val < (u8)VALIDATE_MODE_MAX) {
*macsec_validation_val = *reg_validate_val - 1;
return;
}
- pr_err("Parse validate type failed, reg validate=%d", *reg_validate_val);
+ pr_err("Parse validate type failed, reg validate=%d",
+ *reg_validate_val);
}
}
-void macsec_adapt_key_handle(struct macsec_context *ctx, struct himacsec_sa *sa, u32 key_len)
+void macsec_adapt_key_handle(struct macsec_context *ctx, struct himacsec_sa *sa,
+ u32 key_len)
{
- memcpy(sa->info.sak, ctx->sa.key, HIMACSEC_MAX_SAK_KEY_LEN);
- memset(ctx->sa.key, 0, HIMACSEC_MAX_SAK_KEY_LEN);
+ (void)memcpy_s(sa->info.sak, HIMACSEC_MAX_SAK_KEY_LEN, ctx->sa.key,
+ HIMACSEC_MAX_SAK_KEY_LEN);
+
+ // Clear key information in parameter buf, the kernel passes in temporary variables
+ (void)memset_s(ctx->sa.key, HIMACSEC_MAX_SAK_KEY_LEN, 0,
+ HIMACSEC_MAX_SAK_KEY_LEN);
reverse_u8_array((u8 *)sa->info.sak, ctx->secy->key_len);
// set 128bit key in high 128bit
if (key_len == HIMACSEC_KEY_LENGTH_128) {
- memcpy(((u8 *)sa->info.sak + HIMACSEC_KEY_LENGTH_128),
- sa->info.sak, HIMACSEC_KEY_LENGTH_128);
- memset(sa->info.sak, 0, HIMACSEC_KEY_LENGTH_128);
+ (void)memcpy_s(((u8 *)sa->info.sak + HIMACSEC_KEY_LENGTH_128),
+ HIMACSEC_KEY_LENGTH_128, sa->info.sak,
+ HIMACSEC_KEY_LENGTH_128);
+ (void)memset_s(sa->info.sak, HIMACSEC_MAX_SAK_KEY_LEN, 0,
+ HIMACSEC_KEY_LENGTH_128);
}
}
-/* Algorithm only has AES, length/xpn enable is in secy */
+/* 算法只有 AES, length/xpn 使能在 secy */
int macsec_adapt_add_tx_sa(struct macsec_context *ctx)
{
struct net_device *netdev = ctx->netdev;
- struct himacsec_sa enc_sa = {0};
+ struct himacsec_sa enc_sa = { 0 };
struct hinic5_nic_dev *nic_dev = macsec_get_nic_dev_by_netdev(netdev);
int ret;
- if (macsec_secy_features_validate(ctx) != 0)
+ if (macsec_secy_features_validate(ctx) != 0) {
return -EINVAL;
+ }
// Adapt kernel 2 stage commit offload
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Add protocol encryption sa failed, nic device is NULL");
return -ENODEV;
}
@@ -245,7 +263,8 @@ int macsec_adapt_add_tx_sa(struct macsec_context *ctx)
macsec_adapt_key_handle(ctx, &enc_sa, ctx->secy->key_len);
// Key length set
- macsec_adapt_convert_key_length(&enc_sa.info.current_key_length, &ctx->secy->key_len, true);
+ macsec_adapt_convert_key_length(&enc_sa.info.current_key_length,
+ &ctx->secy->key_len, true);
enc_sa.info.sci = ntohll(ctx->secy->sci);
enc_sa.info.an = ctx->sa.assoc_num;
@@ -260,13 +279,16 @@ int macsec_adapt_add_tx_sa(struct macsec_context *ctx)
enc_sa.info.ssci = ntohl(ctx->sa.tx_sa->ssci);
// Salt value parameter processing
- memcpy(enc_sa.info.salt, ctx->sa.tx_sa->key.salt.bytes, MACSEC_SALT_LEN);
+ (void)memcpy_s(enc_sa.info.salt, MACSEC_SALT_LEN,
+ ctx->sa.tx_sa->key.salt.bytes, MACSEC_SALT_LEN);
reverse_u8_array((u8 *)enc_sa.info.salt, MACSEC_SALT_LEN);
ret = himacsec_create_sa(nic_dev, &enc_sa.info, MACSEC_OUTBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Add protocol encryption sa failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add protocol encryption sa failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
@@ -279,11 +301,12 @@ int macsec_adapt_del_tx_sa(struct macsec_context *ctx)
struct hinic5_nic_dev *nic_dev = macsec_get_nic_dev_by_netdev(netdev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Del protocol encryption sa failed, nic device is NULL");
return -ENODEV;
}
@@ -291,28 +314,32 @@ int macsec_adapt_del_tx_sa(struct macsec_context *ctx)
sci = ntohll(ctx->secy->sci);
assoc_num = ctx->sa.assoc_num;
ret = himacsec_destroy_sa(nic_dev, sci, assoc_num, MACSEC_OUTBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete protocol encryption sa failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Delete protocol encryption sa failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
int macsec_adapt_add_rx_sa(struct macsec_context *ctx)
{
struct net_device *netdev = ctx->netdev;
- struct himacsec_sa dec_sa = {0};
+ struct himacsec_sa dec_sa = { 0 };
struct hinic5_nic_dev *nic_dev = macsec_get_nic_dev_by_netdev(netdev);
int ret;
- if (macsec_secy_features_validate(ctx) != 0)
+ if (macsec_secy_features_validate(ctx) != 0) {
return -EINVAL;
+ }
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Add protocol decryption sa failed, macsec device is NULL");
return -ENODEV;
}
@@ -321,7 +348,8 @@ int macsec_adapt_add_rx_sa(struct macsec_context *ctx)
macsec_adapt_key_handle(ctx, &dec_sa, ctx->secy->key_len);
// Set key length
- macsec_adapt_convert_key_length(&dec_sa.info.current_key_length, &ctx->secy->key_len, true);
+ macsec_adapt_convert_key_length(&dec_sa.info.current_key_length,
+ &ctx->secy->key_len, true);
dec_sa.info.sci = ntohll(ctx->sa.rx_sa->sc->sci);
dec_sa.info.an = ctx->sa.assoc_num;
@@ -336,15 +364,18 @@ int macsec_adapt_add_rx_sa(struct macsec_context *ctx)
// Salt value parameter processing
dec_sa.info.ssci = ntohl(ctx->sa.rx_sa->ssci);
- memcpy(dec_sa.info.salt, ctx->sa.rx_sa->key.salt.bytes, MACSEC_SALT_LEN);
+ (void)memcpy_s(dec_sa.info.salt, MACSEC_SALT_LEN,
+ ctx->sa.rx_sa->key.salt.bytes, MACSEC_SALT_LEN);
reverse_u8_array((u8 *)dec_sa.info.salt, MACSEC_SALT_LEN);
/* TODO set lowest_pn */
ret = himacsec_create_sa(nic_dev, &dec_sa.info, MACSEC_INBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Add protocol decryption sa failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add protocol decryption sa failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
@@ -356,40 +387,46 @@ int macsec_adapt_del_rx_sa(struct macsec_context *ctx)
int ret;
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Del protocol decryption sa failed, nic device is NULL");
return -ENODEV;
}
sci = ntohll(ctx->sa.rx_sa->sc->sci);
- ret = himacsec_destroy_sa(nic_dev, sci, ctx->sa.assoc_num, MACSEC_INBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s Delete protocol decryption sa failed, ret=%d",
+ ret = himacsec_destroy_sa(nic_dev, sci, ctx->sa.assoc_num,
+ MACSEC_INBOUND);
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s Delete protocol decryption sa failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
int macsec_adapt_add_rx_sc(struct macsec_context *ctx)
{
struct net_device *netdev = ctx->netdev;
- struct himacsec_sc dec_sc = {0};
+ struct himacsec_sc dec_sc = { 0 };
struct hinic5_nic_dev *nic_dev = macsec_get_nic_dev_by_netdev(netdev);
int ret;
- if (macsec_secy_features_validate(ctx) != 0)
+ if (macsec_secy_features_validate(ctx) != 0) {
return -EINVAL;
+ }
// adapt kernel 2 stage commit offload
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Add protocol decryption sc failed, nic device is NULL");
return -ENODEV;
}
@@ -399,9 +436,11 @@ int macsec_adapt_add_rx_sc(struct macsec_context *ctx)
&ctx->secy->validate_frames, true);
ret = himacsec_create_sc(nic_dev, &dec_sc.info, MACSEC_INBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Add protocol decryption sc failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add protocol decryption sc failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
@@ -411,30 +450,33 @@ static int macsec_update_rxsa_by_rxsc(const struct macsec_rx_sc *ctx_rx_sc,
const struct macsec_rx_sa *rx_sa = NULL;
struct himacsec_sa *dec_sa = NULL;
int ret, i;
-
for (i = 0; i < MACSEC_NUM_AN; i++) {
rx_sa = ctx_rx_sc->sa[i];
- if (!rx_sa)
+ if (rx_sa == NULL) {
continue;
+ }
- dec_sa = himacsec_get_valid_dev_sa(nic_dev, sci, i, MACSEC_INBOUND);
- if (!dec_sa) {
- macsec_err(nic_dev->lld_dev->dev, "Update decryption sc failed, an=%d", i);
+ dec_sa = himacsec_get_valid_dev_sa(nic_dev, sci, i,
+ MACSEC_INBOUND);
+ if (dec_sa == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Update decryption sc failed, an=%d", i);
return -EINVAL;
}
if (ctx_rx_sc->active) {
- /* rx_sc active, the state of SA is determined
- * by the SA state in the standard kernel
- */
- ret = himacsec_sa_active_update(nic_dev, dec_sa, rx_sa->active);
+ /* rx_sc active, the state of SA is determined by the SA state in the standard kernel */
+ ret = himacsec_sa_active_update(nic_dev, dec_sa,
+ rx_sa->active);
} else {
/* rx_sc not active, all SA off */
- ret = himacsec_sa_active_update(nic_dev, dec_sa, (u8)ctx_rx_sc->active);
+ ret = himacsec_sa_active_update(nic_dev, dec_sa,
+ (u8)ctx_rx_sc->active);
}
- if (ret != 0)
+ if (ret != 0) {
return ret;
+ }
}
return 0;
}
@@ -448,28 +490,31 @@ int macsec_adapt_update_rx_sc(struct macsec_context *ctx)
u64 sci;
int ret;
- if (!ctx_rx_sc) {
- pr_info("%s, nothing changed", __func__);
+ if (ctx_rx_sc == NULL) {
+ pr_info("macsec_adapt_update_rx_sc, nothing changed");
return 0;
}
ret = macsec_base_validate(nic_dev, ctx);
if (ret != VALIDATE_RET_OK) {
- pr_err("%s, macsec_base_validate fail", __func__);
+ pr_err("macsec_adapt_update_rx_sc, macsec_base_validate fail");
return ret;
}
sci = ntohll(ctx->rx_sc->sci);
dec_sc = himacsec_get_valid_dev_sc(nic_dev, sci, MACSEC_INBOUND);
- if (!dec_sc) {
- macsec_err(nic_dev->lld_dev->dev, "Update decryption sc failed, not found sc, sci=%llx",
- sci);
+ if (dec_sc == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "Update decryption sc failed, not found sc, sci=%llx",
+ sci);
return -EINVAL;
}
ret = macsec_update_rxsa_by_rxsc(ctx_rx_sc, nic_dev, sci);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Update decryption sc failed, ret=%d", ret);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Update decryption sc failed, ret=%d", ret);
return ret;
}
return 0;
@@ -484,94 +529,106 @@ int macsec_adapt_del_rx_sc(struct macsec_context *ctx)
// adapt kernel 2 stage commit offload
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Del protocol decryption sc failed, nic device is NULL");
return -ENODEV;
}
sci = ntohll(ctx->rx_sc->sci);
ret = himacsec_destroy_sc(nic_dev, sci, MACSEC_INBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete protocol decryption sc failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Delete protocol decryption sc failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
int macsec_adapt_add_secy(struct macsec_context *ctx)
{
struct net_device *netdev = ctx->netdev;
- struct himacsec_sc tx_sc = {0};
+ struct himacsec_sc tx_sc = { 0 };
struct hinic5_nic_dev *nic_dev = macsec_get_nic_dev_by_netdev(netdev);
struct macsec_resource *macsec_res = NULL;
int ret;
- if (macsec_secy_features_validate(ctx) != 0)
+ if (macsec_secy_features_validate(ctx) != 0) {
return -EINVAL;
+ }
// adapt kernel 2 stage commit offload
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Add protocol secy failed, nic device is NULL");
return -ENODEV;
}
macsec_res = nic_dev->macsec_res;
- if (!macsec_res) {
- macsec_err(nic_dev->lld_dev->dev, "Add protocol secy failed, macsec resource is NULL");
+ if (macsec_res == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Add protocol secy failed, macsec resource is NULL");
return -ENODEV;
}
- // Save the offloaded vf index
- if (ctx->secy->netdev)
- macsec_res->offload_child_dev_idx[macsec_res->offload_dev_num++] =
- ctx->secy->netdev->ifindex;
+ // 保存已offload的vf index
+ if (ctx->secy->netdev != NULL) {
+ macsec_res
+ ->offload_child_dev_idx[macsec_res->offload_dev_num++] =
+ ctx->secy->netdev->ifindex;
+ }
tx_sc.info.sci = ntohll(ctx->secy->sci);
tx_sc.info.use_es_enable = ctx->secy->tx_sc.end_station;
tx_sc.info.use_scb_enable = ctx->secy->tx_sc.scb;
tx_sc.info.include_sci_enable = ctx->secy->tx_sc.send_sci;
- tx_sc.info.protect_frames = ctx->secy->protect_frames; // Indicates whether to protect
- // (verification is also protection)
- /* 0: integrity only
- * 1:confidentiality, cannot configure offset protection
- */
- tx_sc.info.protection_mode = ctx->secy->tx_sc.encrypt;
-
- /* Call service layer */
+ tx_sc.info.protect_frames =
+ ctx->secy->protect_frames; // 表示是否保护(只有校验也是保护)
+ tx_sc.info.protection_mode =
+ ctx->secy->tx_sc
+ .encrypt; // 0: integrity only 1:confidentiality, 无法配置偏移保护
+
+ /* 调用 service 层 */
ret = himacsec_create_sc(nic_dev, &tx_sc.info, MACSEC_OUTBOUND);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Add protocol encryption sc failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add protocol encryption sc failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
-int macsec_adapt_clean_up_rx_sc(struct net_device *netdev, struct hinic5_nic_dev *nic_dev,
+int macsec_adapt_clean_up_rx_sc(struct net_device *netdev,
+ struct hinic5_nic_dev *nic_dev,
struct macsec_context *ctx)
{
struct macsec_rx_sc *rx_sc = NULL;
u64 rx_sci;
int ret = 0;
- if (!ctx->secy || !ctx->secy->rx_sc) {
+ if ((ctx->secy == NULL) || (ctx->secy->rx_sc == NULL)) {
pr_info("%s: Delete protocol decryption sc skip, decryption sc not exist",
netdev->name);
return 0;
}
rx_sc = ctx->secy->rx_sc;
- while (rx_sc) {
+ while (rx_sc != NULL) {
rx_sci = ntohll(ctx->secy->rx_sc->sci);
ret |= himacsec_destroy_sc(nic_dev, rx_sci, MACSEC_INBOUND);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete decryption sc failed, sci=%llx, ret=%d",
- netdev->name, rx_sci, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Delete decryption sc failed, sci=%llx, ret=%d",
+ netdev->name, rx_sci, ret);
}
rx_sc = rx_sc->next;
}
@@ -587,11 +644,12 @@ int macsec_adapt_del_secy(struct macsec_context *ctx)
// adapt kernel 2 stage commit offload
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- if (ctx->prepare != 0)
+ if (ctx->prepare != 0) {
return 0;
+ }
#endif
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Delete protocol secy failed, macsec device is NULL");
return -ENODEV;
}
@@ -599,16 +657,20 @@ int macsec_adapt_del_secy(struct macsec_context *ctx)
// delete macsec tx config
ret = himacsec_destroy_sc(nic_dev, tx_sci, MACSEC_OUTBOUND);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete protocol encryption sc failed, sci=%llx, ret=%d",
- netdev->name, tx_sci, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Delete protocol encryption sc failed, sci=%llx, ret=%d",
+ netdev->name, tx_sci, ret);
return ret;
}
// delete macsec rx config
ret = macsec_adapt_clean_up_rx_sc(netdev, nic_dev, ctx);
- if (ret != 0)
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete protocol decryption sc failed, ret=%d",
+ if (ret != 0) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Delete protocol decryption sc failed, ret=%d",
netdev->name, ret);
+ }
return ret;
}
@@ -623,26 +685,31 @@ int macsec_adapt_update_tx_sa(struct macsec_context *ctx)
int ret;
u8 active;
- if (!nic_dev) {
+ if (nic_dev == NULL) {
pr_err("Update encryption sa failed, nic device is NULL");
return -ENODEV;
}
- ret = macsec_sa_update_validate(nic_dev, ctx, &macsec_sa, MACSEC_OUTBOUND, tx_sci);
- if (ret != VALIDATE_RET_OK)
+ ret = macsec_sa_update_validate(nic_dev, ctx, &macsec_sa,
+ MACSEC_OUTBOUND, tx_sci);
+ if (ret != VALIDATE_RET_OK) {
return ret;
+ }
- // 1. If sa active is the same before and after command, no processing
- if (macsec_sa->info.enable_transmit == (u8)ctx_tx_sa->active)
+ // 1、命令前后,sa active 相同,不作处理
+ if (macsec_sa->info.enable_transmit == (u8)ctx_tx_sa->active) {
return 0;
+ }
- // 2. Changed sa enable config
+ // 2、改变了 sa enable 配置
active = macsec_sa->info.enable_transmit;
macsec_sa->info.enable_transmit = (u8)ctx_tx_sa->active;
- ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, &macsec_sa->info, MACSEC_CMD_ENC_SA_UPDATE);
+ ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, &macsec_sa->info,
+ MACSEC_CMD_ENC_SA_UPDATE);
if (ret != 0) {
macsec_sa->info.enable_transmit = active;
- macsec_err(nic_dev->lld_dev->dev, "Update encryption sa failed, ret=%d", ret);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Update encryption sa failed, ret=%d", ret);
}
return ret;
@@ -657,11 +724,14 @@ int macsec_adapt_update_rx_sa(struct macsec_context *ctx)
u64 rx_sci = ntohll(ctx_rx_sa->sc->sci);
int ret;
- ret = macsec_sa_update_validate(nic_dev, ctx, &macsec_sa, MACSEC_INBOUND, rx_sci);
- if (ret != VALIDATE_RET_OK)
+ ret = macsec_sa_update_validate(nic_dev, ctx, &macsec_sa,
+ MACSEC_INBOUND, rx_sci);
+ if (ret != VALIDATE_RET_OK) {
return ret;
+ }
- return himacsec_sa_active_update(nic_dev, macsec_sa, (u8)ctx_rx_sa->active);
+ return himacsec_sa_active_update(nic_dev, macsec_sa,
+ (u8)ctx_rx_sa->active);
}
static int macsec_update_txsa_by_txsc(const struct macsec_tx_sc *ctx_tx_sc,
@@ -671,24 +741,31 @@ static int macsec_update_txsa_by_txsc(const struct macsec_tx_sc *ctx_tx_sc,
struct himacsec_sa *enc_sa = NULL;
int ret, i;
- // Traverse and update ctx_tx_sa
+ // 遍历更新ctx_tx_sa
for (i = 0; i < MACSEC_NUM_AN; i++) {
tx_sa = ctx_tx_sc->sa[i];
- if (!tx_sa)
+ if (tx_sa == NULL) {
continue;
+ }
- enc_sa = himacsec_get_valid_dev_sa(nic_dev, sci, i, MACSEC_OUTBOUND);
- if (!enc_sa) {
- macsec_err(nic_dev->lld_dev->dev, "%s, get sa failed, an= %d", __func__, i);
+ enc_sa = himacsec_get_valid_dev_sa(nic_dev, sci, i,
+ MACSEC_OUTBOUND);
+ if (enc_sa == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s, get sa failed, an= %d", __func__, i);
return -EINVAL;
}
- if (ctx_tx_sc->active)
- ret = himacsec_sa_active_update(nic_dev, enc_sa, tx_sa->active);
- else
- ret = himacsec_sa_active_update(nic_dev, enc_sa, (u8)ctx_tx_sc->active);
- if (ret != 0)
+ if (ctx_tx_sc->active) {
+ ret = himacsec_sa_active_update(nic_dev, enc_sa,
+ tx_sa->active);
+ } else {
+ ret = himacsec_sa_active_update(nic_dev, enc_sa,
+ (u8)ctx_tx_sc->active);
+ }
+ if (ret != 0) {
return ret;
+ }
}
return 0;
}
@@ -702,8 +779,8 @@ static int macsec_adapt_update_tx_sc(struct macsec_context *ctx)
int ret;
u64 sci;
- if (!ctx_tx_sc) {
- pr_info("%s, nothing changed", __func__);
+ if (ctx_tx_sc == NULL) {
+ pr_info("macsec_adapt_update_tx_sc, nothing changed");
return 0;
}
@@ -715,33 +792,40 @@ static int macsec_adapt_update_tx_sc(struct macsec_context *ctx)
sci = ntohll(ctx->secy->sci);
enc_sc = himacsec_get_valid_dev_sc(nic_dev, sci, MACSEC_OUTBOUND);
- if (!enc_sc) {
- macsec_err(nic_dev->lld_dev->dev, "%s, update encryption sc failed, sc not found, sci=0x%llx",
- __func__, sci);
+ if (enc_sc == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s, update encryption sc failed, sc not found, sci=0x%llx",
+ __func__, sci);
return -EINVAL;
}
if (ctx_tx_sc->encrypt) {
- macsec_info(nic_dev->lld_dev->dev, "%s, encrypt is true, set protection_mode CONFIDENTIALITY",
- __func__);
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s, encrypt is true, set protection_mode CONFIDENTIALITY",
+ __func__);
enc_sc->info.protection_mode = PROTECTION_MODE_CONFIDENTIALITY;
}
- // Update encoding_sa
+ // 更新encoding_sa
if (enc_sc->info.encoding_sa != ctx_tx_sc->encoding_sa) {
enc_sc->info.encoding_sa = ctx_tx_sc->encoding_sa;
ret = himacsec_set_sc(nic_dev, &enc_sc->info, MACSEC_OUTBOUND);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s, himacsec_set_sc(sci=0x%llx) failed, ret: %d",
- __func__, sci, ret);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s, himacsec_set_sc(sci=0x%llx) failed, ret: %d",
+ __func__, sci, ret);
return ret;
}
}
ret = macsec_update_txsa_by_txsc(ctx_tx_sc, nic_dev, sci);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s, update encryption sc failed, ret= %d",
- __func__, ret);
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s, update encryption sc failed, ret= %d", __func__,
+ ret);
return ret;
}
@@ -750,21 +834,24 @@ static int macsec_adapt_update_tx_sc(struct macsec_context *ctx)
int macsec_adapt_update_secy(struct macsec_context *ctx)
{
- /* Secy involves all sc and sa config, complex flow, not allowed to modify temporarily */
+ /* Secy 涉及到所有 sc、sa 的配置,流程复杂,暂时不允许做修改 */
int ret;
- if (!macsec_secy_features_validate(ctx))
+ if (!macsec_secy_features_validate(ctx)) {
return -EINVAL;
+ }
ret = macsec_adapt_update_tx_sc(ctx);
if (ret != 0) {
- pr_err("%s update tx_sc failed, ret=%d", __func__, ret);
+ pr_err("macsec_adapt_update_secy update tx_sc failed, ret=%d",
+ ret);
return ret;
}
ret = macsec_adapt_update_rx_sc(ctx);
if (ret != 0) {
- pr_err("%s update rx_sc failed, ret=%d", __func__, ret);
+ pr_err("macsec_adapt_update_secy update rx_sc failed, ret=%d",
+ ret);
return ret;
}
@@ -796,9 +883,11 @@ void himacsec_offload_init(struct hinic5_nic_dev *nic_dev)
struct net_device *netdev = nic_dev->netdev;
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (macsec_res->spec.max_sa == 2) { /* 2 SA mode */
- macsec_info(nic_dev->lld_dev->dev, "%s: Sc mode is 0, do not support offload protocol macsec",
- netdev->name);
+ if (macsec_res->spec.max_sa == 2) { /* 2 SA模式 */
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: Sc mode is 0, do not support offload protocol macsec",
+ netdev->name);
return;
}
@@ -810,9 +899,11 @@ bool himacsec_check_offload(u32 ifindex, u32 *offload)
{
u32 i;
- for (i = 0; i < MACSEC_SC_NUM; i++)
- if (offload[i] == ifindex)
+ for (i = 0; i < MACSEC_SC_NUM; i++) {
+ if (offload[i] == ifindex) {
return true;
+ }
+ }
return false;
}
@@ -829,73 +920,87 @@ int himacsec_get_offload_idx(u32 ifindex, u32 *offload, u32 *index)
return -1;
}
-/* Because vf ifindex is saved as array in himacsec_dev,
- * need to move forward from the currently deleted vf index when deleting
- */
+/* 因为在himacsec_dev里以数组的形式保存了vf的ifindex,所以需要在删除的时候从当前待删除的vf索引开始进行前移 */
int himacsec_dev_del_offload(u32 ifindex, struct macsec_resource *macsec_res)
{
u32 index = 0;
int ret = 0;
- if (macsec_res->offload_dev_num == 0)
+ if (macsec_res->offload_dev_num == 0) {
return 0;
+ }
- ret = himacsec_get_offload_idx(ifindex, macsec_res->offload_child_dev_idx, &index);
- if (ret < 0)
+ ret = himacsec_get_offload_idx(
+ ifindex, macsec_res->offload_child_dev_idx, &index);
+ if (ret < 0) {
return ret;
+ }
- for (; index < macsec_res->offload_dev_num - 1; index++)
+ for (; index < macsec_res->offload_dev_num - 1; index++) {
macsec_res->offload_child_dev_idx[index] =
- macsec_res->offload_child_dev_idx[index + 1];
- // offload vf count minus 1
+ macsec_res->offload_child_dev_idx[index + 1];
+ }
+ // offload的vf数量减1
macsec_res->offload_dev_num--;
return ret;
}
-void himacsec_remove_macsec_offload(struct net_device *dev, struct macsec_resource *macsec_res,
+void himacsec_remove_macsec_offload(struct net_device *dev,
+ struct macsec_resource *macsec_res,
struct hinic5_lld_dev *lld_dev)
{
int ret = 0;
struct net_device *lower_dev;
struct list_head *iter;
- // Traverse all lower devices
+ // 遍历所有下层设备
rcu_read_lock();
netdev_for_each_upper_dev_rcu(dev, lower_dev, iter) {
- // Check if it is a macsec device
+ // 检查是否是macsec设备
if (lower_dev->rtnl_link_ops &&
lower_dev->rtnl_link_ops->kind &&
- strcmp(lower_dev->rtnl_link_ops->kind, HIMACSEC_DEV_LINK_KIND) == 0) {
- macsec_info(lld_dev->dev, "Unregistering macsec offload for dev: %s, lower_dev %s, pf_ifindex: %d, vf_ifindex: %d ",
- dev->name, lower_dev->name, dev->ifindex, lower_dev->ifindex);
-
- // Unregister link, delete vf device
- if (himacsec_check_offload((u32)lower_dev->ifindex,
- macsec_res->offload_child_dev_idx)) {
- macsec_info(lld_dev->dev, "dev %s is offload , delete link",
+ strcmp(lower_dev->rtnl_link_ops->kind,
+ HIMACSEC_DEV_LINK_KIND) == 0) {
+ macsec_info(
+ lld_dev->dev,
+ "Unregistering macsec offload for dev: %s, lower_dev %s, pf_ifindex: %d, vf_ifindex: %d ",
+ dev->name, lower_dev->name, dev->ifindex,
+ lower_dev->ifindex);
+
+ // 卸载链路,删除vf设备
+ if (himacsec_check_offload(
+ (u32)lower_dev->ifindex,
+ macsec_res->offload_child_dev_idx)) {
+ macsec_info(lld_dev->dev,
+ "dev %s is offload , delete link",
lower_dev->name);
rtnl_lock();
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)) /* LINUX_VERSION_CODE < 6.6.0 */
+#if (LINUX_VERSION_CODE < \
+ KERNEL_VERSION(6, 6, 0)) /* LINUX_VERSION_CODE < 6.6.0 */
rtnl_delete_link(lower_dev);
#else /* LINUX_VERSION_CODE >= 6.6.0 */
rtnl_delete_link(lower_dev, 0, NULL);
#endif
rtnl_unlock();
- // Delete vf_ifindex recorded in offload_child_dev_idx
- ret = himacsec_dev_del_offload(lower_dev->ifindex, macsec_res);
+ // 删除offload_child_dev_idx中记录的vf_ifindex
+ ret = himacsec_dev_del_offload(
+ lower_dev->ifindex, macsec_res);
if (ret < 0) {
- macsec_err(lld_dev->dev, "delete child dev index fail: if_index is not in offload list, if_index: %d",
- lower_dev->ifindex);
+ macsec_err(
+ lld_dev->dev,
+ "delete child dev index fail: if_index is not in offload list, if_index: %d",
+ lower_dev->ifindex);
break;
}
- } else {
- // Not unregistering link, return directly
- // (vf link created by stack, no need to delete)
- macsec_info(lld_dev->dev, "dev %s is not offload , skip delete link",
- lower_dev->name);
+ } else { // 非卸载链路,直接返回(协议栈创建的vf链路,不需要删除)
+ macsec_info(
+ lld_dev->dev,
+ "dev %s is not offload , skip delete link",
+ lower_dev->name);
}
} else {
- macsec_info(lld_dev->dev, "%s is not a macsec device\n", lower_dev->name);
+ macsec_info(lld_dev->dev, "%s is not a macsec device\n",
+ lower_dev->name);
}
}
@@ -907,8 +1012,9 @@ void himacsec_offload_deinit(struct hinic5_nic_dev *nic_dev)
struct net_device *netdev = nic_dev->netdev;
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (!netdev->macsec_ops)
+ if (netdev->macsec_ops == NULL) {
return;
+ }
netdev->macsec_ops = NULL;
netdev->features &= ~NETIF_F_HW_MACSEC;
@@ -920,10 +1026,12 @@ void himacsec_offload_deinit(struct hinic5_nic_dev *nic_dev)
void himacsec_offload_init(struct hinic5_nic_dev *nic_dev)
{
+ return;
}
void himacsec_offload_deinit(struct hinic5_nic_dev *nic_dev)
{
+ return;
}
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_service.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_service.c
index dd6815eb0..7927c7b5d 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_service.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/macsec/hinic5_macsec_service.c
@@ -1,15 +1,12 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_macsec_service.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : macsec service code
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: macsec 业务代码
+ * Create: 2024/03/01
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": [MACsec]" fmt
#include "ossl_knl.h"
+#include "securec.h"
#include "hinic5_srv_nic.h"
#include "hinic5_nic_dev.h"
@@ -19,7 +16,8 @@
#include "hinic5_macsec_common.h"
#include "hinic5_macsec_dev.h"
-int himacsec_get_sci_port(u8 *port, u8 *cos, u64 sci, struct macsec_resource *macsec_res)
+int himacsec_get_sci_port(u8 *port, u8 *cos, u64 sci,
+ struct macsec_resource *macsec_res)
{
himacsec_spec_s *spec = &macsec_res->spec;
u8 port_cos = (u8)sci;
@@ -29,26 +27,28 @@ int himacsec_get_sci_port(u8 *port, u8 *cos, u64 sci, struct macsec_resource *ma
return 0;
}
-/* Get sc corresponding to sci:
- * 1. Parse sci to get sc_index.
- * 2. Return corresponding address based on array subscript.
+/* 获取sci对应的 sc:
+ * 1.解析sci,获得sc_index.
+ * 2.根据数组下标返回对应地址.
*/
-struct himacsec_sc *himacsec_get_dev_sc(struct hinic5_nic_dev *nic_dev, crypt_direction_e direct)
+struct himacsec_sc *himacsec_get_dev_sc(struct hinic5_nic_dev *nic_dev,
+ crypt_direction_e direct)
{
u32 port_id = 0;
- if (nic_dev->macsec_res)
+ if (nic_dev->macsec_res != NULL) {
port_id = nic_dev->macsec_res->function_port;
- else
+ } else {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
+ }
return get_g_macsec_port_res(direct, port_id);
}
-/* Get sc corresponding to sci and verify it matches the parameter sci:
- * 1. Get sc content for the sci corresponding sc_index.
- * 2. Check if the sc is valid.
+/* 获取sci对应的sc,并校验该sc是否与参数sci内容一致:
+ * 1.获取sci对应sc_index的sc内容.
+ * 2.检查该sc是否有效.
*/
struct himacsec_sc *himacsec_get_valid_dev_sc(struct hinic5_nic_dev *nic_dev,
u64 sci, crypt_direction_e direct)
@@ -59,16 +59,19 @@ struct himacsec_sc *himacsec_get_valid_dev_sc(struct hinic5_nic_dev *nic_dev,
// 1. get sc
knl_sc = himacsec_get_dev_sc(nic_dev, direct);
- if (!knl_sc)
+ if (knl_sc == NULL) {
return NULL;
+ }
sc_status = knl_sc->status.status.sc;
priv_sci = knl_sc->info.sci;
// 2. check sc
- if ((MACSEC_SC_STATUS_VALID(sc_status) == 0) || sci != priv_sci) {
- macsec_info(nic_dev->lld_dev->dev, "%s: Can not find kernel device sc, direct=0x%x, target sci=%llx, sc status=%d",
- nic_dev->netdev->name, direct, priv_sci, sc_status);
+ if ((MACSEC_SC_STATUS_VALID(sc_status) == 0) || (sci != priv_sci)) {
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: Can not find kernel device sc, direct=0x%x, target sci=%llx, sc status=%d",
+ nic_dev->netdev->name, direct, priv_sci, sc_status);
return NULL;
}
@@ -82,16 +85,18 @@ struct himacsec_sa *himacsec_get_dev_sa(struct hinic5_nic_dev *nic_dev, u64 sci,
u32 sa_index = 0;
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (!macsec_res) {
+ if (macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
return NULL;
}
sc = himacsec_get_valid_dev_sc(nic_dev, sci, direct);
- if (!sc) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Get kernel device sa failed, sc not found, direct=0x%x, sci=%llx, an=%d",
- nic_dev->netdev->name, direct, sci, an);
+ if (sc == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Get kernel device sa failed, sc not found, direct=0x%x, sci=%llx, an=%d",
+ nic_dev->netdev->name, direct, sci, an);
return NULL;
}
sa_index = an % macsec_res->spec.max_sa;
@@ -99,36 +104,44 @@ struct himacsec_sa *himacsec_get_dev_sa(struct hinic5_nic_dev *nic_dev, u64 sci,
}
struct himacsec_sa *himacsec_get_valid_dev_sa(struct hinic5_nic_dev *nic_dev,
- u64 sci, u8 an, crypt_direction_e direct)
+ u64 sci, u8 an,
+ crypt_direction_e direct)
{
struct himacsec_sa *sa = NULL;
sa = himacsec_get_dev_sa(nic_dev, sci, an, direct);
- if (!sa)
+ if (sa == NULL) {
return NULL;
+ }
- if ((MACSEC_SA_STATUS_VALID(sa->status.status.sa) == 0) || an != sa->info.an) {
- macsec_info(nic_dev->lld_dev->dev, "%s: Get kernel device sa failed, direct=0x%x, sci=%llx, target an=%d, already exist an=%d",
- nic_dev->netdev->name, direct, sci, an, sa->info.an);
+ if ((MACSEC_SA_STATUS_VALID(sa->status.status.sa) == 0) ||
+ (an != sa->info.an)) {
+ macsec_info(
+ nic_dev->lld_dev->dev,
+ "%s: Get kernel device sa failed, direct=0x%x, sci=%llx, target an=%d, already exist an=%d",
+ nic_dev->netdev->name, direct, sci, an, sa->info.an);
return NULL;
}
return sa;
}
-int himacsec_del_sa(struct hinic5_nic_dev *nic_dev, u64 sci, u8 assoc_num, crypt_direction_e direct)
+int himacsec_del_sa(struct hinic5_nic_dev *nic_dev, u64 sci, u8 assoc_num,
+ crypt_direction_e direct)
{
- macsec_sa_info_s sa_info = {0};
+ macsec_sa_info_s sa_info = { 0 };
struct net_device *netdev = nic_dev->netdev;
struct himacsec_sa *priv_sa_ptr = NULL;
- macsec_mbox_sa_op_cmd_e sa_op = (direct == MACSEC_OUTBOUND)
- ? MACSEC_CMD_ENC_SA_DELETE
- : MACSEC_CMD_DEC_SA_DELETE;
+ macsec_mbox_sa_op_cmd_e sa_op = (direct == MACSEC_OUTBOUND) ?
+ MACSEC_CMD_ENC_SA_DELETE :
+ MACSEC_CMD_DEC_SA_DELETE;
int ret;
- priv_sa_ptr = himacsec_get_valid_dev_sa(nic_dev, sci, assoc_num, direct);
- if (!priv_sa_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Delete sa failed, sa not found, direct=0x%x",
+ priv_sa_ptr =
+ himacsec_get_valid_dev_sa(nic_dev, sci, assoc_num, direct);
+ if (priv_sa_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Delete sa failed, sa not found, direct=0x%x",
netdev->name, direct);
return -ENOENT;
}
@@ -137,13 +150,16 @@ int himacsec_del_sa(struct hinic5_nic_dev *nic_dev, u64 sci, u8 assoc_num, crypt
sa_info.an = assoc_num;
ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, &sa_info, sa_op);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sc delete failed, direct=0x%x, ret=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd sc delete failed, direct=0x%x, ret=%d",
netdev->name, direct, ret);
return ret;
}
- memset(priv_sa_ptr, 0, sizeof(struct himacsec_sa));
- macsec_info(nic_dev->lld_dev->dev, "%s: Delete sa success, direct=0x%x, sci=%llx, an=%d",
+ (void)memset_s(priv_sa_ptr, sizeof(struct himacsec_sa), 0,
+ sizeof(struct himacsec_sa));
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: Delete sa success, direct=0x%x, sci=%llx, an=%d",
netdev->name, direct, sci, assoc_num);
return ret;
}
@@ -153,52 +169,59 @@ int himacsec_add_sa(struct hinic5_nic_dev *nic_dev, macsec_sa_info_s *sa_info,
{
struct net_device *netdev = nic_dev->netdev;
struct himacsec_sa *priv_sa_ptr = NULL;
- macsec_mbox_sa_op_cmd_e sa_op = (direct == MACSEC_OUTBOUND)
- ? MACSEC_CMD_ENC_SA_CREATE
- : MACSEC_CMD_DEC_SA_CREATE;
+ macsec_mbox_sa_op_cmd_e sa_op = (direct == MACSEC_OUTBOUND) ?
+ MACSEC_CMD_ENC_SA_CREATE :
+ MACSEC_CMD_DEC_SA_CREATE;
int ret;
- priv_sa_ptr = himacsec_get_dev_sa(nic_dev, sa_info->sci, sa_info->an, direct);
- if (!priv_sa_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Add sa failed, sc not found", netdev->name);
+ priv_sa_ptr =
+ himacsec_get_dev_sa(nic_dev, sa_info->sci, sa_info->an, direct);
+ if (priv_sa_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add sa failed, sc not found", netdev->name);
return -EINVAL;
}
ret = himacsec_cmd_exec_sa_op(nic_dev->lld_dev, sa_info, sa_op);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sa create failed, direct=0x%x, ret=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd sa create failed, direct=0x%x, ret=%d",
netdev->name, direct, ret);
return ret;
}
priv_sa_ptr->status.status.sa = SA_STATUS_CREATED;
- memcpy(&priv_sa_ptr->info, sa_info, sizeof(macsec_sa_info_s));
- macsec_info(nic_dev->lld_dev->dev, "%s: Add sa success, direct=0x%x, sci=%llx, an=%d",
+ (void)memcpy_s(&priv_sa_ptr->info, sizeof(macsec_sa_info_s), sa_info,
+ sizeof(macsec_sa_info_s));
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: Add sa success, direct=0x%x, sci=%llx, an=%d",
netdev->name, direct, sa_info->sci, sa_info->an);
himacsec_dfx_show_sa(nic_dev, sa_info, direct);
return ret;
}
-int himacsec_create_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *sc_info,
- crypt_direction_e direct)
+int himacsec_create_sc(struct hinic5_nic_dev *nic_dev,
+ macsec_sc_info_s *sc_info, crypt_direction_e direct)
{
struct himacsec_sc *priv_sc_ptr = NULL;
struct net_device *netdev = nic_dev->netdev;
- macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND)
- ? MACSEC_CMD_ENC_SC_CREATE
- : MACSEC_CMD_DEC_SC_CREATE;
+ macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND) ?
+ MACSEC_CMD_ENC_SC_CREATE :
+ MACSEC_CMD_DEC_SC_CREATE;
int ret;
// 1. get target sc_index's data
priv_sc_ptr = himacsec_get_dev_sc(nic_dev, direct);
- if (!priv_sc_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "Add sc failed, priv_sc_ptr is NULL");
+ if (priv_sc_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "Add sc failed, priv_sc_ptr is NULL");
return -EINVAL;
}
// 2. check target sc_idnex's has valid sc
if (MACSEC_SC_STATUS_VALID(priv_sc_ptr->status.status.sc) != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Add sc failed, sc already exists, direct=0x%x",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Add sc failed, sc already exists, direct=0x%x",
netdev->name, direct);
return -EEXIST;
}
@@ -206,47 +229,56 @@ int himacsec_create_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *sc_info
// 3. create sc
ret = himacsec_cmd_exec_sc_op(nic_dev->lld_dev, sc_info, sc_op);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sc create failed, direct=0x%x, ret=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd sc create failed, direct=0x%x, ret=%d",
netdev->name, direct, ret);
return ret;
}
- (void)memcpy(&priv_sc_ptr->info, sc_info, sizeof(macsec_sc_info_s));
+ (void)memcpy_s(&priv_sc_ptr->info, sizeof(macsec_sc_info_s), sc_info,
+ sizeof(macsec_sc_info_s));
priv_sc_ptr->status.status.sc = SC_STATUS_CREATED;
- macsec_info(nic_dev->lld_dev->dev, "%s: Add encryption sc success, sci=%llx",
- netdev->name, sc_info->sci);
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: Add encryption sc success, sci=%llx", netdev->name,
+ sc_info->sci);
himacsec_dfx_show_sc(nic_dev, &priv_sc_ptr->info, direct);
return ret;
}
-int himacsec_destroy_sc(struct hinic5_nic_dev *nic_dev, u64 sci, crypt_direction_e direct)
+int himacsec_destroy_sc(struct hinic5_nic_dev *nic_dev, u64 sci,
+ crypt_direction_e direct)
{
struct net_device *netdev = nic_dev->netdev;
struct himacsec_sc *priv_sc_ptr = NULL;
- macsec_sc_info_s sc_info = {0};
- macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND)
- ? MACSEC_CMD_ENC_SC_DELETE
- : MACSEC_CMD_DEC_SC_DELETE;
+ macsec_sc_info_s sc_info = { 0 };
+ macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND) ?
+ MACSEC_CMD_ENC_SC_DELETE :
+ MACSEC_CMD_DEC_SC_DELETE;
int ret;
// 1. get and check SCI corresponding to scindex
priv_sc_ptr = himacsec_get_valid_dev_sc(nic_dev, sci, direct);
- if (!priv_sc_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sc delete failed, sc not found, direct=0x%x",
- netdev->name, direct);
+ if (priv_sc_ptr == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Exec cmd sc delete failed, sc not found, direct=0x%x",
+ netdev->name, direct);
return -EINVAL;
}
sc_info.sci = sci;
ret = himacsec_cmd_exec_sc_op(nic_dev->lld_dev, &sc_info, sc_op);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sc delete failed, direct=0x%x, ret=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd sc delete failed, direct=0x%x, ret=%d",
netdev->name, direct, ret);
return ret;
}
- memset(priv_sc_ptr, 0, sizeof(struct himacsec_sc));
- macsec_info(nic_dev->lld_dev->dev, "%s: Delete sc success, direct=0x%x, sci=%llx",
+ (void)memset_s(priv_sc_ptr, sizeof(struct himacsec_sc), 0,
+ sizeof(struct himacsec_sc));
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: Delete sc success, direct=0x%x, sci=%llx",
netdev->name, direct, sci);
return 0;
}
@@ -256,47 +288,54 @@ int himacsec_set_sc(struct hinic5_nic_dev *nic_dev, macsec_sc_info_s *sc_info,
{
struct himacsec_sc *priv_sc_ptr = NULL;
struct net_device *netdev = nic_dev->netdev;
- macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND)
- ? MACSEC_CMD_ENC_SC_UPDATE
- : MACSEC_CMD_DEC_SC_UPDATE;
+ macsec_mbox_sc_op_cmd_e sc_op = (direct == MACSEC_OUTBOUND) ?
+ MACSEC_CMD_ENC_SC_UPDATE :
+ MACSEC_CMD_DEC_SC_UPDATE;
int ret;
- // Retrieve the data from the drive for write-back preparation.
+ // 取出驱动内数据准备回写
priv_sc_ptr = himacsec_get_valid_dev_sc(nic_dev, sc_info->sci, direct);
- if (!priv_sc_ptr) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Set sc failed, sc not found, direct=0x%x",
+ if (priv_sc_ptr == NULL) {
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Set sc failed, sc not found, direct=0x%x",
netdev->name, direct);
return -EINVAL;
}
- // execute command
+ // 执行命令
ret = himacsec_cmd_exec_sc_op(nic_dev->lld_dev, sc_info, sc_op);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Exec cmd sc set failed, direct=0x%x, ret=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Exec cmd sc set failed, direct=0x%x, ret=%d",
netdev->name, direct, ret);
return ret;
}
- // Writing back data in the driver.
- memcpy(&priv_sc_ptr->info, sc_info, sizeof(macsec_sc_info_s));
- macsec_info(nic_dev->lld_dev->dev, "%s: Set sc success, direct=0x%x, sci=%llx",
- netdev->name, direct, sc_info->sci);
+ // 回写驱动内数据
+ (void)memcpy_s(&priv_sc_ptr->info, sizeof(macsec_sc_info_s), sc_info,
+ sizeof(macsec_sc_info_s));
+ macsec_info(nic_dev->lld_dev->dev,
+ "%s: Set sc success, direct=0x%x, sci=%llx", netdev->name,
+ direct, sc_info->sci);
himacsec_dfx_show_sc(nic_dev, &priv_sc_ptr->info, direct);
return ret;
}
-int himacsec_update_sa_an(struct hinic5_nic_dev *nic_dev, struct himacsec_sc *sc,
- u32 sa_index, u8 an, crypt_direction_e direct)
+int himacsec_update_sa_an(struct hinic5_nic_dev *nic_dev,
+ struct himacsec_sc *sc, u32 sa_index, u8 an,
+ crypt_direction_e direct)
{
- struct himacsec_sc temp_sc = {0};
+ struct himacsec_sc temp_sc = { 0 };
int ret;
- memcpy(&temp_sc, sc, sizeof(struct himacsec_sc));
+ (void)memcpy_s(&temp_sc, sizeof(struct himacsec_sc), sc,
+ sizeof(struct himacsec_sc));
temp_sc.info.sa_an[sa_index] = an;
ret = himacsec_set_sc(nic_dev, &temp_sc.info, direct);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Update sa_an failed, sci=0x%016llx, an=%d",
+ macsec_err(nic_dev->lld_dev->dev,
+ "%s: Update sa_an failed, sci=0x%016llx, an=%d",
nic_dev->netdev->name, sc->info.sci, an);
}
return ret;
@@ -310,31 +349,36 @@ int himacsec_update_sc_in_sa_add(struct hinic5_nic_dev *nic_dev, u64 sci, u8 an,
int ret;
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (!macsec_res) {
+ if (macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
return -EINVAL;
}
- // sa_index ensure that the array does not exceed the boundary.
+ // sa_index 需要保证数组不越界
sa_index = an % macsec_res->spec.max_sa;
if (sa_index >= HIMACSEC_MAX_SA_IN_SC) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Update sc info in sa operation failed, sa_index overflow, an=%d, max_sa=%d",
- nic_dev->netdev->name, an, macsec_res->spec.max_sa);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Update sc info in sa operation failed, sa_index overflow, an=%d, max_sa=%d",
+ nic_dev->netdev->name, an, macsec_res->spec.max_sa);
return -EINVAL;
}
sc = himacsec_get_valid_dev_sc(nic_dev, sci, direct);
- if (!sc) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Update sc info in sa operation failed, sci=%llx not found",
- nic_dev->netdev->name, sci);
+ if (sc == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Update sc info in sa operation failed, sci=%llx not found",
+ nic_dev->netdev->name, sci);
return -EINVAL;
}
- // update sa_an
+ // 更新 sa_an
ret = himacsec_update_sa_an(nic_dev, sc, sa_index, an, direct);
- if (ret != 0)
+ if (ret != 0) {
return ret;
+ }
sc->info.sa_an[sa_index] = an;
return 0;
}
@@ -346,16 +390,19 @@ int himacsec_create_sa(struct hinic5_nic_dev *nic_dev, macsec_sa_info_s *sa,
ret = himacsec_add_sa(nic_dev, sa, direct);
if (ret != 0) {
- macsec_err(nic_dev->lld_dev->dev, "Create sa failed, ret=0x%x, direct=0x%x",
- ret, direct);
+ macsec_err(nic_dev->lld_dev->dev,
+ "Create sa failed, ret=0x%x, direct=0x%x", ret,
+ direct);
return ret;
}
ret = himacsec_update_sc_in_sa_add(nic_dev, sa->sci, sa->an, direct);
if (ret != 0) {
if (himacsec_del_sa(nic_dev, sa->sci, sa->an, direct) != 0) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Fallback to delete sa data failed, direct=0x%x",
- nic_dev->netdev->name, direct);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Fallback to delete sa data failed, direct=0x%x",
+ nic_dev->netdev->name, direct);
}
}
return ret;
@@ -369,36 +416,43 @@ int himacsec_destroy_sa(struct hinic5_nic_dev *nic_dev, u64 sci, u8 assoc_num,
int ret;
struct macsec_resource *macsec_res = nic_dev->macsec_res;
- if (!macsec_res) {
+ if (macsec_res == NULL) {
macsec_err(nic_dev->lld_dev->dev, "%s: MACsec resource is NULL",
nic_dev->netdev->name);
return -EINVAL;
}
ret = himacsec_del_sa(nic_dev, sci, assoc_num, direct);
- if (ret != 0)
+ if (ret != 0) {
return ret;
+ }
// 清理 sa_an
sc = himacsec_get_valid_dev_sc(nic_dev, sci, direct);
- if (!sc) {
- macsec_err(nic_dev->lld_dev->dev, "%s: Del sa, update sc failed, direct=0x%x, sci=%llx not found",
- nic_dev->netdev->name, direct, sci);
+ if (sc == NULL) {
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: Del sa, update sc failed, direct=0x%x, sci=%llx not found",
+ nic_dev->netdev->name, direct, sci);
return -EINVAL;
}
- // sa_index ensure that the array does not exceed the boundary.
+ // sa_index 需要保证数组不越界
sa_index = assoc_num % macsec_res->spec.max_sa;
if (sa_index >= HIMACSEC_MAX_SA_IN_SC) {
- macsec_err(nic_dev->lld_dev->dev, "%s: sa_index overflow, direct=0x%x, an=%d, max_sa=%d",
- nic_dev->netdev->name, direct, assoc_num, macsec_res->spec.max_sa);
+ macsec_err(
+ nic_dev->lld_dev->dev,
+ "%s: sa_index overflow, direct=0x%x, an=%d, max_sa=%d",
+ nic_dev->netdev->name, direct, assoc_num,
+ macsec_res->spec.max_sa);
return -EINVAL;
}
ret = himacsec_update_sa_an(nic_dev, sc, sa_index, 0, direct);
- if (ret != 0)
+ if (ret != 0) {
return ret;
+ }
sc->info.sa_an[sa_index] = 0;
return 0;
-}
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.c
index 091881e2b..fca7acc8e 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_filter.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
#include <linux/kernel.h>
@@ -69,8 +62,8 @@ void hinic5_clean_mac_list_filter(struct hinic5_nic_dev *nic_dev)
}
}
-static struct hinic5_mac_filter *hinic5_find_mac(const struct list_head *filter_list,
- u8 *addr)
+static struct hinic5_mac_filter *
+hinic5_find_mac(const struct list_head *filter_list, u8 *addr)
{
struct hinic5_mac_filter *f = NULL;
@@ -82,8 +75,7 @@ static struct hinic5_mac_filter *hinic5_find_mac(const struct list_head *filter_
}
static void hinic5_add_filter(struct hinic5_nic_dev *nic_dev,
- struct list_head *mac_filter_list,
- u8 *addr)
+ struct list_head *mac_filter_list, u8 *addr)
{
struct hinic5_mac_filter *f = NULL;
@@ -92,7 +84,7 @@ static void hinic5_add_filter(struct hinic5_nic_dev *nic_dev,
return;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
- if (!f)
+ if (f == NULL)
return;
ether_addr_copy(f->addr, addr);
@@ -119,12 +111,13 @@ static void hinic5_del_filter(struct hinic5_nic_dev *nic_dev,
f->state = HINIC5_MAC_WAIT_HW_UNSYNC;
}
-static struct hinic5_mac_filter *hinic5_mac_filter_entry_clone(const struct hinic5_mac_filter *src)
+static struct hinic5_mac_filter *
+hinic5_mac_filter_entry_clone(const struct hinic5_mac_filter *src)
{
struct hinic5_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
- if (!f)
+ if (f == NULL)
return NULL;
*f = *src;
@@ -159,7 +152,7 @@ static void hinic5_undo_add_filter_entries(struct list_head *filter_list,
list_for_each_entry_safe(f, ftmp, from, list) {
tmp = hinic5_find_mac(filter_list, f->addr);
- if (tmp && tmp->state == HINIC5_MAC_HW_SYNCED)
+ if ((tmp != NULL) && tmp->state == HINIC5_MAC_HW_SYNCED)
tmp->state = HINIC5_MAC_WAIT_HW_SYNC;
}
}
@@ -188,7 +181,8 @@ static int hinic5_mac_filter_sync_hw(struct hinic5_nic_dev *nic_dev,
list_for_each_entry_safe(f, ftmp, del_list, list) {
err = hinic5_uc_unsync(netdev, f->addr);
if (err != 0) { /* ignore errors when delete mac */
- nic_err(nic_dev->lld_dev->dev, "Failed to delete mac\n");
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to delete mac\n");
}
list_del(&f->list);
@@ -200,7 +194,8 @@ static int hinic5_mac_filter_sync_hw(struct hinic5_nic_dev *nic_dev,
list_for_each_entry_safe(f, ftmp, add_list, list) {
err = hinic5_uc_sync(netdev, f->addr);
if (err != 0) {
- nic_err(nic_dev->lld_dev->dev, "Failed to add mac\n");
+ nic_err(nic_dev->lld_dev->dev,
+ "Failed to add mac\n");
return err;
}
@@ -238,7 +233,7 @@ static int hinic5_mac_filter_sync(struct hinic5_nic_dev *nic_dev,
continue;
fclone = hinic5_mac_filter_entry_clone(f);
- if (!fclone) {
+ if (fclone == NULL) {
err = -ENOMEM;
break;
}
@@ -250,14 +245,16 @@ static int hinic5_mac_filter_sync(struct hinic5_nic_dev *nic_dev,
if (err != 0) {
hinic5_undo_del_filter_entries(mac_filter_list, &tmp_del_list);
hinic5_undo_add_filter_entries(mac_filter_list, &tmp_add_list);
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to clone mac_filter_entry\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to clone mac_filter_entry\n");
hinic5_cleanup_filter_list(&tmp_del_list);
hinic5_cleanup_filter_list(&tmp_add_list);
return -ENOMEM;
}
- add_count = hinic5_mac_filter_sync_hw(nic_dev, &tmp_del_list, &tmp_add_list);
+ add_count = hinic5_mac_filter_sync_hw(nic_dev, &tmp_del_list,
+ &tmp_add_list);
if (list_empty(&tmp_add_list) != 0)
return add_count;
@@ -272,7 +269,7 @@ static int hinic5_mac_filter_sync(struct hinic5_nic_dev *nic_dev,
continue;
fclone = hinic5_mac_filter_entry_clone(f);
- if (!fclone)
+ if (fclone == NULL)
break;
f->state = HINIC5_MAC_WAIT_HW_SYNC;
@@ -294,25 +291,25 @@ static void hinic5_mac_filter_sync_all(struct hinic5_nic_dev *nic_dev)
if (test_bit(HINIC5_MAC_FILTER_CHANGED, &nic_dev->flags) != 0) {
clear_bit(HINIC5_MAC_FILTER_CHANGED, &nic_dev->flags);
- add_count = hinic5_mac_filter_sync(nic_dev,
- &nic_dev->uc_filter_list,
- true);
+ add_count = hinic5_mac_filter_sync(
+ nic_dev, &nic_dev->uc_filter_list, true);
if (add_count < 0 && HINIC5_SUPPORT_PROMISC(nic_dev->hwdev)) {
set_bit(HINIC5_PROMISC_FORCE_ON,
&nic_dev->rx_mod_state);
- nicif_info(nic_dev, drv, netdev, "Promisc mode forced on\n");
+ nicif_info(nic_dev, drv, netdev,
+ "Promisc mode forced on\n");
} else if (add_count != 0) {
clear_bit(HINIC5_PROMISC_FORCE_ON,
&nic_dev->rx_mod_state);
}
- add_count = hinic5_mac_filter_sync(nic_dev,
- &nic_dev->mc_filter_list,
- false);
+ add_count = hinic5_mac_filter_sync(
+ nic_dev, &nic_dev->mc_filter_list, false);
if (add_count < 0 && HINIC5_SUPPORT_ALLMULTI(nic_dev->hwdev)) {
set_bit(HINIC5_ALLMULTI_FORCE_ON,
&nic_dev->rx_mod_state);
- nicif_info(nic_dev, drv, netdev, "All multicast mode forced on\n");
+ nicif_info(nic_dev, drv, netdev,
+ "All multicast mode forced on\n");
} else if (add_count != 0) {
clear_bit(HINIC5_ALLMULTI_FORCE_ON,
&nic_dev->rx_mod_state);
@@ -333,7 +330,7 @@ static void hinic5_update_mac_filter(struct hinic5_nic_dev *nic_dev,
netif_addr_lock_bh(nic_dev->netdev);
netdev_hw_addr_list_for_each(ha, src_list) {
filter = hinic5_find_mac(filter_list, ha->addr);
- if (!filter)
+ if (filter == NULL)
hinic5_add_filter(nic_dev, filter_list, ha->addr);
else if (filter->state == HINIC5_MAC_WAIT_HW_UNSYNC)
filter->state = HINIC5_MAC_HW_SYNCED;
@@ -372,7 +369,7 @@ static void hinic5_update_mc_filter(struct hinic5_nic_dev *nic_dev,
netif_addr_lock_bh(nic_dev->netdev);
netdev_for_each_mc_addr(ha, nic_dev->netdev) {
filter = hinic5_find_mac(filter_list, ha->da_addr);
- if (!filter)
+ if (filter == NULL)
hinic5_add_filter(nic_dev, filter_list, ha->da_addr);
else if (filter->state == HINIC5_MAC_WAIT_HW_UNSYNC)
filter->state = HINIC5_MAC_HW_SYNCED;
@@ -402,7 +399,8 @@ static void update_mac_filter(struct hinic5_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
- if (test_and_clear_bit(HINIC5_UPDATE_MAC_FILTER, &nic_dev->flags) != 0) {
+ if (test_and_clear_bit(HINIC5_UPDATE_MAC_FILTER, &nic_dev->flags) !=
+ 0) {
hinic5_update_mac_filter(nic_dev, &netdev->uc,
&nic_dev->uc_filter_list);
@@ -410,8 +408,7 @@ static void update_mac_filter(struct hinic5_nic_dev *nic_dev)
hinic5_update_mac_filter(nic_dev, &netdev->mc,
&nic_dev->mc_filter_list);
#else
- hinic5_update_mc_filter(nic_dev,
- &nic_dev->mc_filter_list);
+ hinic5_update_mc_filter(nic_dev, &nic_dev->mc_filter_list);
#endif
}
}
@@ -426,15 +423,13 @@ static void sync_rx_mode_to_hw(struct hinic5_nic_dev *nic_dev, int promisc_en,
rx_mod |= ((promisc_en != 0) ? NIC_RX_MODE_PROMISC : 0);
rx_mod |= ((allmulti_en != 0) ? NIC_RX_MODE_MC_ALL : 0);
- if (promisc_en != test_bit(HINIC5_HW_PROMISC_ON,
- &nic_dev->rx_mod_state))
- nicif_info(nic_dev, drv, netdev,
- "%s promisc mode\n",
+ if (promisc_en !=
+ test_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state))
+ nicif_info(nic_dev, drv, netdev, "%s promisc mode\n",
(promisc_en != 0) ? "Enter" : "Left");
if (allmulti_en !=
test_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state))
- nicif_info(nic_dev, drv, netdev,
- "%s all_multi mode\n",
+ nicif_info(nic_dev, drv, netdev, "%s all_multi mode\n",
(allmulti_en != 0) ? "Enter" : "Left");
err = hinic5_set_rx_mode(nic_dev->hwdev, rx_mod);
@@ -443,17 +438,19 @@ static void sync_rx_mode_to_hw(struct hinic5_nic_dev *nic_dev, int promisc_en,
return;
}
- (promisc_en != 0) ? set_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state) :
+ (promisc_en != 0) ?
+ set_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state) :
clear_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state);
- (allmulti_en != 0) ? set_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state) :
+ (allmulti_en != 0) ?
+ set_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state) :
clear_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state);
}
void hinic5_set_rx_mode_work(struct work_struct *work)
{
struct hinic5_nic_dev *nic_dev =
- container_of(work, struct hinic5_nic_dev, rx_mode_work);
+ container_of(work, struct hinic5_nic_dev, rx_mode_work);
struct net_device *netdev = nic_dev->netdev;
int promisc_en = 0, allmulti_en = 0;
@@ -463,18 +460,17 @@ void hinic5_set_rx_mode_work(struct work_struct *work)
if (HINIC5_SUPPORT_PROMISC(nic_dev->hwdev))
promisc_en = ((netdev->flags & IFF_PROMISC) != 0) ||
- test_bit(HINIC5_PROMISC_FORCE_ON,
- &nic_dev->rx_mod_state);
+ test_bit(HINIC5_PROMISC_FORCE_ON,
+ &nic_dev->rx_mod_state);
if (HINIC5_SUPPORT_ALLMULTI(nic_dev->hwdev))
allmulti_en = ((netdev->flags & IFF_ALLMULTI) != 0) ||
- test_bit(HINIC5_ALLMULTI_FORCE_ON,
- &nic_dev->rx_mod_state);
+ test_bit(HINIC5_ALLMULTI_FORCE_ON,
+ &nic_dev->rx_mod_state);
if (promisc_en !=
- test_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state) ||
+ test_bit(HINIC5_HW_PROMISC_ON, &nic_dev->rx_mod_state) ||
allmulti_en !=
- test_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state))
+ test_bit(HINIC5_HW_ALLMULTI_ON, &nic_dev->rx_mod_state))
sync_rx_mode_to_hw(nic_dev, promisc_en, allmulti_en);
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.h
index 613ef6ebe..5a0dda4e5 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_filter.h
@@ -1,17 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_filter.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_FILTER_H
-#define HINIC5_FILTER_H
+#define HINIC5_FILTER_H
-#define HINIC5_DEFAULT_RX_MODE (NIC_RX_MODE_UC | NIC_RX_MODE_MC | \
- NIC_RX_MODE_BC)
+#define HINIC5_DEFAULT_RX_MODE \
+ (NIC_RX_MODE_UC | NIC_RX_MODE_MC | NIC_RX_MODE_BC)
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.c
index c4e4e19a8..5607cb560 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_netdev_ops.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Netdev operations implementation
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
#include <net/dsfield.h>
@@ -27,9 +20,9 @@
#endif
#include "hinic5_hw.h"
#include "hinic5_crm.h"
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
#include "nic_cfg_comm.h"
-#include "hinic5_hinic5_vram.h"
+#include "hinic5_vram.h"
#include "hinic5_nic_io.h"
#include "hinic5_nic_dev.h"
#include "hinic5_srv_nic.h"
@@ -61,47 +54,84 @@ static void hinic5_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
-static int hinic5_alloc_txrxq_resources(struct hinic5_nic_dev *nic_dev,
- struct hinic5_dyna_txrxq_params *q_params)
+static int alloc_txrxq_arrays(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_txrxq_params *q_params)
{
u32 size;
- int err;
u16 total_num_qps = q_params->num_qps + q_params->xdp_qps;
size = sizeof(*q_params->txqs_res) * (total_num_qps);
q_params->txqs_res = kzalloc(size, GFP_KERNEL);
- if (!q_params->txqs_res) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txqs resources array\n");
+ if (q_params->txqs_res == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc txqs resources array\n");
return -ENOMEM;
}
size = sizeof(*q_params->rxqs_res) * (total_num_qps);
q_params->rxqs_res = kzalloc(size, GFP_KERNEL);
- if (!q_params->rxqs_res) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc rxqs resource array\n");
- err = -ENOMEM;
+ if (q_params->rxqs_res == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc rxqs resource array\n");
goto alloc_rxqs_res_arr_err;
}
size = sizeof(*q_params->irq_cfg) * (total_num_qps);
q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
- err = hinic5_alloc_txqs_res(nic_dev, total_num_qps,
+ return 0;
+
+alloc_irq_cfg_err:
+ kfree(q_params->rxqs_res);
+ q_params->rxqs_res = NULL;
+
+alloc_rxqs_res_arr_err:
+ kfree(q_params->txqs_res);
+ q_params->txqs_res = NULL;
+
+ return -ENOMEM;
+}
+
+static void free_txrxq_arrays(struct hinic5_dyna_txrxq_params *q_params)
+{
+ kfree(q_params->irq_cfg);
+ q_params->irq_cfg = NULL;
+ kfree(q_params->rxqs_res);
+ q_params->rxqs_res = NULL;
+ kfree(q_params->txqs_res);
+ q_params->txqs_res = NULL;
+}
+
+static int
+hinic5_alloc_txrxq_resources(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_txrxq_params *q_params)
+{
+ int err;
+
+ err = alloc_txrxq_arrays(nic_dev, q_params);
+ if (err != 0)
+ return err;
+
+ err = hinic5_alloc_txqs_res(nic_dev,
+ q_params->num_qps + q_params->xdp_qps,
q_params->sq_depth, q_params->txqs_res);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txqs resource\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc txqs resource\n");
goto alloc_txqs_res_err;
}
- err = hinic5_alloc_rxqs_res(nic_dev, total_num_qps,
+ err = hinic5_alloc_rxqs_res(nic_dev,
+ q_params->num_qps + q_params->xdp_qps,
q_params->rq_depth, q_params->rxqs_res);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc rxqs resource\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc rxqs resource\n");
goto alloc_rxqs_res_err;
}
@@ -112,22 +142,14 @@ static int hinic5_alloc_txrxq_resources(struct hinic5_nic_dev *nic_dev,
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
-
-alloc_irq_cfg_err:
- kfree(q_params->rxqs_res);
- q_params->rxqs_res = NULL;
-
-alloc_rxqs_res_arr_err:
- kfree(q_params->txqs_res);
- q_params->txqs_res = NULL;
+ free_txrxq_arrays(q_params);
return err;
}
-static void hinic5_free_txrxq_resources(struct hinic5_nic_dev *nic_dev,
- struct hinic5_dyna_txrxq_params *q_params)
+static void
+hinic5_free_txrxq_resources(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_txrxq_params *q_params)
{
u16 total_num_qps = q_params->num_qps + q_params->xdp_qps;
@@ -149,6 +171,7 @@ static void hinic5_free_txrxq_resources(struct hinic5_nic_dev *nic_dev,
static void hinic5_remove_configure_txrxqs(struct hinic5_nic_dev *nic_dev)
{
hinic5_remove_configure_rxqs(nic_dev);
+ return;
}
static int hinic5_configure_txrxqs(struct hinic5_nic_dev *nic_dev,
@@ -156,17 +179,16 @@ static int hinic5_configure_txrxqs(struct hinic5_nic_dev *nic_dev,
{
int err;
u16 total_num_qps = q_params->num_qps + q_params->xdp_qps;
-
- err = hinic5_configure_txqs(nic_dev, total_num_qps,
- q_params->sq_depth, q_params->txqs_res);
+ err = hinic5_configure_txqs(nic_dev, total_num_qps, q_params->sq_depth,
+ q_params->txqs_res);
if (err != 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to configure txqs\n");
return err;
}
- err = hinic5_configure_rxqs(nic_dev, total_num_qps,
- q_params->rq_depth, q_params->rxqs_res);
+ err = hinic5_configure_rxqs(nic_dev, total_num_qps, q_params->rq_depth,
+ q_params->rxqs_res);
if (err != 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to configure rxqs\n");
@@ -190,11 +212,12 @@ static void config_dcb_qps_map(struct hinic5_nic_dev *nic_dev)
/* For now, we don't support to change num_cos */
if (num_cos > nic_dev->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC5_DCB_ENABLE, &nic_dev->flags);
- clear_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_hinic5_vram->flags);
+ clear_bit(HINIC5_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -208,8 +231,7 @@ static int hinic5_configure(struct hinic5_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
- int is_in_kexec = hinic5_vram_get_kexec_flag();
-
+ int is_in_kexec = vram5_get_kexec_flag();
if (is_in_kexec == 0) {
err = hinic5_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
if (err != 0) {
@@ -221,7 +243,8 @@ static int hinic5_configure(struct hinic5_nic_dev *nic_dev)
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic5_rx_configure(netdev, test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic5_rx_configure(
+ netdev, test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
if (err != 0) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -253,7 +276,8 @@ static u16 hinic5_qp_irq_change(struct hinic5_nic_dev *nic_dev,
&qps_irq_info[nic_dev->num_qp_irq],
&resp_irq_num);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irqs\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc irqs\n");
return nic_dev->num_qp_irq;
}
@@ -279,7 +303,8 @@ static void config_dcb_num_qps(struct hinic5_nic_dev *nic_dev,
{
u8 num_cos = q_params->num_cos;
- if (num_cos == 0 || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if ((num_cos == 0) || num_cos > nic_dev->cos_config_num_max ||
+ num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic5_update_qp_cos_cfg(nic_dev);
@@ -288,27 +313,38 @@ static void config_dcb_num_qps(struct hinic5_nic_dev *nic_dev,
int hinic5_set_usr_qps_num(struct net_device *netdev, u16 usr_qps_num)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
-
if (usr_qps_num + nic_dev->q_params.num_qps > nic_dev->max_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "The usr qps num is too big, usr qps num: %u, knl qps num: %u\n",
- usr_qps_num, nic_dev->q_params.num_qps);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "The usr qps num is too big, usr qps num: %u, knl qps num: %u\n",
+ usr_qps_num, nic_dev->q_params.num_qps);
return -EINVAL;
}
nic_dev->usr_qps_num = usr_qps_num;
return 0;
}
+u16 hinic5_get_usr_qps_num(struct net_device *netdev)
+{
+ struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
+
+ return nic_dev->usr_qps_num;
+}
+
static void hinic5_knl_qps_num_check(struct hinic5_nic_dev *nic_dev)
{
- /* nic_dev->usr_qps_num is configured by product side */
- if (nic_dev->usr_qps_num == 0)
+ /* nic_dev->usr_qps_num由产品侧配置 */
+ if (nic_dev->usr_qps_num == 0) {
return;
- if (nic_dev->usr_qps_num + nic_dev->q_params.num_qps > nic_dev->max_qps) {
- nic_dev->q_params.num_qps = nic_dev->max_qps - nic_dev->usr_qps_num;
- nicif_warn(nic_dev, drv, nic_dev->netdev,
- "Can not get enough knl qps, adjust kernel qps num to %u\n",
- nic_dev->q_params.num_qps);
+ }
+ if (nic_dev->usr_qps_num + nic_dev->q_params.num_qps >
+ nic_dev->max_qps) {
+ nic_dev->q_params.num_qps =
+ nic_dev->max_qps - nic_dev->usr_qps_num;
+ nicif_warn(
+ nic_dev, drv, nic_dev->netdev,
+ "Can not get enough knl qps, adjust kernel qps num to %u\n",
+ nic_dev->q_params.num_qps);
}
}
@@ -318,11 +354,12 @@ static void hinic5_config_num_qps(struct hinic5_nic_dev *nic_dev,
u16 alloc_num_irq, cur_num_irq;
u16 dst_num_irq;
- /* Validate knl qps based on usr qps */
+ /* 根据 usr qps 校验 knl qps */
(void)hinic5_knl_qps_num_check(nic_dev);
- if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) == 0)
+ if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) == 0) {
q_params->num_qps = 1;
+ }
config_dcb_num_qps(nic_dev, q_params, q_params->num_qps);
if (nic_dev->num_qp_irq >= q_params->num_qps + q_params->xdp_qps)
@@ -330,21 +367,26 @@ static void hinic5_config_num_qps(struct hinic5_nic_dev *nic_dev,
cur_num_irq = nic_dev->num_qp_irq;
- alloc_num_irq = hinic5_qp_irq_change(nic_dev, q_params->num_qps + q_params->xdp_qps);
+ alloc_num_irq = hinic5_qp_irq_change(
+ nic_dev, q_params->num_qps + q_params->xdp_qps);
if (alloc_num_irq < q_params->num_qps + q_params->xdp_qps) {
if (q_params->xdp_qps != 0) {
- /* Enabling XDP and the number of XDP and kernel-equalized queues. */
- q_params->num_qps = alloc_num_irq / XDP_QPS_NUM_EXPANSION;
- q_params->xdp_qps = alloc_num_irq / XDP_QPS_NUM_EXPANSION;
+ /* 使能XDP,XDP和内核平分队列数 */
+ q_params->num_qps =
+ alloc_num_irq / XDP_QPS_NUM_EXPANSION;
+ q_params->xdp_qps =
+ alloc_num_irq / XDP_QPS_NUM_EXPANSION;
} else {
q_params->num_qps = alloc_num_irq;
}
config_dcb_num_qps(nic_dev, q_params, q_params->num_qps);
nicif_warn(nic_dev, drv, nic_dev->netdev,
- "Can not get enough irqs, adjust num_qps to %u\n", q_params->num_qps);
+ "Can not get enough irqs, adjust num_qps to %u\n",
+ q_params->num_qps);
/* The current irq may be in use, we must keep it */
- dst_num_irq = (u16)max_t(u16, cur_num_irq, q_params->num_qps + q_params->xdp_qps);
+ dst_num_irq = (u16)max_t(u16, cur_num_irq,
+ q_params->num_qps + q_params->xdp_qps);
hinic5_qp_irq_change(nic_dev, dst_num_irq);
}
@@ -363,12 +405,16 @@ static int hinic5_setup_num_qps(struct hinic5_nic_dev *nic_dev)
irq_size = sizeof(*nic_dev->qps_irq_info) * nic_dev->max_qps;
if (irq_size == 0) {
- nicif_err(nic_dev, drv, netdev, "Cannot allocate zero size entries\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Cannot allocate zero size entries\n");
return -EINVAL;
}
nic_dev->qps_irq_info = kzalloc(irq_size, GFP_KERNEL);
- if (!nic_dev->qps_irq_info)
+ if (nic_dev->qps_irq_info == NULL) {
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to alloc qps_irq_info\n");
return -ENOMEM;
+ }
hinic5_config_num_qps(nic_dev, &nic_dev->q_params);
@@ -386,44 +432,57 @@ static void hinic5_destroy_num_qps(struct hinic5_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic5_set_flow_bifurcation_group_num(struct net_device *netdev, u8 group_num)
+int hinic5_set_flow_bifurcation_group_num(struct net_device *netdev,
+ u8 group_num)
{
int err;
u8 enable_queue_pooling;
struct hinic5_nic_dev *nic_dev = NULL;
- if (!netdev)
+ if (netdev == NULL) {
return -ENODEV;
+ }
nic_dev = netdev_priv(netdev);
- if (group_num < HINIC5_GROUP_NUMBER_MIN || group_num > HINIC5_GROUP_NUMBER_MAX) {
- nicif_err(nic_dev, drv, netdev, "The group number: %d is out of [%d, %d].\n",
- group_num, HINIC5_GROUP_NUMBER_MIN, HINIC5_GROUP_NUMBER_MAX);
+ if (group_num < HINIC5_GROUP_NUMBER_MIN ||
+ group_num > HINIC5_GROUP_NUMBER_MAX) {
+ nicif_err(nic_dev, drv, netdev,
+ "The group number: %d is out of [%d, %d].\n",
+ group_num, HINIC5_GROUP_NUMBER_MIN,
+ HINIC5_GROUP_NUMBER_MAX);
return -EINVAL;
}
nic_dev->flow_bifur_group_num = (u8)roundup_pow_of_two(group_num);
if (nic_dev->flow_bifur_group_num == 0) {
- nicif_err(nic_dev, drv, netdev, "The value of flow_bifur_group_num: %d is 0\n",
+ nicif_err(nic_dev, drv, netdev,
+ "The value of flow_bifur_group_num: %d is 0\n",
nic_dev->flow_bifur_group_num);
return -EINVAL;
}
- enable_queue_pooling = nic_dev->flow_bifur_group_num > HINIC5_GROUP_NUMBER_MIN ? 1 : 0;
+ enable_queue_pooling =
+ nic_dev->flow_bifur_group_num > HINIC5_GROUP_NUMBER_MIN ? 1 : 0;
hinic5_set_queue_pooling(nic_dev->hwdev, enable_queue_pooling);
- if (nic_dev->q_params.num_qps > (nic_dev->max_qps / nic_dev->flow_bifur_group_num)) {
- nicif_err(nic_dev, drv, netdev,
- "The value of qp_nums: %d in use is greater than (max_qps / group_num): %d\n",
- nic_dev->q_params.num_qps,
- (nic_dev->max_qps / nic_dev->flow_bifur_group_num));
+ if (nic_dev->q_params.num_qps >
+ (nic_dev->max_qps / nic_dev->flow_bifur_group_num)) {
+ nicif_err(
+ nic_dev, drv, netdev,
+ "The value of qp_nums: %d in use is greater than (max_qps / group_num): %d\n",
+ nic_dev->q_params.num_qps,
+ (nic_dev->max_qps / nic_dev->flow_bifur_group_num));
return -EINVAL;
}
- nic_dev->usr_qps_num = nic_dev->max_qps - nic_dev->max_qps / nic_dev->flow_bifur_group_num;
+ nic_dev->usr_qps_num = nic_dev->max_qps -
+ nic_dev->max_qps / nic_dev->flow_bifur_group_num;
- err = hinic5_rx_configure(netdev, test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic5_rx_configure(
+ netdev, test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to configure rx when switch flow bifur group num.\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Failed to configure rx when switch flow bifur group num.\n");
return err;
}
return 0;
@@ -438,40 +497,51 @@ int hinic5_cfg_flow_bifurcation_paras(struct net_device *netdev, u8 op_code,
u16 indir_start;
struct hinic5_nic_dev *nic_dev = NULL;
- if (!netdev)
+ if (netdev == NULL) {
return -ENODEV;
+ }
nic_dev = netdev_priv(netdev);
- if (group_id < HINIC5_GROUP_NUMBER_MIN || group_id > nic_dev->flow_bifur_group_num) {
- nicif_err(nic_dev, drv, netdev,
- "The group id: %u is invalid, current group num: %u\n",
- group_id, nic_dev->flow_bifur_group_num);
+ if (group_id < HINIC5_GROUP_NUMBER_MIN ||
+ group_id >= nic_dev->flow_bifur_group_num) {
+ nicif_err(
+ nic_dev, drv, netdev,
+ "The group id: %u is invalid, current group num: %u\n",
+ group_id, nic_dev->flow_bifur_group_num);
return -EINVAL;
}
- if (!indir) {
+ if (indir == NULL) {
nicif_err(nic_dev, drv, netdev, "The indir is NULL\n");
return -EINVAL;
}
- expect_indir_length = NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
+ expect_indir_length =
+ NIC_RSS_INDIR_SIZE / nic_dev->flow_bifur_group_num;
if (indir_length != expect_indir_length) {
- nicif_err(nic_dev, drv, netdev,
- "The indir_length: %u is invalid, expect_indir_length: %u\n",
- indir_length, expect_indir_length);
+ nicif_err(
+ nic_dev, drv, netdev,
+ "The indir_length: %u is invalid, expect_indir_length: %u\n",
+ indir_length, expect_indir_length);
return -EINVAL;
}
indir_start = group_id * indir_length;
if (op_code == 0) {
- memcpy(indir, nic_dev->rss_indir + indir_start, sizeof(u32) * indir_length);
+ (void)memcpy_s(indir, sizeof(u32) * indir_length,
+ nic_dev->rss_indir + indir_start,
+ sizeof(u32) * indir_length);
return 0;
}
- memcpy(nic_dev->rss_indir + indir_start, indir, sizeof(u32) * indir_length);
+ (void)memcpy_s(nic_dev->rss_indir + indir_start,
+ sizeof(u32) * indir_length, indir,
+ sizeof(u32) * indir_length);
err = hinic5_rss_set_indir_tbl(nic_dev->hwdev, nic_dev->rss_indir);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to set rss indir table when cfg flow bifur.\n");
+ nicif_err(
+ nic_dev, drv, netdev,
+ "Failed to set rss indir table when cfg flow bifur.\n");
return -EFAULT;
}
return 0;
@@ -543,9 +613,10 @@ static void hinic5_print_link_message(struct hinic5_nic_dev *nic_dev,
((link_status != 0) ? "up" : "down"));
}
-static int hinic5_alloc_channel_resources(struct hinic5_nic_dev *nic_dev,
- struct hinic5_dyna_qp_params *qp_params,
- struct hinic5_dyna_txrxq_params *trxq_params)
+static int
+hinic5_alloc_channel_resources(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_qp_params *qp_params,
+ struct hinic5_dyna_txrxq_params *trxq_params)
{
int err;
@@ -557,13 +628,15 @@ static int hinic5_alloc_channel_resources(struct hinic5_nic_dev *nic_dev,
err = hinic5_alloc_qps(nic_dev->hwdev, nic_dev->qps_irq_info,
qp_params);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc qps\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc qps\n");
return err;
}
err = hinic5_alloc_txrxq_resources(nic_dev, trxq_params);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc txrxq resources\n");
hinic5_free_qps(nic_dev->hwdev, qp_params);
return err;
}
@@ -571,9 +644,10 @@ static int hinic5_alloc_channel_resources(struct hinic5_nic_dev *nic_dev,
return 0;
}
-static void hinic5_free_channel_resources(struct hinic5_nic_dev *nic_dev,
- struct hinic5_dyna_qp_params *qp_params,
- struct hinic5_dyna_txrxq_params *trxq_params)
+static void
+hinic5_free_channel_resources(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_qp_params *qp_params,
+ struct hinic5_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic5_free_txrxq_resources(nic_dev, trxq_params);
@@ -589,25 +663,29 @@ static int hinic5_open_channel(struct hinic5_nic_dev *nic_dev,
err = hinic5_init_qps(nic_dev->hwdev, qp_params);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to init qps\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to init qps\n");
return err;
}
err = hinic5_configure_txrxqs(nic_dev, trxq_params);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to configure txrxqs\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to configure txrxqs\n");
goto cfg_txrxqs_err;
}
err = hinic5_qps_irq_init(nic_dev);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to init txrxq irq\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to init txrxq irq\n");
goto init_qp_irq_err;
}
err = hinic5_configure(nic_dev);
if (err != 0) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to init txrxq irq\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to init txrxq irq\n");
goto configure_err;
}
@@ -642,8 +720,9 @@ int hinic5_vport_up(struct hinic5_nic_dev *nic_dev)
int err;
err = hinic5_cache_out_qps_res(nic_dev->hwdev);
- if (err != 0)
+ if (err != 0) {
return err;
+ }
glb_func_id = hinic5_global_func_id(nic_dev->hwdev);
err = hinic5_set_vport_enable(nic_dev->hwdev, glb_func_id, true,
@@ -668,14 +747,15 @@ int hinic5_vport_up(struct hinic5_nic_dev *nic_dev)
netif_carrier_on(netdev);
} else {
err = hinic5_get_link_state(nic_dev->hwdev, &link_status);
- if (err == 0 && link_status != 0)
+ if ((err == 0) && (link_status != 0))
netif_carrier_on(netdev);
}
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC5_MODERATONE_DELAY);
if (test_bit(HINIC5_RXQ_RECOVERY, &nic_dev->flags) != 0)
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work,
+ HZ);
hinic5_print_link_message(nic_dev, link_status);
@@ -712,7 +792,8 @@ void hinic5_vport_down(struct hinic5_nic_dev *nic_dev)
hinic5_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
if (nic_dev->state != 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Skip changing mag status!\n");
else
hinic5_maybe_set_port_state(nic_dev, false);
@@ -727,11 +808,13 @@ void hinic5_vport_down(struct hinic5_nic_dev *nic_dev)
*/
msleep(nic_dev->timeout.wait_flush_qp_res_timeout);
- if (nic_dev->usr_qps_num > 0)
- hinic5_flush_qps_res_by_nums(nic_dev->hwdev,
- nic_dev->max_qps - nic_dev->usr_qps_num);
- else
+ if (nic_dev->usr_qps_num > 0) {
+ hinic5_flush_qps_res_by_nums(
+ nic_dev->hwdev,
+ nic_dev->max_qps - nic_dev->usr_qps_num);
+ } else {
hinic5_flush_qps_res(nic_dev->hwdev);
+ }
}
}
@@ -740,8 +823,8 @@ int hinic5_change_channel_settings(struct hinic5_nic_dev *nic_dev,
hinic5_reopen_handler reopen_handler,
const void *priv_data)
{
- struct hinic5_dyna_qp_params new_qp_params = {0};
- struct hinic5_dyna_qp_params cur_qp_params = {0};
+ struct hinic5_dyna_qp_params new_qp_params = { 0 };
+ struct hinic5_dyna_qp_params cur_qp_params = { 0 };
int err;
u16 num_qps;
@@ -762,8 +845,9 @@ int hinic5_change_channel_settings(struct hinic5_nic_dev *nic_dev,
&nic_dev->q_params);
}
num_qps = trxq_params->num_qps + trxq_params->xdp_qps;
- if (nic_dev->num_qp_irq > num_qps)
+ if (nic_dev->num_qp_irq > num_qps) {
hinic5_qp_irq_change(nic_dev, num_qps);
+ }
nic_dev->q_params = *trxq_params;
err = hinic5_open_channel(nic_dev, &new_qp_params, trxq_params);
@@ -775,7 +859,8 @@ int hinic5_change_channel_settings(struct hinic5_nic_dev *nic_dev,
goto vport_up_err;
clear_bit(HINIC5_CHANGE_RES_INVALID, &nic_dev->flags);
- nicif_info(nic_dev, drv, nic_dev->netdev, "Change channel settings success\n");
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Change channel settings success\n");
return 0;
@@ -791,21 +876,23 @@ int hinic5_change_channel_settings(struct hinic5_nic_dev *nic_dev,
int hinic5_open(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic5_dyna_qp_params qp_params = {0};
+ struct hinic5_dyna_qp_params qp_params = { 0 };
int err;
- err = hinic5_wait_for_devices_flush(NULL, 0, NULL);
+ err = wait5_for_devices_flush(NULL, 0, NULL);
if (err != 0)
return err;
if (test_bit(HINIC5_INTF_UP, &nic_dev->flags) != 0) {
- nicif_info(nic_dev, drv, netdev, "Netdev already open, do nothing\n");
+ nicif_info(nic_dev, drv, netdev,
+ "Netdev already open, do nothing\n");
return 0;
}
err = hinic5_init_nicio_res(nic_dev->hwdev, nic_dev->usr_qps_num);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to init nicio resources\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to init nicio resources\n");
return err;
}
@@ -849,15 +936,16 @@ int hinic5_open(struct net_device *netdev)
}
#ifdef HAVE_XDP_SUPPORT
-int hinic5_set_xdp_num(struct hinic5_nic_dev *nic_dev, struct hinic5_dyna_txrxq_params *trxq_params)
+int hinic5_set_xdp_num(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_dyna_txrxq_params *trxq_params)
{
if (hinic5_is_xdp_enable(nic_dev)) {
trxq_params->xdp_qps = trxq_params->num_qps;
- /* When XDP is enabled,
- * check that kernel queue num plus XDP queue num is less than max queue num
- */
- if (trxq_params->num_qps + trxq_params->xdp_qps > nic_dev->max_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to change num qps\n");
+ /* 使能 XDP 的情况,需要检查内核队列数和XDP队列数和小于最大队列数 */
+ if (trxq_params->num_qps + trxq_params->xdp_qps >
+ nic_dev->max_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to change num qps\n");
return -EINVAL;
}
} else {
@@ -870,7 +958,7 @@ int hinic5_set_xdp_num(struct hinic5_nic_dev *nic_dev, struct hinic5_dyna_txrxq_
int hinic5_safe_switch_channels(struct hinic5_nic_dev *nic_dev)
{
int err;
- struct hinic5_dyna_txrxq_params q_params = {0};
+ struct hinic5_dyna_txrxq_params q_params = { 0 };
q_params = nic_dev->q_params;
q_params.sq_depth = nic_dev->q_params.sq_depth;
@@ -889,10 +977,11 @@ int hinic5_safe_switch_channels(struct hinic5_nic_dev *nic_dev)
int hinic5_close(struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic5_dyna_qp_params qp_params = {0};
+ struct hinic5_dyna_qp_params qp_params = { 0 };
if (test_and_clear_bit(HINIC5_INTF_UP, &nic_dev->flags) == 0) {
- nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
+ nicif_info(nic_dev, drv, netdev,
+ "Netdev already close, do nothing\n");
return 0;
}
@@ -924,10 +1013,10 @@ int hinic5_flush_nic_dev(void *priv_data)
int err;
net_dev = hinic5_get_netdev_by_lld(lld_dev);
- if (!net_dev)
+ if (net_dev == NULL)
return -ENODEV;
- is_in_kexec = hinic5_vram_get_kexec_flag();
+ is_in_kexec = vram5_get_kexec_flag();
nic_dev = netdev_priv(net_dev);
@@ -938,8 +1027,8 @@ int hinic5_flush_nic_dev(void *priv_data)
return err;
}
-#define IPV6_ADDR_LEN 4
-#define PKT_INFO_LEN 9
+#define IPV6_ADDR_LEN 4
+#define PKT_INFO_LEN 9
#define BITS_PER_TUPLE 32
static u32 calc_xor_rss(u8 *rss_tuple, u32 len)
{
@@ -960,24 +1049,25 @@ static u32 calc_toep_rss(const u32 *rss_tuple, u32 len, const u32 *rss_key)
for (i = 1; i <= len; i++) {
for (j = 0; j < BITS_PER_TUPLE; j++)
- if ((rss_tuple[i - 1] & ((u32)1 <<
- (u32)((BITS_PER_TUPLE - 1) - j))) != 0)
+ if ((rss_tuple[i - 1] &
+ ((u32)1 << (u32)((BITS_PER_TUPLE - 1) - j))) != 0)
rss ^= (rss_key[i - 1] << j) |
- (u32)((u64)rss_key[i] >>
- (BITS_PER_TUPLE - j));
+ (u32)((u64)rss_key[i] >>
+ (BITS_PER_TUPLE - j));
}
return rss;
}
-#define RSS_VAL(val, type) \
+#define RSS_VAL(val, type) \
(((type) == HINIC5_RSS_HASH_ENGINE_TYPE_TOEP) ? ntohl(val) : (val))
-static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tuple,
- u8 hash_engine, u32 *len, unsigned char *l3_hdr)
+static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tuple, u8 hash_engine,
+ u32 *len, unsigned char *l3_hdr)
{
unsigned char *l4_hdr = (skb->encapsulation != 0) ?
- skb_inner_transport_header(skb) : skb_transport_header(skb);
+ skb_inner_transport_header(skb) :
+ skb_transport_header(skb);
struct ipv6hdr *ipv6hdr = (struct ipv6hdr *)l3_hdr;
u32 *saddr = (u32 *)(u8 *)&ipv6hdr->saddr;
u32 *daddr = (u32 *)(u8 *)&ipv6hdr->daddr;
@@ -992,14 +1082,14 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tuple,
*len = IPV6_ADDR_LEN + IPV6_ADDR_LEN;
/* IPv6 packets with extension headers(include IPv6 fragment packets)
- * re hashed according to L3(s_ip&d_ip), align with ucode RSS.
- */
+ are hashed according to L3(s_ip&d_ip), align with ucode RSS. */
if ((uintptr_t)l3_hdr + sizeof(*ipv6hdr) == (uintptr_t)l4_hdr)
return ipv6hdr->nexthdr;
return 0;
}
-static u32 calc_rss_prepare(struct sk_buff *skb, u32 *rss_tuple, struct hinic5_nic_dev *nic_dev)
+static u32 calc_rss_prepare(struct sk_buff *skb, u32 *rss_tuple,
+ struct hinic5_nic_dev *nic_dev)
{
u32 len = 0;
u8 l4_proto = 0;
@@ -1009,50 +1099,82 @@ static u32 calc_rss_prepare(struct sk_buff *skb, u32 *rss_tuple, struct hinic5_n
u8 tunnel_flag = skb->encapsulation;
struct nic_rss_type rss_type = nic_dev->rss_type;
u8 hash_engine = nic_dev->rss_hash_engine;
-
- l3_hdr = (tunnel_flag != 0) ? skb_inner_network_header(skb) : skb_network_header(skb);
+ l3_hdr = (tunnel_flag != 0) ? skb_inner_network_header(skb) :
+ skb_network_header(skb);
iphdr = (struct iphdr *)l3_hdr;
if (iphdr->version == IPV4_VERSION) {
rss_tuple[len++] = RSS_VAL(iphdr->daddr, hash_engine);
rss_tuple[len++] = RSS_VAL(iphdr->saddr, hash_engine);
- /* IP fragmented packets are hashed according to L3(s_ip&d_ip),
- * align with ucode RSS.
- */
+ /* IP fragmented packets are hashed according to L3(s_ip&d_ip), align with ucode RSS. */
l4_proto = ip_is_fragment(iphdr) ? 0 : iphdr->protocol;
} else if (iphdr->version == IPV6_VERSION) {
- l4_proto = parse_ipv6_info(skb, (u32 *)rss_tuple, hash_engine, &len, l3_hdr);
+ l4_proto = parse_ipv6_info(skb, (u32 *)rss_tuple, hash_engine,
+ &len, l3_hdr);
} else {
return len;
}
if ((iphdr->version == IPV4_VERSION &&
- ((l4_proto == IPPROTO_UDP && rss_type.udp_ipv4 != 0) ||
- (l4_proto == IPPROTO_TCP && rss_type.tcp_ipv4 != 0))) ||
+ ((l4_proto == IPPROTO_UDP && (rss_type.udp_ipv4 != 0)) ||
+ (l4_proto == IPPROTO_TCP && (rss_type.tcp_ipv4 != 0)))) ||
(iphdr->version == IPV6_VERSION &&
- ((l4_proto == IPPROTO_UDP && rss_type.udp_ipv6 != 0) ||
- (l4_proto == IPPROTO_TCP && rss_type.tcp_ipv6 != 0)))) {
- l4_hdr = (tunnel_flag != 0) ?
- skb_inner_transport_header(skb) : skb_transport_header(skb);
+ ((l4_proto == IPPROTO_UDP && (rss_type.udp_ipv6 != 0)) ||
+ (l4_proto == IPPROTO_TCP && (rss_type.tcp_ipv6 != 0))))) {
+ l4_hdr = (tunnel_flag != 0) ? skb_inner_transport_header(skb) :
+ skb_transport_header(skb);
/* High 16 bits are dport, low 16 bits are sport. */
rss_tuple[len++] = ((u32)ntohs(*((u16 *)l4_hdr + 1U)) << 16) |
- ntohs(*(u16 *)l4_hdr);
+ ntohs(*(u16 *)l4_hdr);
} /* rss_type.ipv4 and rss_type.ipv6 default on. */
return len;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u32 select_queue_tunnel_hash(struct sk_buff *skb, struct iphdr *iphdr,
+ u8 hash_engine, u32 *rss_tuple,
+ struct hinic5_nic_dev *nic_dev)
+{
+ struct ipv6hdr *ipv6hdr = NULL;
+ u32 *saddr = NULL;
+ u32 *daddr = NULL;
+ u32 len = 0;
+
+ if (iphdr->version == IPV4_VERSION) {
+ if (ip_is_fragment(iphdr)) {
+ rss_tuple[len++] = RSS_VAL(iphdr->daddr, hash_engine);
+ rss_tuple[len++] = RSS_VAL(iphdr->saddr, hash_engine);
+ return len;
+ }
+ } else if (iphdr->version == IPV6_VERSION) {
+ ipv6hdr = ipv6_hdr(skb);
+ saddr = (u32 *)(u8 *)&ipv6hdr->saddr;
+ daddr = (u32 *)(u8 *)&ipv6hdr->daddr;
+ if (skb_network_header(skb) + sizeof(*ipv6hdr) !=
+ skb_transport_header(skb)) {
+ for (len = 0; len < IPV6_ADDR_LEN; len++) {
+ rss_tuple[len] =
+ RSS_VAL(daddr[len], hash_engine);
+ /* The offset of the sport relative to the dport is 4 */
+ rss_tuple[len + IPV6_ADDR_LEN] =
+ RSS_VAL(saddr[len], hash_engine);
+ }
+ return (len + IPV6_ADDR_LEN);
+ }
+ }
+
+ return calc_rss_prepare(skb, rss_tuple, nic_dev);
+}
+
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(dev);
struct iphdr *iphdr = NULL;
- struct ipv6hdr *ipv6hdr = NULL;
- u32 rss_tuple[PKT_INFO_LEN] = {0};
+ u32 rss_tuple[PKT_INFO_LEN] = { 0 };
u32 len = 0;
u32 hash = 0;
- u32 *saddr = NULL;
- u32 *daddr = NULL;
u8 hash_engine = nic_dev->rss_hash_engine;
if (skb_rx_queue_recorded(skb)) {
@@ -1066,46 +1188,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
iphdr = ip_hdr(skb);
/* If the tunnel packet has outer IP fragmentation or an IPv6 extension header,
- * it should be hashed directly at the L3.
- */
+ it should be hashed directly at the L3. */
if (skb->encapsulation != 0) {
- if (iphdr->version == IPV4_VERSION) {
- if (ip_is_fragment(iphdr)) {
- rss_tuple[len++] = RSS_VAL(iphdr->daddr, hash_engine);
- rss_tuple[len++] = RSS_VAL(iphdr->saddr, hash_engine);
- goto hash_by_l3;
- }
- } else if (iphdr->version == IPV6_VERSION) {
- ipv6hdr = ipv6_hdr(skb);
- saddr = (u32 *)(u8 *)&ipv6hdr->saddr;
- daddr = (u32 *)(u8 *)&ipv6hdr->daddr;
- if (skb_network_header(skb) + sizeof(*ipv6hdr) !=
- skb_transport_header(skb)) {
- for (len = 0; len < IPV6_ADDR_LEN; len++) {
- rss_tuple[len] = RSS_VAL(daddr[len], hash_engine);
- /* The offset of the sport relative to the dport is 4 */
- rss_tuple[(u32)(len + IPV6_ADDR_LEN)] =
- RSS_VAL(saddr[len], hash_engine);
- }
- len += IPV6_ADDR_LEN;
- goto hash_by_l3;
- }
- } else {
+ len = select_queue_tunnel_hash(skb, iphdr, hash_engine,
+ rss_tuple, nic_dev);
+ if (len == 0)
+ return HINIC5_INVALID_QUEUE;
+ } else {
+ len = calc_rss_prepare(skb, rss_tuple, nic_dev);
+ if (len == 0)
return HINIC5_INVALID_QUEUE;
- }
}
- /* Calculate the RSS tuple and length for
- * the inner layer of tunnel packets or non-tunnel packets.
- */
- len = calc_rss_prepare(skb, (u32 *)rss_tuple, nic_dev);
- if (len == 0)
- return HINIC5_INVALID_QUEUE;
-
-hash_by_l3:
if (hash_engine == HINIC5_RSS_HASH_ENGINE_TYPE_TOEP)
- hash = calc_toep_rss((u32 *)rss_tuple, len,
- nic_dev->rss_hkey_be);
+ hash = calc_toep_rss(rss_tuple, len, nic_dev->rss_hkey_be);
else
hash = calc_xor_rss((u8 *)rss_tuple, len * (u32)sizeof(u32));
@@ -1113,14 +1209,16 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic5_get_dscp_up(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic5_get_dscp_up(struct hinic5_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
return nic_dev->hw_dcb_cfg.default_cos;
return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
@@ -1153,7 +1251,8 @@ static u16 hinic5_select_queue(struct net_device *netdev, struct sk_buff *skb)
u8 cos, qp_num;
if (test_bit(HINIC5_SAME_RXTX, &nic_dev->flags) != 0) {
- txq = select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ txq = select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
if (txq != HINIC5_INVALID_QUEUE)
return txq;
}
@@ -1174,7 +1273,9 @@ static u16 hinic5_select_queue(struct net_device *netdev, struct sk_buff *skb)
if (test_bit(HINIC5_DCB_ENABLE, &nic_dev->flags) != 0) {
if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
if (skb->vlan_tci != 0)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = nic_dev->hw_dcb_cfg
+ .pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
cos = nic_dev->hw_dcb_cfg.default_cos;
} else {
@@ -1182,18 +1283,27 @@ static u16 hinic5_select_queue(struct net_device *netdev, struct sk_buff *skb)
}
qp_num = (nic_dev->hw_dcb_cfg.cos_qp_num[cos] != 0) ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] :
+ 0;
txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
}
-static void hinic5_get_tx_stats64(struct hinic5_nic_dev *nic_dev,
- u64 *bytes, u64 *packets, u64 *dropped, unsigned int *start)
+static void hinic5_get_tx_stats64(struct hinic5_nic_dev *nic_dev, void *stats)
{
+#ifdef HAVE_NDO_GET_STATS64
+ struct rtnl_link_stats64 *_stats = stats;
+#else
+ struct net_device_stats *_stats = stats;
+#endif
struct hinic5_txq_stats *txq_stats = NULL;
struct hinic5_txq *txq = NULL;
+ unsigned int start;
+ u64 packets = 0;
+ u64 dropped = 0;
+ u64 bytes = 0;
int i;
for (i = 0; i < nic_dev->max_qps; i++) {
@@ -1203,12 +1313,56 @@ static void hinic5_get_tx_stats64(struct hinic5_nic_dev *nic_dev,
txq = &nic_dev->txqs[i];
txq_stats = &txq->txq_stats;
do {
- *start = u64_stats_fetch_begin(&txq_stats->syncp);
- *bytes += txq_stats->bytes;
- *packets += txq_stats->packets;
- *dropped += txq_stats->dropped;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, *start));
+ start = u64_stats_fetch_begin(&txq_stats->syncp);
+ bytes += txq_stats->bytes;
+ packets += txq_stats->packets;
+ dropped += txq_stats->dropped;
+ } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ }
+
+ _stats->tx_packets = packets;
+ _stats->tx_bytes = bytes;
+ _stats->tx_dropped = dropped;
+}
+
+static void hinic5_get_rx_stats64(struct hinic5_nic_dev *nic_dev, void *stats)
+{
+#ifdef HAVE_NDO_GET_STATS64
+ struct rtnl_link_stats64 *_stats = stats;
+#else
+ struct net_device_stats *_stats = stats;
+#endif
+ u64 multi_cast = 0;
+ u64 packets = 0;
+ u64 dropped = 0;
+ u64 errors = 0;
+ u64 bytes = 0;
+ struct hinic5_rxq_stats *rxq_stats = NULL;
+ struct hinic5_rxq *rxq = NULL;
+ unsigned int start;
+ int i;
+
+ for (i = 0; i < nic_dev->max_qps; i++) {
+ if (!nic_dev->rxqs)
+ break;
+
+ rxq = &nic_dev->rxqs[i];
+ rxq_stats = &rxq->rxq_stats;
+ do {
+ start = u64_stats_fetch_begin(&rxq_stats->syncp);
+ bytes += rxq_stats->bytes;
+ packets += rxq_stats->packets;
+ errors += rxq_stats->csum_errors +
+ rxq_stats->other_errors;
+ dropped += rxq_stats->dropped;
+ multi_cast += rxq_stats->pkt_mc;
+ } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
}
+ _stats->rx_packets = packets;
+ _stats->rx_bytes = bytes;
+ _stats->rx_errors = errors;
+ _stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
+ _stats->multicast = multi_cast;
}
#ifdef HAVE_NDO_GET_STATS64
@@ -1216,8 +1370,8 @@ static void hinic5_get_tx_stats64(struct hinic5_nic_dev *nic_dev,
static void hinic5_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats)
#else
-static struct rtnl_link_stats64 *hinic5_get_stats64(struct net_device *netdev,
- struct rtnl_link_stats64 *stats)
+static struct rtnl_link_stats64 *
+hinic5_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
#endif
#else /* !HAVE_NDO_GET_STATS64 */
@@ -1232,52 +1386,14 @@ static struct net_device_stats *hinic5_get_stats(struct net_device *netdev)
struct net_device_stats *stats = &nic_dev->net_stats;
#endif /* HAVE_NETDEV_STATS_IN_NETDEV */
#endif /* HAVE_NDO_GET_STATS64 */
- struct hinic5_rxq_stats *rxq_stats = NULL;
- struct hinic5_rxq *rxq = NULL;
- u64 bytes, packets, dropped, errors, multi_cast;
- unsigned int start;
- int i;
-
- bytes = 0;
- packets = 0;
- dropped = 0;
- hinic5_get_tx_stats64(nic_dev, &bytes, &packets, &dropped, &start);
- /* Consistent with 1823V100, PF only to reduce channel pressure */
+ /* 读取硬件统计,使用workq确保过程中不会sleep */
if (!HINIC5_FUNC_IS_VF(nic_dev->hwdev)) {
queue_work(nic_dev->workq, &nic_dev->update_stats_work);
}
- stats->tx_packets = packets;
- stats->tx_bytes = bytes;
- stats->tx_dropped = dropped;
-
- bytes = 0;
- packets = 0;
- errors = 0;
- dropped = 0;
- multi_cast = 0;
- for (i = 0; i < nic_dev->max_qps; i++) {
- if (!nic_dev->rxqs)
- break;
-
- rxq = &nic_dev->rxqs[i];
- rxq_stats = &rxq->rxq_stats;
- do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
- bytes += rxq_stats->bytes;
- packets += rxq_stats->packets;
- errors += rxq_stats->csum_errors +
- rxq_stats->other_errors;
- dropped += rxq_stats->dropped;
- multi_cast += rxq_stats->pkt_mc;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
- }
- stats->rx_packets = packets;
- stats->rx_bytes = bytes;
- stats->rx_errors = errors;
- stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
- stats->multicast = multi_cast;
+ hinic5_get_tx_stats64(nic_dev, stats);
+ hinic5_get_rx_stats64(nic_dev, stats);
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1300,17 +1416,20 @@ static void hinic5_tx_timeout(struct net_device *netdev)
HINIC5_NIC_STATS_INC(nic_dev, netdev_tx_timeout);
nicif_err(nic_dev, drv, netdev, "Tx timeout\n");
- for (q_id = 0; q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; q_id++) {
+ for (q_id = 0;
+ q_id < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ q_id++) {
if (!netif_xmit_stopped(netdev_get_tx_queue(netdev, q_id)))
continue;
txq = &nic_dev->txqs[q_id];
sq = nic_dev->txqs[q_id].sq;
sw_pi = hinic5_get_sq_local_pi(sq);
hw_ci = hinic5_get_sq_hw_ci(sq);
- nicif_info(nic_dev, drv, netdev,
- "txq%u: sw_pi: %u, hw_ci: %u, sw_ci: %u, napi->state: 0x%lx.\n",
- q_id, sw_pi, hw_ci, hinic5_get_sq_local_ci(sq),
- nic_dev->q_params.irq_cfg[q_id].napi.state);
+ nicif_info(
+ nic_dev, drv, netdev,
+ "txq%u: sw_pi: %u, hw_ci: %u, sw_ci: %u, napi->state: 0x%lx.\n",
+ q_id, sw_pi, hw_ci, hinic5_get_sq_local_ci(sq),
+ nic_dev->q_params.irq_cfg[q_id].napi.state);
if (sw_pi != hw_ci) {
hw_err = true;
@@ -1322,7 +1441,8 @@ static void hinic5_tx_timeout(struct net_device *netdev)
set_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag);
}
-__weak int hinic5_change_mtu_pre_hook(struct net_device *netdev, int new_mtu)
+__attribute__((weak)) int hinic5_change_mtu_pre_hook(struct net_device *netdev,
+ int new_mtu)
{
return 0;
}
@@ -1332,8 +1452,9 @@ static int hinic5_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
- int is_in_kexec = hinic5_vram_get_kexec_flag();
-#if defined(HAVE_XDP_SUPPORT) && (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
+ int is_in_kexec = vram5_get_kexec_flag();
+#if defined(HAVE_XDP_SUPPORT) && \
+ (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
u32 xdp_max_mtu;
#endif
@@ -1344,11 +1465,13 @@ static int hinic5_change_mtu(struct net_device *netdev, int new_mtu)
}
if (is_in_kexec != 0) {
- nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ nicif_info(nic_dev, drv, netdev,
+ "Hotreplace skip change mtu\n");
return err;
}
-#if defined(HAVE_XDP_SUPPORT) && (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
+#if defined(HAVE_XDP_SUPPORT) && \
+ (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
if (hinic5_is_xdp_enable(nic_dev)) {
xdp_max_mtu = (u32)hinic5_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1361,19 +1484,20 @@ static int hinic5_change_mtu(struct net_device *netdev, int new_mtu)
err = hinic5_set_port_mtu(nic_dev->hwdev, (u16)mtu);
if (err != 0) {
- nicif_err(nic_dev, drv, netdev, "Failed to change port mtu to %d\n",
- new_mtu);
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to change port mtu to %d\n", new_mtu);
} else {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
- netdev->mtu, new_mtu);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Change mtu from %u to %d\n", netdev->mtu, new_mtu);
netdev->mtu = mtu;
- nic_dev->nic_hinic5_vram->hinic5_vram_mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
}
-__weak int hinic5_set_mac_addr_pre_hook(struct net_device *netdev, void *addr)
+__attribute__((weak)) int
+hinic5_set_mac_addr_pre_hook(struct net_device *netdev, void *addr)
{
return 0;
}
@@ -1395,12 +1519,12 @@ static int hinic5_set_mac_addr(struct net_device *netdev, void *addr)
if (ether_addr_equal(netdev->dev_addr, (const u8 *)saddr->sa_data)) {
nicif_info(nic_dev, drv, netdev,
- "Already using mac address %pM\n",
- saddr->sa_data);
+ "Already using mac address %pM\n", saddr->sa_data);
return 0;
}
- err = hinic5_update_mac(nic_dev->hwdev, nic_dev->netdev->dev_addr, (u8 *)saddr->sa_data, 0,
+ err = hinic5_update_mac(nic_dev->hwdev, nic_dev->netdev->dev_addr,
+ (u8 *)saddr->sa_data, 0,
hinic5_global_func_id(nic_dev->hwdev));
if (err != 0)
return err;
@@ -1428,27 +1552,31 @@ static int hinic5_udp_tunnel_port_config(struct net_device *netdev,
ret = hinic5_vxlan_port_config(nic_dev->hwdev, func_id,
dst_port, action, 0);
if (ret != 0 && ret != -EOPNOTSUPP) {
- nicif_warn(nic_dev, drv, netdev, "Setting vxlan port %u to device not supported\n",
- dst_port);
- break;
+ nicif_warn(
+ nic_dev, drv, netdev,
+ "Setting vxlan port %u to device not supported\n",
+ dst_port);
}
- fallthrough;
+ break;
default:
ret = -EINVAL;
+ break;
}
return ret;
}
#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_NDO_UDP_TUNNEL_ADD
-static void hinic5_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+static void hinic5_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
{
if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
return;
hinic5_udp_tunnel_port_config(netdev, ti, HINIC5_CMD_OP_ADD);
}
-static void hinic5_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+static void hinic5_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
{
if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
return;
@@ -1477,9 +1605,9 @@ static void
static int
#endif
hinic5_vlan_rx_add_vid(struct net_device *netdev,
- #if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
+#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
__always_unused __be16 proto,
- #endif
+#endif
u16 vid)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1521,9 +1649,9 @@ static void
static int
#endif
hinic5_vlan_rx_kill_vid(struct net_device *netdev,
- #if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
+#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
__always_unused __be16 proto,
- #endif
+#endif
u16 vid)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1532,7 +1660,7 @@ hinic5_vlan_rx_kill_vid(struct net_device *netdev,
int col, line;
int err = 0;
- col = VID_COL(nic_dev, vid);
+ col = VID_COL(nic_dev, vid);
line = (int)(VID_LINE(nic_dev, vid));
/* In the broadcast scenario, ucode finds the corresponding function
@@ -1586,11 +1714,13 @@ static int hinic5_vlan_restore(struct net_device *netdev)
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
- err = netdev->netdev_ops->ndo_vlan_rx_kill_vid(netdev,
- htons(ETH_P_8021Q), i);
+ err = netdev->netdev_ops->ndo_vlan_rx_kill_vid(
+ netdev, htons(ETH_P_8021Q), i);
if (err != 0) {
- hinic5_err(nic_dev, drv, "delete vlan %u failed, err code %d\n",
- i, err);
+ hinic5_err(
+ nic_dev, drv,
+ "delete vlan %u failed, err code %d\n",
+ i, err);
break;
}
#else
@@ -1598,11 +1728,13 @@ static int hinic5_vlan_restore(struct net_device *netdev)
#endif
} else if (vlandev && (vlan_bitmap[line] & (1UL << col)) == 0) {
#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
- err = netdev->netdev_ops->ndo_vlan_rx_add_vid(netdev,
- htons(ETH_P_8021Q), i);
+ err = netdev->netdev_ops->ndo_vlan_rx_add_vid(
+ netdev, htons(ETH_P_8021Q), i);
if (err != 0) {
- hinic5_err(nic_dev, drv, "restore vlan %u failed, err code %d\n",
- i, err);
+ hinic5_err(
+ nic_dev, drv,
+ "restore vlan %u failed, err code %d\n",
+ i, err);
break;
}
#else
@@ -1617,7 +1749,7 @@ static int hinic5_vlan_restore(struct net_device *netdev)
}
#endif
-#define SET_FEATURES_OP_STR(op) (((op) != 0) ? "Enable" : "Disable")
+#define SET_FEATURES_OP_STR(op) (((op) != 0) ? "Enable" : "Disable")
static int set_feature_rx_csum(struct hinic5_nic_dev *nic_dev,
netdev_features_t wanted_features,
@@ -1676,9 +1808,11 @@ static int set_feature_lro(struct hinic5_nic_dev *nic_dev,
if ((changed & NETIF_F_LRO) == 0)
return 0;
-#if defined(HAVE_XDP_SUPPORT) && (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
+#if defined(HAVE_XDP_SUPPORT) && \
+ (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
if (en && hinic5_is_xdp_enable(nic_dev)) {
- hinic5_err(nic_dev, drv, "Can not enable LRO when xdp is enable\n");
+ hinic5_err(nic_dev, drv,
+ "Can not enable LRO when xdp is enable\n");
*failed_features |= NETIF_F_LRO;
return -EINVAL;
}
@@ -1808,8 +1942,7 @@ static int hinic5_set_features(struct net_device *netdev,
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- return set_features(nic_dev, nic_dev->netdev->features,
- features);
+ return set_features(nic_dev, nic_dev->netdev->features, features);
}
int hinic5_set_hw_features(struct hinic5_nic_dev *nic_dev)
@@ -1851,7 +1984,8 @@ static int hinic5_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic5_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || vf >= hinic5_get_vf_num(adapter->lld_dev))
+ if (is_multicast_ether_addr(mac) ||
+ vf >= hinic5_get_vf_num(adapter->lld_dev))
return -EINVAL;
err = hinic5_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1864,19 +1998,20 @@ static int hinic5_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
else
nic_info(adapter->lld_dev->dev, "Deleting MAC on VF %d\n", vf);
- nic_info(adapter->lld_dev->dev, "Please reload the VF driver to make this change effective.");
+ nic_info(adapter->lld_dev->dev,
+ "Please reload the VF driver to make this change effective.");
return 0;
}
#ifdef IFLA_VF_MAX
-static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
- u16 vlan, u8 qos)
+static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf, u16 vlan,
+ u8 qos)
{
int err = 0;
u16 old_vlan = cur_vlanprio & VLAN_VID_MASK;
- if (vlan != 0 || qos != 0) {
+ if ((vlan != 0) || (qos != 0)) {
if (cur_vlanprio != 0) {
err = hinic5_kill_vf_vlan(hwdev, OS_VF_ID_TO_HW(vf));
if (err != 0)
@@ -1887,14 +2022,16 @@ static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
err = hinic5_kill_vf_vlan(hwdev, OS_VF_ID_TO_HW(vf));
}
- if (err == 0)
- err = hinic5_update_mac_vlan(hwdev, old_vlan, vlan, OS_VF_ID_TO_HW(vf));
+ if (err == 0) {
+ err = hinic5_update_mac_vlan(hwdev, old_vlan, vlan,
+ OS_VF_ID_TO_HW(vf));
+ }
return err;
}
-#define HINIC5_MAX_VLAN_ID 4094
-#define HINIC5_MAX_QOS_NUM 7
+#define HINIC5_MAX_VLAN_ID 4094
+#define HINIC5_MAX_QOS_NUM 7
#ifdef IFLA_VF_VLAN_INFO_MAX
static int hinic5_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
@@ -1916,8 +2053,8 @@ static int hinic5_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
return -EPROTONOSUPPORT;
#endif
vlanprio = vlan | (qos << HINIC5_VLAN_PRIORITY_SHIFT);
- cur_vlanprio = hinic5_vf_info_vlanprio(adapter->hwdev,
- OS_VF_ID_TO_HW(vf));
+ cur_vlanprio =
+ hinic5_vf_info_vlanprio(adapter->hwdev, OS_VF_ID_TO_HW(vf));
/* duplicate request, so just return success */
if (vlanprio == cur_vlanprio)
return 0;
@@ -1937,24 +2074,25 @@ static int hinic5_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
if (vf >= hinic5_get_vf_num(adapter->lld_dev))
return -EINVAL;
- cur_spoofchk = hinic5_vf_info_spoofchk(adapter->hwdev,
- OS_VF_ID_TO_HW(vf));
+ cur_spoofchk =
+ hinic5_vf_info_spoofchk(adapter->hwdev, OS_VF_ID_TO_HW(vf));
/* same request, so just return success */
if ((setting && cur_spoofchk) || (!setting && !cur_spoofchk))
return 0;
- err = hinic5_set_vf_spoofchk(adapter->hwdev,
- (u16)OS_VF_ID_TO_HW(vf), setting);
+ err = hinic5_set_vf_spoofchk(adapter->hwdev, (u16)OS_VF_ID_TO_HW(vf),
+ setting);
if (err == 0)
- nicif_info(adapter, drv, netdev, "Set VF %d spoofchk %s\n",
- vf, setting ? "on" : "off");
+ nicif_info(adapter, drv, netdev, "Set VF %d spoofchk %s\n", vf,
+ setting ? "on" : "off");
return err;
}
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic5_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic5_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic5_nic_dev *adapter = netdev_priv(netdev);
int err;
@@ -1963,17 +2101,17 @@ static int hinic5_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setti
if (vf >= hinic5_get_vf_num(adapter->lld_dev))
return -EINVAL;
- cur_trust = hinic5_get_vf_trust(adapter->hwdev,
- OS_VF_ID_TO_HW(vf));
+ cur_trust = hinic5_get_vf_trust(adapter->hwdev, OS_VF_ID_TO_HW(vf));
/* same request, so just return success */
if ((setting && cur_trust) || (!setting && !cur_trust))
return 0;
- err = hinic5_set_vf_trust(adapter->hwdev,
- (u16)OS_VF_ID_TO_HW(vf), setting);
+ err = hinic5_set_vf_trust(adapter->hwdev, (u16)OS_VF_ID_TO_HW(vf),
+ setting);
if (err == 0)
- nicif_info(adapter, drv, netdev, "Set VF %d trusted %s successfully\n",
- vf, setting ? "on" : "off");
+ nicif_info(adapter, drv, netdev,
+ "Set VF %d trusted %s successfully\n", vf,
+ setting ? "on" : "off");
else
nicif_err(adapter, drv, netdev, "Failed set VF %d trusted %s\n",
vf, setting ? "on" : "off");
@@ -1982,8 +2120,8 @@ static int hinic5_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setti
}
#endif
-static int hinic5_ndo_get_vf_config(struct net_device *netdev,
- int vf, struct ifla_vf_info *ivi)
+static int hinic5_ndo_get_vf_config(struct net_device *netdev, int vf,
+ struct ifla_vf_info *ivi)
{
struct hinic5_nic_dev *adapter = netdev_priv(netdev);
@@ -2005,14 +2143,14 @@ static int hinic5_ndo_get_vf_config(struct net_device *netdev,
**/
int hinic5_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
{
- static const char * const vf_link[] = {"auto", "enable", "disable"};
+ static const char *const vf_link[] = { "auto", "enable", "disable" };
struct hinic5_nic_dev *adapter = netdev_priv(netdev);
int err;
/* validate the request */
if (vf_id >= hinic5_get_vf_num(adapter->lld_dev)) {
- nicif_err(adapter, drv, netdev,
- "Invalid VF Identifier %d\n", vf_id);
+ nicif_err(adapter, drv, netdev, "Invalid VF Identifier %d\n",
+ vf_id);
return -EINVAL;
}
@@ -2031,7 +2169,9 @@ static int is_set_vf_bw_param_valid(const struct hinic5_nic_dev *adapter,
int enable_vf_num = hinic5_get_vf_num(adapter->lld_dev);
if (!HINIC5_SUPPORT_RATE_LIMIT(adapter->hwdev)) {
- nicif_err(adapter, drv, adapter->netdev, "Current function doesn't support to set vf rate limit\n");
+ nicif_err(
+ adapter, drv, adapter->netdev,
+ "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
@@ -2043,33 +2183,44 @@ static int is_set_vf_bw_param_valid(const struct hinic5_nic_dev *adapter,
}
if (max_tx_rate < min_tx_rate) {
- nicif_err(adapter, drv, adapter->netdev, "Invalid rate, max rate %d must greater than min rate %d\n",
- max_tx_rate, min_tx_rate);
+ nicif_err(
+ adapter, drv, adapter->netdev,
+ "Invalid rate, max rate %d must greater than min rate %d\n",
+ max_tx_rate, min_tx_rate);
return -EINVAL;
}
return 0;
}
-#define HINIC5_TX_RATE_TABLE_FULL 12
+#define HINIC5_TX_RATE_TABLE_FULL 12
#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
-static int hinic5_ndo_set_vf_bw(struct net_device *netdev,
- int vf, int min_tx_rate, int max_tx_rate)
+static int hinic5_ndo_set_vf_bw(struct net_device *netdev, int vf,
+ int min_tx_rate, int max_tx_rate)
#else
static int hinic5_ndo_set_vf_bw(struct net_device *netdev, int vf,
int max_tx_rate)
#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */
{
struct hinic5_nic_dev *adapter = netdev_priv(netdev);
- struct mag_port_info port_info = {0};
+ struct mag_port_info port_info = { 0 };
#ifndef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
int min_tx_rate = 0;
#endif
u8 link_status = 0;
- u32 speeds[] = {0, SPEED_10, SPEED_100, SPEED_1000, SPEED_10000,
- SPEED_25000, SPEED_40000, SPEED_50000, SPEED_100000, SPEED_200000,
- SPEED_400000, SPEED_400000};
+ u32 speeds[] = { 0,
+ SPEED_10,
+ SPEED_100,
+ SPEED_1000,
+ SPEED_10000,
+ SPEED_25000,
+ SPEED_40000,
+ SPEED_50000,
+ SPEED_100000,
+ SPEED_200000,
+ SPEED_400000,
+ SPEED_400000 };
int err = 0;
err = is_set_vf_bw_param_valid(adapter, vf, min_tx_rate, max_tx_rate);
@@ -2078,23 +2229,26 @@ static int hinic5_ndo_set_vf_bw(struct net_device *netdev, int vf,
err = hinic5_get_link_state(adapter->hwdev, &link_status);
if (err != 0) {
- nicif_err(adapter, drv, netdev, "Get link status failed when set vf tx rate\n");
+ nicif_err(adapter, drv, netdev,
+ "Get link status failed when set vf tx rate\n");
return -EIO;
}
if (link_status == 0) {
- nicif_err(adapter, drv, netdev, "Link status must be up when set vf tx rate\n");
+ nicif_err(adapter, drv, netdev,
+ "Link status must be up when set vf tx rate\n");
return -EINVAL;
}
err = hinic5_get_port_info(adapter->hwdev, &port_info,
HINIC5_CHANNEL_NIC);
- if (err != 0 || port_info.speed >= PORT_SPEED_UNKNOWN)
+ if ((err != 0) || port_info.speed >= PORT_SPEED_UNKNOWN)
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
- nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
+ nicif_err(adapter, drv, netdev,
+ "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
}
@@ -2103,25 +2257,28 @@ static int hinic5_ndo_set_vf_bw(struct net_device *netdev, int vf,
(u32)max_tx_rate, (u32)min_tx_rate);
if (err != 0) {
nicif_err(adapter, drv, netdev,
- "Unable to set VF %d max rate %d min rate %d%s\n",
- vf, max_tx_rate, min_tx_rate,
+ "Unable to set VF %d max rate %d min rate %d%s\n", vf,
+ max_tx_rate, min_tx_rate,
err == HINIC5_TX_RATE_TABLE_FULL ?
- ", tx rate profile is full" : "");
+ ", tx rate profile is full" :
+ "");
return -EIO;
}
#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
nicif_info(adapter, drv, netdev,
- "Set VF %d max tx rate %d min tx rate %d successfully\n",
- vf, max_tx_rate, min_tx_rate);
+ "Set VF %d max tx rate %d min tx rate %d successfully\n", vf,
+ max_tx_rate, min_tx_rate);
#else
- nicif_info(adapter, drv, netdev, "Set VF %d tx rate %d successfully\n", vf, max_tx_rate);
+ nicif_info(adapter, drv, netdev, "Set VF %d tx rate %d successfully\n",
+ vf, max_tx_rate);
#endif
return 0;
}
-#if defined(HAVE_XDP_SUPPORT) && (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
+#if defined(HAVE_XDP_SUPPORT) && \
+ (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
bool hinic5_is_xdp_enable(struct hinic5_nic_dev *nic_dev)
{
return !!nic_dev->xdp_prog;
@@ -2130,9 +2287,10 @@ bool hinic5_is_xdp_enable(struct hinic5_nic_dev *nic_dev)
int hinic5_xdp_max_mtu(struct hinic5_nic_dev *nic_dev)
{
/* To Check MTU, support use integreted cqe, XDP_PACKET_HEADROOM and skb_shared_info */
- return nic_dev->rx_buff_len - (ETH_HLEN + ETH_FCS_LEN +
- VLAN_HLEN + VLAN_HLEN) - HINIC5_COMPACT_CQE_16B -
- XDP_PACKET_HEADROOM - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ return nic_dev->rx_buff_len -
+ (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + VLAN_HLEN) -
+ HINIC5_COMPACT_CQE_16B - XDP_PACKET_HEADROOM -
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
}
#if (defined(HAVE_NDO_BPF) || defined(HAVE_NDO_XDP))
@@ -2144,19 +2302,23 @@ static int hinic5_xdp_setup(struct hinic5_nic_dev *nic_dev,
int max_mtu = hinic5_xdp_max_mtu(nic_dev);
int q_id, err = 0;
- if ((XDP_QPS_NUM_EXPANSION * nic_dev->q_params.num_qps) > nic_dev->max_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to setup xdp program, max qps %u is less than double of current qps %u, please reduce current num qps\n",
- nic_dev->max_qps, nic_dev->q_params.num_qps);
- NL_SET_ERR_MSG_MOD(extack,
- "Failed to setup xdp program, max qps is less than double of current qps");
+ if ((XDP_QPS_NUM_EXPANSION * nic_dev->q_params.num_qps) >
+ nic_dev->max_qps) {
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to setup xdp program, max qps %u is less than double of current qps %u, please reduce current num qps\n",
+ nic_dev->max_qps, nic_dev->q_params.num_qps);
+ NL_SET_ERR_MSG_MOD(
+ extack,
+ "Failed to setup xdp program, max qps is less than double of current qps");
return -EINVAL;
}
if (nic_dev->netdev->mtu > (u32)max_mtu) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to setup xdp program, the current MTU %u is larger than max allowed MTU %d\n",
- nic_dev->netdev->mtu, max_mtu);
+ nicif_err(
+ nic_dev, drv, nic_dev->netdev,
+ "Failed to setup xdp program, the current MTU %u is larger than max allowed MTU %d\n",
+ nic_dev->netdev->mtu, max_mtu);
NL_SET_ERR_MSG_MOD(extack,
"MTU too large for loading xdp program");
return -EINVAL;
@@ -2165,8 +2327,8 @@ static int hinic5_xdp_setup(struct hinic5_nic_dev *nic_dev,
if ((nic_dev->netdev->features & NETIF_F_LRO) != 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program while LRO is on\n");
- NL_SET_ERR_MSG_MOD(extack,
- "Failed to setup xdp program while LRO is on");
+ NL_SET_ERR_MSG_MOD(
+ extack, "Failed to setup xdp program while LRO is on");
return -EINVAL;
}
@@ -2176,12 +2338,14 @@ static int hinic5_xdp_setup(struct hinic5_nic_dev *nic_dev,
if (!nic_dev->remove_flag && netif_running(nic_dev->netdev)) {
err = hinic5_safe_switch_channels(nic_dev);
- if (err)
+ if (err != 0) {
return err;
+ }
}
- for (q_id = 0; q_id < nic_dev->max_qps; q_id++)
+ for (q_id = 0; q_id < nic_dev->max_qps; q_id++) {
xchg(&nic_dev->rxqs[q_id].xdp_prog, nic_dev->xdp_prog);
+ }
return 0;
}
@@ -2199,8 +2363,8 @@ static int hinic5_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
return hinic5_xdp_setup(nic_dev, xdp->prog, xdp->extack);
#ifdef HAVE_XDP_QUERY_PROG
case XDP_QUERY_PROG:
- xdp->prog_id = nic_dev->xdp_prog ?
- nic_dev->xdp_prog->aux->id : 0;
+ xdp->prog_id = nic_dev->xdp_prog ? nic_dev->xdp_prog->aux->id :
+ 0;
return 0;
#endif
default:
@@ -2210,7 +2374,8 @@ static int hinic5_xdp(struct net_device *netdev, struct netdev_xdp *xdp)
#endif
#endif
-static int hinic5_netdev_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+static int hinic5_netdev_ioctl(struct net_device *netdev, struct ifreq *ifr,
+ int cmd)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -2232,15 +2397,15 @@ static const struct net_device_ops hinic5_netdev_ops = {
.ndo_setup_tc = hinic5_setup_tc,
#endif
#ifdef HAVE_NDO_GET_STATS64
- .ndo_get_stats64 = hinic5_get_stats64,
+ .ndo_get_stats64 = hinic5_get_stats64,
#else
.ndo_get_stats = hinic5_get_stats,
#endif /* HAVE_NDO_GET_STATS64 */
-#ifdef HAVE_NDO_ETH_IOCTL
- .ndo_eth_ioctl = hinic5_netdev_ioctl,
-#else
+#ifdef HAVE_NDO_DO_IOCTL
.ndo_do_ioctl = hinic5_netdev_ioctl,
+#else
+ .ndo_eth_ioctl = hinic5_netdev_ioctl,
#endif
.ndo_tx_timeout = hinic5_tx_timeout,
.ndo_select_queue = hinic5_select_queue,
@@ -2263,34 +2428,34 @@ static const struct net_device_ops hinic5_netdev_ops = {
* fields from with the net_device_ops struct and ndo_size is checked
* to determine whether or not the offset is valid.
*/
- .ndo_size = sizeof(const struct net_device_ops),
+ .ndo_size = sizeof(const struct net_device_ops),
#endif
#ifdef IFLA_VF_MAX
- .ndo_set_vf_mac = hinic5_ndo_set_vf_mac,
+ .ndo_set_vf_mac = hinic5_ndo_set_vf_mac,
#ifdef HAVE_NET_DEV_OPS_EXT_NDO_SET_VF_VLAN
.extended.ndo_set_vf_vlan = hinic5_ndo_set_vf_vlan,
#else
- .ndo_set_vf_vlan = hinic5_ndo_set_vf_vlan,
+ .ndo_set_vf_vlan = hinic5_ndo_set_vf_vlan,
#endif
#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
- .ndo_set_vf_rate = hinic5_ndo_set_vf_bw,
+ .ndo_set_vf_rate = hinic5_ndo_set_vf_bw,
#else
- .ndo_set_vf_tx_rate = hinic5_ndo_set_vf_bw,
+ .ndo_set_vf_tx_rate = hinic5_ndo_set_vf_bw,
#endif /* HAVE_NDO_SET_VF_MIN_MAX_TX_RATE */
#ifdef HAVE_VF_SPOOFCHK_CONFIGURE
- .ndo_set_vf_spoofchk = hinic5_ndo_set_vf_spoofchk,
+ .ndo_set_vf_spoofchk = hinic5_ndo_set_vf_spoofchk,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
#ifdef HAVE_NET_DEVICE_OPS_EXTENDED
.extended.ndo_set_vf_trust = hinic5_ndo_set_vf_trust,
#else
- .ndo_set_vf_trust = hinic5_ndo_set_vf_trust,
+ .ndo_set_vf_trust = hinic5_ndo_set_vf_trust,
#endif /* HAVE_NET_DEVICE_OPS_EXTENDED */
#endif /* HAVE_NDO_SET_VF_TRUST */
- .ndo_get_vf_config = hinic5_ndo_get_vf_config,
+ .ndo_get_vf_config = hinic5_ndo_get_vf_config,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2320,7 +2485,7 @@ static const struct net_device_ops_ext hinic5_netdev_ops_ext = {
#endif /* HAVE_NET_DEVICE_OPS_EXT */
#ifdef HAVE_NDO_SET_VF_LINK_STATE
- .ndo_set_vf_link_state = hinic5_ndo_set_vf_link_state,
+ .ndo_set_vf_link_state = hinic5_ndo_set_vf_link_state,
#endif
#ifdef HAVE_NDO_SET_FEATURES
@@ -2335,7 +2500,7 @@ static const struct net_device_ops hinic5vf_netdev_ops = {
.ndo_start_xmit = hinic5_xmit_frame,
#ifdef HAVE_NDO_GET_STATS64
- .ndo_get_stats64 = hinic5_get_stats64,
+ .ndo_get_stats64 = hinic5_get_stats64,
#else
.ndo_get_stats = hinic5_get_stats,
#endif /* HAVE_NDO_GET_STATS64 */
@@ -2411,5 +2576,5 @@ void hinic5_set_netdev_ops(struct hinic5_nic_dev *nic_dev)
bool hinic5_is_netdev_ops_match(const struct net_device *netdev)
{
return netdev->netdev_ops == &hinic5_netdev_ops ||
- netdev->netdev_ops == &hinic5vf_netdev_ops;
+ netdev->netdev_ops == &hinic5vf_netdev_ops;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.h
index ec2580132..d95a195fe 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_netdev_ops.h
@@ -1,20 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_netdev_ops.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_NETDEV_OPS_H
-#define HINIC5_NETDEV_OPS_H
+#define HINIC5_NETDEV_OPS_H
-#define HINIC5_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
+#define HINIC5_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC5_INVALID_QUEUE 0xFFFF
/* to enable xdp, we suppose we can double current qps */
#define XDP_QPS_NUM_EXPANSION 2
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_nic_dev.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_nic_dev.h
index 423770e7b..3ad4fa497 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/netdev/hinic5_nic_dev.h
@@ -1,15 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_nic_dev.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : NIC device header file
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_NIC_DEV_H
-#define HINIC5_NIC_DEV_H
+#define HINIC5_NIC_DEV_H
#include <linux/netdevice.h>
#include <linux/semaphore.h>
@@ -28,15 +21,15 @@
#include "hinic5_dcb.h"
#include "hinic5_profile.h"
#include "hinic5_macsec_dev.h"
-#include "hinic5_vram_common.h"
+#include "vram_common.h"
-#define HINIC5_NIC_DRV_NAME "hinic5"
-#define HINIC5_NIC_DRV_VERSION "100.0.1.102"
+#define HINIC5_NIC_DRV_NAME "hinic5"
+#define HINIC5_NIC_DRV_VERSION GLOBAL_VERSION_STR
-#define HINIC5_FUNC_IS_VF(hwdev) (hinic5_func_type(hwdev) == TYPE_VF)
+#define HINIC5_FUNC_IS_VF(hwdev) (hinic5_func_type(hwdev) == TYPE_VF)
-#define HINIC5_AVG_PKT_SMALL 256U
-#define HINIC5_MODERATONE_DELAY HZ
+#define HINIC5_AVG_PKT_SMALL 256U
+#define HINIC5_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
#define LP_PKT_LEN 60
@@ -60,22 +53,20 @@ enum hinic5_flags {
HINIC5_DCB_UP_COS_SETTING,
};
-#define HINIC5_CHANNEL_RES_VALID(nic_dev) \
- ((test_bit(HINIC5_INTF_UP, &(nic_dev)->flags) != 0) && \
- (test_bit(HINIC5_CHANGE_RES_INVALID, &(nic_dev)->flags) == 0))
+#define HINIC5_CHANNEL_RES_VALID(nic_dev) \
+ ((test_bit(HINIC5_INTF_UP, &(nic_dev)->flags) != 0) && \
+ (test_bit(HINIC5_CHANGE_RES_INVALID, &(nic_dev)->flags) == 0))
-#define RX_BUFF_NUM_PER_PAGE 2
+#define RX_BUFF_NUM_PER_PAGE 2
-#define VLAN_BITMAP_BYTE_SIZE(nic_dev) (sizeof(*(nic_dev)->vlan_bitmap))
-#define VLAN_BITMAP_BITS_SIZE(nic_dev) (VLAN_BITMAP_BYTE_SIZE(nic_dev) * 8)
-#define VLAN_NUM_BITMAPS(nic_dev) (VLAN_N_VID / \
- VLAN_BITMAP_BITS_SIZE(nic_dev))
-#define VLAN_BITMAP_SIZE(nic_dev) (VLAN_N_VID / \
- VLAN_BITMAP_BYTE_SIZE(nic_dev))
-#define VID_LINE(nic_dev, vid) ((vid) / VLAN_BITMAP_BITS_SIZE(nic_dev))
-#define VID_COL(nic_dev, vid) ((vid) & (VLAN_BITMAP_BITS_SIZE(nic_dev) - 1))
+#define VLAN_BITMAP_BYTE_SIZE(nic_dev) (sizeof(*(nic_dev)->vlan_bitmap))
+#define VLAN_BITMAP_BITS_SIZE(nic_dev) (VLAN_BITMAP_BYTE_SIZE(nic_dev) * 8)
+#define VLAN_NUM_BITMAPS(nic_dev) (VLAN_N_VID / VLAN_BITMAP_BITS_SIZE(nic_dev))
+#define VLAN_BITMAP_SIZE(nic_dev) (VLAN_N_VID / VLAN_BITMAP_BYTE_SIZE(nic_dev))
+#define VID_LINE(nic_dev, vid) ((vid) / VLAN_BITMAP_BITS_SIZE(nic_dev))
+#define VID_COL(nic_dev, vid) ((vid) & (VLAN_BITMAP_BITS_SIZE(nic_dev) - 1))
-#define NIC_DRV_DEFAULT_FEATURE NIC_F_ALL_MASK
+#define NIC_DRV_DEFAULT_FEATURE NIC_F_ALL_MASK
enum hinic5_event_work_flags {
EVENT_WORK_TX_TIMEOUT,
@@ -106,7 +97,7 @@ struct hinic5_irq {
/* IRQ corresponding index number */
u16 msix_entry_idx;
u16 rsvd1;
- u32 irq_id; /* The IRQ number from OS */
+ u32 irq_id; /* The IRQ number from OS */
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
@@ -129,12 +120,12 @@ struct hinic5_dyna_txrxq_params {
struct hinic5_irq *irq_cfg;
};
-#define HINIC5_NIC_STATS_INC(nic_dev, field) \
-do { \
- u64_stats_update_begin(&(nic_dev)->stats.syncp); \
- (nic_dev)->stats.field++; \
- u64_stats_update_end(&(nic_dev)->stats.syncp); \
-} while (0)
+#define HINIC5_NIC_STATS_INC(nic_dev, field) \
+ do { \
+ u64_stats_update_begin(&(nic_dev)->stats.syncp); \
+ (nic_dev)->stats.field++; \
+ u64_stats_update_end(&(nic_dev)->stats.syncp); \
+ } while (0)
struct hinic5_nic_stats {
u64 netdev_tx_timeout;
@@ -152,10 +143,10 @@ struct hinic5_nic_stats {
};
#define HINIC5_TCAM_DYNAMIC_BLOCK_SIZE 16
-#define HINIC5_MAX_TCAM_FILTERS 1024
+#define HINIC5_MAX_TCAM_FILTERS 1024
-#define HINIC5_PKT_TCAM_DYNAMIC_INDEX_START(block_index) \
- (HINIC5_TCAM_DYNAMIC_BLOCK_SIZE * (block_index))
+#define HINIC5_PKT_TCAM_DYNAMIC_INDEX_START(block_index) \
+ (HINIC5_TCAM_DYNAMIC_BLOCK_SIZE * (block_index))
struct hinic5_rx_flow_rule {
struct list_head rules;
@@ -189,26 +180,26 @@ struct hinic5_tcam_info {
struct hinic5_tcam_dynamic_block_info tcam_dynamic_info;
};
-struct hinic5_hinic5_vram {
- u32 hinic5_vram_mtu;
- u16 hinic5_vram_num_qps;
+struct hinic5_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
unsigned long flags;
/* dcb */
- u8 trust; /* pcp, dscp */
- u8 default_cos;
+ u8 trust; /* pcp, dscp */
+ u8 default_cos;
};
struct hinic5_ptp_ctrl {
- unsigned long flags; /* PTP_TX_BUSY flag, ses enum hinic5_ptp_flags */
+ unsigned long flags; /* PTP_TX_BUSY flag, ses enum hinic5_ptp_flags */
void *hwdev;
- u32 inc_val; /* rtc inc val per cycle */
+ u32 inc_val; /* rtc inc val per cycle */
struct ptp_clock *ptp_clock;
- struct ptp_clock_info ptp_info;
- spinlock_t ptp_clock_lock; /* lock for access ptp hw reg */
+ struct ptp_clock_info ptp_info;
+ spinlock_t ptp_clock_lock; /* lock for access ptp hw reg */
struct sk_buff *tx_saved_skb;
- struct hwtstamp_config config;
- unsigned long tx_start; /* PTP tx send jiffies */
+ struct hwtstamp_config config;
+ unsigned long tx_start; /* PTP tx send jiffies */
int tx_enable;
int rx_enable;
};
@@ -223,18 +214,20 @@ struct hinic5_tx_rx_ops {
void (*tx_set_wqe_offload)(struct hinic5_offload_info *offload_info,
struct hinic5_sq_wqe_combo *wqe_combo);
void (*rx_get_cqe_info)(struct hinic5_rq_cqe *rx_cqe,
- struct hinic5_cqe_info *cqe_info, u8 cqe_mode, bool enable_pfe);
- bool (*rx_cqe_done)(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **rx_cqe);
+ struct hinic5_cqe_info *cqe_info, u8 cqe_mode,
+ bool enable_pfe);
+ bool (*rx_cqe_done)(struct hinic5_rxq *rxq,
+ struct hinic5_rq_cqe **rx_cqe);
hinic5_nic_cqe_cb cqe_cb[SERVICE_T_MAX];
- unsigned long cqe_cb_state[SERVICE_T_MAX];
- unsigned long cqe_cb_running[SERVICE_T_MAX];
+ unsigned long cqe_cb_state[SERVICE_T_MAX];
+ unsigned long cqe_cb_running[SERVICE_T_MAX];
};
struct hinic5_nic_dev {
struct net_device *netdev;
struct hinic5_lld_dev *lld_dev;
void *hwdev;
- void *extend; /* Product-specific custom data structure */
+ void *extend; /* 产品自定义数据结构 */
/* Currently, 1 indicates is_in_kexec. */
u32 state;
@@ -270,8 +263,8 @@ struct hinic5_nic_dev {
struct hinic5_dcb_config hw_dcb_cfg;
- struct hinic5_hinic5_vram *nic_hinic5_vram;
- char nic_hinic5_vram_name[HINIC5_VRAM_NAME_MAX_LEN];
+ struct hinic5_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
int disable_port_cnt;
@@ -284,7 +277,7 @@ struct hinic5_nic_dev {
struct net_device_stats net_stats;
#endif
- struct hinic5_nic_stats stats;
+ struct hinic5_nic_stats stats;
/* lock for nic resource */
struct mutex nic_mutex;
@@ -306,13 +299,13 @@ struct hinic5_nic_dev {
struct workqueue_struct *workq;
struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct delayed_work moderation_task;
struct list_head uc_filter_list;
struct list_head mc_filter_list;
unsigned long rx_mod_state;
int netdev_uc_cnt;
- int netdev_mc_cnt;
+ int netdev_mc_cnt;
int lb_test_rx_idx;
int lb_pkt_len;
@@ -326,7 +319,7 @@ struct hinic5_nic_dev {
bool remove_flag;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic5_event_work_flags */
unsigned long event_flag;
@@ -338,7 +331,7 @@ struct hinic5_nic_dev {
u8 hw_default_cos;
u8 tx_wqe_compact_task;
u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ struct delayed_work rxq_check_work;
struct hinic5_ptp_ctrl ptp_ctrl;
struct hinic5_tx_rx_ops tx_rx_ops;
@@ -347,7 +340,7 @@ struct hinic5_nic_dev {
struct hinic5_timeout timeout;
- struct macsec_resource *macsec_res; // MACsec module uses resource
+ struct macsec_resource *macsec_res; // MACsec模块使用资源
struct work_struct arp_dual_work;
struct sk_buff_head arp_queue;
@@ -366,27 +359,26 @@ struct hinic5_nic_dev {
#define nicif_dbg(priv, type, dev, fmt, args...) \
netif_level(dbg, priv, type, dev, "[NIC]" fmt, ##args)
-#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
-do { \
- if ((nic_dev)->netdev && (nic_dev)->netdev->reg_state \
- == NETREG_REGISTERED) \
- nicif_##level((nic_dev), msglvl, (nic_dev)->netdev, \
- format, ## arg); \
- else \
- nic_##level((nic_dev)->lld_dev->dev, \
- format, ## arg); \
-} while (0)
+#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
+ do { \
+ if ((nic_dev)->netdev != NULL && \
+ (nic_dev)->netdev->reg_state == NETREG_REGISTERED) \
+ nicif_##level((nic_dev), msglvl, (nic_dev)->netdev, \
+ format, ##arg); \
+ else \
+ nic_##level((nic_dev)->lld_dev->dev, format, ##arg); \
+ } while (0)
-#define hinic5_info(nic_dev, msglvl, format, arg...) \
- hinic_msg(info, nic_dev, msglvl, format, ## arg)
+#define hinic5_info(nic_dev, msglvl, format, arg...) \
+ hinic_msg(info, nic_dev, msglvl, format, ##arg)
-#define hinic5_warn(nic_dev, msglvl, format, arg...) \
- hinic_msg(warn, nic_dev, msglvl, format, ## arg)
+#define hinic5_warn(nic_dev, msglvl, format, arg...) \
+ hinic_msg(warn, nic_dev, msglvl, format, ##arg)
-#define hinic5_err(nic_dev, msglvl, format, arg...) \
- hinic_msg(err, nic_dev, msglvl, format, ## arg)
+#define hinic5_err(nic_dev, msglvl, format, arg...) \
+ hinic_msg(err, nic_dev, msglvl, format, ##arg)
-struct hinic5_uld_info *hinic5_get_nic_uld_info(void);
+struct hinic5_uld_info *get_nic_uld_info(void);
u32 hinic5_get_io_stats_size(const struct hinic5_nic_dev *nic_dev);
@@ -402,8 +394,8 @@ void hinic5_set_ethtool_ops(struct net_device *netdev);
void hinic5vf_set_ethtool_ops(struct net_device *netdev);
-int hinic5_nic_ioctl(void *uld_dev, u32 cmd, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size);
+int nic_ioctl(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
void hinic5_update_num_qps(struct net_device *netdev);
@@ -434,9 +426,9 @@ int hinic5_maybe_set_port_state(struct hinic5_nic_dev *nic_dev, bool enable);
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic5_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *link_settings);
-int hinic5_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings
- *link_settings);
+int hinic5_set_link_ksettings(
+ struct net_device *netdev,
+ const struct ethtool_link_ksettings *link_settings);
#endif
#endif
@@ -466,17 +458,19 @@ int hinic5_set_xdp_num(struct hinic5_nic_dev *nic_dev,
#endif
#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
-int hinic5_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam);
-int hinic5_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam);
+int hinic5_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam);
+int hinic5_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam);
#endif
#ifdef HAVE_UDP_TUNNEL_NIC_INFO
-/* set vxlan dport */
int hinic5_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
- unsigned int entry, struct udp_tunnel_info *ti);
+ unsigned int entry,
+ struct udp_tunnel_info *ti); /* 设置vxlan dport */
int hinic5_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
- unsigned int entry, struct udp_tunnel_info *ti);
+ unsigned int entry,
+ struct udp_tunnel_info *ti);
#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
#endif
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.c
index 299aecea0..89866e877 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_rx.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : RX queue implementation
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
#include <linux/types.h>
@@ -56,7 +49,7 @@ static bool rx_alloc_mapped_page(struct hinic5_nic_dev *nic_dev,
if (likely(dma != 0))
return true;
- /* alloc new page for storage */
+ /* alloc new page for storage */
#ifdef HAVE_PAGE_POOL_SUPPORT
if (rx_info->page_pool) {
page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
@@ -68,14 +61,15 @@ static bool rx_alloc_mapped_page(struct hinic5_nic_dev *nic_dev,
goto set_rx_info;
}
#endif
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(nic_dev->lld_dev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(nic_dev->lld_dev->dev, page, 0,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -107,13 +101,14 @@ static u32 hinic5_rx_fill_wqe(struct hinic5_rxq *rxq)
rq_wqe = hinic5_rq_wqe_addr(rxq->rq, (u16)i);
if (rxq->rq->wqe_type == HINIC5_EXTEND_RQ_WQE) {
- /* unit of cqe length is 16B */
+ /* unit of cqe length is 16B */
hinic5_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (HINIC5_CQE_LEN >> HINIC5_CQE_SIZE_SHIFT));
+ (HINIC5_CQE_LEN >>
+ HINIC5_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
- nic_dev->rx_buff_len;
+ nic_dev->rx_buff_len;
} else if (rxq->rq->wqe_type == HINIC5_NORMAL_RQ_WQE) {
rq_wqe->normal_wqe.cqe_hi_addr =
upper_32_bits(rx_info->cqe_dma);
@@ -146,9 +141,11 @@ static u32 hinic5_rx_fill_buffers(struct hinic5_rxq *rxq)
}
#ifdef HAVE_XDP_SUPPORT
- dma_addr = (rxq->xdp_headroom_flag == 0) ?
- rx_info->buf_dma_addr + rx_info->page_offset :
- rx_info->buf_dma_addr + rx_info->page_offset + XDP_PACKET_HEADROOM;
+ dma_addr =
+ (rxq->xdp_headroom_flag == 0) ?
+ rx_info->buf_dma_addr + rx_info->page_offset :
+ rx_info->buf_dma_addr + rx_info->page_offset +
+ XDP_PACKET_HEADROOM;
#else
dma_addr = rx_info->buf_dma_addr + rx_info->page_offset;
#endif
@@ -161,14 +158,14 @@ static u32 hinic5_rx_fill_buffers(struct hinic5_rxq *rxq)
rq_wqe->compact_wqe.buf_lo_addr =
hinic5_hw_be32(lower_32_bits(dma_addr));
- rxq->next_to_update = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
+ rxq->next_to_update =
+ (u16)((rxq->next_to_update + 1) & rxq->q_mask);
}
if (likely(i != 0)) {
- hinic5_write_db(rxq->rq,
- (rxq->q_id & 0x3),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
+ hinic5_write_db(rxq->rq, (rxq->q_id & 0x3), RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update
+ << rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -204,8 +201,7 @@ static void hinic5_rx_free_buffers(struct hinic5_nic_dev *nic_dev, u32 q_depth,
#ifdef HAVE_PAGE_POOL_SUPPORT
if (rx_info->page_pool && rx_info->page) {
- page_pool_put_page(rx_info->page_pool,
- rx_info->page,
+ page_pool_put_page(rx_info->page_pool, rx_info->page,
nic_dev->rx_buff_len, false);
goto clean_info;
}
@@ -242,8 +238,7 @@ void hinic5_reuse_rx_page(struct hinic5_rxq *rxq,
/* sync the buffer for use by the device */
dma_sync_single_range_for_device(rxq->dev, new_rx_info->buf_dma_addr,
- new_rx_info->page_offset,
- rxq->buf_len,
+ new_rx_info->page_offset, rxq->buf_len,
DMA_FROM_DEVICE);
}
@@ -261,10 +256,8 @@ static bool hinic5_add_rx_frag(struct hinic5_rxq *rxq,
prefetch(va + L1_CACHE_BYTES);
#endif
- dma_sync_single_range_for_cpu(rxq->dev,
- rx_info->buf_dma_addr,
- rx_info->page_offset,
- rxq->buf_len,
+ dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
+ rx_info->page_offset, rxq->buf_len,
DMA_FROM_DEVICE);
if (size <= HINIC5_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
@@ -272,7 +265,8 @@ static bool hinic5_add_rx_frag(struct hinic5_rxq *rxq,
#ifdef HAVE_PAGE_POOL_SUPPORT
if (rx_info->page_pool) {
- page_pool_put_page(rx_info->page_pool, page, rxq->buf_len, false);
+ page_pool_put_page(rx_info->page_pool, page,
+ rxq->buf_len, false);
return false;
}
#endif
@@ -287,7 +281,8 @@ static bool hinic5_add_rx_frag(struct hinic5_rxq *rxq,
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)rx_info->page_offset + packet_offset, (int)size, rxq->buf_len);
+ (int)rx_info->page_offset + packet_offset, (int)size,
+ rxq->buf_len);
#ifdef HAVE_PAGE_POOL_SUPPORT
if (rx_info->page_pool) {
@@ -312,8 +307,8 @@ static bool hinic5_add_rx_frag(struct hinic5_rxq *rxq,
discard_page:
/* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr, rxq->dma_rx_buff_size,
+ DMA_FROM_DEVICE);
return false;
}
@@ -355,14 +350,17 @@ static void packaging_skb(struct hinic5_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic5_add_rx_frag(rxq, rx_info, skb, size, temp_offset)))
+ if (likely(hinic5_add_rx_frag(rxq, rx_info, skb, size,
+ temp_offset))) {
hinic5_reuse_rx_page(rxq, rx_info);
+ }
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
temp_sge_num--;
- temp_offset = 0; /* only the first (compact) sge use the offset */
+ temp_offset =
+ 0; /* only the first (compact) sge use the offset */
frag_num++;
}
}
@@ -380,7 +378,7 @@ struct sk_buff *hinic5_fetch_rx_buffer(struct hinic5_rxq *rxq,
u16 wqebb_cnt = 0;
head_skb = netdev_alloc_skb_ip_align(netdev, HINIC5_RX_HDR_SIZE);
- if (unlikely(!head_skb))
+ if (unlikely((head_skb == NULL)))
return NULL;
sge_num = HINIC5_GET_SGE_NUM(pkt_len + packet_offset, rxq);
@@ -388,14 +386,14 @@ struct sk_buff *hinic5_fetch_rx_buffer(struct hinic5_rxq *rxq,
skb_num = 1;
else
skb_num = (sge_num / MAX_SKB_FRAGS) +
- (((sge_num % MAX_SKB_FRAGS) != 0) ? 1 : 0);
+ (((sge_num % MAX_SKB_FRAGS) != 0) ? 1 : 0);
while (unlikely(skb_num > 1)) {
cur_skb = netdev_alloc_skb_ip_align(netdev, HINIC5_RX_HDR_SIZE);
if (unlikely(!cur_skb))
goto alloc_skb_fail;
- if (!skb) {
+ if (skb == NULL) {
skb_shinfo(head_skb)->frag_list = cur_skb;
skb = cur_skb;
} else {
@@ -431,8 +429,8 @@ void hinic5_rxq_get_stats(struct hinic5_rxq *rxq,
start = u64_stats_fetch_begin(&rxq_stats->syncp);
stats->bytes = rxq_stats->bytes;
stats->packets = rxq_stats->packets;
- stats->errors = rxq_stats->csum_errors +
- rxq_stats->other_errors;
+ stats->errors =
+ rxq_stats->csum_errors + rxq_stats->other_errors;
stats->csum_errors = rxq_stats->csum_errors;
stats->other_errors = rxq_stats->other_errors;
stats->dropped = rxq_stats->dropped;
@@ -478,13 +476,14 @@ static void rxq_stats_init(struct hinic5_rxq *rxq)
}
#ifndef HAVE_ETH_GET_HEADLEN_FUNC
-static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max_len)
+static unsigned int hinic5_eth_get_headlen(unsigned char *data,
+ unsigned int max_len)
{
-#define IP_FRAG_OFFSET 0x1FFF
-#define FCOE_HLEN 38
-#define ETH_P_8021_AD 0x88A8
-#define ETH_P_8021_Q 0x8100
-#define TCP_HEAD_OFFSET 12
+#define IP_FRAG_OFFSET 0x1FFF
+#define FCOE_HLEN 38
+#define ETH_P_8021_AD 0x88A8
+#define ETH_P_8021_Q 0x8100
+#define TCP_HEAD_OFFSET 12
union {
unsigned char *data;
struct ethhdr *eth;
@@ -503,8 +502,8 @@ static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) {
+ if (protocol == __constant_htons(ETH_P_8021_AD) ||
+ protocol == __constant_htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -517,7 +516,7 @@ static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max
/* L3 header */
switch (protocol) {
- case htons(ETH_P_IP):
+ case __constant_htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -534,7 +533,7 @@ static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max
hdr.data += hlen;
break;
- case htons(ETH_P_IPV6):
+ case __constant_htons(ETH_P_IPV6):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct ipv6hdr)))
return max_len;
@@ -543,7 +542,7 @@ static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max
hdr.data += sizeof(struct ipv6hdr);
break;
- case htons(ETH_P_FCOE):
+ case __constant_htons(ETH_P_FCOE):
hdr.data += FCOE_HLEN;
break;
@@ -560,9 +559,9 @@ static unsigned int hinic5_eth_get_headlen(unsigned char *data, unsigned int max
/* L4 header length = (13st byte & 0xF0) >> 2 */
if (((hdr.data[TCP_HEAD_OFFSET] & 0xF0) >>
- HINIC5_HEADER_DATA_UNIT) > sizeof(struct tcphdr))
+ HINIC5_HEADER_DATA_UNIT) > sizeof(struct tcphdr))
hdr.data += ((hdr.data[TCP_HEAD_OFFSET] & 0xF0) >>
- HINIC5_HEADER_DATA_UNIT);
+ HINIC5_HEADER_DATA_UNIT);
else
hdr.data += sizeof(struct tcphdr);
break;
@@ -624,7 +623,8 @@ static void hinic5_pull_tail(struct sk_buff *skb)
skb->tail += pull_len;
}
-static void hinic5_rx_csum(struct hinic5_rxq *rxq, const struct hinic5_cqe_info *cqe_info,
+static void hinic5_rx_csum(struct hinic5_rxq *rxq,
+ const struct hinic5_cqe_info *cqe_info,
struct sk_buff *skb)
{
struct net_device *netdev = rxq->netdev;
@@ -638,7 +638,7 @@ static void hinic5_rx_csum(struct hinic5_rxq *rxq, const struct hinic5_cqe_info
if (unlikely(cqe_info->csum_err != 0)) {
/* pkt type is recognized by HW, and csum is wrong */
if ((cqe_info->csum_err & (HINIC5_RX_CSUM_HW_CHECK_NONE |
- HINIC5_RX_CSUM_IPSU_OTHER_ERR)) == 0)
+ HINIC5_RX_CSUM_IPSU_OTHER_ERR)) == 0)
rxq->rxq_stats.csum_errors++;
skb->ip_summed = CHECKSUM_NONE;
return;
@@ -687,11 +687,13 @@ static void hinic5_copy_lp_data(struct hinic5_nic_dev *nic_dev,
u8 *lb_buf = nic_dev->lb_test_rx_buf;
void *frag_data = NULL;
int lb_len = nic_dev->lb_pkt_len;
- int pkt_offset, frag_len, i;
+ int pkt_offset, frag_len, i, ret;
if (nic_dev->lb_test_rx_idx == LP_PKT_CNT) {
nic_dev->lb_test_rx_idx = 0;
- nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
+ nicif_warn(
+ nic_dev, rx_err, netdev,
+ "Loopback test warning, receive too many test pkts\n");
}
if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
@@ -702,12 +704,25 @@ static void hinic5_copy_lp_data(struct hinic5_nic_dev *nic_dev,
pkt_offset = nic_dev->lb_test_rx_idx * lb_len;
frag_len = (int)skb_headlen(skb);
- memcpy(lb_buf + pkt_offset, skb->data, (size_t)(u32)frag_len);
+ ret = memcpy_s(lb_buf + pkt_offset,
+ LP_PKT_CNT * LP_PKT_LEN - pkt_offset, skb->data,
+ (size_t)(u32)frag_len);
+ if (unlikely(ret != 0)) {
+ nicif_warn(nic_dev, rx_err, netdev, "Cpy skb hdr failed\n");
+ return;
+ }
pkt_offset += frag_len;
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
frag_data = skb_frag_address(&skb_shinfo(skb)->frags[i]);
frag_len = (int)skb_frag_size(&skb_shinfo(skb)->frags[i]);
- memcpy(lb_buf + pkt_offset, frag_data, (size_t)(u32)frag_len);
+ ret = memcpy_s(lb_buf + pkt_offset,
+ LP_PKT_CNT * LP_PKT_LEN - pkt_offset, frag_data,
+ (size_t)(u32)frag_len);
+ if (unlikely(ret != 0)) {
+ nicif_warn(nic_dev, rx_err, netdev,
+ "Cpy skb frag %d failed\n", i);
+ return;
+ }
pkt_offset += frag_len;
}
nic_dev->lb_test_rx_idx++;
@@ -720,12 +735,15 @@ static inline void hinic5_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
proto = __vlan_get_protocol(skb, eth->h_proto, NULL);
- skb_shinfo(skb)->gso_size = (u16)DIV_ROUND_UP((skb->len - skb_headlen(skb)), num_lro);
- skb_shinfo(skb)->gso_type = (proto == htons(ETH_P_IP)) ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
+ skb_shinfo(skb)->gso_size =
+ (u16)DIV_ROUND_UP((skb->len - skb_headlen(skb)), num_lro);
+ skb_shinfo(skb)->gso_type = (proto == htons(ETH_P_IP)) ? SKB_GSO_TCPV4 :
+ SKB_GSO_TCPV6;
skb_shinfo(skb)->gso_segs = num_lro;
}
-static int recv_one_pkt(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic5_rxq *rxq,
+ struct hinic5_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -733,9 +751,7 @@ static int recv_one_pkt(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
if (hinic5_xdp_process_packet(rxq, cqe_info, &skb)) {
- /* The XDP program has processed the packet
- * and does not need to be sent to the protocol stack
- */
+ /* The XDP program has processed the packet and does not need to be sent to the protocol stack */
return HINIC5_XDP_PROCESSED;
}
#else
@@ -750,8 +766,9 @@ static int recv_one_pkt(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info
if (skb_is_nonlinear(skb))
hinic5_pull_tail(skb);
- if (cqe_info->ts_flag != 0)
+ if (cqe_info->ts_flag != 0) {
hinic5_ptp_rx_hwtstamp(nic_dev, skb);
+ }
hinic5_rx_csum(rxq, cqe_info, skb);
@@ -760,12 +777,14 @@ static int recv_one_pkt(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info
#endif
#if defined(NETIF_F_HW_VLAN_CTAG_RX)
- if (((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) != 0) && cqe_info->vlan_offload != 0) {
+ if (((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) != 0) &&
+ cqe_info->vlan_offload != 0) {
#else
if ((netdev->features & NETIF_F_HW_VLAN_RX) && cqe_info->vlan_offload) {
#endif
/* if the packet is a vlan pkt, the vid may be 0 */
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), cqe_info->vlan_tag);
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ cqe_info->vlan_tag);
}
if (unlikely(test_bit(HINIC5_LP_TEST, &nic_dev->flags) != 0))
@@ -789,13 +808,15 @@ static int recv_one_pkt(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info
return 0;
}
-#define LRO_PKT_HDR_LEN_IPV4 66
-#define LRO_PKT_HDR_LEN_IPV6 86
-#define LRO_PKT_HDR_LEN(ip_type) \
- ((ip_type) == HINIC5_RX_IPV6_PKT ? LRO_PKT_HDR_LEN_IPV6 : LRO_PKT_HDR_LEN_IPV4)
+#define LRO_PKT_HDR_LEN_IPV4 66
+#define LRO_PKT_HDR_LEN_IPV6 86
+#define LRO_PKT_HDR_LEN(ip_type) \
+ ((ip_type) == HINIC5_RX_IPV6_PKT ? LRO_PKT_HDR_LEN_IPV6 : \
+ LRO_PKT_HDR_LEN_IPV4)
void hinic5_rx_get_cqe_info(struct hinic5_rq_cqe *cqe,
- struct hinic5_cqe_info *info, u8 cqe_mode, bool enable_pfe)
+ struct hinic5_cqe_info *info, u8 cqe_mode,
+ bool enable_pfe)
{
u32 dw0 = hinic5_hw_cpu32(cqe->status);
u32 dw1 = hinic5_hw_cpu32(cqe->vlan_len);
@@ -816,38 +837,65 @@ void hinic5_rx_get_cqe_info(struct hinic5_rq_cqe *cqe,
info->rss_hash_value = hinic5_hw_cpu32(cqe->hash_val);
}
-void hinic5_rx_get_compact_cqe_info(struct hinic5_rq_cqe *cqe,
- struct hinic5_cqe_info *info, u8 cqe_mode, bool enable_pfe)
+static void rx_compact_cqe_convert_endian(struct hinic5_rq_cqe *cqe,
+ u8 cqe_mode, u32 *dw, int size)
{
- u32 dw0, dw1, dw2, dw3;
+ int i = 0;
if (cqe_mode != HINIC5_RQ_CQE_INTEGRATE) {
- dw0 = hinic5_hw_cpu32(cqe->status);
- dw1 = hinic5_hw_cpu32(cqe->vlan_len);
- dw2 = hinic5_hw_cpu32(cqe->offload_type);
- dw3 = hinic5_hw_cpu32(cqe->hash_val);
- } else {
- /*
- * When rx wqe is compact, cqe is integrated with packet by big endian,
- * explicit endian conversion is needed.
- */
- dw0 = be32_to_cpu(cqe->status);
- dw1 = be32_to_cpu(cqe->vlan_len);
- dw2 = be32_to_cpu(cqe->offload_type);
- dw3 = be32_to_cpu(cqe->hash_val);
+ for (; i < size; i++) {
+ dw[i] = hinic5_hw_cpu32(((u32 *)(void *)cqe)[i]);
+ }
+ return;
}
- info->cqe_type = RQ_COMPACT_CQE_STATUS_GET(dw0, CQE_TYPE);
- info->csum_err = RQ_COMPACT_CQE_STATUS_GET(dw0, CSUM_ERR);
- info->vlan_offload = RQ_COMPACT_CQE_STATUS_GET(dw0, VLAN_EN);
- info->pkt_fmt = RQ_COMPACT_CQE_STATUS_GET(dw0, PKT_FORMAT);
- info->ip_type = RQ_COMPACT_CQE_STATUS_GET(dw0, IP_TYPE);
- info->cqe_len = RQ_COMPACT_CQE_STATUS_GET(dw0, CQE_LEN);
- info->pkt_type = RQ_COMPACT_CQE_STATUS_GET(dw0, PKT_TYPE);
- info->pkt_len = RQ_COMPACT_CQE_STATUS_GET(dw0, PKT_LEN);
- info->ts_flag = RQ_COMPACT_CQE_STATUS_GET(dw0, TS_FLAG);
- info->pkt_mc = RQ_COMPACT_CQE_STATUS_GET(dw0, PKT_MC);
- info->rss_hash_value = dw1;
+ /*
+ * When rx wqe is compact, cqe is integrated with packet by big endian,
+ * explicit endian conversion is needed.
+ */
+ for (; i < size; i++)
+ dw[i] = be32_to_cpu(((u32 *)(void *)cqe)[i]);
+}
+
+static void rx_get_compact_16byte_cqe_info(struct hinic5_cqe_info *info,
+ u32 dw2, u32 dw3, bool enable_pfe)
+{
+ info->lro_num = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, NUM_LRO);
+ info->vlan_tag = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, VLAN);
+ if (enable_pfe) {
+ info->pfe_pkt_src =
+ RQ_COMPACT_CQE_OFFLOAD_GET(dw2, PFE_PKT_SRC);
+ info->pfe_port_id =
+ RQ_COMPACT_CQE_OFFLOAD_GET(dw2, PFE_PORT_ID);
+ info->flow_mark_vld =
+ RQ_COMPACT_CQE_OFFLOAD_GET(dw2, FLOW_MARK_VLD);
+ info->src_func_id =
+ (u16)((RQ_COMPACT_CQE_OFFLOAD_GET(dw2, SRC_FUNC_ID_HIGH)
+ << RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_SHIFT) |
+ RQ_COMPACT_CQE_OFFLOAD_GET(dw3, SRC_FUNC_ID_LOW));
+ info->flow_mark = RQ_COMPACT_CQE_OFFLOAD_GET(dw3, FLOW_MARK);
+ }
+}
+
+void hinic5_rx_get_compact_cqe_info(struct hinic5_rq_cqe *cqe,
+ struct hinic5_cqe_info *info, u8 cqe_mode,
+ bool enable_pfe)
+{
+ u32 dw[4];
+
+ rx_compact_cqe_convert_endian(cqe, cqe_mode, dw, ARRAY_SIZE(dw));
+
+ info->cqe_type = RQ_COMPACT_CQE_STATUS_GET(dw[0], CQE_TYPE);
+ info->csum_err = RQ_COMPACT_CQE_STATUS_GET(dw[0], CSUM_ERR);
+ info->vlan_offload = RQ_COMPACT_CQE_STATUS_GET(dw[0], VLAN_EN);
+ info->pkt_fmt = RQ_COMPACT_CQE_STATUS_GET(dw[0], PKT_FORMAT);
+ info->ip_type = RQ_COMPACT_CQE_STATUS_GET(dw[0], IP_TYPE);
+ info->cqe_len = RQ_COMPACT_CQE_STATUS_GET(dw[0], CQE_LEN);
+ info->pkt_type = RQ_COMPACT_CQE_STATUS_GET(dw[0], PKT_TYPE);
+ info->pkt_len = RQ_COMPACT_CQE_STATUS_GET(dw[0], PKT_LEN);
+ info->ts_flag = RQ_COMPACT_CQE_STATUS_GET(dw[0], TS_FLAG);
+ info->pkt_mc = RQ_COMPACT_CQE_STATUS_GET(dw[0], PKT_MC);
+ info->rss_hash_value = dw[1];
switch (info->csum_err) {
case NIC_RX_COMPACT_CSUM_OTHER_ERROR:
@@ -861,18 +909,8 @@ void hinic5_rx_get_compact_cqe_info(struct hinic5_rq_cqe *cqe,
}
if (info->cqe_len == RQ_COMPACT_CQE_16BYTE) {
- info->lro_num = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, NUM_LRO);
- info->vlan_tag = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, VLAN);
- if (enable_pfe) {
- info->pfe_pkt_src = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, PFE_PKT_SRC);
- info->pfe_port_id = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, PFE_PORT_ID);
- info->flow_mark_vld = RQ_COMPACT_CQE_OFFLOAD_GET(dw2, FLOW_MARK_VLD);
- info->src_func_id =
- (u16)((RQ_COMPACT_CQE_OFFLOAD_GET(dw2, SRC_FUNC_ID_HIGH)
- << RQ_COMPACT_CQE_OFFLOAD_SRC_FUNC_ID_SHIFT) |
- RQ_COMPACT_CQE_OFFLOAD_GET(dw3, SRC_FUNC_ID_LOW));
- info->flow_mark = RQ_COMPACT_CQE_OFFLOAD_GET(dw3, FLOW_MARK);
- }
+ rx_get_compact_16byte_cqe_info(info, dw[0x2], dw[0x3],
+ enable_pfe);
} else {
info->lro_num = 0;
info->vlan_tag = 0;
@@ -880,13 +918,15 @@ void hinic5_rx_get_compact_cqe_info(struct hinic5_rq_cqe *cqe,
if (cqe_mode == HINIC5_RQ_CQE_INTEGRATE) {
info->packet_offset = info->cqe_len == RQ_COMPACT_CQE_16BYTE ?
- HINIC5_COMPACT_CQE_16B : HINIC5_COMPACT_CQE_8B;
+ HINIC5_COMPACT_CQE_16B :
+ HINIC5_COMPACT_CQE_8B;
} else {
info->packet_offset = 0;
}
}
-bool hinic5_rx_integrated_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **rx_cqe)
+bool hinic5_rx_integrated_cqe_done(struct hinic5_rxq *rxq,
+ struct hinic5_rq_cqe **rx_cqe)
{
u16 sw_ci;
u16 hw_ci;
@@ -896,28 +936,28 @@ bool hinic5_rx_integrated_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe
if (hw_ci == sw_ci)
return false;
/* make sure we read cqe info in dma */
- dma_sync_single_range_for_cpu(rxq->dev, rxq->rx_info[sw_ci].buf_dma_addr,
+ dma_sync_single_range_for_cpu(rxq->dev,
+ rxq->rx_info[sw_ci].buf_dma_addr,
rxq->rx_info[sw_ci].page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
-#ifdef HAVE_XDP_SUPPORT
- if (rxq->xdp_headroom_flag == 0)
- *rx_cqe = (struct hinic5_rq_cqe *)
- ((u8 *)page_address(rxq->rx_info[sw_ci].page) +
- rxq->rx_info[sw_ci].page_offset);
- else
- *rx_cqe = (struct hinic5_rq_cqe *)
- ((u8 *)page_address(rxq->rx_info[sw_ci].page) +
- rxq->rx_info[sw_ci].page_offset + XDP_PACKET_HEADROOM);
-#else
- *rx_cqe = (struct hinic5_rq_cqe *)
- ((u8 *)page_address(rxq->rx_info[sw_ci].page) +
- rxq->rx_info[sw_ci].page_offset);
-#endif
+ if (rxq->xdp_headroom_flag == 0) {
+ *rx_cqe = (struct hinic5_rq_cqe
+ *)((u8 *)page_address(
+ rxq->rx_info[sw_ci].page) +
+ rxq->rx_info[sw_ci].page_offset);
+ } else {
+ *rx_cqe = (struct hinic5_rq_cqe
+ *)((u8 *)page_address(
+ rxq->rx_info[sw_ci].page) +
+ rxq->rx_info[sw_ci].page_offset +
+ XDP_PACKET_HEADROOM);
+ }
return true;
}
-bool hinic5_rx_separate_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **rx_cqe)
+bool hinic5_rx_separate_cqe_done(struct hinic5_rxq *rxq,
+ struct hinic5_rq_cqe **rx_cqe)
{
u32 sw_ci, status = 0;
@@ -932,13 +972,14 @@ bool hinic5_rx_separate_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **
}
void hinic5_rx_cqe_sendup_convert(struct hinic5_rq_cqe *rx_cqe,
- struct hinic5_rq_cqe *rx_cqe_sendup, u8 cqe_mode)
+ struct hinic5_rq_cqe *rx_cqe_sendup,
+ u8 cqe_mode)
{
if (cqe_mode == HINIC5_RQ_CQE_INTEGRATE) {
/*
- * When rx wqe is compact, cqe is integrated with packet by big endian,
- * explicit endian conversion is needed.
- */
+ * When rx wqe is compact, cqe is integrated with packet by big endian,
+ * explicit endian conversion is needed.
+ */
rx_cqe_sendup->status = be32_to_cpu(rx_cqe->status);
rx_cqe_sendup->vlan_len = be32_to_cpu(rx_cqe->vlan_len);
rx_cqe_sendup->offload_type = be32_to_cpu(rx_cqe->offload_type);
@@ -946,24 +987,30 @@ void hinic5_rx_cqe_sendup_convert(struct hinic5_rq_cqe *rx_cqe,
} else {
rx_cqe_sendup->status = hinic5_hw_cpu32(rx_cqe->status);
rx_cqe_sendup->vlan_len = hinic5_hw_cpu32(rx_cqe->vlan_len);
- rx_cqe_sendup->offload_type = hinic5_hw_cpu32(rx_cqe->offload_type);
+ rx_cqe_sendup->offload_type =
+ hinic5_hw_cpu32(rx_cqe->offload_type);
rx_cqe_sendup->hash_val = hinic5_hw_cpu32(rx_cqe->hash_val);
}
}
-static int rx_cqe_check(struct hinic5_nic_dev *nic_dev, struct hinic5_rq_cqe *rx_cqe)
+static int rx_cqe_check(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_rq_cqe *rx_cqe)
{
- struct hinic5_rq_cqe rx_cqe_sendup = {0};
+ struct hinic5_rq_cqe rx_cqe_sendup = { 0 };
int i, ret = 0;
for (i = 0; i < SERVICE_T_MAX; i++) {
if (nic_dev->tx_rx_ops.cqe_cb[i] &&
test_bit(i, &nic_dev->tx_rx_ops.cqe_cb_state[i])) {
- hinic5_rx_cqe_sendup_convert(rx_cqe, &rx_cqe_sendup, nic_dev->cqe_mode);
+ hinic5_rx_cqe_sendup_convert(rx_cqe, &rx_cqe_sendup,
+ nic_dev->cqe_mode);
set_bit(i, &nic_dev->tx_rx_ops.cqe_cb_running[i]);
- ret = nic_dev->tx_rx_ops.cqe_cb[i](nic_dev->lld_dev, &rx_cqe_sendup);
+ ret = nic_dev->tx_rx_ops.cqe_cb[i](nic_dev->lld_dev,
+ &rx_cqe_sendup);
if (ret != 0) {
- clear_bit(i, &nic_dev->tx_rx_ops.cqe_cb_running[i]);
+ clear_bit(
+ i,
+ &nic_dev->tx_rx_ops.cqe_cb_running[i]);
break;
}
clear_bit(i, &nic_dev->tx_rx_ops.cqe_cb_running[i]);
@@ -972,7 +1019,8 @@ static int rx_cqe_check(struct hinic5_nic_dev *nic_dev, struct hinic5_rq_cqe *rx
return ret;
}
-static void rx_free_warning_wqe(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info)
+static void rx_free_warning_wqe(struct hinic5_rxq *rxq,
+ struct hinic5_cqe_info *cqe_info)
{
u8 sge_num, packet_offset;
u32 pkt_len;
@@ -985,31 +1033,46 @@ static void rx_free_warning_wqe(struct hinic5_rxq *rxq, struct hinic5_cqe_info *
rxq->delta += sge_num;
}
+static void hinic5_rx_poll_update_stats(struct hinic5_rxq *rxq, int pkts,
+ u64 rx_bytes, u64 dropped, u64 pkt_mc)
+{
+ u64_stats_update_begin(&rxq->rxq_stats.syncp);
+
+ rxq->rxq_stats.packets += (u64)pkts;
+ rxq->rxq_stats.bytes += rx_bytes;
+ rxq->rxq_stats.dropped += dropped;
+ rxq->rxq_stats.pkt_mc += pkt_mc;
+
+ u64_stats_update_end(&rxq->rxq_stats.syncp);
+}
+
int hinic5_rx_poll(struct hinic5_rxq *rxq, int budget)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(rxq->netdev);
- u32 dropped = 0;
- u64 pkt_mc = 0;
struct hinic5_rq_cqe *rx_cqe = NULL;
struct hinic5_cqe_info *cqe_info = NULL;
- u64 rx_bytes = 0;
+ u64 rx_bytes = 0, dropped = 0, pkt_mc = 0;
int pkts = 0;
u16 num_wqe = 0;
u16 sw_ci = 0;
- bool enable_pfe = HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD);
+ bool enable_pfe =
+ HINIC5_SUPPORT_FEATURE(nic_dev->hwdev, TC_FLOWER_OFFLOAD);
int ret = 0;
while (likely(pkts < budget)) {
- if (!nic_dev->tx_rx_ops.rx_cqe_done(rxq, &rx_cqe))
+ if (!nic_dev->tx_rx_ops.rx_cqe_done(rxq, &rx_cqe)) {
break;
+ }
/* make sure we read rx_done before packet length */
rmb();
sw_ci = (u16)(rxq->cons_idx & rxq->q_mask);
cqe_info = rxq->rx_info[sw_ci].cqe_info;
- nic_dev->tx_rx_ops.rx_get_cqe_info(rx_cqe, cqe_info, nic_dev->cqe_mode, enable_pfe);
+ nic_dev->tx_rx_ops.rx_get_cqe_info(
+ rx_cqe, cqe_info, nic_dev->cqe_mode, enable_pfe);
- if (nic_dev->support_htn && (rx_cqe_check(nic_dev, rx_cqe) != 0)) {
+ if (nic_dev->support_htn &&
+ (rx_cqe_check(nic_dev, rx_cqe) != 0)) {
rx_free_warning_wqe(rxq, cqe_info);
dropped++;
rx_cqe->status = 0;
@@ -1020,23 +1083,23 @@ int hinic5_rx_poll(struct hinic5_rxq *rxq, int budget)
if (ret < 0)
break;
- /* In separate CQE mode, the done bit needs to be cleared */
+ /* 分离cqe场景下需要清零done bit */
if (nic_dev->cqe_mode == HINIC5_RQ_CQE_SEPARATE)
rx_cqe->status = 0;
- #ifdef HAVE_XDP_SUPPORT
+#ifdef HAVE_XDP_SUPPORT
if (ret == HINIC5_XDP_PROCESSED)
continue;
- #endif
+#endif
rx_bytes += cqe_info->pkt_len;
pkts++;
- if (cqe_info->pkt_mc == MULTICAST)
- pkt_mc++;
+ pkt_mc = (cqe_info->pkt_mc == MULTICAST) ? pkt_mc + 1 : pkt_mc;
if (cqe_info->lro_num > 1) {
- rx_bytes += ((cqe_info->lro_num - 1) * LRO_PKT_HDR_LEN(cqe_info->ip_type));
+ rx_bytes += ((cqe_info->lro_num - 1) *
+ LRO_PKT_HDR_LEN(cqe_info->ip_type));
num_wqe += HINIC5_GET_SGE_NUM(cqe_info->pkt_len, rxq);
}
@@ -1047,12 +1110,8 @@ int hinic5_rx_poll(struct hinic5_rxq *rxq, int budget)
if (rxq->delta >= HINIC5_RX_BUFFER_WRITE)
hinic5_rx_fill_buffers(rxq);
- u64_stats_update_begin(&rxq->rxq_stats.syncp);
- rxq->rxq_stats.packets += (u64)(u32)pkts;
- rxq->rxq_stats.bytes += rx_bytes;
- rxq->rxq_stats.dropped += (u64)dropped;
- rxq->rxq_stats.pkt_mc += pkt_mc;
- u64_stats_update_end(&rxq->rxq_stats.syncp);
+ hinic5_rx_poll_update_stats(rxq, pkts, rx_bytes, dropped, pkt_mc);
+
#ifdef HAVE_XDP_SUPPORT
hinic5_xdp_flush_if_needed(nic_dev);
#endif
@@ -1060,13 +1119,14 @@ int hinic5_rx_poll(struct hinic5_rxq *rxq, int budget)
}
#ifdef HAVE_PAGE_POOL_SUPPORT
-static struct page_pool *hinic5_create_page_pool(struct hinic5_nic_dev *nic_dev,
- u32 rq_depth,
- struct hinic5_rx_info *rx_info_arr)
+static struct page_pool *
+hinic5_create_page_pool(struct hinic5_nic_dev *nic_dev, u32 rq_depth,
+ struct hinic5_rx_info *rx_info_arr)
{
struct page_pool_params pp_params = {
#ifdef HAVE_PP_FLAG_PAGE_FRAG
- .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
#else
.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
#endif
@@ -1082,8 +1142,8 @@ static struct page_pool *hinic5_create_page_pool(struct hinic5_nic_dev *nic_dev,
struct page_pool *page_pool = NULL;
u32 i;
- page_pool = nic_dev->page_pool_enabled ?
- page_pool_create(&pp_params) : NULL;
+ page_pool = nic_dev->page_pool_enabled ? page_pool_create(&pp_params) :
+ NULL;
for (i = 0; i < rq_depth; i++)
rx_info_arr[i].page_pool = page_pool;
return page_pool;
@@ -1105,13 +1165,15 @@ int hinic5_alloc_rxqs_res(struct hinic5_nic_dev *nic_dev, u16 num_rq,
size = sizeof(*rqres->rx_info) * rq_depth;
rqres->rx_info = kzalloc(size, GFP_KERNEL);
- if (!rqres->rx_info)
+ if (!rqres->rx_info) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc rxq%d rx info\n", idx);
goto err_alloc_rx_info;
+ }
if (nic_dev->cqe_mode == HINIC5_RQ_CQE_SEPARATE) {
- rqres->cqe_start_vaddr = dma_zalloc_coherent(nic_dev->lld_dev->dev,
- cqe_mem_size,
- &rqres->cqe_start_paddr,
- GFP_KERNEL);
+ rqres->cqe_start_vaddr = dma_zalloc_coherent(
+ nic_dev->lld_dev->dev, cqe_mem_size,
+ &rqres->cqe_start_paddr, GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
@@ -1120,22 +1182,27 @@ int hinic5_alloc_rxqs_res(struct hinic5_nic_dev *nic_dev, u16 num_rq,
}
rqres->cqe_info = kzalloc(cqe_info_mem_size, GFP_KERNEL);
- if (!rqres->cqe_info)
+ if (!rqres->cqe_info) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc rxq%d cqe_info\n", idx);
goto err_alloc_cqe_info;
+ }
#ifdef HAVE_PAGE_POOL_SUPPORT
if (nic_dev->page_pool_enabled) {
- rqres->page_pool = hinic5_create_page_pool(nic_dev, rq_depth,
- rqres->rx_info);
+ rqres->page_pool = hinic5_create_page_pool(
+ nic_dev, rq_depth, rqres->rx_info);
if (!rqres->page_pool) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to create rxq%d page pool\n", idx);
+ "Failed to create rxq%d page pool\n",
+ idx);
goto err_create_page_pool;
}
}
#endif
- pkts = hinic5_rx_alloc_buffers(nic_dev, rq_depth, rqres->rx_info);
+ pkts = hinic5_rx_alloc_buffers(nic_dev, rq_depth,
+ rqres->rx_info);
if (pkts == 0) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
@@ -1154,7 +1221,8 @@ int hinic5_alloc_rxqs_res(struct hinic5_nic_dev *nic_dev, u16 num_rq,
kfree(rqres->cqe_info);
err_alloc_cqe_info:
if (nic_dev->cqe_mode == HINIC5_RQ_CQE_SEPARATE) {
- dma_free_coherent(nic_dev->lld_dev->dev, cqe_mem_size, rqres->cqe_start_vaddr,
+ dma_free_coherent(nic_dev->lld_dev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
}
err_alloc_cqe:
@@ -1183,7 +1251,8 @@ void hinic5_free_rxqs_res(struct hinic5_nic_dev *nic_dev, u16 num_rq,
kfree(rqres->cqe_info);
if (nic_dev->cqe_mode == HINIC5_RQ_CQE_SEPARATE) {
dma_free_coherent(nic_dev->lld_dev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr, rqres->cqe_start_paddr);
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
}
kfree(rqres->rx_info);
}
@@ -1207,14 +1276,16 @@ void hinic5_remove_configure_rxqs(struct hinic5_nic_dev *nic_dev)
int idx = 0;
struct hinic5_rxq *rxq = NULL;
- for (idx = 0; idx < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; idx++) {
+ for (idx = 0;
+ idx < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ idx++) {
rxq = &nic_dev->rxqs[idx];
rxq->xdp_prog = NULL;
xdp_rxq_info_unreg(&rxq->xdp_rxq);
}
#endif
+ return;
}
-
int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic5_dyna_rxq_res *rxqs_res)
{
@@ -1243,7 +1314,7 @@ int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev, u16 num_rq,
rxq->last_sw_pi = rxq->q_depth - 1;
rxq->rx_info = rqres->rx_info;
#ifdef HAVE_XDP_SUPPORT
- rxq->xdp_headroom_flag = nic_dev->xdp_prog ? 1 : 0;
+ rxq->xdp_headroom_flag = (nic_dev->xdp_prog != NULL) ? 1 : 0;
#endif
/* fill cqe */
@@ -1258,18 +1329,22 @@ int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev, u16 num_rq,
}
}
- for (idx = 0; idx < rq_depth; idx++)
+ for (idx = 0; idx < rq_depth; idx++) {
rxq->rx_info[idx].cqe_info = &rqres->cqe_info[idx];
+ }
- rxq->rq = hinic5_get_nic_queue(nic_dev->hwdev, rxq->q_id, HINIC5_RQ);
- if (!rxq->rq) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to get rq\n");
+ rxq->rq = hinic5_get_nic_queue(nic_dev->hwdev, rxq->q_id,
+ HINIC5_RQ);
+ if (rxq->rq == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to get rq\n");
return -EINVAL;
}
pkts = hinic5_rx_fill_wqe(rxq);
if (pkts != rxq->q_depth) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to fill rx wqe\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to fill rx wqe\n");
return -EFAULT;
}
@@ -1282,7 +1357,8 @@ int hinic5_configure_rxqs(struct hinic5_nic_dev *nic_dev, u16 num_rq,
#ifdef HAVE_XDP_SUPPORT
rxq->xdp_prog = nic_dev->xdp_prog;
#ifdef HAVE_XDP_RXQ_INFO_REG_NAPI_ID
- err = xdp_rxq_info_reg(&rxq->xdp_rxq, nic_dev->netdev, q_id, q_id);
+ err = xdp_rxq_info_reg(&rxq->xdp_rxq, nic_dev->netdev, q_id,
+ q_id);
#else
err = xdp_rxq_info_reg(&rxq->xdp_rxq, nic_dev->netdev, q_id);
#endif
@@ -1318,8 +1394,10 @@ int hinic5_alloc_rxqs(struct net_device *netdev)
}
nic_dev->rxqs = kzalloc(rxq_size, GFP_KERNEL);
- if (!nic_dev->rxqs)
+ if (nic_dev->rxqs == NULL) {
+ nic_err(dev, "Failed to allocate rxqs\n");
return -ENOMEM;
+ }
for (q_id = 0; q_id < num_rxqs; q_id++) {
rxq = &nic_dev->rxqs[q_id];
@@ -1346,10 +1424,11 @@ int hinic5_rx_configure(struct net_device *netdev, u8 dcb_en)
/* Set all rq mapping to all iq in default */
- memset(rq2iq_map, 0xFF, sizeof(rq2iq_map));
+ (void)memset_s(rq2iq_map, sizeof(rq2iq_map), 0xFF, sizeof(rq2iq_map));
if (test_bit(HINIC5_RSS_ENABLE, &nic_dev->flags) != 0) {
- err = hinic5_rss_init(nic_dev, rq2iq_map, sizeof(rq2iq_map), dcb_en);
+ err = hinic5_rss_init(nic_dev, rq2iq_map, sizeof(rq2iq_map),
+ dcb_en);
if (err != 0) {
nicif_err(nic_dev, drv, netdev, "Failed to init rss\n");
return -EFAULT;
@@ -1367,7 +1446,7 @@ void hinic5_rx_remove_configure(struct net_device *netdev)
hinic5_rss_deinit(nic_dev);
}
-int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
+int rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
{
struct hinic5_rxq *rxq = &nic_dev->rxqs[q_id];
struct hinic5_rq_wqe *rq_wqe = NULL;
@@ -1387,7 +1466,8 @@ int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
buff_pi = rxq->restore_pi;
if ((((rxq->cons_idx & rxq->q_mask) + rxq->q_depth -
- rxq->next_to_update) % rxq->q_depth) != rxq->delta)
+ rxq->next_to_update) %
+ rxq->q_depth) != rxq->delta)
return -EINVAL;
for (i = 0; i < free_wqebbs; i++) {
@@ -1395,7 +1475,8 @@ int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
if (unlikely(!rx_alloc_mapped_page(nic_dev, rx_info))) {
RXQ_STATS_INC(rxq, alloc_rx_buf_err);
- rxq->restore_pi = (u16)((rxq->restore_pi + i) & rxq->q_mask);
+ rxq->restore_pi =
+ (u16)((rxq->restore_pi + i) & rxq->q_mask);
return -ENOMEM;
}
@@ -1418,16 +1499,17 @@ int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
rxq->restore_buf_num++;
}
- nic_info(nic_dev->lld_dev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
+ nic_info(nic_dev->lld_dev->dev, "rxq %u restore_buf_num:%u\n", q_id,
+ rxq->restore_buf_num);
- rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+ rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
if (rx_info->buf_dma_addr != 0) {
dma_unmap_page(nic_dev->lld_dev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
rx_info->buf_dma_addr = 0;
}
- if (rx_info->page) {
+ if (rx_info->page != NULL) {
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
@@ -1439,7 +1521,8 @@ int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
rxq->next_to_alloc = rxq->next_to_update;
for (i = 0; i < rxq->q_depth; i++) {
- if (HINIC5_GET_RX_DONE(hinic5_hw_cpu32(rxq->rx_info[i].cqe->status)) == 0)
+ if (HINIC5_GET_RX_DONE(
+ hinic5_hw_cpu32(rxq->rx_info[i].cqe->status)) == 0)
continue;
RXQ_STATS_INC(rxq, restore_drop_sge);
@@ -1452,18 +1535,20 @@ int hinic5_rxq_restore(struct hinic5_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- hinic5_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
+ hinic5_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1), RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
return 0;
}
-bool hinic5_rxq_is_normal(struct hinic5_rxq *rxq, struct rxq_check_info rxq_info)
+bool rxq_is_normal(struct hinic5_rxq *rxq, struct rxq_check_info rxq_info)
{
u32 status;
- if (rxq->rxq_stats.packets != rxq->last_packets || rxq_info.hw_pi != rxq_info.hw_ci ||
- rxq_info.hw_ci != rxq->last_hw_ci || rxq->next_to_update != rxq->last_sw_pi)
+ if (rxq->rxq_stats.packets != rxq->last_packets ||
+ rxq_info.hw_pi != rxq_info.hw_ci ||
+ rxq_info.hw_ci != rxq->last_hw_ci ||
+ rxq->next_to_update != rxq->last_sw_pi)
return true;
/* hw rx no wqe and driver rx no packet recv */
@@ -1485,7 +1570,8 @@ bool hinic5_rxq_is_normal(struct hinic5_rxq *rxq, struct rxq_check_info rxq_info
void hinic5_rxq_check_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic5_nic_dev *nic_dev = container_of(delay, struct hinic5_nic_dev, rxq_check_work);
+ struct hinic5_nic_dev *nic_dev =
+ container_of(delay, struct hinic5_nic_dev, rxq_check_work);
struct rxq_check_info *rxq_info = NULL;
struct hinic5_rxq *rxq = NULL;
u64 size;
@@ -1496,7 +1582,8 @@ void hinic5_rxq_check_work_handler(struct work_struct *work)
return;
if (test_bit(HINIC5_RXQ_RECOVERY, &nic_dev->flags) != 0)
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work,
+ HZ);
#ifdef HAVE_PAGE_POOL_SUPPORT
if (nic_dev->page_pool_enabled)
@@ -1508,10 +1595,11 @@ void hinic5_rxq_check_work_handler(struct work_struct *work)
return;
rxq_info = kzalloc(size, GFP_KERNEL);
- if (!rxq_info)
+ if (rxq_info == NULL)
return;
- err = hinic5_get_rxq_hw_info(nic_dev->hwdev, rxq_info, nic_dev->q_params.num_qps,
+ err = hinic5_get_rxq_hw_info(nic_dev->hwdev, rxq_info,
+ nic_dev->q_params.num_qps,
nic_dev->rxqs[0].rq->wqe_type);
if (err != 0) {
nic_dev->rxq_get_err_times++;
@@ -1522,20 +1610,24 @@ void hinic5_rxq_check_work_handler(struct work_struct *work)
for (qid = 0; qid < nic_dev->q_params.num_qps; qid++) {
rxq = &nic_dev->rxqs[qid];
- if (!hinic5_rxq_is_normal(rxq, rxq_info[qid])) {
+ if (!rxq_is_normal(rxq, rxq_info[qid])) {
rxq->rx_check_err_cnt++;
if (rxq->rx_check_err_cnt < RXQ_CHECK_ERR_TIMES)
continue;
if (rxq->rxq_print_times <= RXQ_PRINT_MAX_TIMES) {
- nic_warn(nic_dev->lld_dev->dev, "rxq %u wqe abnormal, hw_pi:%u, hw_ci:%u, sw_pi:%u, sw_ci:%u delta:%u\n",
- qid, rxq_info[qid].hw_pi, rxq_info[qid].hw_ci,
- rxq->next_to_update,
- rxq->cons_idx & rxq->q_mask, rxq->delta);
+ nic_warn(
+ nic_dev->lld_dev->dev,
+ "rxq %u wqe abnormal, hw_pi:%u, hw_ci:%u, sw_pi:%u, sw_ci:%u delta:%u\n",
+ qid, rxq_info[qid].hw_pi,
+ rxq_info[qid].hw_ci,
+ rxq->next_to_update,
+ rxq->cons_idx & rxq->q_mask,
+ rxq->delta);
rxq->rxq_print_times++;
}
- if (hinic5_rxq_restore(nic_dev, qid, rxq_info[qid].hw_ci) != 0)
+ if (rxq_restore(nic_dev, qid, rxq_info[qid].hw_ci) != 0)
continue;
}
@@ -1553,8 +1645,8 @@ void hinic5_rxq_check_work_handler(struct work_struct *work)
kfree(rxq_info);
}
-int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type event,
- hinic5_cqe_cb cqe_cb)
+int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type event, hinic5_cqe_cb cqe_cb)
{
struct hinic5_nic_dev *nic_dev = NULL;
@@ -1563,8 +1655,9 @@ int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_t
return -EINVAL;
nic_dev = hinic5_get_uld_dev_unsafe(lld_dev, SERVICE_T_NIC);
- if (!nic_dev) {
- nic_err(lld_dev->dev, "There's no net device attached on the pci device");
+ if (nic_dev == NULL) {
+ nic_err(lld_dev->dev,
+ "There's no net device attached on the pci device");
return -EINVAL;
}
@@ -1575,22 +1668,24 @@ int hinic5_register_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_t
}
EXPORT_SYMBOL(hinic5_register_cqe_cb);
-void hinic5_unregister_cqe_cb(struct hinic5_lld_dev *lld_dev, enum hinic5_service_type event)
+void hinic5_unregister_cqe_cb(struct hinic5_lld_dev *lld_dev,
+ enum hinic5_service_type event)
{
struct hinic5_nic_dev *nic_dev = NULL;
- if (!lld_dev || event >= SERVICE_T_MAX || !hinic5_support_nic(lld_dev->hwdev, NULL))
+ if (!lld_dev || event >= SERVICE_T_MAX ||
+ !hinic5_support_nic(lld_dev->hwdev, NULL))
return;
nic_dev = hinic5_get_uld_dev_unsafe(lld_dev, SERVICE_T_NIC);
- if (!nic_dev)
+ if (nic_dev == NULL)
return;
clear_bit(event, &nic_dev->tx_rx_ops.cqe_cb_state[event]);
- while (test_bit(event,
- &nic_dev->tx_rx_ops.cqe_cb_running[event]))
- usleep_range(HINIC5_RQ_CQE_USLEEP_LOW_BOUND, HINIC5_RQ_CQE_USLEEP_HIGH_BOUND);
+ while (test_bit(event, &nic_dev->tx_rx_ops.cqe_cb_running[event]))
+ usleep_range(HINIC5_RQ_CQE_USLEEP_LOW_BOUND,
+ HINIC5_RQ_CQE_USLEEP_HIGH_BOUND);
nic_dev->tx_rx_ops.cqe_cb[event] = NULL;
}
EXPORT_SYMBOL(hinic5_unregister_cqe_cb);
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.h
index 97525a6b7..8eb1adc36 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_rx.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_rx.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_RX_H
#define HINIC5_RX_H
@@ -24,51 +17,51 @@
#include "hinic5_nic_rq.h"
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC5_RX_HDR_SIZE 256
-#define HINIC5_RX_BUFFER_WRITE 16
+#define HINIC5_RX_HDR_SIZE 256
+#define HINIC5_RX_BUFFER_WRITE 16
-#define HINIC5_RX_TCP_PKT 0x3
-#define HINIC5_RX_UDP_PKT 0x4
-#define HINIC5_RX_SCTP_PKT 0x7
+#define HINIC5_RX_TCP_PKT 0x3
+#define HINIC5_RX_UDP_PKT 0x4
+#define HINIC5_RX_SCTP_PKT 0x7
-#define HINIC5_RX_IPV4_PKT 0
-#define HINIC5_RX_IPV6_PKT 1
-#define HINIC5_RX_INVALID_IP_TYPE 2
+#define HINIC5_RX_IPV4_PKT 0
+#define HINIC5_RX_IPV6_PKT 1
+#define HINIC5_RX_INVALID_IP_TYPE 2
-#define HINIC5_RX_PKT_FORMAT_NON_TUNNEL 0
-#define HINIC5_RX_PKT_FORMAT_VXLAN 1
+#define HINIC5_RX_PKT_FORMAT_NON_TUNNEL 0
+#define HINIC5_RX_PKT_FORMAT_VXLAN 1
-#define RXQ_STATS_INC(rxq, field) \
-do { \
- u64_stats_update_begin(&(rxq)->rxq_stats.syncp); \
- (rxq)->rxq_stats.field++; \
- u64_stats_update_end(&(rxq)->rxq_stats.syncp); \
-} while (0)
+#define RXQ_STATS_INC(rxq, field) \
+ do { \
+ u64_stats_update_begin(&(rxq)->rxq_stats.syncp); \
+ (rxq)->rxq_stats.field++; \
+ u64_stats_update_end(&(rxq)->rxq_stats.syncp); \
+ } while (0)
-#define HINIC5_GET_SGE_NUM(pkt_len, rxq) \
- ((u8)(((pkt_len) >> (rxq)->rx_buff_shift) + \
- ((((pkt_len) & ((rxq)->buf_len - 1)) != 0) ? 1 : 0)))
+#define HINIC5_GET_SGE_NUM(pkt_len, rxq) \
+ ((u8)(((pkt_len) >> (rxq)->rx_buff_shift) + \
+ ((((pkt_len) & ((rxq)->buf_len - 1)) != 0) ? 1 : 0)))
/* rx cqe checksum err */
-#define HINIC5_RX_CSUM_IP_CSUM_ERR BIT(0)
-#define HINIC5_RX_CSUM_TCP_CSUM_ERR BIT(1)
-#define HINIC5_RX_CSUM_UDP_CSUM_ERR BIT(2)
-#define HINIC5_RX_CSUM_IGMP_CSUM_ERR BIT(3)
-#define HINIC5_RX_CSUM_ICMPV4_CSUM_ERR BIT(4)
-#define HINIC5_RX_CSUM_ICMPV6_CSUM_ERR BIT(5)
-#define HINIC5_RX_CSUM_SCTP_CRC_ERR BIT(6)
-#define HINIC5_RX_CSUM_HW_CHECK_NONE BIT(7)
-#define HINIC5_RX_CSUM_IPSU_OTHER_ERR BIT(8)
+#define HINIC5_RX_CSUM_IP_CSUM_ERR BIT(0)
+#define HINIC5_RX_CSUM_TCP_CSUM_ERR BIT(1)
+#define HINIC5_RX_CSUM_UDP_CSUM_ERR BIT(2)
+#define HINIC5_RX_CSUM_IGMP_CSUM_ERR BIT(3)
+#define HINIC5_RX_CSUM_ICMPV4_CSUM_ERR BIT(4)
+#define HINIC5_RX_CSUM_ICMPV6_CSUM_ERR BIT(5)
+#define HINIC5_RX_CSUM_SCTP_CRC_ERR BIT(6)
+#define HINIC5_RX_CSUM_HW_CHECK_NONE BIT(7)
+#define HINIC5_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC5_HEADER_DATA_UNIT 2
#define HINIC5_CQE_LEN 32
#define HINIC5_COMPACT_CQE_8B 8
#define HINIC5_COMPACT_CQE_16B 16
-#define HINIC5_RQ_CQE_SEPARATE 0
-#define HINIC5_RQ_CQE_INTEGRATE 1
+#define HINIC5_RQ_CQE_SEPARATE 0
+#define HINIC5_RQ_CQE_INTEGRATE 1
-#define HINIC5_RQ_CQE_USLEEP_LOW_BOUND 900
+#define HINIC5_RQ_CQE_USLEEP_LOW_BOUND 900
#define HINIC5_RQ_CQE_USLEEP_HIGH_BOUND 1000
/* flow bifurcation */
@@ -76,27 +69,27 @@ do { \
#define HINIC5_GROUP_NUMBER_MAX 8
struct hinic5_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 restore_drop_sge;
- u64 pkt_mc;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 restore_drop_sge;
+ u64 pkt_mc;
#ifdef HAVE_XDP_SUPPORT
- u64 xdp_dropped;
- u64 xdp_redirected;
- u64 xdp_large_pkt;
+ u64 xdp_dropped;
+ u64 xdp_redirected;
+ u64 xdp_large_pkt;
#endif
#ifdef HAVE_NDO_GET_STATS64
- struct u64_stats_sync syncp;
+ struct u64_stats_sync syncp;
#else
- struct u64_stats_sync_empty syncp;
+ struct u64_stats_sync_empty syncp;
#endif
};
@@ -131,7 +124,7 @@ struct hinic5_rxq {
u32 rx_buff_shift;
u32 dma_rx_buff_size;
- struct hinic5_rxq_stats rxq_stats;
+ struct hinic5_rxq_stats rxq_stats;
u32 cons_idx;
u32 delta;
@@ -220,10 +213,12 @@ void hinic5_rxq_clean_stats(struct hinic5_rxq_stats *rxq_stats);
void hinic5_rxq_check_work_handler(struct work_struct *work);
void hinic5_rx_get_cqe_info(struct hinic5_rq_cqe *cqe,
- struct hinic5_cqe_info *info, u8 cqe_mode, bool enable_pfe);
+ struct hinic5_cqe_info *info, u8 cqe_mode,
+ bool enable_pfe);
void hinic5_rx_get_compact_cqe_info(struct hinic5_rq_cqe *cqe,
- struct hinic5_cqe_info *info, u8 cqe_mode, bool enable_pfe);
+ struct hinic5_cqe_info *info, u8 cqe_mode,
+ bool enable_pfe);
void hinic5_reuse_rx_page(struct hinic5_rxq *rxq,
struct hinic5_rx_info *old_rx_info);
@@ -231,8 +226,10 @@ void hinic5_reuse_rx_page(struct hinic5_rxq *rxq,
struct sk_buff *hinic5_fetch_rx_buffer(struct hinic5_rxq *rxq,
const struct hinic5_cqe_info *cqe_info);
-bool hinic5_rx_separate_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **rx_cqe);
+bool hinic5_rx_separate_cqe_done(struct hinic5_rxq *rxq,
+ struct hinic5_rq_cqe **rx_cqe);
-bool hinic5_rx_integrated_cqe_done(struct hinic5_rxq *rxq, struct hinic5_rq_cqe **rx_cqe);
+bool hinic5_rx_integrated_cqe_done(struct hinic5_rxq *rxq,
+ struct hinic5_rq_cqe **rx_cqe);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.c
index cd084c647..4782a2840 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_tx.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : TX queue implementation
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -38,28 +31,27 @@
#include "hinic5_ptp.h"
#include "hinic5_tx.h"
-/* 1872 FT B600 temporary solution, to be removed after config file adaptation */
-#define QP_COS_MASK 7
+/* 1872 FT B600临时修改方案,配置文件适配后删除 */
+#define QP_COS_MASK 7
static char qp_cos_mask = QP_COS_MASK;
module_param(qp_cos_mask, byte, 0444);
MODULE_PARM_DESC(qp_cos_mask, "QP COS mask, 0-255 (default=0)");
/* The 1823v200 product non-tso SGEs is 32, and that of the 1825v100&1872v100 is 38.
- * The number of non-tso SGEs is strictly constrained to 32.
- */
-#define HINIC5_NONTSO_PKT_MAX_SGE 32
+ The number of non-tso SGEs is strictly constrained to 32. */
+#define HINIC5_NONTSO_PKT_MAX_SGE 32
-#define MIN_SKB_LEN 32
+#define MIN_SKB_LEN 32
-#define MAX_PAYLOAD_OFFSET 221
+#define MAX_PAYLOAD_OFFSET 221
-#define NIC_QID(q_id, nic_dev) ((q_id) & ((nic_dev)->num_qps - 1))
+#define NIC_QID(q_id, nic_dev) ((q_id) & ((nic_dev)->num_qps - 1))
-#define HINIC5_TX_TASK_WRAPPED 1
-#define HINIC5_TX_BD_DESC_WRAPPED 2
+#define HINIC5_TX_TASK_WRAPPED 1
+#define HINIC5_TX_BD_DESC_WRAPPED 2
-#define NON_TSO_SKB_SIZE_MAX 0xFFFF
-#define TSO_SKB_SIZE_MAX 0x3FFFF
+#define NON_TSO_SKB_SIZE_MAX 0xFFFF
+#define TSO_SKB_SIZE_MAX 0x3FFFF
void hinic5_txq_get_stats(struct hinic5_txq *txq,
struct hinic5_txq_stats *stats)
@@ -153,7 +145,7 @@ static inline void hinic5_set_buf_desc(struct hinic5_sq_bufdesc *buf_descs,
{
buf_descs->hi_addr = hinic5_hw_be32(upper_32_bits(addr));
buf_descs->lo_addr = hinic5_hw_be32(lower_32_bits(addr));
- buf_descs->len = hinic5_hw_be32(len);
+ buf_descs->len = hinic5_hw_be32(len);
buf_descs->rsvd = 0;
}
@@ -170,7 +162,8 @@ static int tx_map_skb(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb,
u32 j, i;
int err;
- dma_info[0].dma = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+ dma_info[0].dma =
+ dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_info[0].dma) != 0) {
TXQ_STATS_INC(txq, map_frag_err);
return -EFAULT;
@@ -189,9 +182,8 @@ static int tx_map_skb(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb,
buf_desc = wqe_combo->bds_sec2;
i++;
- dma_info[i].dma = skb_frag_dma_map(dev, frag, 0,
- skb_frag_size(frag),
- DMA_TO_DEVICE);
+ dma_info[i].dma = skb_frag_dma_map(
+ dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_info[i].dma) != 0) {
TXQ_STATS_INC(txq, map_frag_err);
i--;
@@ -200,8 +192,7 @@ static int tx_map_skb(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb,
}
dma_info[i].len = skb_frag_size(frag);
- hinic5_set_buf_desc(buf_desc, dma_info[i].dma,
- dma_info[i].len);
+ hinic5_set_buf_desc(buf_desc, dma_info[i].dma, dma_info[i].len);
buf_desc++;
}
@@ -210,11 +201,10 @@ static int tx_map_skb(struct hinic5_nic_dev *nic_dev, struct sk_buff *skb,
frag_map_err:
for (j = 0; j < i;) {
j++;
- dma_unmap_page(dev, dma_info[j].dma,
- dma_info[j].len, DMA_TO_DEVICE);
+ dma_unmap_page(dev, dma_info[j].dma, dma_info[j].len,
+ DMA_TO_DEVICE);
}
- dma_unmap_single(dev, dma_info[0].dma, dma_info[0].len,
- DMA_TO_DEVICE);
+ dma_unmap_single(dev, dma_info[0].dma, dma_info[0].len, DMA_TO_DEVICE);
return err;
}
@@ -227,13 +217,11 @@ static inline void tx_unmap_skb(struct hinic5_nic_dev *nic_dev,
for (i = 0; i < valid_nr_frags;) {
i++;
- dma_unmap_page(dev,
- dma_info[i].dma,
- dma_info[i].len, DMA_TO_DEVICE);
+ dma_unmap_page(dev, dma_info[i].dma, dma_info[i].len,
+ DMA_TO_DEVICE);
}
- dma_unmap_single(dev, dma_info[0].dma,
- dma_info[0].len, DMA_TO_DEVICE);
+ dma_unmap_single(dev, dma_info[0].dma, dma_info[0].len, DMA_TO_DEVICE);
}
union hinic5_l4 {
@@ -250,10 +238,10 @@ enum sq_l3_type {
};
enum sq_l4offload_type {
- OFFLOAD_DISABLE = 0,
- TCP_OFFLOAD_ENABLE = 1,
+ OFFLOAD_DISABLE = 0,
+ TCP_OFFLOAD_ENABLE = 1,
SCTP_OFFLOAD_ENABLE = 2,
- UDP_OFFLOAD_ENABLE = 3,
+ UDP_OFFLOAD_ENABLE = 3,
};
/* initialize l4_len and offset */
@@ -266,7 +254,7 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic5_l4 *l4,
*l4_offload = TCP_OFFLOAD_ENABLE;
/* To keep same with TSO, payload offset begins from paylaod */
*offset = (l4->tcp->doff << TCP_HDR_DATA_OFF_UNIT_SHIFT) +
- TRANSPORT_OFFSET(l4->hdr, skb);
+ TRANSPORT_OFFSET(l4->hdr, skb);
break;
case IPPROTO_UDP:
@@ -279,7 +267,8 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic5_l4 *l4,
}
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
-static inline int hinic5_check_tunnel_pkt_support(struct net_device *netdev, u8 l4_proto,
+static inline int hinic5_check_tunnel_pkt_support(struct net_device *netdev,
+ u8 l4_proto,
union hinic5_l4 l4)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
@@ -309,8 +298,8 @@ static inline int hinic5_check_tunnel_pkt_support(struct net_device *netdev, u8
}
#endif
static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic5_ip *ip,
- union hinic5_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
+ union hinic5_l4 *l4, enum sq_l3_type *l3_type,
+ u8 *l4_proto)
{
unsigned char *exthdr = NULL;
@@ -375,8 +364,9 @@ static void hinic5_set_unknown_tunnel_csum(struct sk_buff *skb)
if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
skb_csum = *(__sum16 *)(skb->data + csum_offset);
- if (skb_csum == 0xffff)
+ if (skb_csum == 0xffff) {
*(__sum16 *)(skb->data + csum_offset) = 0;
+ }
}
}
@@ -419,7 +409,8 @@ static int hinic5_tx_csum(struct hinic5_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (hinic5_check_tunnel_pkt_support(txq->netdev, l4_proto, l4) != 0) {
+ if (hinic5_check_tunnel_pkt_support(txq->netdev, l4_proto,
+ l4) != 0) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
hinic5_set_unknown_tunnel_csum(skb);
return 0;
@@ -435,8 +426,8 @@ static int hinic5_tx_csum(struct hinic5_txq *txq, struct sk_buff *skb,
static void hinic5_set_tso_info(struct hinic5_offload_info *offload_info,
struct hinic5_queue_info *queue_info,
- enum sq_l4offload_type l4_offload,
- u32 offset, u32 mss)
+ enum sq_l4offload_type l4_offload, u32 offset,
+ u32 mss)
{
if (l4_offload == TCP_OFFLOAD_ENABLE) {
queue_info->tso = 1;
@@ -455,10 +446,11 @@ static void hinic5_set_tso_info(struct hinic5_offload_info *offload_info,
queue_info->mss = (u16)mss;
}
-static inline void hinic5_inner_tso_offload(struct hinic5_offload_info *offload_info,
- struct hinic5_queue_info *queue_info,
- struct sk_buff *skb,
- union hinic5_ip ip, union hinic5_l4 l4)
+static inline void
+hinic5_inner_tso_offload(struct hinic5_offload_info *offload_info,
+ struct hinic5_queue_info *queue_info,
+ struct sk_buff *skb, union hinic5_ip ip,
+ union hinic5_l4 l4)
{
u8 l4_proto;
u32 offset = 0;
@@ -542,7 +534,8 @@ static int hinic5_tso(struct hinic5_offload_info *offload_info,
l4_proto = ip.v6->nexthdr;
l4_ptr.hdr = skb_transport_header(skb);
if (l4_ptr.hdr != exthdr)
- ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_proto, &frag_off);
+ ipv6_skip_exthdr(skb, exthdr - skb->data,
+ &l4_proto, &frag_off);
} else {
l4_proto = IPPROTO_RAW;
}
@@ -558,16 +551,19 @@ static int hinic5_tso(struct hinic5_offload_info *offload_info,
return 1;
}
-static inline void hinic5_set_vlan_tx_offload(struct hinic5_offload_info *offload_info,
- u16 vlan_tag, u8 vlan_type)
+static inline void
+hinic5_set_vlan_tx_offload(struct hinic5_offload_info *offload_info,
+ u16 vlan_tag, u8 vlan_type)
{
offload_info->vlan1_tag = vlan_tag;
offload_info->vlan_sel = vlan_type;
offload_info->vlan_valid = 1;
}
-u32 hinic5_tx_offload(struct sk_buff *skb, struct hinic5_offload_info *offload_info,
- struct hinic5_queue_info *queue_info, struct hinic5_txq *txq)
+u32 hinic5_tx_offload(struct sk_buff *skb,
+ struct hinic5_offload_info *offload_info,
+ struct hinic5_queue_info *queue_info,
+ struct hinic5_txq *txq)
{
u32 offload = 0;
int tso_cs_en;
@@ -598,8 +594,9 @@ u32 hinic5_tx_offload(struct sk_buff *skb, struct hinic5_offload_info *offload_i
}
if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) != 0)) {
offload |= TX_OFFLOAD_PTP;
- if (hinic5_ptp_tx_process(nic_dev, skb) == 0)
+ if (hinic5_ptp_tx_process(nic_dev, skb) == 0) {
offload_info->pkt_1588 = 1;
+ }
}
return offload;
@@ -612,7 +609,7 @@ static void get_pkt_stats(struct hinic5_tx_info *tx_info, struct sk_buff *skb)
if (skb_is_gso(skb)) {
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
- defined(HAVE_SK_BUFF_ENCAPSULATION))
+ defined(HAVE_SK_BUFF_ENCAPSULATION))
if (skb->encapsulation != 0) {
#ifdef HAVE_SKB_INNER_TRANSPORT_OFFSET
ihs = skb_inner_transport_offset(skb) +
@@ -624,17 +621,19 @@ static void get_pkt_stats(struct hinic5_tx_info *tx_info, struct sk_buff *skb)
} else {
#endif
#endif
- ihs = (u32)(skb_transport_offset(skb)) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
- defined(HAVE_SK_BUFF_ENCAPSULATION))
+ defined(HAVE_SK_BUFF_ENCAPSULATION))
}
#endif
#endif
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = (skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ? skb->len :
+ ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -692,7 +691,8 @@ static u16 hinic5_set_wqe_combo(struct hinic5_txq *txq,
wqe_combo->first_bds_num = first_part_wqebbs_num;
}
- return hinic5_get_and_update_sq_owner(txq->sq, *curr_pi, wqe_combo->wqebb_cnt);
+ return hinic5_get_and_update_sq_owner(txq->sq, *curr_pi,
+ wqe_combo->wqebb_cnt);
}
void hinic5_tx_set_normal_task_offload(struct hinic5_offload_info *offload,
@@ -707,17 +707,18 @@ void hinic5_tx_set_normal_task_offload(struct hinic5_offload_info *offload,
}
task->pkt_info0 =
- SQ_TASK_INFO0_SET(offload->inner_l4_en, INNER_L4_EN) |
- SQ_TASK_INFO0_SET(offload->inner_l3_en, INNER_L3_EN) |
- SQ_TASK_INFO0_SET(offload->encapsulation, TUNNEL_FLAG) |
- SQ_TASK_INFO0_SET(offload->out_l3_en, OUT_L3_EN) |
- SQ_TASK_INFO0_SET(offload->out_l4_en, OUT_L4_EN);
+ SQ_TASK_INFO0_SET(offload->inner_l4_en, INNER_L4_EN) |
+ SQ_TASK_INFO0_SET(offload->inner_l3_en, INNER_L3_EN) |
+ SQ_TASK_INFO0_SET(offload->encapsulation, TUNNEL_FLAG) |
+ SQ_TASK_INFO0_SET(offload->out_l3_en, OUT_L3_EN) |
+ SQ_TASK_INFO0_SET(offload->out_l4_en, OUT_L4_EN);
task->ip_identify = 0;
task->pkt_info2 = 0;
- task->vlan_offload = SQ_TASK_INFO3_SET(offload->vlan1_tag, VLAN_TAG) |
- SQ_TASK_INFO3_SET(offload->vlan_sel, VLAN_TYPE) |
- SQ_TASK_INFO3_SET(offload->vlan_valid, VLAN_TAG_VALID);
+ task->vlan_offload =
+ SQ_TASK_INFO3_SET(offload->vlan1_tag, VLAN_TAG) |
+ SQ_TASK_INFO3_SET(offload->vlan_sel, VLAN_TYPE) |
+ SQ_TASK_INFO3_SET(offload->vlan_valid, VLAN_TAG_VALID);
task->pkt_info0 = hinic5_hw_be32(task->pkt_info0);
task->vlan_offload = hinic5_hw_be32(task->vlan_offload);
}
@@ -726,16 +727,14 @@ void hinic5_tx_set_compact_task_offload(struct hinic5_offload_info *offload,
struct hinic5_sq_wqe_combo *wqe_combo)
{
struct hinic5_sq_task *task = wqe_combo->task;
-
- task->pkt_info0 =
- SQ_TASK_INFO_SET(offload->out_l3_en, OUT_L3_EN) |
- SQ_TASK_INFO_SET(offload->out_l4_en, OUT_L4_EN) |
- SQ_TASK_INFO_SET(offload->inner_l3_en, INNER_L3_EN) |
- SQ_TASK_INFO_SET(offload->inner_l4_en, INNER_L4_EN) |
- SQ_TASK_INFO_SET(offload->vlan_valid, VLAN_VALID) |
- SQ_TASK_INFO_SET(offload->vlan_sel, VLAN_SEL) |
- SQ_TASK_INFO_SET(offload->vlan1_tag, VLAN_TAG) |
- SQ_TASK_INFO_SET(offload->pkt_1588, PKT_1588);
+ task->pkt_info0 = SQ_TASK_INFO_SET(offload->out_l3_en, OUT_L3_EN) |
+ SQ_TASK_INFO_SET(offload->out_l4_en, OUT_L4_EN) |
+ SQ_TASK_INFO_SET(offload->inner_l3_en, INNER_L3_EN) |
+ SQ_TASK_INFO_SET(offload->inner_l4_en, INNER_L4_EN) |
+ SQ_TASK_INFO_SET(offload->vlan_valid, VLAN_VALID) |
+ SQ_TASK_INFO_SET(offload->vlan_sel, VLAN_SEL) |
+ SQ_TASK_INFO_SET(offload->vlan1_tag, VLAN_TAG) |
+ SQ_TASK_INFO_SET(offload->pkt_1588, PKT_1588);
task->pkt_info0 = hinic5_hw_be32(task->pkt_info0);
}
@@ -744,13 +743,13 @@ static void hinic5_set_wqe_queue_info(struct hinic5_sq_wqe_combo *wqe_combo,
{
u32 *qsf = &wqe_combo->ctrl_bd0->queue_info;
*qsf = SQ_CTRL_QUEUE_INFO_SET(1, UC) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->sctp, SCTP) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->udp_dp_en, UDP_DP_EN) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->tso, TSO) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->ufo, UFO) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->payload_offset, PLDOFF) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->pkt_type, PKT_TYPE) |
- SQ_CTRL_QUEUE_INFO_SET(queue_info->mss, MSS);
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->sctp, SCTP) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->udp_dp_en, UDP_DP_EN) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->tso, TSO) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->ufo, UFO) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->payload_offset, PLDOFF) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->pkt_type, PKT_TYPE) |
+ SQ_CTRL_QUEUE_INFO_SET(queue_info->mss, MSS);
if (SQ_CTRL_QUEUE_INFO_GET(*qsf, MSS) == 0) {
*qsf |= SQ_CTRL_QUEUE_INFO_SET(TX_MSS_DEFAULT, MSS);
@@ -768,24 +767,28 @@ static void hinic5_set_wqe_queue_info(struct hinic5_sq_wqe_combo *wqe_combo,
* @nr_descs: total sge_num, include bd0 in cs
*/
static void hinic5_prepare_sq_ctrl(struct hinic5_sq_wqe_combo *wqe_combo,
- struct hinic5_queue_info *queue_info, int nr_descs, u16 owner)
+ struct hinic5_queue_info *queue_info,
+ int nr_descs, u16 owner)
{
struct hinic5_sq_wqe_desc *wqe_desc = wqe_combo->ctrl_bd0;
- wqe_desc->ctrl_len |=
- SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT) |
- SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) |
- SQ_CTRL_SET(owner, OWNER);
+ wqe_desc->ctrl_len |= SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT) |
+ SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) |
+ SQ_CTRL_SET(owner, OWNER);
if (wqe_combo->wqe_type == SQ_WQE_EXTENDED_TYPE) {
- wqe_desc->ctrl_len |= SQ_CTRL_SET(nr_descs, BUFDESC_NUM) |
- SQ_CTRL_SET(wqe_combo->task_type, TASKSECT_LEN);
+ wqe_desc->ctrl_len |=
+ SQ_CTRL_SET(nr_descs, BUFDESC_NUM) |
+ SQ_CTRL_SET(wqe_combo->task_type, TASKSECT_LEN);
hinic5_set_wqe_queue_info(wqe_combo, queue_info);
} else {
/* compact wqe not support TSO offload */
- wqe_desc->ctrl_len |= SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->sctp, SCTP) |
- SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->udp_dp_en, UDP_DP_EN) |
- SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->pkt_type, PKT_TYPE);
+ wqe_desc->ctrl_len |=
+ SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->sctp, SCTP) |
+ SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->udp_dp_en,
+ UDP_DP_EN) |
+ SQ_CTRL_15BIT_QUEUE_INFO_SET(queue_info->pkt_type,
+ PKT_TYPE);
}
wqe_desc->ctrl_len = hinic5_hw_be32(wqe_desc->ctrl_len);
@@ -796,9 +799,9 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
struct hinic5_txq *txq)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic5_sq_wqe_combo wqe_combo = {0};
- struct hinic5_offload_info offload_info = {0};
- struct hinic5_queue_info queue_info = {0};
+ struct hinic5_sq_wqe_combo wqe_combo = { 0 };
+ struct hinic5_offload_info offload_info = { 0 };
+ struct hinic5_queue_info queue_info = { 0 };
struct hinic5_tx_info *tx_info = NULL;
u32 offload;
u16 owner = 0, pi = 0;
@@ -825,7 +828,7 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
max_wqe_len = skb_is_gso(skb) ? TSO_SKB_SIZE_MAX : NON_TSO_SKB_SIZE_MAX;
frag_size = skb_headlen(skb);
- if (unlikely(frag_size > max_wqe_len || frag_size == 0)) {
+ if (unlikely((frag_size > max_wqe_len) || (frag_size == 0))) {
TXQ_STATS_INC(txq, frag_size_err);
goto tx_drop_pkts;
}
@@ -839,8 +842,8 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
find_zero_sge_len = true;
continue;
} else if (unlikely((find_zero_sge_len) ||
- (frag_size > max_wqe_len) ||
- (total_size > max_wqe_len))) {
+ (frag_size > max_wqe_len) ||
+ (total_size > max_wqe_len))) {
TXQ_STATS_INC(txq, frag_size_err);
goto tx_drop_pkts;
}
@@ -863,11 +866,12 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
} else if (offload == 0 && num_sge == 1) {
/* no TS in current wqe */
wqebb_cnt -= 1;
- if (unlikely(num_sge == 1 && skb->len > COMPACET_WQ_SKB_MAX_LEN))
+ if (unlikely(num_sge == 1 &&
+ skb->len > COMPACET_WQ_SKB_MAX_LEN)) {
goto tx_drop_pkts;
+ }
} else if ((nic_dev->tx_wqe_compact_task != 0) &&
- ((offload & TX_OFFLOAD_TSO) == 0) &&
- num_sge == 1) {
+ ((offload & TX_OFFLOAD_TSO) == 0) && num_sge == 1) {
/* One more wqebb is needed for compact task under two situations:
* 1. TSO: MSS field is needed, no available space for compact task in compact wqe.
* 2. SGE number > 1: WQE is handled as extented wqe by nic.
@@ -898,8 +902,9 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
skb_tx_timestamp(skb);
- hinic5_write_db(txq->sq, (txq->cos & nic_dev->cos_mask_mode) & (u8)qp_cos_mask, SQ_CFLAG_DP,
- hinic5_get_sq_local_pi(txq->sq));
+ hinic5_write_db(txq->sq,
+ (txq->cos & nic_dev->cos_mask_mode) & (u8)qp_cos_mask,
+ SQ_CFLAG_DP, hinic5_get_sq_local_pi(txq->sq));
return NETDEV_TX_OK;
@@ -912,8 +917,7 @@ static netdev_tx_t hinic5_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_OK;
}
-netdev_tx_t hinic5_lb_xmit_frame(struct sk_buff *skb,
- struct net_device *netdev)
+netdev_tx_t hinic5_lb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
u16 q_id = skb_get_queue_mapping(skb);
@@ -929,16 +933,18 @@ bool hinic5_check_skb_need_dual_send(struct sk_buff *skb)
struct icmp6hdr icmp6;
} *combined = NULL, _combined;
- /* ARP packet */
- if (skb->protocol == htons(ETH_P_ARP))
+ /* ARP报文 */
+ if (skb->protocol == htons(ETH_P_ARP)) {
return true;
+ }
if (skb->protocol == htons(ETH_P_IPV6)) {
combined = skb_header_pointer(skb, (int)skb_mac_header_len(skb),
- sizeof(_combined),
- &_combined);
+ sizeof(_combined), &_combined);
if (combined && combined->ip6.nexthdr == NEXTHDR_ICMP &&
- (combined->icmp6.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION ||
- combined->icmp6.icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT))
+ (combined->icmp6.icmp6_type ==
+ NDISC_NEIGHBOUR_SOLICITATION ||
+ combined->icmp6.icmp6_type ==
+ NDISC_NEIGHBOUR_ADVERTISEMENT))
return true;
}
@@ -946,7 +952,7 @@ bool hinic5_check_skb_need_dual_send(struct sk_buff *skb)
}
static int txq_free_old_skbs(struct hinic5_txq *txq, int budget);
-#define XMIT_CLEAN_BUDGET 1024 /* clean unused skbs as much as possible */
+#define XMIT_CLEAN_BUDGET 1024 /* clean unused skbs as much as possible */
netdev_tx_t hinic5_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
@@ -960,7 +966,7 @@ netdev_tx_t hinic5_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- /* Check if ARP dual send is needed */
+ /* 检查是否需要进行arp双发 */
if (hinic5_check_dev_need_dual_send(nic_dev->hwdev) &&
hinic5_check_skb_need_dual_send(skb)) {
skb_queue_tail(&nic_dev->arp_queue, skb_get(skb));
@@ -1025,9 +1031,7 @@ static int txq_free_old_skbs(struct hinic5_txq *txq, int budget)
struct hinic5_tx_info *tx_info = NULL;
u64 tx_bytes = 0, nr_pkts = 0;
int pkts = 0;
-#ifdef HAVE_XDP_SUPPORT
u32 xmit_pkts = 0;
-#endif
u16 wqebb_cnt = 0;
u16 hw_ci, sw_ci;
@@ -1039,7 +1043,7 @@ static int txq_free_old_skbs(struct hinic5_txq *txq, int budget)
tx_info = &txq->tx_info[sw_ci];
/* Whether all of the wqebb of this wqe is completed */
- if (hw_ci == sw_ci ||
+ if ((hw_ci == sw_ci) ||
((u16)(hw_ci - sw_ci) & txq->q_mask) < tx_info->wqebb_cnt)
break;
@@ -1051,10 +1055,9 @@ static int txq_free_old_skbs(struct hinic5_txq *txq, int budget)
tx_bytes += tx_info->num_bytes;
nr_pkts += tx_info->num_pkts;
pkts++;
-#ifdef HAVE_XDP_SUPPORT
- if (tx_info->xdpf)
+ if (tx_info->xdpf) {
xmit_pkts++;
-#endif
+ }
tx_free_skb(nic_dev, tx_info);
} while (likely(pkts < budget));
@@ -1069,7 +1072,7 @@ static int txq_free_old_skbs(struct hinic5_txq *txq, int budget)
u64_stats_update_end(&txq->txq_stats.syncp);
#ifdef HAVE_XDP_SUPPORT
- /* xmit_pkts stats will not appear simultaneously with tx_bytes stats */
+ /* xmit_pkts的统计不会和tx_bytes的统计同时出现 */
u64_stats_update_begin(&txq->xdptxq_stats.syncp);
txq->xdptxq_stats.xdp_xmits += xmit_pkts;
u64_stats_update_end(&txq->xdptxq_stats.syncp);
@@ -1108,7 +1111,8 @@ static inline void txq_wake(struct hinic5_txq *txq)
int hinic5_tx_poll(struct hinic5_txq *txq, int budget)
{
const u16 q_id = txq->sq->q_id;
- struct netdev_queue *netdev_txq = netdev_get_tx_queue(txq->netdev, q_id);
+ struct netdev_queue *netdev_txq =
+ netdev_get_tx_queue(txq->netdev, q_id);
int pkts = 0;
if (__netif_tx_trylock(netdev_txq)) {
@@ -1130,7 +1134,7 @@ void hinic5_set_txq_cos(struct hinic5_nic_dev *nic_dev, u16 start_qid,
nic_dev->txqs[idx + start_qid].cos = cos;
}
-#define HINIC5_BDS_PER_SQ_WQEBB \
+#define HINIC5_BDS_PER_SQ_WQEBB \
(HINIC5_SQ_WQEBB_SIZE / sizeof(struct hinic5_sq_bufdesc))
int hinic5_alloc_txqs_res(struct hinic5_nic_dev *nic_dev, u16 num_sq,
@@ -1145,17 +1149,16 @@ int hinic5_alloc_txqs_res(struct hinic5_nic_dev *nic_dev, u16 num_sq,
size = sizeof(*tqres->tx_info) * sq_depth;
tqres->tx_info = kzalloc(size, GFP_KERNEL);
- if (!tqres->tx_info) {
+ if (tqres->tx_info == NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d tx info\n", idx);
goto err_out;
}
size = sizeof(*tqres->bds) *
- (sq_depth * HINIC5_BDS_PER_SQ_WQEBB +
- HINIC5_MAX_SQ_SGE);
+ (sq_depth * HINIC5_BDS_PER_SQ_WQEBB + HINIC5_MAX_SQ_SGE);
tqres->bds = kzalloc(size, GFP_KERNEL);
- if (!tqres->bds) {
+ if (tqres->bds == NULL) {
kfree(tqres->tx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
@@ -1214,7 +1217,7 @@ int hinic5_configure_txqs(struct hinic5_nic_dev *nic_dev, u16 num_sq,
&tqres->bds[idx * HINIC5_BDS_PER_SQ_WQEBB];
txq->sq = hinic5_get_nic_queue(nic_dev->hwdev, q_id, HINIC5_SQ);
- if (!txq->sq) {
+ if (txq->sq == NULL) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get %u sq\n", q_id);
return -EFAULT;
@@ -1239,8 +1242,10 @@ int hinic5_alloc_txqs(struct net_device *netdev)
}
nic_dev->txqs = kzalloc(txq_size, GFP_KERNEL);
- if (!nic_dev->txqs)
+ if (nic_dev->txqs == NULL) {
+ nic_err(dev, "Failed to allocate txqs\n");
return -ENOMEM;
+ }
for (q_id = 0; q_id < num_txqs; q_id++) {
txq = &nic_dev->txqs[q_id];
@@ -1274,7 +1279,7 @@ static bool is_hw_complete_sq_process(struct hinic5_io_queue *sq)
return sw_pi == hw_ci;
}
-#define HINIC5_FLUSH_QUEUE_TIMEOUT 1000
+#define HINIC5_FLUSH_QUEUE_TIMEOUT 1000
static int hinic5_stop_sq(struct hinic5_txq *txq)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(txq->netdev);
@@ -1316,13 +1321,14 @@ int hinic5_flush_txqs(struct net_device *netdev)
u16 qid;
int err;
- for (qid = 0; qid < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps; qid++) {
+ for (qid = 0;
+ qid < nic_dev->q_params.num_qps + nic_dev->q_params.xdp_qps;
+ qid++) {
err = hinic5_stop_sq(&nic_dev->txqs[qid]);
if (err != 0)
- nicif_err(nic_dev, drv, netdev,
- "Failed to stop sq%u\n", qid);
+ nicif_err(nic_dev, drv, netdev, "Failed to stop sq%u\n",
+ qid);
}
return 0;
}
-
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.h
index 7e39e5a33..6484edf16 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_tx.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_tx.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_TX_H
#define HINIC5_TX_H
@@ -22,20 +15,20 @@
#include "hinic5_nic_rq.h"
#include "hinic5_nic_io.h"
-#define TXQ_STATS_INC(txq, field) \
-do { \
- u64_stats_update_begin(&(txq)->txq_stats.syncp); \
- (txq)->txq_stats.field++; \
- u64_stats_update_end(&(txq)->txq_stats.syncp); \
-} while (0)
+#define TXQ_STATS_INC(txq, field) \
+ do { \
+ u64_stats_update_begin(&(txq)->txq_stats.syncp); \
+ (txq)->txq_stats.field++; \
+ u64_stats_update_end(&(txq)->txq_stats.syncp); \
+ } while (0)
#ifdef HAVE_XDP_SUPPORT
-#define XDP_TXQ_STATS_INC(txq, field) \
-do { \
- u64_stats_update_begin(&(txq)->xdptxq_stats.syncp); \
- (txq)->xdptxq_stats.field++; \
- u64_stats_update_end(&(txq)->xdptxq_stats.syncp); \
-} while (0)
+#define XDP_TXQ_STATS_INC(txq, field) \
+ do { \
+ u64_stats_update_begin(&(txq)->xdptxq_stats.syncp); \
+ (txq)->xdptxq_stats.field++; \
+ u64_stats_update_end(&(txq)->xdptxq_stats.syncp); \
+ } while (0)
#endif
#define VXLAN_OFFLOAD_PORT_LE 0xb512 /* big end is 4789 */
@@ -62,25 +55,25 @@ enum hinic5_tx_cvlan_type {
};
struct hinic5_txq_stats {
- u64 packets;
- u64 bytes;
- u64 busy;
- u64 wake;
- u64 dropped;
- u64 unfinished;
+ u64 packets;
+ u64 bytes;
+ u64 busy;
+ u64 wake;
+ u64 dropped;
+ u64 unfinished;
/* Subdivision statistics show in private tool */
- u64 skb_pad_err;
- u64 frag_len_overflow;
- u64 offload_cow_skb_err;
- u64 map_frag_err;
- u64 unknown_tunnel_pkt;
- u64 frag_size_err;
- u64 rsvd1;
- u64 rsvd2;
+ u64 skb_pad_err;
+ u64 frag_len_overflow;
+ u64 offload_cow_skb_err;
+ u64 map_frag_err;
+ u64 unknown_tunnel_pkt;
+ u64 frag_size_err;
+ u64 rsvd1;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
- struct u64_stats_sync syncp;
+ struct u64_stats_sync syncp;
#else
struct u64_stats_sync_empty syncp;
#endif
@@ -88,12 +81,12 @@ struct hinic5_txq_stats {
#ifdef HAVE_XDP_SUPPORT
struct hinic5_xdptxq_stats {
- u64 xdp_dropped;
- u64 xdp_xmits;
- u64 map_xdpf_err;
+ u64 xdp_dropped;
+ u64 xdp_xmits;
+ u64 map_xdpf_err;
#ifdef HAVE_NDO_GET_STATS64
- struct u64_stats_sync syncp;
+ struct u64_stats_sync syncp;
#else
struct u64_stats_sync_empty syncp;
#endif
@@ -105,9 +98,9 @@ struct hinic5_dma_info {
u32 len;
};
-#define IPV4_VERSION 4
-#define IPV6_VERSION 6
-#define TCP_HDR_DOFF_UNIT 2
+#define IPV4_VERSION 4
+#define IPV6_VERSION 6
+#define TCP_HDR_DOFF_UNIT 2
#define TRANSPORT_OFFSET(l4_hdr, skb) ((u32)((l4_hdr) - (skb)->data))
union hinic5_ip {
@@ -169,8 +162,10 @@ struct hinic5_dyna_txq_res {
netdev_tx_t hinic5_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
-u32 hinic5_tx_offload(struct sk_buff *skb, struct hinic5_offload_info *offload_info,
- struct hinic5_queue_info *queue_info, struct hinic5_txq *txq);
+u32 hinic5_tx_offload(struct sk_buff *skb,
+ struct hinic5_offload_info *offload_info,
+ struct hinic5_queue_info *queue_info,
+ struct hinic5_txq *txq);
void hinic5_txq_get_stats(struct hinic5_txq *txq,
struct hinic5_txq_stats *stats);
@@ -210,8 +205,10 @@ void hinic5_set_txq_cos(struct hinic5_nic_dev *nic_dev, u16 start_qid,
static inline __sum16 csum_magic(union hinic5_ip *ip, unsigned short proto)
{
return (ip->v4->version == IPV4_VERSION) ?
- csum_tcpudp_magic(ip->v4->saddr, ip->v4->daddr, 0, (u8)proto, 0) :
- csum_ipv6_magic(&ip->v6->saddr, &ip->v6->daddr, 0, (u8)proto, 0);
+ csum_tcpudp_magic(ip->v4->saddr, ip->v4->daddr, 0,
+ (u8)proto, 0) :
+ csum_ipv6_magic(&ip->v6->saddr, &ip->v6->daddr, 0,
+ (u8)proto, 0);
}
void hinic5_tx_set_normal_task_offload(struct hinic5_offload_info *offload,
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.c b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.c
index 8d4679f3a..f1ea2390f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.c
@@ -1,12 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_xdp.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : XDP implementation
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
#define pr_fmt(fmt) KBUILD_MODNAME ": [NIC]" fmt
@@ -39,7 +32,8 @@ int tx_map_xdpf(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq, u16 pi,
struct xdp_frame *xdpf = txq->tx_info[pi].xdpf;
struct device *dev = nic_dev->lld_dev->dev;
- dma_info->dma = dma_map_single(dev, xdpf->data, xdpf->len, DMA_TO_DEVICE);
+ dma_info->dma =
+ dma_map_single(dev, xdpf->data, xdpf->len, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_info->dma) != 0) {
XDP_TXQ_STATS_INC(txq, map_xdpf_err);
return -EFAULT;
@@ -54,23 +48,23 @@ int tx_map_xdpf(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq, u16 pi,
return 0;
}
-void hinic5_prepare_xdp_sq_ctrl(struct hinic5_sq_wqe_combo *wqe_combo, u16 owner)
+void hinic5_prepare_xdp_sq_ctrl(struct hinic5_sq_wqe_combo *wqe_combo,
+ u16 owner)
{
struct hinic5_sq_wqe_desc *wqe_desc = wqe_combo->ctrl_bd0;
-
- wqe_desc->ctrl_len |=
- SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT) |
- SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) |
- SQ_CTRL_SET(owner, OWNER);
+ wqe_desc->ctrl_len |= SQ_CTRL_SET(SQ_NORMAL_WQE, DATA_FORMAT) |
+ SQ_CTRL_SET(wqe_combo->wqe_type, EXTENDED) |
+ SQ_CTRL_SET(owner, OWNER);
wqe_desc->ctrl_len = hinic5_hw_be32(wqe_desc->ctrl_len);
wqe_desc->queue_info = 0;
+ return;
}
-int hinic5_xdp_xmit_frame(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq,
- struct xdp_frame *xdpf)
+int hinic5_xdp_xmit_frame(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_txq *txq, struct xdp_frame *xdpf)
{
- struct hinic5_sq_wqe_combo wqe_combo = {0};
+ struct hinic5_sq_wqe_combo wqe_combo = { 0 };
u16 pi = 0, owner = 0;
/* Always use compact wqe for xdp */
if (unlikely(hinic5_maybe_stop_tx(txq, 1) != 0)) {
@@ -96,7 +90,8 @@ int hinic5_xdp_xmit_frame(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq
return 0;
}
-int hinic5_xdp_xmit_frames(struct net_device *dev, int n, struct xdp_frame **frames, u32 flags)
+int hinic5_xdp_xmit_frames(struct net_device *dev, int n,
+ struct xdp_frame **frames, u32 flags)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(dev);
struct hinic5_txq *txq = NULL;
@@ -114,14 +109,14 @@ int hinic5_xdp_xmit_frames(struct net_device *dev, int n, struct xdp_frame **fra
if (unlikely(nic_dev->q_params.xdp_qps == 0))
return -EINVAL;
- /* XDP queue is isolated from kernel TX queue, XDP uses the second half of queues */
- q_id = raw_smp_processor_id() % nic_dev->q_params.xdp_qps + nic_dev->q_params.num_qps;
+ /* xdp队列和内核TX队列隔离,xdp走后一半队列 */
+ q_id = raw_smp_processor_id() % nic_dev->q_params.xdp_qps +
+ nic_dev->q_params.num_qps;
txq = &nic_dev->txqs[q_id];
for (i = 0; i < n; i++) {
struct xdp_frame *xdpf = frames[i];
-
if (unlikely(hinic5_xdp_xmit_frame(nic_dev, txq, xdpf) != 0)) {
xdp_return_frame(xdpf);
XDP_TXQ_STATS_INC(txq, xdp_dropped);
@@ -130,20 +125,22 @@ int hinic5_xdp_xmit_frames(struct net_device *dev, int n, struct xdp_frame **fra
}
if ((flags & XDP_XMIT_FLUSH) != 0) {
- hinic5_write_db(txq->sq, (txq->cos & nic_dev->cos_mask_mode), SQ_CFLAG_DP,
- hinic5_get_sq_local_pi(txq->sq));
+ hinic5_write_db(txq->sq, (txq->cos & nic_dev->cos_mask_mode),
+ SQ_CFLAG_DP, hinic5_get_sq_local_pi(txq->sq));
}
return n - drops;
}
-struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp, struct hinic5_nic_dev *nic_dev)
+struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp,
+ struct hinic5_nic_dev *nic_dev)
{
struct xdp_frame *xdp_frame = NULL;
int metasize, headroom;
#if (KERNEL_VERSION(5, 8, 0) < LINUX_VERSION_CODE)
- if (xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL)
+ if (xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL) {
return xdp_convert_zc_to_xdp_frame(xdp);
+ }
#endif
xdp_frame = xdp->data_hard_start;
@@ -154,12 +151,13 @@ struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp, struct hinic5_nic_d
if (unlikely((headroom - metasize) < sizeof(*xdp_frame)))
return NULL;
#ifdef HAVE_XDP_FRAME_SZ
- if (unlikely(xdp->data_end > xdp_data_hard_end(xdp)))
+ if (unlikely(xdp->data_end > xdp_data_hard_end(xdp))) {
return NULL;
+ }
xdp_frame->frame_sz = xdp->frame_sz;
#endif
xdp_frame->data = xdp->data;
- xdp_frame->len = xdp->data_end - xdp->data;
+ xdp_frame->len = xdp->data_end - xdp->data;
xdp_frame->headroom = (u16)(headroom - sizeof(*xdp_frame));
#ifdef HAVE_XDP_DATA_META
xdp_frame->metasize = (u32)metasize;
@@ -169,14 +167,15 @@ struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp, struct hinic5_nic_d
return xdp_frame;
}
-bool hinic5_xmit_xdp_buff(struct net_device *netdev, u16 q_id, struct xdp_buff *xdp)
+bool hinic5_xmit_xdp_buff(struct net_device *netdev, u16 q_id,
+ struct xdp_buff *xdp)
{
struct hinic5_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic5_txq *txq = NULL;
struct xdp_frame *xdpf = NULL;
u16 dst_qid;
- /* XDP queue is isolated from kernel TX queue, XDP uses the second half of queues */
+ /* xdp队列和内核TX队列隔离,xdp走后一半队列 */
dst_qid = q_id + nic_dev->q_params.num_qps;
txq = &nic_dev->txqs[dst_qid];
xdpf = xdp_convert_to_frame(xdp, nic_dev);
@@ -190,8 +189,8 @@ bool hinic5_xmit_xdp_buff(struct net_device *netdev, u16 q_id, struct xdp_buff *
XDP_TXQ_STATS_INC(txq, xdp_dropped);
return false;
}
- hinic5_write_db(txq->sq, (txq->cos & nic_dev->cos_mask_mode), SQ_CFLAG_DP,
- hinic5_get_sq_local_pi(txq->sq));
+ hinic5_write_db(txq->sq, (txq->cos & nic_dev->cos_mask_mode),
+ SQ_CFLAG_DP, hinic5_get_sq_local_pi(txq->sq));
return true;
}
@@ -205,16 +204,30 @@ static void update_drop_rx_info(struct hinic5_rxq *rxq, u16 weqbb_num)
while (weqbb_num_tmp != 0) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
- if (likely(page_to_nid(rx_info->page) == numa_node_id())) {
- hinic5_reuse_rx_page(rxq, rx_info);
- } else {
- if (rx_info->buf_dma_addr != 0) {
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
- if (rx_info->page)
- __free_pages(rx_info->page, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, true);
+ } else
+#endif
+ {
+ if (likely(page_to_nid(rx_info->page) ==
+ numa_node_id())) {
+ hinic5_reuse_rx_page(rxq, rx_info);
+ } else {
+ if (rx_info->buf_dma_addr != 0) {
+ dma_unmap_page(rxq->dev,
+ rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size,
+ DMA_FROM_DEVICE);
+ }
+
+ if (rx_info->page) {
+ __free_pages(rx_info->page,
+ nic_dev->page_order);
+ }
+ }
}
rx_info->buf_dma_addr = 0;
@@ -228,13 +241,20 @@ static void update_drop_rx_info(struct hinic5_rxq *rxq, u16 weqbb_num)
static bool hinic5_add_rx_frag_with_xdp(struct hinic5_rxq *rxq, u32 pkt_len,
struct hinic5_rx_info *rx_info,
- struct sk_buff *skb, struct xdp_buff *xdp)
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
{
struct page *page = rx_info->page;
-
if (pkt_len <= HINIC5_RX_HDR_SIZE) {
__skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page,
+ false);
+ return false;
+ }
+#endif
if (likely(page_to_nid(page) == numa_node_id()))
return true;
@@ -243,9 +263,16 @@ static bool hinic5_add_rx_frag_with_xdp(struct hinic5_rxq *rxq, u32 pkt_len,
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + (xdp->data - xdp->data_hard_start)),
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
(int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
if (unlikely(page_to_nid(page) != numa_node_id()))
goto umap_page;
if (unlikely(page_count(page) != 1))
@@ -256,8 +283,8 @@ static bool hinic5_add_rx_frag_with_xdp(struct hinic5_rxq *rxq, u32 pkt_len,
return true;
umap_page:
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr, rxq->dma_rx_buff_size,
+ DMA_FROM_DEVICE);
return false;
}
@@ -270,8 +297,9 @@ static void hinic5_xdp_set_data(struct hinic5_rxq *rxq, struct xdp_buff *xdp,
xdp->rxq = &rxq->xdp_rxq;
}
-static int hinic5_run_xdp_prog(struct hinic5_rxq *rxq, struct bpf_prog *xdp_prog,
- struct xdp_buff *xdp, u32 *pkt_len)
+static int hinic5_run_xdp_prog(struct hinic5_rxq *rxq,
+ struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
+ u32 *pkt_len)
{
u32 act;
int err;
@@ -294,8 +322,9 @@ static int hinic5_run_xdp_prog(struct hinic5_rxq *rxq, struct bpf_prog *xdp_prog
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
get_page(rx_info->page);
#ifdef HAVE_XDP_FRAME_SZ
- if (unlikely(xdp->data_end > xdp_data_hard_end(xdp)))
+ if (unlikely(xdp->data_end > xdp_data_hard_end(xdp))) {
goto out_failure;
+ }
#endif
err = xdp_do_redirect(netdev, xdp, xdp_prog);
if (unlikely(err != 0)) {
@@ -318,18 +347,18 @@ static int hinic5_run_xdp_prog(struct hinic5_rxq *rxq, struct bpf_prog *xdp_prog
return result;
}
-static void hinic5_prepare_xdp_buff(struct hinic5_rxq *rxq, struct xdp_buff *xdp,
- u32 pkt_len, u32 packet_offset)
+static void hinic5_prepare_xdp_buff(struct hinic5_rxq *rxq,
+ struct xdp_buff *xdp, u32 pkt_len,
+ u32 packet_offset)
{
- u8 *va;
+ u8 *va = NULL;
struct hinic5_rx_info *rx_info = NULL;
-
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
va = (u8 *)page_address(rx_info->page) + rx_info->page_offset;
prefetch(va);
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
- rx_info->page_offset,
- rxq->buf_len, DMA_FROM_DEVICE);
+ rx_info->page_offset, rxq->buf_len,
+ DMA_FROM_DEVICE);
hinic5_xdp_set_data(rxq, xdp, va, pkt_len, packet_offset);
#ifdef HAVE_XDP_FRAME_SZ
@@ -341,7 +370,8 @@ static void hinic5_prepare_xdp_buff(struct hinic5_rxq *rxq, struct xdp_buff *xdp
prefetchw(xdp->data_hard_start);
}
-static void hinic5_handle_xdp_result(struct hinic5_rxq *rxq, int result, u16 weqbb_num)
+static void hinic5_handle_xdp_result(struct hinic5_rxq *rxq, int result,
+ u16 weqbb_num)
{
switch (result) {
case HINIC5_XDP_PKT_DROP:
@@ -353,11 +383,13 @@ static void hinic5_handle_xdp_result(struct hinic5_rxq *rxq, int result, u16 weq
default:
break;
}
- if (result != HINIC5_XDP_PKT_PASS)
+ if (result != HINIC5_XDP_PKT_PASS) {
update_drop_rx_info(rxq, weqbb_num);
+ }
}
-int hinic5_run_xdp(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info, struct xdp_buff *xdp)
+int hinic5_run_xdp(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info,
+ struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic5_nic_dev *nic_dev = NULL;
@@ -381,12 +413,6 @@ int hinic5_run_xdp(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info, str
goto xdp_out;
}
-#ifdef HAVE_PAGE_POOL_SUPPORT
- if (nic_dev->page_pool_enabled) {
- result = HINIC5_XDP_PROG_EMPTY;
- goto unlock_rcu;
- }
-#endif
hinic5_prepare_xdp_buff(rxq, xdp, pkt_len, packet_offset);
result = hinic5_run_xdp_prog(rxq, xdp_prog, xdp, &pkt_len);
cqe_info->pkt_len = (u16)pkt_len;
@@ -409,12 +435,14 @@ struct sk_buff *hinic5_fetch_rx_buffer_xdp(struct hinic5_rxq *rxq, u32 pkt_len,
rx_info = &rxq->rx_info[sw_ci];
skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC5_RX_HDR_SIZE);
- if (unlikely(!skb))
+ if (unlikely(!skb)) {
return NULL;
+ }
reuse = hinic5_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
- if (likely(reuse))
+ if (likely(reuse)) {
hinic5_reuse_rx_page(rxq, rx_info);
+ }
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -437,7 +465,8 @@ void hinic5_xdp_flush_if_needed(const struct hinic5_nic_dev *nic_dev)
}
/* Function to determine XDP status and build skb accordingly */
-bool hinic5_xdp_process_packet(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info,
+bool hinic5_xdp_process_packet(struct hinic5_rxq *rxq,
+ struct hinic5_cqe_info *cqe_info,
struct sk_buff **skb)
{
u32 xdp_status;
@@ -453,12 +482,13 @@ bool hinic5_xdp_process_packet(struct hinic5_rxq *rxq, struct hinic5_cqe_info *c
}
/* Build skb based on XDP program configuration */
- if (xdp_status != HINIC5_XDP_PROG_EMPTY)
+ if (xdp_status != HINIC5_XDP_PROG_EMPTY) {
*skb = hinic5_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
- else
+ } else {
*skb = hinic5_fetch_rx_buffer(rxq, cqe_info);
+ }
return 0;
}
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.h
index 40aaea13b..9d54cb7bc 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/host/service/nic/linux/nicio/hinic5_xdp.h
@@ -1,12 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_xdp.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
+/* Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. */
#ifndef HINIC5_XDP_H
#define HINIC5_XDP_H
@@ -50,25 +43,30 @@ enum hinic5_xdp_pkt {
int tx_map_xdpf(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq, u16 pi,
struct hinic5_sq_wqe_combo *wqe_combo);
-void hinic5_prepare_xdp_sq_ctrl(struct hinic5_sq_wqe_combo *wqe_combo, u16 owner);
+void hinic5_prepare_xdp_sq_ctrl(struct hinic5_sq_wqe_combo *wqe_combo,
+ u16 owner);
-int hinic5_xdp_xmit_frame(struct hinic5_nic_dev *nic_dev, struct hinic5_txq *txq,
- struct xdp_frame *xdpf);
+int hinic5_xdp_xmit_frame(struct hinic5_nic_dev *nic_dev,
+ struct hinic5_txq *txq, struct xdp_frame *xdpf);
-int hinic5_xdp_xmit_frames(struct net_device *dev, int n, struct xdp_frame **frames,
- u32 flags);
-bool hinic5_xmit_xdp_buff(struct net_device *netdev, u16 q_id, struct xdp_buff *xdp);
+int hinic5_xdp_xmit_frames(struct net_device *dev, int n,
+ struct xdp_frame **frames, u32 flags);
+bool hinic5_xmit_xdp_buff(struct net_device *netdev, u16 q_id,
+ struct xdp_buff *xdp);
-struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp, struct hinic5_nic_dev *nic_dev);
+struct xdp_frame *xdp_convert_to_frame(struct xdp_buff *xdp,
+ struct hinic5_nic_dev *nic_dev);
-int hinic5_run_xdp(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info, struct xdp_buff *xdp);
+int hinic5_run_xdp(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info,
+ struct xdp_buff *xdp);
struct sk_buff *hinic5_fetch_rx_buffer_xdp(struct hinic5_rxq *rxq, u32 pkt_len,
struct xdp_buff *xdp);
void hinic5_xdp_flush_if_needed(const struct hinic5_nic_dev *nic_dev);
-bool hinic5_xdp_process_packet(struct hinic5_rxq *rxq, struct hinic5_cqe_info *cqe_info,
+bool hinic5_xdp_process_packet(struct hinic5_rxq *rxq,
+ struct hinic5_cqe_info *cqe_info,
struct sk_buff **skb);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/bond_cfm_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/bond_cfm_cmd.h
index 135f1b461..acf485306 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/bond_cfm_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/bond_cfm_cmd.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : bond_cfm_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : cfm bond data structure
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * Description : cfm bond datastruct
+ * Creation time : 2026/04/16
*/
#ifndef BOND_CFM_CMD_H
@@ -14,51 +10,45 @@
#include "bond_mpu_cmd_defs.h"
#include "nic_mpu_cmd_structs.h"
-#define ETH_ALEN 6 /* Ethernet address length */
+#define ETH_ALEN 6 /**< Ethernet address length */
-#define BOND_MAX_PORT_NUM 4 /* Maximum number of ports supported by bond */
-#define BOND_MAX_HOST_NUM 4 /* Maximum number of hosts supported by bond */
+#define BOND_MAX_PORT_NUM 4 /**< bond 支持最大port数量 */
+#define BOND_MAX_HOST_NUM 4 /**< bond 支持最大host数量 */
/**
* @brief enum bond_mpu_type
- * @details bonding type, full offload bond or half offload bond
+ * @details bonding类型,全卸载bond或者半卸载bond
*/
-enum bond_mpu_type {
- BOND_TYPE_HALF,
- BOND_TYPE_FULL,
- BOND_TYPE_BUTT
-};
+enum bond_mpu_type { BOND_TYPE_HALF, BOND_TYPE_FULL, BOND_TYPE_BUTT };
struct bond_half_data_s {
- u16 bond_mode; /* bond mode:1 for active-backup,
- * 2 for balance-xor,4 for 802.3ad
- */
- u16 bond_id; /* bond id */
- u16 up_delay; /* default:200ms */
- u16 down_delay; /* default:200ms */
- u32 active_slaves : 8; /* active port slaves(bitmaps) */
- u32 slaves : 8; /* bond port id bitmaps */
- u32 lacp_collect_slaves : 8; /* slave bitmap available for LACP packet send/receive */
- u32 hash_policy : 8; /* hash:0 for layer 2 ,1 for layer 2+3 ,2 for layer 3+4 */
- u32 first_roce_func; /* RoCE used */
- u32 bond_pf_bitmap; /* slave pf bitmap */
- u32 user_bitmap; /* user bitmap */
- u8 bond_name[BOND_NAME_MAX_LEN]; /* bond name, length must be less than 16 */
+ u16 bond_mode; /**< bond mode:1 for active-backup,2 for balance-xor,4 for 802.3ad */
+ u16 bond_id; /**< bond id */
+ u16 up_delay; /**< defualt:200ms */
+ u16 down_delay; /**< defualt:200ms */
+ u32 active_slaves : 8; /**< active port slaves(bitmaps) */
+ u32 slaves : 8; /**< bond port id bitmaps */
+ u32 lacp_collect_slaves : 8; /**< 可用于LACP报文收发的slave bitmap */
+ u32 hash_policy : 8; /**< hash:0 for layer 2 ,1 for layer 2+3 ,2 for layer 3+4 */
+ u32 first_roce_func; /**< RoCE used */
+ u32 bond_pf_bitmap; /**< slave pf bitmap */
+ u32 user_bitmap; /**< user bitmap */
+ u8 bond_name[BOND_NAME_MAX_LEN]; /**< bond name, length must be less than 16 */
u32 rsvd[8];
};
struct bond_full_data_s {
- u32 bond_id; /* bond device number, valid on output, filled when mpu operation succeeds */
- u32 master_slave_port_id; /* master/slave port id, smallest port id as master port */
- u32 slave_bitmap; /* bond port id bitmap */
- u32 poll_timeout; /* bond device link check time */
- u32 up_delay; /* reserved for now */
- u32 down_delay; /* reserved for now */
- u32 bond_mode; /* reserved for now */
- u32 xmit_hash_policy; /* hash policy, used for microcode routing logic */
- u8 lacp_rate; /* lacp negotiation rate, 0 for slow, 1 for fast */
- u8 rsvd1[3]; /* reserved field */
- u32 rsvd[9]; /* reserved field */
+ u32 bond_id; /**< bond设备号,output时有效,mpu操作成功返回时回填 */
+ u32 master_slave_port_id; /**< 主从端口id,最小的port id作为主口 */
+ u32 slave_bitmap; /**< bond port id bitmap */
+ u32 poll_timeout; /**< bond设备链路检查时间 */
+ u32 up_delay; /**< 暂时预留 */
+ u32 down_delay; /**< 暂时预留 */
+ u32 bond_mode; /**< 暂时预留 */
+ u32 xmit_hash_policy; /**< hash策略,用于微码选路逻辑 */
+ u8 lacp_rate; /**< lacp协商速率 0 为慢速, 1 为快速 */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 rsvd[9]; /**< 保留域段 */
};
typedef union tag_cfm_bond_data {
@@ -69,38 +59,38 @@ typedef union tag_cfm_bond_data {
typedef struct tag_cfm_bond_cmd {
struct mgmt_msg_head comm_head;
u16 sub_cmd;
- u8 rsvd0;
- u8 bond_type;
+ u8 rsvd0;
+ u8 bond_type;
cfm_bond_data_u data;
u8 rsvd1[32];
} cfm_bond_cmd_s;
/**
- * @brief Defines a structure for storing bond status information
- * @details This structure contains various information about bond status,
- * such as bond_id, link status, slave port status, port count, etc.,
- * and also contains lacp information for each port,
- * as well as the number of times each host successfully and failed to report lacp negotiation results.
+ * @brief 定义了一个用于存储bond状态信息的结构体
+ * @details 该结构体包含了bond状态的各种信息,如bond_id、链路状态、slave port状态、port个数等,并且还包含了每个port的lacp信息,以及每个host成功和失败上报lacp协商结果的次数等。
*/
typedef struct tag_bond_full_get {
- u32 bond_id; /* bond id */
- u32 bon_mmi_status; /* link status of this bond sub-device */
- u32 active_bitmap; /* slave port status of this bond sub-device */
- u32 port_count; /* number of this bond sub-device */
- struct lacp_port_info port_info[BOND_MAX_PORT_NUM];/* lacp information for each port */
- u64 success_report_cnt[BOND_MAX_HOST_NUM];/* number of times each host successfully reported lacp negotiation result */
- u64 fail_report_cnt[BOND_MAX_HOST_NUM]; /* number of times each host failed to report lacp negotiation result */
- u64 poll_timeout; /* poll timeout */
- u64 fast_periodic_timeout; /* fast periodic timeout */
- u64 slow_periodic_timeout; /* slow periodic timeout */
- u64 short_timeout; /* short timeout */
- u64 long_timeout; /* long timeout */
- u64 aggregate_wait_timeout; /* aggregate wait timeout */
- u64 tx_period_timeout; /* tx period timeout */
- u64 rx_marker_timer; /* RX marker timer */
- u8 bond_mode; /* bond mode */
- u8 arp_dual_en; /* arp dual send enable flag */
- u8 rsvd[6]; /* reserved field */
+ u32 bond_id; /**< bond id */
+ u32 bon_mmi_status; /**< 该bond子设备的链路状态 */
+ u32 active_bitmap; /**< 该bond子设备的slave port状态 */
+ u32 port_count; /**< 该bond子设备个数 */
+ struct lacp_port_info
+ port_info[BOND_MAX_PORT_NUM]; /**< 每个port的lacp信息 */
+ u64 success_report_cnt
+ [BOND_MAX_HOST_NUM]; /**< 每个host成功上报lacp协商结果次数 */
+ u64 fail_report_cnt
+ [BOND_MAX_HOST_NUM]; /**< 每个host上报lacp协商结果失败次数 */
+ u64 poll_timeout; /**< 轮询超时时间 */
+ u64 fast_periodic_timeout; /**< 快速周期性超时时间 */
+ u64 slow_periodic_timeout; /**< 慢速周期性超时时间 */
+ u64 short_timeout; /**< 短超时时间 */
+ u64 long_timeout; /**< 长超时时间 */
+ u64 aggregate_wait_timeout; /**< 聚合等待超时时间 */
+ u64 tx_period_timeout; /**< 发送周期超时时间 */
+ u64 rx_marker_timer; /**< RX标记定时器 */
+ u8 bond_mode; /**< bond模式 */
+ u8 arp_dual_en; /**< arp双发使能标记 */
+ u8 rsvd[6]; /**< 保留域段 */
} bond_full_get_s;
typedef union tag_cfm_bond_get_s {
@@ -111,48 +101,47 @@ typedef union tag_cfm_bond_get_s {
typedef struct tag_cfm_bond_info_get {
struct mgmt_msg_head comm_head;
u16 sub_cmd;
- u8 rsvd0;
- u8 bond_type;
+ u8 rsvd0;
+ u8 bond_type;
cfm_bond_get_u data;
} cfm_bond_info_get_s;
-/* bond configuration information structure */
+/* bond配置信息结构体 */
typedef struct tag_cfm_bond_cfg_cmd {
- struct mgmt_msg_head head; /* message header */
- u32 cfg_bitmap; /* bond cfg bitmap */
- u8 bond_name[BOND_NAME_MAX_LEN]; /* if bond_id_vld=0 input, else output */
- u8 op_code; /* operation type: 0: query GET, 1: configure SET */
- u8 arp_en; /* ARP dual send enable */
- u8 rsvd0[2]; /* reserved field */
- u32 rsvd1[58]; /* reserved field */
+ struct mgmt_msg_head head; /**< 消息头 */
+ u32 cfg_bitmap; /**< bond cfg bitmap */
+ u8 bond_name[BOND_NAME_MAX_LEN]; /**< if bond_id_vld=0 input, else output */
+ u8 op_code; /**< 操作类型:0: 查询GET,1:配置SET */
+ u8 arp_en; /**< ARP双发使能 */
+ u8 rsvd0[2]; /**< 保留字段 */
+ u32 rsvd1[58]; /**< 保留字段 */
} cfm_bond_cfg_cmd_s;
/**
- * @brief Defines the information required to create a bond device
- * @details This structure contains various parameters required to create a bond device,
- * such as bond device number, master/slave port id, bond port id bitmap, etc.
+ * @brief 定义了创建bond设备所需的信息
+ * @details 该结构体包含了创建bond设备所需的各种参数,如bond设备号、主从端口id、bond port id bitmap等。
*/
struct hinic5_create_bond_info {
- u32 bond_id; /* bond device number, valid on output, filled when mpu operation succeeds */
- u32 master_slave_port_id; /* master/slave port id, smallest port id as master port */
- u32 slave_bitmap; /* bond port id bitmap */
- u32 poll_timeout; /* bond device link check time */
- u32 up_delay; /* reserved for now */
- u32 down_delay; /* reserved for now */
- u32 bond_mode; /* reserved for now */
- u32 xmit_hash_policy; /* hash policy, used for microcode routing logic */
- u8 lacp_rate; /* lacp negotiation rate, 0 for slow, 1 for fast */
- u8 rsvd1[3]; /* reserved field */
- u32 rsvd[1]; /* reserved field */
+ u32 bond_id; /**< bond设备号,output时有效,mpu操作成功返回时回填 */
+ u32 master_slave_port_id; /**< 主从端口id,最小的port id作为主口 */
+ u32 slave_bitmap; /**< bond port id bitmap */
+ u32 poll_timeout; /**< bond设备链路检查时间 */
+ u32 up_delay; /**< 暂时预留 */
+ u32 down_delay; /**< 暂时预留 */
+ u32 bond_mode; /**< 暂时预留 */
+ u32 xmit_hash_policy; /**< hash策略,用于微码选路逻辑 */
+ u8 lacp_rate; /**< lacp协商速率 0 为慢速, 1 为快速 */
+ u8 rsvd1[3]; /**< 保留域段 */
+ u32 rsvd[1]; /**< 保留域段 */
};
/**
- * @brief Message interface structure for creating bond
- * @details This structure is used for the message interface to create bond
+ * @brief 创建bond的消息接口结构体
+ * @details 该结构体用于创建bond的消息接口
*/
struct hinic5_cmd_create_bond {
- struct hinic5_mgmt_msg_head head; /* command message header */
- struct hinic5_create_bond_info create_bond_info; /* information for creating bond */
+ struct hinic5_mgmt_msg_head head; /**< 命令字消息头 */
+ struct hinic5_create_bond_info create_bond_info; /**< 创建bond的信息 */
};
-#endif /* BOND_CFM_CMD_H */
+#endif /* BOND_CFM_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/qos_base_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/qos_base_cmd.h
index b241bdef2..86a3d619a 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/qos_base_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/cfm/qos_base_cmd.h
@@ -1,11 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : qos_base_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : qos data structure
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+ * Description : qos datastruct
+ * Creation time : 2026/03/11
*/
#ifndef QOS_BASE_CMD_H
@@ -14,30 +10,48 @@
#include "mpu_cmd_base_defs.h"
/**
- * @brief enum qos_cc_l2d parm command
+ * @brief enum qos_th parm command
*/
-typedef enum tag_qos_cc_l2d_parm {
- QOS_CC_L2D_PARM_INVALID = 0, /**< parm command invalid */
- QOS_CC_L2D_PARM_NIC_OQ_THRD, /**< parm command nic_oq_thrd */
- QOS_CC_L2D_PARM_ROCE_OQ_THRD, /**< parm command roce_oq_thrd */
- QOS_CC_L2D_PARM_UBOE_OQ_THRD, /**< parm command uboe_oq_thrd */
- QOS_CC_L2D_PARM_HCT_EN, /**< parm command hct_en */
-} qos_cc_l2d_parm_e;
+typedef enum tag_qos_th_parm {
+ QOS_TH_PARM_INVALID = 0, /**< parm command invalid */
+ QOS_TH_PARM_ROCE_OQ_TH, /**< parm command roce_oq_th */
+ QOS_TH_PARM_UBOE_OQ_TH, /**< parm command uboe_oq_th */
+ QOS_TH_PARM_NIC_OQ_TH, /**< parm command nic_oq_th */
+ QOS_TH_PARM_VIRTIO_OQ_TH, /**< parm command virtio_oq_th */
+ QOS_TH_PARM_CPB_WATERLINE, /**< parm command cpb_cos_th */
+ QOS_TH_PARM_EN, /**< parm command en */
+} qos_th_parm_e;
/**
- * @brief struct qos_cc_l2d tbl command
+ * @brief struct qos_th tbl command
*/
-typedef struct tag_qos_cc_l2d_tbl {
+typedef struct tag_qos_th_tbl {
union {
struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
- u32 nic_oq_thrd : 10;
- u32 nic_oq_thrd_mark : 1;
- u32 rsvd : 21;
+ u32 host_oq_en : 1;
+ u32 host_oq_en_mark : 1;
+ u32 net_oq_en : 1;
+ u32 net_oq_en_mark : 1;
+ u32 roce_cpb_waterline_en : 1;
+ u32 roce_cpb_waterline_en_mask : 1;
+ u32 roce_cpb_waterline_set_mask : 1;
+ u32 uboe_cpb_waterline_en : 1;
+ u32 uboe_cpb_waterline_en_mask : 1;
+ u32 uboe_cpb_waterline_set_mask : 1;
+ u32 rsvd : 22;
#else
- u32 rsvd : 21;
- u32 nic_oq_thrd_mark : 1;
- u32 nic_oq_thrd : 10;
+ u32 rsvd : 22;
+ u32 uboe_cpb_waterline_set_mask : 1;
+ u32 uboe_cpb_waterline_en_mask : 1;
+ u32 uboe_cpb_waterline_en : 1;
+ u32 roce_cpb_waterline_set_mask : 1;
+ u32 roce_cpb_waterline_en_mask : 1;
+ u32 roce_cpb_waterline_en : 1;
+ u32 net_oq_en_mark : 1;
+ u32 net_oq_en : 1;
+ u32 host_oq_en_mark : 1;
+ u32 host_oq_en : 1;
#endif
} bs;
u32 value;
@@ -46,13 +60,13 @@ typedef struct tag_qos_cc_l2d_tbl {
union {
struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
- u32 roce_oq_thrd : 10;
- u32 roce_oq_thrd_mark : 1;
+ u32 nic_oq_th : 10;
+ u32 nic_oq_th_mark : 1;
u32 rsvd : 21;
#else
u32 rsvd : 21;
- u32 roce_oq_thrd_mark : 1;
- u32 roce_oq_thrd : 10;
+ u32 nic_oq_th_mark : 1;
+ u32 nic_oq_th : 10;
#endif
} bs;
u32 value;
@@ -61,13 +75,13 @@ typedef struct tag_qos_cc_l2d_tbl {
union {
struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
- u32 uboe_oq_thrd : 10;
- u32 uboe_oq_thrd_mark : 1;
+ u32 roce_oq_th : 10;
+ u32 roce_oq_th_mark : 1;
u32 rsvd : 21;
#else
u32 rsvd : 21;
- u32 uboe_oq_thrd_mark : 1;
- u32 uboe_oq_thrd : 10;
+ u32 roce_oq_th_mark : 1;
+ u32 roce_oq_th : 10;
#endif
} bs;
u32 value;
@@ -76,41 +90,82 @@ typedef struct tag_qos_cc_l2d_tbl {
union {
struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
- u32 host_cg_tran_en : 1;
- u32 host_cg_tran_mark : 1;
- u32 rsvd : 30;
+ u32 uboe_oq_th : 10;
+ u32 uboe_oq_th_mark : 1;
+ u32 rsvd : 21;
#else
- u32 rsvd : 30;
- u32 host_cg_tran_mark : 1;
- u32 host_cg_tran_en : 1;
+ u32 rsvd : 21;
+ u32 uboe_oq_th_mark : 1;
+ u32 uboe_oq_th : 10;
#endif
} bs;
u32 value;
} dw3;
- u32 dw_rsvd[4];
-} qos_cc_l2d_tbl_s;
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 virtio_oq_th : 10;
+ u32 virtio_oq_th_mark : 1;
+ u32 rsvd : 21;
+#else
+ u32 rsvd : 21;
+ u32 virtio_oq_th_mark : 1;
+ u32 virtio_oq_th : 10;
+#endif
+ } bs;
+ u32 value;
+ } dw4;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 roce_cpb_hi_waterline : 16;
+ u32 roce_cpb_lw_waterline : 16;
+#else
+ u32 roce_cpb_lw_waterline : 16;
+ u32 roce_cpb_hi_waterline : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw5;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 uboe_cpb_hi_waterline : 16;
+ u32 uboe_cpb_lw_waterline : 16;
+#else
+ u32 uboe_cpb_lw_waterline : 16;
+ u32 uboe_cpb_hi_waterline : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw6;
+
+ u32 dw_rsvd[1];
+} qos_th_tbl_s;
-/* For scalability, actual pass-through size is 32B, union occupies 64B */
-#define CFM_QOS_CC_L2D_DATA_LEN 64
+#define CFM_QOS_TH_DATA_LEN \
+ 64 /* 考虑可扩展性,实际透传大小32B,联合体占位64B */
-/* L2DMEM write request */
-typedef struct tag_cfm_l2dmem_req {
+/* L2DMEM写请求 */
+typedef struct tag_cfm_qos_th_req {
struct mgmt_msg_head head;
- /* For scalability */
+ /* 考虑可扩展性 */
union {
- u32 padding[CFM_QOS_CC_L2D_DATA_LEN];
- qos_cc_l2d_tbl_s l2d_tbl;
+ u32 padding[CFM_QOS_TH_DATA_LEN];
+ qos_th_tbl_s l2d_tbl;
} cfg;
-} qos_cc_l2d_req_s;
+} qos_th_req_s;
-/* L2DMEM read response */
-typedef struct tag_cfm_l2dmem_rsp {
+/* L2DMEM读响应 */
+typedef struct tag_cfm_qos_th_rsp {
struct mgmt_msg_head head;
union {
- u32 padding[CFM_QOS_CC_L2D_DATA_LEN];
- qos_cc_l2d_tbl_s l2d_tbl;
+ u32 padding[CFM_QOS_TH_DATA_LEN];
+ qos_th_tbl_s l2d_tbl;
} cfg;
-} qos_cc_l2d_rsp_s;
+} qos_th_rsp_s;
-#endif /* QOS_BASE_CMD_H */
+#endif /* QOS_BASE_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/inband_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/inband_mpu_cmd_defs.h
index d3527572e..fcc34af8f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/inband_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_fw_msg/mpu/inband_mpu_cmd_defs.h
@@ -1,17 +1,14 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : inband_mpu_cmd_defs.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
* Description : mpu cmd
+ * Creation time : 2026/04/10
*/
#ifndef INBAND_MPU_CMD_DEFS_H
#define INBAND_MPU_CMD_DEFS_H
#include "mpu_cmd_base_defs.h"
+#include "outband_mpu_ncsi_cmd_defs.h"
typedef struct {
struct mgmt_msg_head head;
@@ -46,9 +43,9 @@ struct nic_cmd_set_uart_log_cmd {
};
enum log_or_index_type {
- MPU_COMM_GET_LOG = 0, /**< Get mpu log */
- MPU_COMM_GET_INDEX, /**< Get index log */
- NPU_COMM_GET_SIM_DATA, /**< Get microcode dictionary from flash */
+ MPU_COMM_GET_LOG = 0, /**< 获取mpu日志 */
+ MPU_COMM_GET_INDEX, /**< 获取index日志 */
+ NPU_COMM_GET_SIM_DATA, /**< 从flash中获取微码字典 */
};
enum log_module_type {
@@ -76,37 +73,31 @@ struct nic_log_info {
struct mgmt_msg_head msg_head;
u32 offset;
- u8 log_or_index; // 0:log; 1:index;
- u8 type; // 0:up; 1:ucode;
- // 2:smu;(log_or_index: 0, this bit: log type,
- // 1, this bit: dictionary type)
- // 3:mpu lastword 4:npu lastword
- // 5:mpu cnt dictionary file, 6: npu cnt dictionary file
- u8 area; // 0:ram;
- // 1:flash; (this bit is only valid when log_or_index is 0)
- u8 rsvd1; // reserved
- u8 data[MAX_LOG_BUF_SIZE]; // 1KB data per fetch
+ u8 log_or_index; // 0:log; 1:index;
+ u8 type; // 0:up; 1:ucode; 2:smu;(log_or_index: 0, 此位:日志类型, 1, 此位:字典类型)
+ // 3:mpu lastword 4.npu lastword
+ // 5:mpu cnt 字典文件, 6. npu cnt 字典文件
+ u8 area; // 0:ram; 1:flash;(只有当log_or_index为0的时候,此位有效)
+ u8 rsvd1; // reserved
+ u8 data[MAX_LOG_BUF_SIZE]; // 单次获取1KB数据
};
-/* Log control info (pi and log sequence info reserved for log anti-overwrite function) */
+/* 日志控制信息(用于日志防覆盖功能保留的pi和日志次序等信息) */
typedef struct {
- u32 log_valid; /* Log valid bit */
+ u32 log_valid; /* 日志有效位 */
u32 rsv_log_pi;
- u32 pi; /* Log offset */
- /* Log sequence number, incremented by 1 per write, identifies which log session,
- * and the next partition to write to (even: master partition, odd: backup partition)
- */
- u32 log_seq;
- u32 info_rsv[2]; /* Log reserved info rsv field */
+ u32 pi; /* 日志偏移 */
+ u32 log_seq; /* 日志序列号,每写一次递增1,标识是哪一次的日志,以及下次要写入的分区(偶数写入主区,奇数写入备区) */
+ u32 info_rsv[2]; /* 日志保留信息rsv字段 */
} log_ctrl_info_s;
typedef struct {
- u32 log_type : 2; /* Log data source, 0:up, 1:ucode, 2:sec */
+ u32 log_type : 2; /* 日志数据的来源,0:代表up,1:代表ucode,2:表示sec */
u32 rsvd1 : 6;
u32 core_id : 2;
- u32 time_sync : 1; /* Whether time is synced, MPU_LOG_TIME_SYNC_TYPE type */
- u32 patch_log : 1; /* Patch log flag, 0: non-patch log, 1: patch log */
- u32 patch_log_level : 3; /* Patch log level */
+ u32 time_sync : 1; /* 时间是否已同步,MPU_LOG_TIME_SYNC_TYPE类型 */
+ u32 patch_log : 1; /* 补丁日志标识,0:非补丁日志,1:补丁日志 */
+ u32 patch_log_level : 3; /* 补丁日志级别 */
u32 rsvd3 : 17;
} log_head_mpu;
@@ -117,16 +108,16 @@ typedef struct {
} log_head_imp;
typedef struct {
- u32 log_type : 2; /* Log data source, 0:up, 1:ucode, 2:sec */
- u32 core_id : 6; /* Microcode core id, valid when type is 1 */
- u32 thread_id : 2; /* Microcode thread id, valid when type is 1 */
- u32 srv_data : 22; /* Feature private data */
+ u32 log_type : 2; /* 日志数据的来源,0:代表up,1:代表ucode,2:表示sec */
+ u32 core_id : 6; /* 微码core id,当type为1时生效 */
+ u32 thread_id : 2; /* 微码thread id,当type为1时生效 */
+ u32 srv_data : 22; /* 特性私有数据 */
} log_head_def;
-/* User log entry */
+/* user日志条目 */
#define LOG_USER_ITEM 4
-/* Log storage format, total size is 32B */
+/* 日志的存储格式,总大小为32B */
typedef struct {
/* DW0 */
union {
@@ -136,15 +127,15 @@ typedef struct {
} head;
/* DW1 */
- u16 file_id; /* Stored file ID */
- u16 code_line_num; /* Line where the print code is located */
+ u16 file_id; /* 存放文件ID */
+ u16 code_line_num; /* 打印代码所在行 */
/* DW2~DW3 */
- u32 time_l32; /* Time counter (low) */
- u32 time_h32; /* Time counter (high) */
+ u32 time_l32; /* 时间计数 */
+ u32 time_h32; /* 时间计数 */
/* Dw4~DW7 */
- u32 user_val[LOG_USER_ITEM]; /* Determined by each log entry type */
+ u32 user_val[LOG_USER_ITEM]; /* 根据每种类型的日志条目确定 */
} log_item_s;
typedef struct tag_mpu_mctp_counter_info {
@@ -215,25 +206,277 @@ typedef struct tag_mpu_mctp_counter_info {
} mpu_mctp_counter_info_s;
#define OOB_INFO_BUFFER_MAX 1024
-typedef struct comm_cmd_oob_info_resp_new {
+typedef struct {
struct mgmt_msg_head head; /* 8B */
u8 oob_info_buf[OOB_INFO_BUFFER_MAX];
} comm_cmd_oob_info_resp_new;
enum sfp_type_enum {
- SFP_TYPE_SFP = 0,
- SFP_TYPE_QSFP = 1,
- SFP_TYPE_OSFP = 2,
- SFP_TYPE_DSFP = 3,
- SFP_TYPE_COUNT
+ SFP_TYPE_SFP = 0,
+ SFP_TYPE_QSFP = 1,
+ SFP_TYPE_OSFP = 2,
+ SFP_TYPE_DSFP = 3,
+ SFP_TYPE_COUNT
};
enum power_channel_enum {
- POWER_CHANNEL_INDEX_0 = 0,
- POWER_CHANNEL_INDEX_1 = 1,
- POWER_CHANNEL_INDEX_2 = 2,
- POWER_CHANNEL_INDEX_3 = 3,
- POWER_CHANNEL_INDEX_COUNT
+ POWER_CHANNEL_INDEX_0 = 0,
+ POWER_CHANNEL_INDEX_1 = 1,
+ POWER_CHANNEL_INDEX_2 = 2,
+ POWER_CHANNEL_INDEX_3 = 3,
+ POWER_CHANNEL_INDEX_COUNT
+};
+
+typedef struct tag_mpu_ncsi_counter_info_s {
+ u32 ncsi_rx_octets_total_ok; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_octets_bad; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_uc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_mc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_bc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_64octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_65to127octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_128to255octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_255to511octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_512to1023octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_1024to1518octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pkts_1519tomaxoctets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_fcs_errs; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_tagged; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_data_errs; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_align_errs; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_long_errs; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_jabber_errs; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pause_maccontrol_framcounter; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_unknow_maccontrol_framcounter; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_very_long_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_runt_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_short_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_filt_pkt_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_octets_total_filt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_octets_transmitte_ok; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_octets_transmitte_bad; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_uc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_mc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_bc_pkts; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_64octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_65to127octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_128to255octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_255to511octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_512to1023octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_1024to1518octets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pkts_1519tomaxoctets; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_underrun; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_tagged; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_crc_err; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pause_frams; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_overrun_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_lengthfield_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_fail_comma_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_frm_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_frm_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_xon_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_xoff_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_xon_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_empty_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_app_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_add_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_txbd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_txbd_empty_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_txbd_code_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_txbd_min_frame_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_txbd_max_frame_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rls_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_pkt_cnt_low; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_pkt_cnt_high; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_pkt_disc_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pt_ch_err_cnt0; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pt_ch_err_cnt1; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pt_ch_err_cnt2; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pt_ch_err_cnt3; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_pt_pkt_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_ctrl_ok_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_ctrl_disc_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_ctrl_chksum_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_ctrl_pkt_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_ctrl_len_mismatch_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_tx_ctrl_len_short; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_ch_ok_cnt0; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_ch_ok_cnt1; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_ch_ok_cnt2; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_pt_ch_ok_cnt3; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_rx_ctrl_pavload_len_err_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 ncsi_ipsurx_hit_count; /**< ncsi寄存器,定义详见nmanager */
+ u32 pie_to_mpu_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 pie_to_ipsu_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 pie_to_ncsi_bd_cnt; /**< ncsi寄存器,定义详见nmanager */
+ u32 rsv[10];
+} mpu_ncsi_counter_info_s; /**< ncsi寄存器,定义详见nmanager */
+
+#define NCSI_COUNT_OPT_TYPE_READ 0 /**< ncsi counter读 */
+#define NCSI_COUNT_OPT_TYPE_CLEAR 1 /**< nsci counter清除 */
+
+struct comm_cmd_ncsi_counter_req { /**< 获取ncsi counter */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+ u8 opt_type; /**< 0:read counter 1:counter clear */
+ u8 rsvd[3];
};
-#endif
+struct comm_cmd_ncsi_counter_resp { /**< 获取ncsi counter */
+ struct mgmt_msg_head head; /**< mbox消息头 */
+
+ mpu_ncsi_counter_info_s ncsi_cnt_info; /**< counter信息 */
+};
+
+#pragma pack(1)
+typedef struct tag_ncsi_chan_info {
+ u8 aen_en; /* AEN enable */
+ u8 index; /* index of channel */
+ u8 port; /* net port number */
+ u8 state; /* NCSI state(enum) */
+ u8 ncsi_port_en; /* 标识该port的开关情况(1:开;0:关) */
+ u8 rsv[3];
+ ncsi_chan_capa_s capabilities;
+ ncsi_parameters_s parameters;
+} ncsi_chan_info_s;
+
+typedef struct tag_ncsi_public_info {
+ u8 ncsi_ver;
+ u8 ncsi_pkg_id; // 需读取寄存器查询获得
+ u8 arb_en; /* arbitration en */
+ u8 duplex_set; /* 双工模式 */
+ u8 chan_num; /* 虚拟channel数量,硬件最大只支持4个,使用多少个可由软件配置寄存器决定 */
+ u8 iid; /* identify new instances of a command */
+ u8 lldp_over_ncsi_enable;
+ u8 lldp_over_mctp_enable;
+ u32 magicwd;
+ u8 lldp_tx_enable;
+ u8 rsd[2];
+ u8 crc_flag;
+ u32 crc;
+} ncsi_pubcli_info_s;
+
+/* 一个port的ncsi配置结构体 */
+typedef struct {
+ ncsi_pubcli_info_s ncsi_public_info;
+ ncsi_chan_info_s ncsi_chan_info;
+} comm_cmd_ncsi_settings;
+
+#define IPSURX_MAC_NUM 0x4
+#define IPSURX_MAC_BYTES 0x6
+#define IPSURX_VLAN_NUM 0x8
+
+typedef struct tag_ncsi_filter_cfg {
+ /* 1.ipsurx的过滤配置 */
+ u32 ipsurx_ncsi_ctrl;
+ u32 ipsurx_ncsi_filter_mng;
+
+ u8 ipsurx_mac_cfg[IPSURX_MAC_NUM][IPSURX_MAC_BYTES];
+ u8 ipsurx_mac_vld[IPSURX_MAC_NUM];
+
+ u32 ipsurx_ncsi_vlan_en;
+ u16 ipsurx_vlan_tag[IPSURX_VLAN_NUM];
+ u16 ipsurx_vlan_vld[IPSURX_VLAN_NUM];
+
+ u32 ipsurx_ncsi_bc_ctrl;
+ u32 ipsurx_ncsi_mc_ctrl;
+
+ /* 2.ncsi的过滤配置 */
+ u8 ncsi_smac_cfg[IPSURX_MAC_BYTES];
+ u32 ncsi_chnl_ctrl;
+
+ /* 3.微码的过滤配置 */
+ u8 lldp_fwd_en; /* lldp forward enable(4 port) */
+ u8 lacp_fwd_en; /* lacp forward enable(4 port) */
+ u8 ncsi_arp_en;
+ u8 lldp_over_ncsi_enable;
+ u8 lldp_over_mctp_enable;
+ u8 lldp_tx_enable;
+ u8 rsv[22];
+} comm_cmd_ncsi_filter_cfg;
+
+typedef enum {
+ OPERATOR_OBJECT_NCSI = 0,
+ OPERATOR_OBJECT_PIE,
+ OPERATOR_OBJECT_MCTP,
+} oob_info_object_e;
+
+typedef enum {
+ OPERATOR_TYPE_READ_RAM_CFG = 0,
+ OPERATOR_TYPE_READ_FLASH_CFG,
+ OPERATOR_TYPE_READ_REG_CFG,
+ OPERATOR_TYPE_CLEAR_FLASH_CFG,
+ OPERATOR_TYPE_CLEAR_COUNTER,
+ OPERATOR_TYPE_READ_COUNTER,
+} oob_info_type_e;
+
+/* oob cfg req */
+typedef struct {
+ struct mgmt_msg_head head; /* 8B */
+
+ u8 port; /* net port number */
+ u8 oob_type; /**< 0:ncsi 1:mctp */
+ u8 opt_type; /**< 0:read ram cfg 1:read flash cfg 2:clear flash cfg 3.clear counter 4.read counter*/
+ u8 rsvd[5];
+} comm_cmd_oob_info_req_s;
+
+typedef struct {
+ u8 ncsi_cable_state; /* 0--线缆不在位,1--线缆在位 */
+ u8 rsvd[3];
+ comm_cmd_ncsi_settings setting_info;
+ comm_cmd_ncsi_filter_cfg filter_cfg;
+} mpu_ncsi_cfg_info_s;
+
+/* PIE统计 */
+typedef struct tag_pie_statistics {
+ u32 recv_correct_pkt;
+ u32 recv_err_pkt;
+ u32 recv_correct_ncsi_pkt;
+ u32 recv_err_ncsi_pkt;
+ u32 send_ncsi_pkt;
+ u32 recv_correct_vnet_pkt;
+ u32 recv_err_vnet_pkt;
+ u32 send_vnet_pkt;
+ u32 recv_lacp_pkt_number;
+ u32 task_sch;
+ u32 bd_oq2up_cvg_int;
+ u32 sgl_cvg_int;
+ u32 bm_fifo_ful_int;
+ u32 oq_eccm_int;
+ u32 oq_eccs_int;
+ u32 tx_parity_int;
+ u32 rx_parity_int;
+ u32 bd_oq2ipsu_ful_int;
+ u32 bd_oq2ncsi_ful_int;
+ u32 bd_oq2up_ful_int;
+ u32 tx_ucerr;
+ u32 rx_ucerr;
+ u32 irq_nums;
+} pie_statistics;
+
+typedef struct {
+ mpu_ncsi_counter_info_s ncsi_cnt_info;
+ pie_statistics pie_cnt_info;
+} oob_counter_info_s;
+
+typedef union {
+ mpu_ncsi_cfg_info_s ncsi_cfg_info;
+ oob_counter_info_s cnt_info;
+} comm_cmd_oob_info_buf;
+
+typedef struct {
+ struct mgmt_msg_head head; /* 8B */
+ comm_cmd_oob_info_buf oob_info_buf;
+} comm_cmd_oob_info_resp;
+
+/* ncsi cfg */
+typedef struct {
+ struct mgmt_msg_head head; /* 8B */
+
+ u8 ncsi_cable_state; /* 0--线缆不在位,1--线缆在位 */
+ u8 setting_type; /* 0表示获取当前ram中的配置, 1表示获取flash中的配置 */
+ u8 port; /* net port number */
+ u8 erase_flag;
+ comm_cmd_ncsi_settings setting_info;
+} comm_cmd_ncsi_cfg_s;
+#pragma pack()
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/bond_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/bond_pub_cmd.h
index 1401f8c19..72ad65281 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/bond_pub_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/bond_pub_cmd.h
@@ -1,30 +1,27 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : bond_pub_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Interface definition for interaction between bond tool and driver
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Filename : bond_pub_cmd.h
+ * Creation time : 2025/09/08
+ * Description : bond工具和驱动的交互接口定义
+ * Version : 1.0
*/
#ifndef BOND_PUB_CMD_H
#define BOND_PUB_CMD_H
-#include "bond_common_defs.h"
#include "hinic5_mt.h"
#define MAX_NETDEV_NUM 4
/**
* @brief enum hinic5_bond_cmd_to_custom_e
- * @details Defines command types related to custom devices
+ * @details 定义了与自定义设备相关的命令类型
*/
enum hinic5_bond_cmd_to_custom_e {
- CMD_CUSTOM_BOND_DEV_CREATE = 1, /**< Create custom device */
- CMD_CUSTOM_BOND_DEV_DELETE, /**< Delete custom device */
- CMD_CUSTOM_BOND_GET_CHIP_NAME, /**< Get chip name */
- CMD_CUSTOM_BOND_GET_CARD_INFO, /**< Get card information */
+ CMD_CUSTOM_BOND_DEV_CREATE = 1, /**< 创建自定义设备 */
+ CMD_CUSTOM_BOND_DEV_DELETE, /**< 删除自定义设备 */
+ CMD_CUSTOM_BOND_GET_CHIP_NAME, /**< 获取芯片名称 */
+ CMD_CUSTOM_BOND_GET_CARD_INFO, /**< 获取卡片信息 */
CMD_CUSTOM_BOND_GET_ULD_DEV_NAME
};
@@ -34,7 +31,7 @@ enum hinic5_bond_cmd_to_custom_e {
/**
* @brief struct bond_dfx_ops_info
- * @details DFX operations for bond binding and unbinding
+ * @details 用于bond绑定解绑的dfx操作
*/
struct bond_dfx_ops_info {
struct mt_msg_head head;
@@ -43,4 +40,4 @@ struct bond_dfx_ops_info {
u32 user;
};
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hisec_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hisec_pub_cmd.h
index fb99e4959..78a59fe04 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hisec_pub_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/hisec_pub_cmd.h
@@ -1,11 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hisec_pub_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Filename : hisec pub cmd
+ * Creation time : 2024/04/10
* Description : COMM Commands and struct define between hinicadmdfx and DRIVER(ipsec)
+ * Version : 1.0
*/
#ifndef HISEC_PUB_CMD_H
@@ -13,7 +11,7 @@
#include "base_type.h"
-/* hisec_cmd_table maximum size is 2MB, minus the size of ipsec_tbl_args */
+/* hisec_cmd_table最大2MB,减去ipsec_tbl_args的大小 */
#define IPSEC_TBL_BUF_MAX (2048 * 1024 - sizeof(ipsec_tbl_args))
typedef enum hisec_driver_cmd_type {
@@ -35,7 +33,7 @@ typedef struct tag_hisec_driver_cmd_hdr {
struct {
u32 rsvd0 : 16;
u32 channel_id : 8; /* logical concurrency channel */
- u32 cmd_type : 8; /* cmd type */
+ u32 cmd_type : 8; /* cmd type */
} bs;
u32 value;
} dw0;
@@ -66,12 +64,12 @@ typedef struct {
u16 exid;
u16 funcid;
- u16 valid;
+ u16 vaild;
u16 dir;
u16 rsvd;
u64 bitmap[IPSEC_ANTIREPLAY_BITMAP_MAX_LEN];
-} ipsec_antireplay_info ;
+} ipsec_antireplay_info;
struct ipsec_soft_antireplay_info {
ipsec_antireplay_info info;
@@ -80,29 +78,29 @@ struct ipsec_soft_antireplay_info {
#define HISEC_ENABLE_HARDWARE_ANTIREPLAY 1
#define HISEC_HARDWARE_ANTIREPLAY_WINDOW_SIZE 64
-/* Software constraint: software anti-replay window minimum size is 256 */
-#define HISEC_SOFTWARE_ANTIREPLAY_MIN_WINDOW_SIZE 256
+#define HISEC_SOFTWARE_ANTIREPLAY_MIN_WINDOW_SIZE \
+ 256 /* 软件约束软件防重放窗口最小为256 */
struct hinic5_ipsec_driver_enc_info {
- u8 proto; /* tcp/udp */
+ u8 proto; /* tcp/udp */
u8 direction; /* out/in */
- u8 mode; /* 0 transport/ 1 tunnel */
- u8 flag; /* 1 - esn */
+ u8 mode; /* 0 transport/ 1 tunnel */
+ u8 flag; /* 1 - esn */
u16 replaywindow; /* 32-64 */
- u8 alg_type; /* 0- aead 1-enc 2-auth 3-enc & auth */
- u8 alg_standard; /* 0 - aes, 1 - SM4 */
+ u8 alg_type; /* 0- aead 1-enc 2-auth 3-enc & auth */
+ u8 alg_standard; /* 0 - aes, 1 - SM4 */
- u8 enc_type; /* hisec_crypto_alg_type */
+ u8 enc_type; /* hisec_crypto_alg_type */
u8 auth_type; /* hisec_crypto_alg_type */
u16 cipher_key_len; /* in bit */
- u32 cipher_key[8]; /* 128bit 192bit 256bit */
- u32 salt; /* 32bit */
+ u32 cipher_key[8]; /* 128bit 192bit 256bit */
+ u32 salt; /* 32bit */
- u16 auth_key_len; /* in bit */
+ u16 auth_key_len; /* in bit */
u16 auth_trunc_len; /* in bit */
- u16 icv_mac_len; /* in bit */
+ u16 icv_mac_len; /* in bit */
u8 out_ip_type;
u8 hard_antireplay_en;
u32 auth_key[32]; /* 1024bit */
@@ -122,12 +120,12 @@ typedef struct tag_hisec_driver_cmd_set_ipsec_sa {
hisec_driver_cmd_hdr_s cmdhdr;
u32 saddr[4];
- u32 daddr[4]; /* ipv4 in daddr[0] */
+ u32 daddr[4]; /* ipv4 in daddr[0] */
u32 spi;
u8 ipsec_proto;
- u8 opid; /* | 0 - add | 1 - del | 2 - update | 3 - flush | */
- u8 iptype; /* | 0 - ipv4 | 1 - ipv6 | */
+ u8 opid; /* | 0 - add | 1 - del | 2 - update | 3 - flush | */
+ u8 iptype; /* | 0 - ipv4 | 1 - ipv6 | */
u8 ipsec_tls_flag;
u16 sport;
@@ -149,18 +147,18 @@ typedef struct tag_hisec_driver_cmd_set_ipsec_sp {
hisec_driver_cmd_hdr_s cmdhdr;
u32 saddr[4];
- u32 daddr[4]; /* dip ipv4 in daddr[0] */
+ u32 daddr[4]; /* dip ipv4 in daddr[0] */
u32 spi;
u16 vid;
u16 dport;
- u8 ulp_proto; /* | 6 - tcp | 17 - udp | */
+ u8 ulp_proto; /* | 6 - tcp | 17 - udp | */
u8 ipsec_proto; /* | 50 - esp | 51 - ah | */
- u8 opid; /* | 0 - add | 1 - del | 2 - update | */
- u8 iptype; /* | 0 - ipv4 | 1 - ipv6 | */
+ u8 opid; /* | 0 - add | 1 - del | 2 - update | */
+ u8 iptype; /* | 0 - ipv4 | 1 - ipv6 | */
- u8 action; /* | 0 - bypass | 1 - protect | 2 - drop | */
+ u8 action; /* | 0 - bypass | 1 - protect | 2 - drop | */
u8 rsvd0;
u16 rsvd1;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/macsec_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/macsec_pub_cmd.h
index bcf6fecdf..e103baa78 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/macsec_pub_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/macsec_pub_cmd.h
@@ -1,10 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : macsec_pub_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
+ * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Creation time : 2024/04/10
* Description : COMM Commands between hinicadmdfx and DRIVER(macsec)
*/
#ifndef MACSEC_PUB_CMD_H
@@ -13,15 +9,15 @@
#include "macsec_mpu_cmd_defs.h"
#define HIMACSEC_MAX_SAK_KEY_LEN 32 // The max sak length is 32B
-#define HIMACSEC_MAX_SA_IN_SC 4 // The macsec protocol stipulates
- // that SC can have a maximum of 4 SAs
+#define HIMACSEC_MAX_SA_IN_SC \
+ 4 // The macsec protocol stipulates that SC can have a maximum of 4 SAs
#define HIMACSEC_SALT_BUF_SIZE 12 // The salt is 12B
#define HIMACSEC_ICV_LEN 16
#define HIMACSEC_TOOL_IN_BUF_MAX 1024
#define HIMACSEC_LIST_OUT_BUF_MAX (8 * 1024)
#define HIMACSEC_MIB_OUT_BUF_MAX (1 * 1024)
#define HIMACSEC_COUNTER_OUT_BUF_MAX 512
-#define HIMACSEC_CRYPTO_ALGO_AES 0 // TODO: Algorithm type unification
+#define HIMACSEC_CRYPTO_ALGO_AES 0 // TODO 算法类型归一
#define HIMACSEC_CRYPTO_ALGO_SM4 1
#define HIMACSEC_POLICY_ENABLE 1
#define HIMACSEC_POLICY_DISABLE 0
@@ -29,40 +25,40 @@
#define HIMACSEC_KEY_LENGTH_256 32
#define HIMACSEC_REG_KEY_LENGTH_128 0
#define HIMACSEC_REG_KEY_LENGTH_256 1
-#define HIMACSEC_XPN_MAX_REPLAY_WINDOWS ((1 << 30) - 1) // Maximum replay window
- // when XPN mode is enabled is 2^30 -1
-#define HIMACSEC_DEFAULT_XPN_THRESHOLD 0xC000000000000000ULL // Default PN threshold in XPN mode
-#define HIMACSEC_DEFAULT_PN_THRESHOLD 0xC0000000ULL // Default PN threshold in non-XPN mode
+#define HIMACSEC_XPN_MAX_REPLAY_WINDOWS \
+ ((1 << 30) - 1) // 使能 xpn 模式下的最大重放窗口为 2^30 -1
+#define HIMACSEC_DEFAULT_XPN_THRESHOLD \
+ 0xC000000000000000ULL // XPN 模式下默认 pn 阈值
+#define HIMACSEC_DEFAULT_PN_THRESHOLD 0xC0000000ULL // 非 XPN 模式下默认 pn 阈值
#define HIMACSEC_SET_SC_ENCODING_SA_BIT_VAL 0x1
#define HIMACSEC_SET_SC_PROTECTION_MODE_BIT_VAL 0x2
#define HIMACSEC_SET_SC_PROTECT_FRAMES_BIT_VAL 0x4
#define HIMACSEC_SET_SC_VALIDATE_FRAMES_BIT_VAL 0x8
-// MIB query types
+// mib 查询的类型
typedef enum {
- HIMACSEC_TOOL_MIB_TYPE_SC = 0, // SC MIB information
- HIMACSEC_TOOL_MIB_TYPE_PORT, // PORT MIB information
+ HIMACSEC_TOOL_MIB_TYPE_SC = 0, // SC MIB 信息
+ HIMACSEC_TOOL_MIB_TYPE_PORT, // PORT MIB 信息
HIMACSEC_TOOL_MIB_TYPE_MAX
} himacsec_tool_mib_type_e;
-// SC protection mode in encryption direction
+// 加密方向 sc 保护模式
typedef enum {
- PROTECTION_MODE_INTERITY_ONLY = 0, // Integrity check only
- PROTECTION_MODE_CONFIDENTIALITY, // Integrity check and encryption
- PROTECTION_MODE_OFFSET_CONFIDENTIALITY, // Integrity check and encryption,
- // encrypted data can be offset by 0/30/50B
+ PROTECTION_MODE_INTERITY_ONLY = 0, // 仅进行完整性校验
+ PROTECTION_MODE_CONFIDENTIALITY, // 进行完整性校验及加密
+ PROTECTION_MODE_OFFSET_CONFIDENTIALITY, // 进行完整性校验及加密,加密数据可偏移 0/30/50B
PROTECTION_MODE_MAX
} himacsec_protection_mode_e;
-// SC validation mode in decryption direction
+// 解密方向 sc 验证模式
typedef enum {
- VALIDATE_MODE_DISABLE = 1, // Do not validate packets
- VALIDATE_MODE_CHECK, // Validate only, no filtering
- VALIDATE_MODE_STRICT, // Validate and filter
+ VALIDATE_MODE_DISABLE = 1, // 不对报文进行校验
+ VALIDATE_MODE_CHECK, // 只进行校验,不进行过滤
+ VALIDATE_MODE_STRICT, // 进行校验及过滤
VALIDATE_MODE_MAX
} himacsec_validate_mode_e;
-// Algorithm definition
+// 算法定义
typedef enum {
HIMACSEC_TOOL_CIPHER_GCM_AES_128 = 0,
HIMACSEC_TOOL_CIPHER_GCM_AES_256,
@@ -73,7 +69,7 @@ typedef enum {
HIMACSEC_TOOL_CIPHER_MAX
} himacsec_tool_algo_e;
-// Supported encryption offset specifications
+// 支持的加密偏移规格
typedef enum {
HIMACSEC_CONFIDENTIALITY_OFFSET_0 = 0,
HIMACSEC_CONFIDENTIALITY_OFFSET_30,
@@ -81,7 +77,7 @@ typedef enum {
HIMACSEC_CONFIDENTIALITY_OFFSET_MAX
} himacsec_confidentiality_ofs_e;
-// MACsec object operation types
+// macsec object 操作对象
typedef enum {
HIMACSEC_TOOL_OBJ_ENC_SC = 0,
HIMACSEC_TOOL_OBJ_DEC_SC,
@@ -90,7 +86,7 @@ typedef enum {
HIMACSEC_TOOL_OBJ_MAX
} himacsec_tool_obj_e;
-typedef enum macsec_direction { // TODO: Unify with IPsec
+typedef enum macsec_direction { // TODO 与 ipsec 归一
MACSEC_INBOUND = 0,
MACSEC_OUTBOUND,
} crypt_direction_e;
@@ -138,19 +134,19 @@ struct himacsec_sc {
struct himacsec_sa sa[HIMACSEC_MAX_SA_IN_SC];
};
-// Command inbuf contains an hdr
+// 命令的 inbuf 包含一个 hdr
typedef struct himacsec_cmd_hdr {
u32 cmd_type;
himacsec_tool_obj_e obj_type;
} himacsec_cmd_hdr_s;
-// inbuf definition
+// inbuf 定义
typedef struct himacsec_cmd_in {
himacsec_cmd_hdr_s hdr;
u8 buf[HIMACSEC_TOOL_IN_BUF_MAX];
} himacsec_cmd_in_s;
-// del command input parameter definition
+// del 命令入参定义
struct himacsec_cmd_del_in {
u64 sci;
u8 an;
@@ -164,7 +160,7 @@ struct himacsec_cmd_set_sc_in {
macsec_sc_info_s sc;
};
-// list and dump command outbuf output parameter definition
+// list 和 dump 命令 outbuf 出参定义
typedef struct himacsec_cmd_list_out {
u32 enc_sc_cnt;
u32 dec_sc_cnt;
@@ -172,26 +168,26 @@ typedef struct himacsec_cmd_list_out {
u8 dec_sc_buf[HIMACSEC_LIST_OUT_BUF_MAX];
} himacsec_cmd_list_out_s;
-// MIB input parameter definition
+// mib 入参定义
struct himacsec_cmd_mib_in {
u64 sci;
himacsec_tool_mib_type_e mib_type;
u32 rsvd;
};
-// MIB output parameter definition
+// mib 出参定义
typedef struct himacsec_cmd_mib_out {
u32 num;
u8 mib_buf[HIMACSEC_MIB_OUT_BUF_MAX];
} himacsec_cmd_mib_out_s;
-// list buf output parameter definition
+// list buf 出参定义
struct himacsec_cmd_list_sc_buf {
struct himacsec_sc sc;
u8 sa_cnt;
};
-// counter output parameter definition
+// counter 出参定义
typedef struct himacsec_cmd_counter_out {
u8 enc_cnt_buf[HIMACSEC_COUNTER_OUT_BUF_MAX];
u8 dec_cnt_buf[HIMACSEC_COUNTER_OUT_BUF_MAX];
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/nic_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/nic_pub_cmd.h
index 00853353d..f47d3f465 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/nic_pub_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/nic_pub_cmd.h
@@ -1,27 +1,17 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : nic_pub_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef NIC_PUB_CMD_H
#define NIC_PUB_CMD_H
#include "hinic5_mt.h"
-/* Queue information related */
+/* 队列信息相关 */
/**
* @brief struct hinic5_tx_hw_page
- * @details Structure for storing hardware page information
+ * @details 用于存储硬件页面信息的结构体
*/
struct hinic5_tx_hw_page {
- u64 phy_addr; /* Physical address */
- u64 *map_addr; /* Mapped address */
+ u64 phy_addr; /**< 物理地址 */
+ u64 *map_addr; /**< 映射地址 */
};
enum hinic5_show_set {
@@ -31,148 +21,142 @@ enum hinic5_show_set {
#define HINIC5_SHOW_ITEM_LEN 32
/**
* @brief struct hinic5_show_item
- * @details Structure for display items
+ * @details 用于显示项的结构体
*/
struct hinic5_show_item {
- char name[HINIC5_SHOW_ITEM_LEN]; /* Item name */
- u8 hexadecimal; /* Value display mode, 0 for decimal, 1 for hexadecimal */
- u8 rsvd[7]; /* Reserved field */
- u64 value; /* Item value */
+ char name[HINIC5_SHOW_ITEM_LEN]; /**< 项的名称 */
+ u8 hexadecimal; /**< 值的显示方式,0表示十进制,1表示十六进制 */
+ u8 rsvd[7]; /**< 保留字段 */
+ u64 value; /**< 项的值 */
};
/**
* @brief struct wqe_info
- * @details Structure for storing work queue related information
+ * @details 用于存储工作队列的相关信息
*/
struct wqe_info {
- int q_id; /* Queue ID */
- void *slq_handle; /* Queue handle */
- unsigned int wqe_id; /* Work queue element ID */
+ int q_id; /**< 队列ID */
+ void *slq_handle; /**< 队列句柄 */
+ unsigned int wqe_id; /**< 工作队列元素ID */
};
/**
* @brief struct nic_sq_info
- * @details Structure for storing network interface send queue information
+ * @details 用于存储网络接口的发送队列信息的结构体
*/
struct nic_sq_info {
- u16 q_id; /* Queue ID */
- u16 pi; /* Producer index */
- u16 ci; /* Consumer index */
- u16 fi; /* Hardware consumer index */
- u32 q_depth; /* Queue depth */
- u16 pi_reverse; /* Reverse producer index */
- u16 wqebb_size; /* Work queue element size */
- u8 priority; /* Priority */
- u64 ci_wqe_page_addr; /* SQ WQ first page address */
- u64 cla_addr; /* WQ block address */
- void *slq_handle; /* Send queue handle */
- struct hinic5_tx_hw_page direct_wqe; /* Direct work queue element */
- struct hinic5_tx_hw_page doorbell; /* Doorbell */
- u32 page_idx; /* Page index */
- u32 glb_sq_id; /* Global send queue ID */
+ u16 q_id; /**< 队列ID */
+ u16 pi; /**< 生产者索引 */
+ u16 ci; /**< 消费者索引 */
+ u16 fi; /**< 硬件消费者索引 */
+ u32 q_depth; /**< 队列深度 */
+ u16 pi_reverse; /**< 生产者索引的反向 */
+ u16 wqebb_size; /**< 工作队列元素的大小 */
+ u8 priority; /**< 优先级 */
+ u64 ci_wqe_page_addr; /**< sq wq首page地址 */
+ u64 cla_addr; /**< wq block地址 */
+ void *slq_handle; /**< 发送队列句柄 */
+ struct hinic5_tx_hw_page direct_wqe; /**< 直接工作队列元素 */
+ struct hinic5_tx_hw_page doorbell; /**< 门铃 */
+ u32 page_idx; /**< 页面索引 */
+ u32 glb_sq_id; /**< 全局发送队列ID */
};
/**
* @brief struct nic_rq_info
- * @details Structure for storing network interface receive queue information
+ * @details 用于存储网络接口的接收队列信息的结构体
*/
struct nic_rq_info {
- u16 q_id; /* Queue ID */
- u16 delta; /* Delta */
+ u16 q_id; /**< 队列ID */
+ u16 delta; /**< 差值 */
u16 hw_ci;
- u16 ci; /* Consumer index */
- u16 sw_pi; /* Software producer index */
- u16 wqebb_size; /* Work queue element size */
- u16 q_depth; /* Queue depth */
- u16 buf_len; /* Buffer length */
-
- void *slq_handle; /* Receive queue handle */
- u64 ci_wqe_page_addr; /* Consumer index work queue element page address */
- u64 ci_cla_tbl_addr; /* Consumer index cache line aligned table address */
-
- u8 coalesc_timer_cfg; /* Interrupt timeout, unit 5us */
- u8 pending_limt; /* Interrupt aggregation count, unit 8pkt */
- u16 msix_idx; /* MSI-X index */
- u32 msix_vector; /* MSI-X vector */
+ u16 ci; /**< 消费者索引 */
+ u16 sw_pi; /**< 软件生产者索引 */
+ u16 wqebb_size; /**< 工作队列元素的大小 */
+ u16 q_depth; /**< 队列深度 */
+ u16 buf_len; /**< 缓冲区长度 */
+
+ void *slq_handle; /**< 接收队列句柄 */
+ u64 ci_wqe_page_addr; /**< 消费者索引工作队列元素的页面地址 */
+ u64 ci_cla_tbl_addr; /**< 消费者索引缓存行对齐表地址 */
+
+ u8 coalesc_timer_cfg; /**< 中断超时时间,单位5us */
+ u8 pending_limt; /**< 中断聚合个数,单位8pkt */
+ u16 msix_idx; /**< MSI-X索引 */
+ u32 msix_vector; /**< MSI-X向量 */
};
-/* QOS related */
+/* QOS相关 */
-#define MT_DCB_OPCODE_WR BIT(0) /* 1 - write, 0 - read */
+#define MT_DCB_OPCODE_WR BIT(0) /* 1 - write, 0 - read */
/**
* @brief struct hinic5_mt_dcb_state
- * @details Structure for storing multi-task data center bridge (DCB) state information
+ * @details 用于存储多任务数据中心桥(DCB)状态信息的结构体
*/
struct hinic5_mt_dcb_state {
- struct mt_msg_head head; /* Message head */
+ struct mt_msg_head head; /**< 消息头 */
- u16 op_code; /* Operation code 0 - get dcb state, 1 - set dcb state */
- u8 state; /* State 0 - disable, 1 - enable dcb */
- u8 rsvd; /* Reserved field */
+ u16 op_code; /**< 操作码 0 - get dcb state, 1 - set dcb state */
+ u8 state; /**< 状态 0 - disable, 1 - enable dcb */
+ u8 rsvd; /**< 保留字段 */
};
-#define CMD_QOS_DEV_TRUST BIT(0)
-#define CMD_QOS_DEV_DFT_COS BIT(1)
-#define CMD_QOS_DEV_PCP2COS BIT(2)
-#define CMD_QOS_DEV_DSCP2COS BIT(3)
+#define CMD_QOS_DEV_TRUST BIT(0)
+#define CMD_QOS_DEV_DFT_COS BIT(1)
+#define CMD_QOS_DEV_PCP2COS BIT(2)
+#define CMD_QOS_DEV_DSCP2COS BIT(3)
/**
* @brief struct hinic5_mt_qos_dev_cfg
- * @details Structure for configuring QoS device
+ * @details 用于配置QoS设备的结构体
*/
struct hinic5_mt_qos_dev_cfg {
- struct mt_msg_head head; /* Message head */
+ struct mt_msg_head head; /**< 消息头部 */
- u8 op_code; /* 0: get 1: set */
+ u8 op_code; /**< 0:get 1: set */
u8 rsvd0;
- u16 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos,
- * bit2 - pcp2cos, bit3 - dscp2cos
- */
+ u16 cfg_bitmap; /**< bit0 - trust, bit1 - dft_cos, bit2 - pcp2cos, bit3 - dscp2cos */
- u8 trust; /* 0 - pcp, 1 - dscp */
+ u8 trust; /**< 0 - pcp, 1 - dscp */
u8 dft_cos;
u16 rsvd1;
- u8 pcp2cos[8]; /* Must configure all 8 together */
- u8 dscp2cos[64]; /* When configuring dscp2cos, if cos value is set to 0xFF,
- * the driver will ignore this dscp priority configuration,
- * allowing multiple dscp to cos mappings to be configured at once
- */
+ u8 pcp2cos[8]; /**< 必须8个一起配置 */
+ u8 dscp2cos[64]; /**< 配置dscp2cos时,若cos值设置为0xFF,驱动则忽略此dscp优先级的配置,允许一次性配置多个dscp跟cos的映射关系 */
u32 rsvd2[4];
};
/**
* @brief struct hinic5_mt_qos_cos_cfg
- * @details Structure for configuring HINIC5 multi-queue QoS class settings
+ * @details 用于配置HINIC5多队列服务质量(QoS)类别设置的结构体
*/
struct hinic5_mt_qos_cos_cfg {
- struct mt_msg_head head; /* Message head, contains message type and length information */
+ struct mt_msg_head head; /**< 消息头部,包含了消息的类型和长度等信息 */
- u8 port_id; /* Port ID, used to identify the port to which the message belongs */
- u8 func_cos_bitmap; /* Function class bitmap, used to identify enabled status of each function class */
- u8 port_cos_bitmap; /* Port class bitmap, used to identify enabled status of each port class */
- u8 func_max_cos_num; /* Maximum number of function classes, used to limit the number of function classes */
+ u8 port_id; /**< 端口ID,用于标识消息所属的端口 */
+ u8 func_cos_bitmap; /**< 功能类别位图,用于标识各个功能类别的使能状态 */
+ u8 port_cos_bitmap; /**< 端口类别位图,用于标识各个端口类别的使能状态 */
+ u8 func_max_cos_num; /**< 功能类别的最大数量,用于限制功能类别的数量 */
u32 rsvd2[4];
};
enum nic_driver_cmd_type {
- NIC_TOOL_CMD_START = 0x120, /* New platform command codes start from 0x120,
- * old command codes are uniformly defined in @driver_cmd_type
- */
-
- /* MACsec tool command set */
- MACSEC_TOOL_OP_LIST = 0x120, /* Get all macsec configuration information from driver memory */
- MACSEC_TOOL_OP_DUMP, /* Get all macsec configuration information from chip */
- MACSEC_TOOL_OP_MIB, /* Get SC MIB information or PORT MIB information from chip */
- MACSEC_TOOL_OP_ADD, /* Add SC or SA configuration */
- MACSEC_TOOL_OP_DEL, /* Delete SC or SA configuration */
- MACSEC_TOOL_OP_SET, /* Modify SC configuration */
- MACSEC_TOOL_OP_FLUSH, /* Clear macsec configuration managed by a device */
+ NIC_TOOL_CMD_START =
+ 0x120, /**< 平台新增命令字从0x120开始,旧命令字统一定义在@driver_cmd_type */
+
+ /* MACsec 工具命令集 */
+ MACSEC_TOOL_OP_LIST = 0x120, /**< 获取驱动内存中所有 macsec 配置信息 */
+ MACSEC_TOOL_OP_DUMP, /**< 获取芯片侧所有 macsec 配置信息 */
+ MACSEC_TOOL_OP_MIB, /**< 获取芯片侧 SC MIB 信息或者 PORT MIB 信息 */
+ MACSEC_TOOL_OP_ADD, /**< 新增 SC 或 SA 配置 */
+ MACSEC_TOOL_OP_DEL, /**< 删除 SC 或 SA 配置 */
+ MACSEC_TOOL_OP_SET, /**< 修改 SC 配置 */
+ MACSEC_TOOL_OP_FLUSH, /**< 清除某个设备管理的 macsec 配置 */
MACSEC_TOOL_OP_MAX = 0x12F,
NIC_CMD_EXTEND_RSV_START = 0x200,
- /* NIC tool reserved command codes, products use command codes in this range */
+ /* NIC工具保留命令字,产品使用该范围内的命令字 */
NIC_CMD_EXTEND_RSV_END = 0x2FF,
};
-#endif /* NIC_PUB_CMD_H */
+#endif /* NIC_PUB_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/sdk_pub_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/sdk_pub_cmd.h
index 0348c8de0..c09a7264f 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/sdk_pub_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/drv_tool_msg/sdk_pub_cmd.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : sdk_pub_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef SDK_PUB_CMD_H
#define SDK_PUB_CMD_H
@@ -16,12 +6,12 @@
/**
* @brief struct wqe_info
- * @details Structure for storing work queue related information
+ * @details 用于存储工作队列的相关信息
*/
struct cmdq_wqe_info {
- int q_id; /* Queue ID */
+ int q_id; /**< 队列ID */
void *rsvd;
- unsigned int wqebb_id; /* Work queue element ID */
+ unsigned int wqebb_id; /**< 工作队列元素ID */
};
#define CMDQ_WQE_DW_NUMBER (16)
@@ -32,18 +22,17 @@ struct sdk_cmdq_wqe_desc {
};
enum sdk_cmd_type {
- SDK_CMD_SET_FREQ_REDUCE_RATIO = SERVICE_DRV_BASE_CMD, /* Set chip time
- * frequency reduction ratio
- */
- SDK_CMD_SET_TIME_DIFF_ENABLE, /* Enable chip time difference statistics */
- SDK_CMD_GET_TIME_DIFF, /* Get chip time difference statistics value */
- SDK_CMD_GET_CMDQ_INFO, /* Get cmdq queue metadata information */
- SDK_CMD_GET_CMDQ_WQE_DESC, /* Get cmdq queue wqe information */
- SDK_CMD_CMDQ_CHANNEL_DETECT, /* cmdq channel connectivity test */
- SDK_CMD_ATTACK_TEST, /* SDK attack test */
+ SDK_CMD_SET_FREQ_REDUCE_RATIO =
+ SERVICE_DRV_BASE_CMD, /**< 设置芯片时间统计的降频比 */
+ SDK_CMD_SET_TIME_DIFF_ENABLE, /**< 设置芯片时间差统计的使能 */
+ SDK_CMD_GET_TIME_DIFF, /**< 获取芯片时间差统计的差值 */
+ SDK_CMD_GET_CMDQ_INFO, /**< 获取cmdq队列的metadata信息 */
+ SDK_CMD_GET_CMDQ_WQE_DESC, /**< 获取cmdq队列的wqe信息 */
+ SDK_CMD_CMDQ_CHANNEL_DETECT, /**< cmdq通道连通性测试 */
+ SDK_CMD_ATTACK_TEST, /**< SDK 攻击测试 */
SDK_CMD_EXTEND_RSV_START = 0x200,
- /* SDK tool reserved command codes, products use command codes in this range */
+ /* SDK工具保留命令字,产品使用该范围内的命令字 */
SDK_CMD_EXTEND_RSV_END = 0x2FF,
};
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/fw_typedef.h b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/fw_typedef.h
index 2b0355f1c..50a6c4bfd 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/fw_typedef.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/dpu_platform_library/include/fw_typedef.h
@@ -1,19 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : fw_typedef.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description :
- */
-
#ifndef FW_TYPEDEF_H
#define FW_TYPEDEF_H
#include "base_type.h"
-typedef enum up_fw_update_type_e {
+typedef enum {
UP_FW_UPDATE_UP_TEXT = 0x0,
UP_FW_UPDATE_UP_DATA = 0x1,
UP_FW_UPDATE_UP_DICT = 0x2,
@@ -62,7 +52,7 @@ typedef enum up_fw_update_type_e {
*/
#define FINAL_SUM(sum) (~(sum))
-typedef struct fw_section_info_s {
+typedef struct {
u32 invalid;
u32 fw_ver;
u32 fw_len;
@@ -70,11 +60,11 @@ typedef struct fw_section_info_s {
u32 fw_info_csum;
} fw_section_info_s;
-typedef struct fw_info_s {
- u32 invalid; // Non-zero means state machine does not exist, 0 means exists
- u32 cfg_index; // Configuration file index, 0~7
- u8 image_state[UP_MAX_FW_TYPE_CNT]; // Primary/standby state, 0 is primary, 1 is standby
- fw_section_info_s fw_attr[UP_MAX_FW_TYPE_CNT]; // Sub-firmware information
+typedef struct {
+ u32 invalid; // 非0,表示状态机不存在,0表示存在
+ u32 cfg_index; // 配置文件index,0~7
+ u8 image_state[UP_MAX_FW_TYPE_CNT]; // 主备状态,0表示主,1表示备
+ fw_section_info_s fw_attr[UP_MAX_FW_TYPE_CNT]; // 子固件信息
u32 csum;
} fw_info_s;
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.c b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.c
index 4303eedab..76b69e267 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.c
@@ -1,11 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_micro_log.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Save parsed information to log file
+ * Huawei HiNIC PCI Express Linux driver
+ * Copyright(c) 2017 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
*/
#include <linux/module.h>
@@ -28,11 +33,13 @@
#include "micro_log_procfs_cmd.h"
#include "micro_log_index.h"
-static bool micro_log_en;
+static bool micro_log_en = false;
module_param(micro_log_en, bool, 0444);
-MODULE_PARM_DESC(micro_log_en, "Enable micorlog write to host - default is false");
+MODULE_PARM_DESC(micro_log_en,
+ "Enable micorlog write to host - default is false");
-static bool micro_asm_mode; // 0: Default from flash; 1: Select /home/microcode.asm
+static bool micro_asm_mode =
+ 0; // 0: 默认从flash中取; 1:选择/home/microcode.asm
module_param(micro_asm_mode, bool, 0444);
MODULE_PARM_DESC(micro_asm_mode, "default micro asm from flash");
@@ -41,49 +48,53 @@ char asm_file_path[MAX_PATH_NAME] = "/home/microcode.asm";
#define NIC_MICRO_ASM_START_ADDR 0x10000000
-const char *micro_log_level[] = {"ERR", "WARN", "INFO", "DEBUG"};
+const char *micro_log_level[] = { "ERR", "WARN", "INFO", "DEBUG" };
-u8 nic_micro_log_dbg;
-u32 poll_log_cnt;
+u8 nic_micro_log_dbg = 0;
+u32 poll_log_cnt = 0;
int nic_micro_log_write_log_write_file(struct micro_log_info *log_info,
- const u8 *func_name, micro_log_item_s *log_item,
+ const u8 *func_name,
+ micro_log_item_s *log_item,
struct file *fp_log_file)
{
u32 err = 0;
- unsigned int level_index = 0;
+ unsigned level_index = 0;
struct timeval txc;
struct rtc_time time;
u64 localtime;
-/*lint -restore*/
+ /*lint -restore*/
level_index = log_item->ctrl_info.bs.type;
if (level_index > ULOG_DEBUG) {
microlog_warning("level_index(%d) err.", level_index);
level_index = ULOG_DEBUG;
}
- /* Get current UTC time */
+ /* 获取当前的UTC时间 */
do_gettimeofday(&(txc));
- /* Convert UTC time to local time */
- hinic5_utctime_to_localtime((u64)txc.tv_sec, &localtime);
+ /* 把UTC时间调整为本地时间 */
+ utctime_to_localtime((u64)txc.tv_sec, &localtime);
- /* Beijing timezone adjustment. */
+ /* 北京时区调整. */
localtime = TIMEZONE_ADJUSTMENT(localtime);
- /* Calculate year, month, day and other time values into tm */
+ /* 算出时间中的年月日等数值到tm中 */
rtc_time_to_tm((time64_t)localtime, &time);
- (void)snprintf(log_info->micro_log_tmpbuf, (unsigned long)MICRO_LOG_MAX_STRING_LEN * 8,
+ (void)snprintf(
+ log_info->micro_log_tmpbuf,
+ (unsigned long)MICRO_LOG_MAX_STRING_LEN * 8,
"[%02u:%02u:%02u.%06u](tile_core_tc:%d_%d_%d)[%d][%s](%s:%d) :",
- time.tm_hour, time.tm_min, time.tm_sec, (u32)txc.tv_usec % 1000000,
- log_item->ctrl_info.bs.tile_id, log_item->ctrl_info.bs.core_id,
+ time.tm_hour, time.tm_min, time.tm_sec,
+ (u32)txc.tv_usec % 1000000, log_item->ctrl_info.bs.tile_id,
+ log_item->ctrl_info.bs.core_id,
log_item->ctrl_info.bs.thread_id,
log_item->line_and_pi.bs.log_seq, micro_log_level[level_index],
func_name, log_item->line_and_pi.bs.line);
- err = hinic5_file_write(fp_log_file, log_info->micro_log_tmpbuf,
+ err = file_write(fp_log_file, log_info->micro_log_tmpbuf,
(u32)strlen(log_info->micro_log_tmpbuf)); //lint !e712
if (err != strlen(log_info->micro_log_tmpbuf)) {
microlog_err("Can't write the cal data to file");
@@ -92,20 +103,21 @@ int nic_micro_log_write_log_write_file(struct micro_log_info *log_info,
return 0;
}
-/*
- * Function : nic_micro_log_write_log_file
- * Description : Save parsed information to log file
- * Type :
- * Input : u8 *buf
- * u8 *func_name
- * micro_log_item_s *log_item
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2015/10/19
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : nic_micro_log_write_log_file
+ Description : 将解析后的信息保存在log文件中
+ Type :
+ Input : u8 *buf
+ u8 *func_name
+ micro_log_item_s *log_item
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2015/10/19
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
int nic_micro_log_write_log_file(struct micro_log_info *log_info, u8 *buf,
u8 *func_name, micro_log_item_s *log_item)
{
@@ -115,10 +127,11 @@ int nic_micro_log_write_log_file(struct micro_log_info *log_info, u8 *buf,
mm_segment_t old_fs;
#endif
- if (nic_micro_log_dbg == 1)
+ if (1 == nic_micro_log_dbg) {
microlog_info("nic_micro_log_dbg in");
+ }
- if (!buf || !func_name || !log_item) {
+ if ((NULL == buf) || (NULL == func_name) || (!log_item)) {
microlog_err("input buf, func_name or log_item is null");
return -EFAULT;
}
@@ -142,20 +155,25 @@ int nic_micro_log_write_log_file(struct micro_log_info *log_info, u8 *buf,
#endif
#endif
- if (nic_micro_log_write_log_write_file(log_info, func_name, log_item, fp) == -EFAULT)
+ if (nic_micro_log_write_log_write_file(log_info, func_name, log_item,
+ fp) == -EFAULT) {
return -EFAULT;
- memset(log_info->micro_log_tmpbuf, 0, sizeof(log_info->micro_log_tmpbuf));
+ }
+ (void)memset(log_info->micro_log_tmpbuf, 0,
+ sizeof(log_info->micro_log_tmpbuf));
-/*lint -save -e668*/
+ /*lint -save -e668*/
(void)snprintf(log_info->micro_log_tmpbuf,
(unsigned long)MICRO_LOG_MAX_STRING_LEN * 8, (char *)buf,
- log_item->data[0], log_item->data[1], log_item->data[2], log_item->data[3],
- log_item->data[4], log_item->data[5], log_item->data[6], log_item->data[7]);
-/*lint -restore*/
- err = hinic5_file_write(fp, log_info->micro_log_tmpbuf,
- (u32)strlen(log_info->micro_log_tmpbuf)); //lint !e712
+ log_item->data[0], log_item->data[1], log_item->data[2],
+ log_item->data[3], log_item->data[4], log_item->data[5],
+ log_item->data[6], log_item->data[7]);
+ /*lint -restore*/
+ err = file_write(fp, log_info->micro_log_tmpbuf,
+ (u32)strlen(log_info->micro_log_tmpbuf)); //lint !e712
if (err != strlen(log_info->micro_log_tmpbuf)) {
- microlog_err("Can't write the cal data to file ERR:[0x%x]", err);
+ microlog_err("Can't write the cal data to file ERR:[0x%x]",
+ err);
return -EFAULT;
}
@@ -170,22 +188,24 @@ int nic_micro_log_write_log_file(struct micro_log_info *log_info, u8 *buf,
return 0;
}
-/*
- * Function : nic_micro_log_get_string_from_data
- * Description : Get string start address
- * Type :
- * Input : struct micro_log_info *log_info
- * unsigned int data_addr
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2015/10/19
- * Modification : Created function
- */
-char *nic_micro_log_get_string_from_data(struct micro_log_info *log_info, unsigned int data_addr)
+/*****************************************************************************
+ Function : nic_micro_log_get_string_from_data
+ Description : 获得字符串起始地址
+ Type :
+ Input : struct micro_log_info *log_info
+ unsigned data_addr
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2015/10/19
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
+char *nic_micro_log_get_string_from_data(struct micro_log_info *log_info,
+ unsigned data_addr)
{
- unsigned int offset;
+ unsigned offset;
char *out_buf;
char *tmp_char;
@@ -198,38 +218,44 @@ char *nic_micro_log_get_string_from_data(struct micro_log_info *log_info, unsign
tmp_char = out_buf;
for (i = 0; i < strlen((char *)out_buf); i++, tmp_char++) {
- if (('%' == *tmp_char) && (('s' == *(tmp_char + 1)) || ('S' == *(tmp_char + 1))))
+ if (('%' == *tmp_char) &&
+ (('s' == *(tmp_char + 1)) || ('S' == *(tmp_char + 1)))) {
memcpy(out_buf, err_string, err_string_len);
+ }
}
- if (nic_micro_log_dbg == 1) {
- pr_info("%s(%d): micro addr : 0x%x\n", __func__, __LINE__, data_addr);
+ if (1 == nic_micro_log_dbg) {
+ pr_info("%s(%d): micro addr : 0x%x\n", __func__, __LINE__,
+ data_addr);
tmp_char = out_buf;
pr_info("%s(%d)get asm data as:\n", __func__, __LINE__);
for (i = 0; i < strlen(out_buf); i++) {
pr_info("0x%02x ", *(tmp_char + i));
- if (0 == ((i + 1) % 16))
+ if (0 == ((i + 1) % 16)) {
pr_info("\n");
+ }
}
}
return out_buf;
}
-/*
- * Function : nic_micro_log_parse_microcode_log
- * Description : Parse microcode log
- * Type :
- * Input : struct micro_log_info *log_info
- * micro_log_item_s *log_item
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2015/10/19
- * Modification : Created function
- */
-int nic_micro_log_parse_microcode_log(struct micro_log_info *log_info, micro_log_item_s *log_item)
+/*****************************************************************************
+ Function : nic_micro_log_parse_microcode_log
+ Description : 解析微码日志
+ Type :
+ Input : struct micro_log_info *log_info
+ micro_log_item_s *log_item
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2015/10/19
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
+int nic_micro_log_parse_microcode_log(struct micro_log_info *log_info,
+ micro_log_item_s *log_item)
{
int err;
@@ -241,40 +267,46 @@ int nic_micro_log_parse_microcode_log(struct micro_log_info *log_info, micro_log
return -EFAULT;
}
- if (nic_micro_log_dbg == 1)
+ if (1 == nic_micro_log_dbg) {
microlog_info("nic_micro_log_dbg in!");
+ }
- /** String address must be greater than first line data address, and must be multiple of 4*/
- if (log_item->string_addr < NIC_MICRO_ASM_START_ADDR ||
- log_item->func_name_addr < NIC_MICRO_ASM_START_ADDR) {
+ /** 字符串地址必须大于第一行data地址, 并且是4的整数倍*/
+ if ((NIC_MICRO_ASM_START_ADDR > log_item->string_addr) ||
+ (NIC_MICRO_ASM_START_ADDR > log_item->func_name_addr)) {
microlog_err("string_addr[%x], func_name_addr[%x]",
log_item->string_addr, log_item->func_name_addr);
return -EFAULT;
}
if (!log_info->micro_log_data_addr) {
- microlog_err("asm file has no data, micro_log_data_addr is NULL");
+ microlog_err(
+ "asm file has no data, micro_log_data_addr is NULL");
return -EFAULT;
}
- log_str = nic_micro_log_get_string_from_data(log_info, log_item->string_addr);
- log_file = nic_micro_log_get_string_from_data(log_info, log_item->func_name_addr);
+ log_str = nic_micro_log_get_string_from_data(log_info,
+ log_item->string_addr);
+ log_file = nic_micro_log_get_string_from_data(log_info,
+ log_item->func_name_addr);
- err = nic_micro_log_write_log_file(log_info, (u8 *)log_str, (u8 *)log_file, log_item);
- if (err != 0) {
+ err = nic_micro_log_write_log_file(log_info, (u8 *)log_str,
+ (u8 *)log_file, log_item);
+ if (0 != err) {
microlog_err("write log file fail.");
return err;
}
- if (nic_micro_log_dbg == 1)
+ if (1 == nic_micro_log_dbg) {
microlog_info("nic_micro_log_dbg out!");
+ }
return 0;
}
int check_param_for_get_asm(struct micro_log_info *log_info)
{
if (!log_info->fp_asm_file) {
- log_info->fp_asm_file = hinic5_file_open(asm_file_path);
+ log_info->fp_asm_file = file_open(asm_file_path);
if (IS_ERR(log_info->fp_asm_file)) {
microlog_err("Can't open /home/microcode.asm file.");
log_info->fp_asm_file = NULL;
@@ -284,33 +316,37 @@ int check_param_for_get_asm(struct micro_log_info *log_info)
return 0;
}
-/*
- * Function : process_per_line_data
- * Description : process_per_line_data for function `nic_micro_log_get_asm_file_data`
- * Type : struct micro_log_info *log_info, u64 datalen
- * Input : void
- * Output : None
- * Return : void
- * Restriction :None
- * History :
- * 1.Date : 2016/3/6
- * Modification : Created function
- */
-int process_per_line_data(struct micro_log_info *log_info, u32 all_line, u64 file_size)
+/*****************************************************************************
+ Function : process_per_line_data
+ Description : process_per_line_data for function `nic_micro_log_get_asm_file_data`
+ Type : struct micro_log_info *log_info, u64 datalen
+ Input : void
+ Output : None
+ Return : void
+ Restriction :None
+ History :
+ 1.Date : 2016/3/6
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
+int process_per_line_data(struct micro_log_info *log_info, u32 all_line,
+ u64 file_size)
{
int read_byte;
u32 i;
u32 file_ops = 0;
u64 datalen = 0;
- unsigned int addr;
- unsigned int data;
- char tmpbuf[MICRO_LOG_MAX_STRING_LEN] = {0};
+ unsigned addr;
+ unsigned data;
+ char tmpbuf[MICRO_LOG_MAX_STRING_LEN] = { 0 };
- /* Get 4 bytes of data from each line */
+ /* 获取每行中的4字节数据 */
for (i = 0; i < all_line; i++) {
- read_byte = hinic5_file_read(log_info->fp_asm_file, tmpbuf, LINE_CHAR_NUM, &file_ops);
+ read_byte = file_read(log_info->fp_asm_file, tmpbuf,
+ LINE_CHAR_NUM, &file_ops);
if (read_byte < 0) {
- microlog_err("Can't read the cal data:%d from file %d.", read_byte, i);
+ microlog_err("Can't read the cal data:%d from file %d.",
+ read_byte, i);
return -EFAULT;
}
@@ -321,13 +357,15 @@ int process_per_line_data(struct micro_log_info *log_info, u32 all_line, u64 fil
(void)sscanf(tmpbuf, "%x : %x", &addr, &data);
- if (nic_micro_log_dbg == 1)
+ if (1 == nic_micro_log_dbg) {
microlog_info("0x%x", data);
+ }
- (void)snprintf((char *)(log_info->micro_log_data_addr + datalen),
- file_size, "%c%c%c%c", (u8)(data >> 24),
- (u8)((data & 0x00ff0000) >> 16),
- (u8)((data & 0x0000ff00) >> 8), (u8)(data & 0xff));
+ (void)snprintf(
+ (char *)(log_info->micro_log_data_addr + datalen),
+ file_size, "%c%c%c%c", (u8)(data >> 24),
+ (u8)((data & 0x00ff0000) >> 16),
+ (u8)((data & 0x0000ff00) >> 8), (u8)(data & 0xff));
datalen += sizeof(data);
if (file_size < datalen) {
@@ -338,18 +376,19 @@ int process_per_line_data(struct micro_log_info *log_info, u32 all_line, u64 fil
return 0;
}
-/*
- * Function : nic_micro_log_get_asm_file_data
- * Description : get microcode.asm data
- * Type :
- * Input : void
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2016/3/6
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : nic_micro_log_get_asm_file_data
+ Description : get microcode.asm data
+ Type :
+ Input : void
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2016/3/6
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
int nic_micro_log_get_asm_file_data(struct micro_log_info *log_info)
{
u64 file_size;
@@ -358,8 +397,9 @@ int nic_micro_log_get_asm_file_data(struct micro_log_info *log_info)
mm_segment_t old_fs;
#endif
- if (check_param_for_get_asm(log_info) != 0)
+ if (check_param_for_get_asm(log_info) != 0) {
return -EFAULT;
+ }
/*lint -save -e501*/
#if defined(HAVE_MM_SEGMENT_T)
@@ -373,24 +413,25 @@ int nic_micro_log_get_asm_file_data(struct micro_log_info *log_info)
old_fs = force_uaccess_begin();
#endif
#endif
-/*lint -restore*/
+ /*lint -restore*/
- file_size = hinic5_get_file_size(log_info->fp_asm_file);
+ file_size = get_file_size(log_info->fp_asm_file);
- /* asm file each line is fixed at 20 bytes, file size is multiple of 20.
- * The last line of asm file is time, no need to save in cache
- */
+ /* asm文件一行固定20字节,文件大小为20倍数。asm文件最后一行为时间,无需保存在缓存中 */
all_line = (u32)(file_size - LINE_CHAR_NUM) / LINE_CHAR_NUM;
- /* asm file one line valid string is 4 bytes, allocated memory only needs 1/5 of asm file */
+ /* asm文件中一行有效字符串为4字节,申请的内存只需asm文件的1/5 */
file_size = (file_size / LINE_CHAR_NUM) * 4;
- log_info->micro_log_data_addr = kzalloc((file_size + 1), GFP_KERNEL);
- if (!log_info->micro_log_data_addr)
+ log_info->micro_log_data_addr =
+ (char *)kzalloc((file_size + 1), GFP_KERNEL);
+ if (!log_info->micro_log_data_addr) {
+ microlog_err("NIC MICRO LOG alloc reosurce fail!");
goto err_close_file;
+ }
/*lint -save -e647*/
- hinic5_set_file_position(log_info->fp_asm_file, 0 * LINE_CHAR_NUM);
+ set_file_position(log_info->fp_asm_file, 0 * LINE_CHAR_NUM);
/*lint -restore*/
if (process_per_line_data(log_info, all_line, file_size) != 0) {
microlog_err("process_per_line_data fail!");
@@ -405,7 +446,7 @@ int nic_micro_log_get_asm_file_data(struct micro_log_info *log_info)
#endif
#endif
- microlog_info("%s success\n", __func__);
+ microlog_info("nic_micro_log_get_asm_file_data success\n");
return 0;
err_free_mem:
@@ -423,40 +464,41 @@ int nic_micro_log_get_asm_file_data(struct micro_log_info *log_info)
force_uaccess_end(old_fs);
#endif
#endif
- hinic5_file_close(log_info->fp_asm_file);
+ file_close(log_info->fp_asm_file);
log_info->fp_asm_file = NULL;
microlog_err("close microcode.asm!");
return -EFAULT;
}
-/*
- * Function : nic_micro_log_create_log_file
- * Description : create microlog.log file
- * Type :
- * Input : void
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2016/3/6
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : nic_micro_log_create_log_file
+ Description : create microlog.log file
+ Type :
+ Input : void
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2016/3/6
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
int nic_micro_log_create_log_file(struct micro_log_info *log_info)
{
- char ulog_file_time[MAX_PATH_NAME] = {0};
+ char ulog_file_time[MAX_PATH_NAME] = { 0 };
struct timeval txc;
struct rtc_time time;
u64 max_time_len;
u64 path_len;
u64 localtime;
- /* Get current UTC time */
+ /* 获取当前的UTC时间 */
do_gettimeofday(&(txc));
- /* Convert UTC time to local time */
- hinic5_utctime_to_localtime(txc.tv_sec, &localtime);
+ /* 把UTC时间调整为本地时间 */
+ utctime_to_localtime(txc.tv_sec, &localtime);
- /* Calculate year, month, day and other time values into tm */
+ /* 算出时间中的年月日等数值到tm中 */
rtc_time_to_tm(localtime, &time);
path_len = strlen(log_file_path) - strlen(".log");
@@ -464,14 +506,13 @@ int nic_micro_log_create_log_file(struct micro_log_info *log_info)
max_time_len = MAX_PATH_NAME - path_len;
(void)snprintf(ulog_file_time + path_len, max_time_len,
- "_%s_%04d_%02d_%02d_%02d_%02d_%02d.log",
- log_info->hinic_micro_log_task.name,
- time.tm_year + 1900,
- time.tm_mon + 1, time.tm_mday,
- time.tm_hour, time.tm_min, time.tm_sec);
+ "_%s_%04d_%02d_%02d_%02d_%02d_%02d.log",
+ log_info->hinic_micro_log_task.name, time.tm_year + 1900,
+ time.tm_mon + 1, time.tm_mday, time.tm_hour, time.tm_min,
+ time.tm_sec);
if (!log_info->fp_log_file) {
- log_info->fp_log_file = hinic5_file_creat(ulog_file_time);
+ log_info->fp_log_file = file_creat(ulog_file_time);
if (IS_ERR(log_info->fp_log_file)) {
microlog_err("Can't create %s file", ulog_file_time);
@@ -483,23 +524,24 @@ int nic_micro_log_create_log_file(struct micro_log_info *log_info)
return 0;
}
-/*
- * Function : nic_micro_log_create_new_log_file
- * Description : create new microcode.log for overflow 1G
- * Type :
- * Input : void
- * Output : None
- * Return :
- * Restriction :
- * History :
- * 1.Date : 2016/3/6
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : nic_micro_log_create_new_log_file
+ Description : create new microcode.log for overflow 1G
+ Type :
+ Input : void
+ Output : None
+ Return :
+ Restriction :
+ History :
+ 1.Date : 2016/3/6
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
int nic_micro_log_create_new_log_file(struct micro_log_info *log_info)
{
u32 file_size;
- char ulog_file_time[MAX_PATH_NAME] = {0};
+ char ulog_file_time[MAX_PATH_NAME] = { 0 };
struct timeval txc;
struct rtc_time time;
u64 max_time_len;
@@ -510,20 +552,20 @@ int nic_micro_log_create_new_log_file(struct micro_log_info *log_info)
microlog_err("fp_log_file is NULL!");
return -EFAULT;
}
- file_size = hinic5_get_file_size(log_info->fp_log_file);
+ file_size = get_file_size(log_info->fp_log_file);
if ((MAX_SIZE_OF_LOG_FILE) <= file_size) {
if (log_info->fp_log_file) {
- hinic5_file_close(log_info->fp_log_file);
+ file_close(log_info->fp_log_file);
log_info->fp_log_file = NULL;
}
- /* Get current UTC time */
+ /* 获取当前的UTC时间 */
do_gettimeofday(&(txc));
- hinic5_utctime_to_localtime(txc.tv_sec, &localtime);
+ utctime_to_localtime(txc.tv_sec, &localtime);
- /* Calculate year, month, day and other time values into tm */
+ /* 算出时间中的年月日等数值到tm中 */
rtc_time_to_tm(localtime, &time);
path_len = strlen(log_file_path) - strlen(".log");
@@ -531,18 +573,18 @@ int nic_micro_log_create_new_log_file(struct micro_log_info *log_info)
max_time_len = MAX_PATH_NAME - path_len;
(void)snprintf(ulog_file_time + path_len, max_time_len,
- "_%s_%04d_%02d_%02d_%02d-%02d.log",
- log_info->hinic_micro_log_task.name,
- time.tm_year + 1900,
- time.tm_mon + 1, time.tm_mday,
- time.tm_hour, time.tm_min);
+ "_%s_%04d_%02d_%02d_%02d-%02d.log",
+ log_info->hinic_micro_log_task.name,
+ time.tm_year + 1900, time.tm_mon + 1,
+ time.tm_mday, time.tm_hour, time.tm_min);
- log_info->fp_log_file = hinic5_file_creat(ulog_file_time);
+ log_info->fp_log_file = file_creat(ulog_file_time);
if (IS_ERR(log_info->fp_log_file)) {
microlog_err("Can't create %s file!", ulog_file_time);
return -EFAULT;
}
}
+
return 0;
}
@@ -550,11 +592,10 @@ int hinic5_micro_log_init_cnt_set(void *hwdev)
{
cmdq_microlog_ctrl_info_set_s microlog_ctrl_info = { { 0 } };
size_t msg_len = sizeof(cmdq_microlog_ctrl_info_set_s);
-
microlog_ctrl_info.microlog_init_flag = 1;
-
return hinic5_set_microlog_cmdq(hwdev, (void *)µlog_ctrl_info,
- msg_len, COMM_CMD_MICROLOG_CTRL_INFO_SET);
+ msg_len,
+ COMM_CMD_MICROLOG_CTRL_INFO_SET);
}
int hinic5_comm_micro_log_init(struct hinic5_hwdev *hwdev)
@@ -585,18 +626,19 @@ int hinic5_comm_micro_log_init(struct hinic5_hwdev *hwdev)
return err;
}
-/*
- * Function : hinic5_micro_log_init
- * Description : micro code's log init
- * Type : void
- * Input : void
- * Output : None
- * Return : int
- * Restriction :
- * History : void
- * 1.Date : 2015/8/15
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : hinic5_micro_log_init
+ Description : micro code's log init
+ Type : void
+ Input : void
+ Output : None
+ Return : int
+ Restriction :
+ History : void
+ 1.Date : 2015/8/15
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
int hinic5_micro_log_init(void *hwdev)
{
int ret = 0;
@@ -616,48 +658,55 @@ int hinic5_micro_log_init(void *hwdev)
return 0;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
if (log_info) {
sdk_info(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "%s(%d):NIC MICRO LOG has already init!\n",
- __func__, __LINE__);
+ "%s(%d):NIC MICRO LOG has already init! \n",
+ __FUNCTION__, __LINE__);
return 0;
}
log_info = kzalloc(sizeof(*log_info), GFP_KERNEL);
- if (!log_info)
+ if (!log_info) {
+ sdk_info(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "%s(%d):alloc log info! \n", __FUNCTION__, __LINE__);
return -ENOMEM;
+ }
chip_node->log_info = log_info;
- /* Allocate 256*256*64B=4M space */
+ /* 申请256*256*64B=4M空间 */
for (i = 0; i < MICRO_LOG_MAX_QUEUE_NUM; i++) {
- v_addr = (u64)dma_zalloc_coherent(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH * MICRO_LOG_ITEM_LEN),
- &p_addr, GFP_KERNEL);
+ v_addr = (u64)dma_zalloc_coherent(
+ ((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN),
+ &p_addr, GFP_KERNEL);
if (!v_addr) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "%s(%d):NIC MICRO LOG alloc queue(%d) reosurce fail!\n",
- __func__, __LINE__, i);
+ "%s(%d):NIC MICRO LOG alloc queue(%d) reosurce fail! \n",
+ __FUNCTION__, __LINE__, i);
goto err_free_mem;
}
log_info->que_addr[MICRO_LOG_VIR_ADDR][i] = v_addr;
log_info->que_addr[MICRO_LOG_PHY_ADDR][i] = p_addr;
- /* Maintain software side queue information BD */
+ /* 维护软件侧队列信息BD */
ret = hinic5_microlog_gpa_set(hwdev, p_addr, i);
if (ret) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "%s(%d):NIC MICRO LOG write table (Lt index%d)fail(%d)!\n",
- __func__, __LINE__, i, ret);
-
- dma_free_coherent(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
- MICRO_LOG_ITEM_LEN),
- (void *)v_addr, p_addr);
+ "%s(%d):NIC MICRO LOG write table (Lt index%d)fail(%d)! \n",
+ __FUNCTION__, __LINE__, i, ret);
+
+ dma_free_coherent(
+ ((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN),
+ (void *)v_addr, p_addr);
v_addr = 0;
p_addr = 0;
log_info->que_addr[MICRO_LOG_VIR_ADDR][i] = v_addr;
@@ -666,7 +715,8 @@ int hinic5_micro_log_init(void *hwdev)
}
}
- memset((void *)&log_info->log_stati_info, 0, sizeof(struct nic_micro_log_statistics_info));
+ memset((void *)&log_info->log_stati_info, 0,
+ sizeof(struct nic_micro_log_statistics_info));
log_info->hwdev = hwdev;
@@ -675,7 +725,7 @@ int hinic5_micro_log_init(void *hwdev)
return 0;
err_free_mem:
- if (i == 0) {
+ if (0 == i) {
kfree(log_info);
chip_node->log_info = NULL;
return -ENOMEM;
@@ -686,7 +736,8 @@ int hinic5_micro_log_init(void *hwdev)
p_addr = log_info->que_addr[MICRO_LOG_PHY_ADDR][i];
dma_free_coherent(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH * MICRO_LOG_ITEM_LEN),
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN),
(void *)v_addr, p_addr);
v_addr = 0;
@@ -707,76 +758,91 @@ static void micro_log_clear_ci_entry_data(struct micro_log_info *log_info)
u32 lt_offset;
size_t len = sizeof(micro_log_item_s);
- lt_index = (log_info->all_ci / MICRO_LOG_MAX_QUEUE_DEPTH) % MICRO_LOG_MAX_QUEUE_NUM;
+ lt_index = (log_info->all_ci / MICRO_LOG_MAX_QUEUE_DEPTH) %
+ MICRO_LOG_MAX_QUEUE_NUM;
lt_offset = log_info->all_ci % MICRO_LOG_MAX_QUEUE_DEPTH;
- memset((micro_log_item_s *)(log_info->que_addr[MICRO_LOG_VIR_ADDR][lt_index] +
- (lt_offset * MICRO_LOG_ITEM_LEN)), 0, len);
+ (void)memset_s(
+ (micro_log_item_s
+ *)(log_info->que_addr[MICRO_LOG_VIR_ADDR][lt_index] +
+ (lt_offset * MICRO_LOG_ITEM_LEN)),
+ len, 0, len);
}
-static void micro_log_get_ci_entry_data(struct micro_log_info *log_info, micro_log_item_s *log_item)
+static void micro_log_get_ci_entry_data(struct micro_log_info *log_info,
+ micro_log_item_s *log_item)
{
u32 i;
u32 lt_index;
u32 lt_offset;
size_t len = sizeof(micro_log_item_s);
- lt_index = (log_info->all_ci / MICRO_LOG_MAX_QUEUE_DEPTH) % MICRO_LOG_MAX_QUEUE_NUM;
+ lt_index = (log_info->all_ci / MICRO_LOG_MAX_QUEUE_DEPTH) %
+ MICRO_LOG_MAX_QUEUE_NUM;
lt_offset = log_info->all_ci % MICRO_LOG_MAX_QUEUE_DEPTH;
- memcpy(log_item,
- (micro_log_item_s *)(log_info->que_addr[MICRO_LOG_VIR_ADDR][lt_index] +
- (lt_offset * MICRO_LOG_ITEM_LEN)), len);
-
- /* First do endian conversion for ctrl info */
+ (void)memcpy_s(
+ log_item, len,
+ (micro_log_item_s
+ *)(log_info->que_addr[MICRO_LOG_VIR_ADDR][lt_index] +
+ (lt_offset * MICRO_LOG_ITEM_LEN)),
+ len);
+
+ /* 先对ctrl信息进行大小端转换 */
log_item->ctrl_info.value = ntohl(log_item->ctrl_info.value);
- /* Do endian conversion */
+ /* 进行大小端转换 */
log_item->string_addr = ntohl(log_item->string_addr);
log_item->func_name_addr = ntohl(log_item->func_name_addr);
- for (i = 0; i < DFX_LOG_PRINT_MAX_PARA; i++)
+ for (i = 0; i < DFX_LOG_PRINT_MAX_PARA; i++) {
log_item->data[i] = ntohl(log_item->data[i]);
+ }
log_item->line_and_pi.value = ntohl(log_item->line_and_pi.value);
}
-int micro_log_file_size_check(struct hinic5_hwdev *hwdev, struct micro_log_info *log_info)
+int micro_log_file_size_check(struct hinic5_hwdev *hwdev,
+ struct micro_log_info *log_info)
{
int ret;
-
- ret = hinic5_microlog_ctrl_info_set(hwdev, log_info->nic_micro_log_enable,
+ ret = hinic5_microlog_ctrl_info_set(hwdev,
+ log_info->nic_micro_log_enable,
log_info->all_ci, INFO_LOG_PRINT);
if (ret) {
- sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl, "%s(%d):Write table (It index 0)fail(%d), all_ci:0x%x\n",
- __func__, __LINE__, ret, log_info->all_ci);
+ sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
+ "%s(%d):Write table (It index 0)fail(%d), all_ci:0x%x\n",
+ __FUNCTION__, __LINE__, ret, log_info->all_ci);
return ret;
}
ret = nic_micro_log_create_new_log_file(log_info);
- if (ret)
+ if (ret) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "%s(%d):nic_micro_log_create_new_log_file fail(%d)!\n",
- __func__, __LINE__, ret);
+ "%s(%d):nic_micro_log_create_new_log_file fail(%d)! \n",
+ __FUNCTION__, __LINE__, ret);
+ }
return ret;
}
-/*
- * Function : nic_micro_log_poll_recv
- * Description : poll receive micro log
- * Type : void
- * Input : void
- * Output : None
- * Return : void
- * Restriction :
- * History : None
- * 1.Date : 2015/8/15
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : nic_micro_log_poll_recv
+ Description : poll receive micro log
+ Type : void
+ Input : void
+ Output : None
+ Return : void
+ Restriction :
+ History : None
+ 1.Date : 2015/8/15
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
static void nic_micro_log_poll_recv(void *hwdev)
{
int ret;
struct card_node *chip_node;
struct micro_log_info *log_info;
micro_log_item_s log_item;
- static u32 count;
+ static u32 count = 0;
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
if (!log_info) {
microlog_err("input param hwdev is illegal!");
@@ -790,19 +856,20 @@ static void nic_micro_log_poll_recv(void *hwdev)
while (log_info->nic_micro_log_enable != 0) {
micro_log_get_ci_entry_data(log_info, &log_item);
- if (log_item.ctrl_info.bs.ctrl_flag == 0)
+ if (log_item.ctrl_info.bs.ctrl_flag == 0) {
break;
+ }
- // Parse log
+ // 解析日志
ret = nic_micro_log_parse_microcode_log(log_info, &log_item);
if (ret != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
- "%s(%d):parse_microcode_log fail(%d)\n",
- __func__, __LINE__, ret);
+ "%s(%d):parse_microcode_log fail(%d) \n",
+ __FUNCTION__, __LINE__, ret);
return;
}
- // Clear corresponding buffer
+ // 清零对应的buffer
micro_log_clear_ci_entry_data(log_info);
log_info->all_ci++;
@@ -814,30 +881,27 @@ static void nic_micro_log_poll_recv(void *hwdev)
if (micro_log_file_size_check(hwdev, log_info) != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"%s(%d):micro_log_file_size_check fail.\n",
- __func__, __LINE__);
+ __FUNCTION__, __LINE__);
} else {
- /* If processing is not successful, the reason poll_log_cnt cannot be cleared
- * is to try updating ci and other operations again outside the while loop
- */
+ // 如果处理不成功,poll_log_cnt不能清零的原因,是为了再while循环外再次尝试更新ci等操作
poll_log_cnt = 0;
}
count = 0;
/* change the same priority task for avoiding long time only do this task */
- msleep(100);
+ msleep(0);
}
- if (count && (!(count % 100)))
- msleep(100);
+ if (count && (!(count % 100))) {
+ msleep(0);
+ }
}
- /* The interface for updating ci changed from mbox to cmdq, there is a problem of log circular printing,
- * so added interception: when log accumulates 16K, ci will be updated once
- */
+ // 更新ci的接口由mbox改为cmdq,存在日志循环打印的问题,因此加上拦截:当日志累积16K,会更新一次ci
if (poll_log_cnt >= MAX_NUM_OF_ONE_TIME_ULOG) {
if (micro_log_file_size_check(hwdev, log_info) != 0) {
sdk_err(((struct hinic5_hwdev *)hwdev)->dev_hdl,
"%s(%d):micro_log_file_size_check fail.\n",
- __func__, __LINE__);
+ __FUNCTION__, __LINE__);
return;
}
poll_log_cnt = 0;
@@ -852,19 +916,20 @@ static void nic_micro_log_disable_func(void *hwdev)
struct card_node *chip_node;
struct micro_log_info *log_info;
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
- /* Delete a thread in polling SM table */
- hinic5_stop_thread(&log_info->hinic_micro_log_task);
+ /* 删除一个轮询SM表格中的线程 */
+ stop_thread(&log_info->hinic_micro_log_task);
hinic5_micro_log_reset(hwdev);
- /* Wait for loop task to stop recording logs, still need to wait 50ms delay */
+ /* 等待循环任务中不在记录日志,仍需等待50ms的延时 */
msleep(MICRO_LOG_POLLING_TIME * 50);
if (log_info->fp_asm_file) {
- hinic5_file_close(log_info->fp_asm_file);
+ file_close(log_info->fp_asm_file);
log_info->fp_asm_file = NULL;
microlog_info("close microcode.asm!");
}
@@ -873,7 +938,7 @@ static void nic_micro_log_disable_func(void *hwdev)
log_info->micro_log_data_addr = NULL;
}
if (log_info->fp_log_file) {
- hinic5_file_close(log_info->fp_log_file);
+ file_close(log_info->fp_log_file);
log_info->fp_log_file = NULL;
microlog_info("close microcode.log!");
}
@@ -886,12 +951,13 @@ static int hinic5_micro_log_ctr32_clear(void *hwdev, u8 cmd)
int err;
if (hinic5_is_chip_present((struct hinic5_hwdev *)hwdev) == false) {
- microlog_warning("chip is absent, microlog not send cmdq to npu!");
+ microlog_warning(
+ "chip is absent, microlog not send cmdq to npu!");
return 0;
}
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
microlog_err("failed to allocate cmd buf!");
return -ENOMEM;
}
@@ -901,8 +967,9 @@ static int hinic5_micro_log_ctr32_clear(void *hwdev, u8 cmd)
err = hinic5_cmdq_direct_resp(hwdev, HINIC5_MOD_COMM, cmd, cmd_buf,
&out_param, 0, HINIC5_CHANNEL_NIC);
if ((err) || (out_param)) {
- microlog_err("failed to clear print cnt, err: %d,out_param: 0x%llx!",
- err, out_param);
+ microlog_err(
+ "failed to clear print cnt, err: %d,out_param: 0x%llx!",
+ err, out_param);
err = -EFAULT;
}
@@ -914,18 +981,16 @@ static int hinic5_micro_log_ctr32_clear(void *hwdev, u8 cmd)
int micro_log_get_asm_file(void *hwdev, struct micro_log_info *log_info)
{
int ret = 0;
-
if (micro_asm_mode == 1) {
- /* Method 1: Default get dictionary file from /home/microcode.asm */
+ /* 方式1:默认从/home/microcode.asm中拿到字典文件 */
ret = nic_micro_log_get_asm_file_data(log_info);
}
- if (ret != 0 || (micro_asm_mode == 0 && !log_info->micro_log_data_addr)) {
- /* Method 2: Method 1 failed (maybe internal processing failed
- * or no microcode.asm file under home),
- * or user manually selects to get dictionary file from flash
- */
- ret = mirco_log_get_sim_data_from_flash((struct hinic5_hwdev *)hwdev, log_info);
+ if ((ret != 0) ||
+ (micro_asm_mode == 0 && log_info->micro_log_data_addr == NULL)) {
+ /* 方式2:方式1失败(可能内部处理失败或者home下无microcode.asm文件),或者用户手动选择从flash中拿到字典文件 */
+ ret = mirco_log_get_sim_data_from_flash(
+ (struct hinic5_hwdev *)hwdev, log_info);
}
return ret;
}
@@ -941,7 +1006,8 @@ int nic_micro_log_enable_func(void *hwdev)
return -EFAULT;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
hinic5_micro_log_reset(hwdev);
@@ -958,13 +1024,16 @@ int nic_micro_log_enable_func(void *hwdev)
if (!log_info->fp_log_file) {
ret = nic_micro_log_create_log_file(log_info);
if (ret) {
- microlog_err("nic_micro_log_create_new_log_file fail(%d)!", ret);
+ microlog_err(
+ "nic_micro_log_create_new_log_file fail(%d)!",
+ ret);
log_info->nic_micro_log_enable = 0;
return ret;
}
}
- ret = hinic5_microlog_ctrl_info_set(hwdev, log_info->nic_micro_log_enable,
+ ret = hinic5_microlog_ctrl_info_set(hwdev,
+ log_info->nic_micro_log_enable,
log_info->all_ci, INFO_LOG_PRINT);
if (ret) {
microlog_err("Write table (It index0)fail(%d)!", ret);
@@ -974,7 +1043,7 @@ int nic_micro_log_enable_func(void *hwdev)
log_info->hinic_micro_log_task.data = hwdev;
log_info->hinic_micro_log_task.thread_fn = nic_micro_log_poll_recv;
- ret = hinic5_creat_thread(&log_info->hinic_micro_log_task);
+ ret = creat_thread(&(log_info->hinic_micro_log_task));
if (ret) {
microlog_err("NIC MICRO LOG create thread fail(%d)!", ret);
return ret;
@@ -994,12 +1063,13 @@ int hinic5_micro_log_func_en(void *hwdev, u8 is_en)
return -EFAULT;
}
- if (is_en > 1) {
+ if (1 < is_en) {
microlog_err("is_en(%u) beyond 1!", is_en);
return -EFAULT;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
if (!log_info) {
@@ -1020,27 +1090,27 @@ int hinic5_micro_log_func_en(void *hwdev, u8 is_en)
microlog_err("nic_micro_log_enable_func fail!");
return -EFAULT;
}
- } else {
+ } else
nic_micro_log_disable_func(hwdev);
- }
microlog_info("micro log func is %s\n", is_en ? "enable" : "disable");
return 0;
}
-/*
- * Function : hinic5_micro_log_uninit
- * Description : nic micro code log uninit
- * Type : void
- * Input : eal_handle handle
- * Output : None
- * Return : void
- * Restriction :Null
- * History : None
- * 1.Date : 2015/9/2
- * Modification : Created function
- */
+/*****************************************************************************
+ Function : hinic5_micro_log_uninit
+ Description : nic micro code log uninit
+ Type : void
+ Input : eal_handle handle
+ Output : None
+ Return : void
+ Restriction :Null
+ History : None
+ 1.Date : 2015/9/2
+ Author : baizhijun 00284562
+ Modification : Created function
+*****************************************************************************/
void hinic5_micro_log_uninit(void *hwdev)
{
int ret;
@@ -1058,7 +1128,8 @@ void hinic5_micro_log_uninit(void *hwdev)
return;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
if (!log_info) {
microlog_warning("micro log is not init!");
@@ -1066,34 +1137,40 @@ void hinic5_micro_log_uninit(void *hwdev)
}
if (log_info->hwdev != hwdev) {
- microlog_err("micro log is not init in this function!");
+ microlog_warning("micro log is not init in this function!");
return;
}
ret = hinic5_micro_log_func_en(hwdev, 0);
- if (ret)
+ if (ret) {
microlog_warning("hinic5_micro_log_func_en fail (%d)!", ret);
+ }
- /* Free 256*64B*192 space */
+ /* 释放256*64B*192 空间 */
for (i = 0; i < MICRO_LOG_MAX_QUEUE_NUM; i++) {
v_addr = log_info->que_addr[MICRO_LOG_VIR_ADDR][i];
p_addr = log_info->que_addr[MICRO_LOG_PHY_ADDR][i];
- dma_free_coherent(((struct hinic5_hwdev *)log_info->hwdev)->dev_hdl,
- (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH * MICRO_LOG_ITEM_LEN),
- (void *)v_addr, (dma_addr_t)p_addr);
+ dma_free_coherent(
+ ((struct hinic5_hwdev *)log_info->hwdev)->dev_hdl,
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN),
+ (void *)v_addr, (dma_addr_t)p_addr);
log_info->que_addr[MICRO_LOG_VIR_ADDR][i] = 0;
log_info->que_addr[MICRO_LOG_PHY_ADDR][i] = 0;
- /* Update queue information to SM table, call chip interface */
+ /* 更新队列信息到SM表格中,调用chip接口 */
ret = hinic5_microlog_gpa_set(hwdev, 0 /* p_addr */, i);
- if (ret != 0)
- microlog_warning("Write table (It index%d)fail(%d)!", i, ret);
+ if (ret != 0) {
+ microlog_warning("Write table (It index%d)fail(%d)!", i,
+ ret);
+ }
}
kfree(log_info);
chip_node->log_info = NULL;
micro_log_procfs_exit();
+ return;
}
void hinic5_micro_log_reset(void *hwdev)
@@ -1104,15 +1181,17 @@ void hinic5_micro_log_reset(void *hwdev)
struct card_node *chip_node;
struct micro_log_info *log_info;
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
log_info = chip_node->log_info;
if (!log_info) {
microlog_err("x86 micro log is not init");
return;
}
- /* Maintain software side queue information BD */
- ret = hinic5_microlog_ctrl_info_set(hwdev, log_info->nic_micro_log_enable,
+ /* 维护软件侧队列信息BD */
+ ret = hinic5_microlog_ctrl_info_set(hwdev,
+ log_info->nic_micro_log_enable,
0 /* ci_index */, INFO_LOG_PRINT);
if (ret) {
microlog_err("Write table (It index 0)fail(%d)!", ret);
@@ -1121,13 +1200,20 @@ void hinic5_micro_log_reset(void *hwdev)
for (i = 0; i < MICRO_LOG_MAX_QUEUE_NUM; i++) {
v_addr = log_info->que_addr[MICRO_LOG_VIR_ADDR][i];
- memset((void *)v_addr, 0,
- (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH * MICRO_LOG_ITEM_LEN));
+ (void)memset_s((void *)v_addr,
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN),
+ 0,
+ (unsigned long)(MICRO_LOG_MAX_QUEUE_DEPTH *
+ MICRO_LOG_ITEM_LEN));
}
- ret = hinic5_micro_log_ctr32_clear(hwdev, COMM_CMD_MICROLOG_PRINT_CNT_CLEAR);
+ ret = hinic5_micro_log_ctr32_clear(hwdev,
+ COMM_CMD_MICROLOG_PRINT_CNT_CLEAR);
if (ret) {
microlog_err("Read ctr (It index 0)fail(%d)!", ret);
return;
}
+
+ return;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.h b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.h
index 97374fc70..ca571c213 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/hinic5_micro_log.h
@@ -1,11 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : hinic5_micro_log.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Micro log header file
+ * Huawei HiNIC PCI Express Linux driver
+ * Copyright(c) 2017 Huawei Technologies Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
*/
#ifndef __NIC_MICRO_LOG_H__
@@ -33,8 +38,8 @@
#define MICRO_LOG_D2_CI_MASK (0x00FF)
#define MICRO_LOG_ALL_MASK (0xFFFF)
-/* This must be fixed at 0, the tool auto-generated TBL_ID_DFX_LOG_POINTER is fixed at position 0 */
-#define TBL_ID_DFX_LOG_POINTER 0
+#define TBL_ID_DFX_LOG_POINTER \
+ 0 // 此处必须固定为0, 工具自动生成的TBL_ID_DFX_LOG_POINTER固定在0位置
/* Type */
#define ULOG_ERR 0
@@ -42,14 +47,24 @@
#define ULOG_INFO 2
#define ULOG_DEBUG 3
+#ifdef CONFIG_HINIC5_MICRO_LOG
int hinic5_comm_micro_log_init(struct hinic5_hwdev *hwdev);
+void hinic5_micro_log_uninit(void *hwdev);
+#else
+int hinic5_comm_micro_log_init(struct hinic5_hwdev *hwdev)
+{
+ return 0;
+}
+
+void hinic5_micro_log_uninit(void *hwdev)
+{
+}
+#endif
int hinic5_micro_log_func_en(void *hwdev, u8 is_en);
int hinic5_micro_log_init(void *hwdev);
-void hinic5_micro_log_uninit(void *hwdev);
-
void hinic5_micro_log_reset(void *hwdev);
#define BEIJING_TIMEZONE 8
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.c b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.c
index 247e4b185..c6f3a1f3c 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.c
@@ -1,11 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_comm.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Microcode host log common functions
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Version : Initial MIRCO_LOG Draft
+ * Created : 2025/02/25
+ * Last Modified : 2025/02/25
+ * Description : 微码主机日志公共函数
*/
#include "micro_log_comm.h"
#include "comm_defs.h"
@@ -14,29 +12,32 @@
#include "hinic5_common.h"
#include "hinic5_hwdev.h"
-int hinic5_set_microlog_cmdq(void *hwdev, void *microlog_msg, size_t msg_len, u8 cmd)
+int hinic5_set_microlog_cmdq(void *hwdev, void *microlog_msg, size_t msg_len,
+ u8 cmd)
{
int err;
u64 out_param = 0;
struct hinic5_cmd_buf *cmd_buf = NULL;
- if (hinic5_is_chip_present((struct hinic5_hwdev *)hwdev) == false)
+ if (hinic5_is_chip_present((struct hinic5_hwdev *)hwdev) == false) {
return 0;
+ }
cmd_buf = hinic5_alloc_cmd_buf(hwdev);
- if (!cmd_buf) {
+ if (cmd_buf == NULL) {
microlog_err("failed to allocate cmd buf!");
return -ENOMEM;
}
cmd_buf->size = msg_len;
- memcpy(cmd_buf->buf, microlog_msg, msg_len);
+ memcpy_s(cmd_buf->buf, cmd_buf->size, microlog_msg, msg_len);
hinic5_cpu_to_be32(cmd_buf->buf, cmd_buf->size);
err = hinic5_cmdq_direct_resp(hwdev, HINIC5_MOD_COMM, cmd, cmd_buf,
&out_param, 0, HINIC5_CHANNEL_NIC);
- if ((err) || (out_param)) {
- microlog_err("cmdq_cmd:%d, err:%d, out_param: 0x%llx!", cmd, err, out_param);
+ if (err != 0 || out_param != 0) {
+ microlog_warning("cmdq_cmd:%d, err:%d, out_param: 0x%llx!", cmd,
+ err, out_param);
err = -EFAULT;
}
@@ -47,7 +48,6 @@ int hinic5_set_microlog_cmdq(void *hwdev, void *microlog_msg, size_t msg_len, u8
int hinic5_microlog_gpa_set(void *hwdev, u64 p_addr, u8 lt_index)
{
cmdq_microlog_gpa_set_s microlog_gpa = { 0 };
-
microlog_gpa.wr_init_pc_h32 = (u32)((p_addr >> 32) & 0xffffffff);
microlog_gpa.wr_init_pc_l32 = (u32)(p_addr & 0xffffffff);
microlog_gpa.lt_index = lt_index;
@@ -61,11 +61,11 @@ int hinic5_microlog_ctrl_info_set(void *hwdev, u8 microlog_en, u32 ci_index,
{
cmdq_microlog_ctrl_info_set_s microlog_ctrl_info = { { 0 } };
size_t msg_len = sizeof(cmdq_microlog_ctrl_info_set_s);
-
microlog_ctrl_info.max_num = MICRO_LOG_MAX_QUEUE_DEPTH;
microlog_ctrl_info.microlog_en = microlog_en;
microlog_ctrl_info.state = state;
microlog_ctrl_info.ci_index = ci_index;
return hinic5_set_microlog_cmdq(hwdev, (void *)µlog_ctrl_info,
- msg_len, COMM_CMD_MICROLOG_CTRL_INFO_SET);
+ msg_len,
+ COMM_CMD_MICROLOG_CTRL_INFO_SET);
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.h b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.h
index 9e6759fdd..9b10892c7 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_comm.h
@@ -1,24 +1,17 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_comm.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Micro log common header
- */
-
#ifndef MICRO_LOG_COMM_H_
#define MICRO_LOG_COMM_H_
#include "ossl_knl.h"
-#define microlog_info(fmt, ...) \
- pr_info("[MICRO_LOG][INFO][%s:%d]:" fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
-#define microlog_warning(fmt, ...) \
- pr_warn("[MICRO_LOG][WARN][%s:%d]:" fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
-#define microlog_err(fmt, ...) \
- pr_err("[MICRO_LOG][ERROR][%s:%d]:" fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
+#define microlog_info(fmt, ...) \
+ pr_info("[MICRO_LOG][INFO][%s:%d]:" fmt "\n", __FUNCTION__, __LINE__, \
+ ##__VA_ARGS__)
+#define microlog_warning(fmt, ...) \
+ pr_warn("[MICRO_LOG][WARN][%s:%d]:" fmt "\n", __FUNCTION__, __LINE__, \
+ ##__VA_ARGS__)
+#define microlog_err(fmt, ...) \
+ pr_err("[MICRO_LOG][ERROR][%s:%d]:" fmt "\n", __FUNCTION__, __LINE__, \
+ ##__VA_ARGS__)
#define MICRO_LOG_VIR_ADDR 0
#define MICRO_LOG_PHY_ADDR 1
@@ -49,10 +42,10 @@ struct micro_log_info {
u32 all_ci;
};
-/* 1) state = 0, do not print logs
- * 2) state = 1, print err logs
- * 3) state = 2, warn logs: include err and warn logs
- * 4) state = 3, info logs: include err, warn, and info logs
+/* 1)state = 0,不打印日志;
+ * 2)state = 1,打印err日志
+ * 3) state = 2,warn日志:包括err、warn日志
+ * 4)state = 3,info日志:包括err、warn、info日志
*/
enum log_level_type {
ALL_LOG_DROP = 0,
@@ -66,9 +59,10 @@ struct log_level_message {
char level_info[LOG_LEVEL_INFO_MAX_SIZE];
};
-int hinic5_set_microlog_cmdq(void *hwdev, void *microlog_msg, size_t msg_len, u8 cmd);
+int hinic5_set_microlog_cmdq(void *hwdev, void *microlog_msg, size_t msg_len,
+ u8 cmd);
int hinic5_microlog_gpa_set(void *hwdev, u64 p_addr, u8 lt_index);
int hinic5_microlog_ctrl_info_set(void *hwdev, u8 microlog_en, u32 ci_index,
enum log_level_type state);
-#endif /* MICRO_LOG_COMM_H_ */
+#endif /* MICRO_LOG_COMM_H_ */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.c b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.c
index f4514dbd2..477318962 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.c
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_index.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Micro log index implementation
- */
-
#include "ossl_knl.h"
#include "micro_log_index.h"
@@ -23,27 +13,29 @@ static int micro_log_read_fw_cfg_info(void *hwdev, fw_info_s *cfg_info)
struct cmd_fw_info query_fw_output;
u16 out_size = sizeof(struct cmd_fw_info);
int ret;
- int err = 0;
+ int err;
- memset(&query_fw_input, 0, sizeof(struct cmd_query_fw));
- memset(&query_fw_output, 0, sizeof(struct cmd_fw_info));
+ (void)memset_s(&query_fw_input, sizeof(struct cmd_query_fw), 0,
+ sizeof(struct cmd_query_fw));
+ (void)memset_s(&query_fw_output, sizeof(struct cmd_fw_info), 0,
+ sizeof(struct cmd_fw_info));
- if (!hwdev || !cfg_info) {
+ if ((hwdev == NULL) || (cfg_info == NULL)) {
microlog_err("point is null\r\n");
return -EINVAL;
}
query_fw_input.offset = 0;
query_fw_input.len = MAX_LOG_BUF_SIZE;
- ret = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- &query_fw_input,
- sizeof(struct cmd_query_fw),
- &query_fw_output, &out_size, 0,
- HINIC5_CHANNEL_COMM);
- if (ret != 0 || out_size == 0 || query_fw_output.head.status != 0) {
- microlog_err("Failed to get length. ret:%d, status:0x%x, out_size:0x%x\n",
- ret, query_fw_output.head.status, out_size);
+ ret = hinic5_msg_to_mgmt_sync(
+ hwdev, HINIC5_MOD_COMM, COMM_MGMT_CMD_QUERY_FW_INFO,
+ &query_fw_input, sizeof(struct cmd_query_fw), &query_fw_output,
+ &out_size, 0, HINIC5_CHANNEL_COMM);
+ if ((ret != 0) || (out_size == 0) ||
+ (query_fw_output.head.status != 0)) {
+ microlog_err(
+ "Failed to get length. ret:%d, status:0x%x, out_size:0x%x\n",
+ ret, query_fw_output.head.status, out_size);
return ret;
}
@@ -52,36 +44,45 @@ static int micro_log_read_fw_cfg_info(void *hwdev, fw_info_s *cfg_info)
return -EFAULT;
}
- memcpy((u8 *)cfg_info, query_fw_output.data, query_fw_output.len);
+ err = memcpy_s((u8 *)cfg_info, sizeof(fw_info_s), query_fw_output.data,
+ query_fw_output.len);
+ if (err != 0) {
+ microlog_err("[micro]Failed to memcpy. ret:%d\n", err);
+ }
return err;
}
-static int micro_log_read_sim_data(void *hwdev, struct nic_log_info *simdata_info,
+static int micro_log_read_sim_data(void *hwdev,
+ struct nic_log_info *simdata_info,
u32 read_offset, u32 sim_data_len)
{
u32 ret;
u16 out_size = sizeof(struct nic_log_info);
struct nic_log_info simdata_buf_in;
- if (!hwdev || !simdata_info) {
+ if ((hwdev == NULL) || (simdata_info == NULL)) {
microlog_err("point is null\r\n");
return -EINVAL;
}
- memset(simdata_info, 0, sizeof(struct nic_log_info));
- memset(&simdata_buf_in, 0, sizeof(struct nic_log_info));
+ (void)memset_s(simdata_info, sizeof(struct nic_log_info), 0,
+ sizeof(struct nic_log_info));
+ (void)memset_s(&simdata_buf_in, sizeof(struct nic_log_info), 0,
+ sizeof(struct nic_log_info));
simdata_buf_in.offset = read_offset;
simdata_buf_in.log_or_index = NPU_COMM_GET_SIM_DATA;
- /* For compatibility with old and new hinic tools, use data[3:0] field instead of file_size, occupying 32bit */
+ /* 考虑到hinic新老工具兼容性,用data[3:0]域段替代file_size, 占用32bit */
*(u32 *)(void *)simdata_buf_in.data = sim_data_len;
ret = hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_COMM,
COMM_MGMT_CMD_GET_LOG, &simdata_buf_in,
sizeof(struct nic_log_info), simdata_info,
&out_size, 0, HINIC5_CHANNEL_COMM);
- if (ret != 0 || out_size == 0 || simdata_info->msg_head.status != 0) {
- microlog_err("Failed to read sim_data, ret:%d, status:0x%x, out_size:0x%x\n",
- ret, simdata_info->msg_head.status, out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (simdata_info->msg_head.status != 0)) {
+ microlog_err(
+ "Failed to read sim_data, ret:%d, status:0x%x, out_size:0x%x\n",
+ ret, simdata_info->msg_head.status, out_size);
}
return ret;
}
@@ -89,7 +90,6 @@ static int micro_log_read_sim_data(void *hwdev, struct nic_log_info *simdata_inf
static int micro_log_get_sim_data_length(void *hwdev, u32 *sim_data_len)
{
fw_info_s cfg_info;
-
if (micro_log_read_fw_cfg_info(hwdev, &cfg_info) != 0) {
microlog_err("Fail to read_fw_cfg_info\n");
return -EFAULT;
@@ -104,7 +104,8 @@ static int micro_log_get_sim_data_length(void *hwdev, u32 *sim_data_len)
return 0;
}
-int mirco_log_get_sim_data_from_flash(void *hwdev, struct micro_log_info *log_info)
+int mirco_log_get_sim_data_from_flash(void *hwdev,
+ struct micro_log_info *log_info)
{
u32 sim_data_len = 0;
u32 i;
@@ -112,21 +113,29 @@ int mirco_log_get_sim_data_from_flash(void *hwdev, struct micro_log_info *log_in
u32 k;
struct nic_log_info simdata_info;
- if (micro_log_get_sim_data_length(hwdev, &sim_data_len) != 0)
+ if (micro_log_get_sim_data_length(hwdev, &sim_data_len) != 0) {
return -EFAULT;
+ }
microlog_info("get sim_data_len(0x%x) ok.", sim_data_len);
- log_info->micro_log_data_addr = kzalloc((sim_data_len + 1), GFP_KERNEL);
- if (!log_info->micro_log_data_addr)
+ log_info->micro_log_data_addr =
+ (char *)kzalloc((sim_data_len + 1), GFP_KERNEL);
+ if (log_info->micro_log_data_addr == NULL) {
+ microlog_err("malloc micro_log_data_addr fail.");
return -EFAULT;
+ }
- /* mbox can read up to 1K data each time */
+ /* mbox每次最多读1K数据 */
for (i = 0, j = 0; i < sim_data_len; i += MAX_LOG_BUF_SIZE) {
- if (micro_log_read_sim_data(hwdev, &simdata_info, i, sim_data_len) != 0)
+ if (micro_log_read_sim_data(hwdev, &simdata_info, i,
+ sim_data_len) != 0) {
goto err_free_mem;
+ }
- for (k = 0; k < MAX_LOG_BUF_SIZE && j < sim_data_len; k++, j++)
+ for (k = 0; k < MAX_LOG_BUF_SIZE && j < sim_data_len;
+ k++, j++) {
log_info->micro_log_data_addr[j] = simdata_info.data[k];
+ }
}
microlog_info("get_sim_data_from_flash ok\n");
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.h b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.h
index aec48c662..ff2cb26b8 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_index.h
@@ -1,19 +1,10 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_index.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Micro log index header
- */
-
#ifndef MICRO_LOG_INDEX_H_
#define MICRO_LOG_INDEX_H_
#include "micro_log_comm.h"
#define FW_TILE_DATA_INDEX 0x5
-int mirco_log_get_sim_data_from_flash(void *hwdev, struct micro_log_info *log_info);
+int mirco_log_get_sim_data_from_flash(void *hwdev,
+ struct micro_log_info *log_info);
-#endif
+#endif
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.c b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.c
index e83cfd03e..356798865 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.c
@@ -1,11 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_procfs_cmd.c
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Used to dynamically change host log state: supports dynamic switching between info and err logs
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Version : Initial MIRCO_LOG Draft
+ * Created : 2025/02/25
+ * Last Modified : 2025/02/25
+ * Description : 用于动态更改主机日志状态: 支持info日志和err日志动态切换
*/
#include <linux/kernel.h>
#include <linux/version.h>
@@ -16,37 +14,40 @@
#include <linux/string.h>
#include <linux/stat.h>
+#include "securec.h"
+
#include "micro_log_procfs_cmd.h"
#include "micro_log_comm.h"
#include "hinic5_hwdev.h"
#include "hinic5_chip_info.h"
/****************************for proc fs****************************************/
-#define MICRO_LOG_PROCFS_NAME "micro_log"
-#define LOG_LEVEL_PROCFS_NAME "log_level"
-#define LOG_LEVEL_MAX_LEN 2 /* Normally only two characters are used:
- * one for log level, one for newline from echo
- */
+#define MICRO_LOG_PROCFS_NAME "micro_log"
+#define LOG_LEVEL_PROCFS_NAME "log_level"
+#define LOG_LEVEL_MAX_LEN \
+ 2 /* 正常情况下:只用到两个字符,分别存字符等级、echo自带的换行符 */
#define DEC_CODE 10
#define HINIC_DEV_NAME_LEN 32
static struct proc_dir_entry *proc_micro_log_dir;
static struct proc_dir_entry *proc_hinic_dev_dir;
static struct proc_dir_entry *proc_log_level_file;
-void *g_micro_log_dev;
+void *g_micro_log_dev = NULL;
-#define PROCFS_RD_BUFFER_SIZE (LOG_LEVEL_INFO_MAX_SIZE + 1)
-static char log_level_procfs_buffer_rd[PROCFS_RD_BUFFER_SIZE] = {0};
+#define PROCFS_RD_BUFFER_SIZE (LOG_LEVEL_INFO_MAX_SIZE + 1)
+static char log_level_procfs_buffer_rd[PROCFS_RD_BUFFER_SIZE] = { 0 };
-static char hinic_dev_name[HINIC_DEV_NAME_LEN + 1] = {0};
+static char hinic_dev_name[HINIC_DEV_NAME_LEN + 1] = { 0 };
static struct log_level_message log_level_msg[] = {
- {ALL_LOG_DROP, "ALL_LOG_DROP"}, {ERR_LOG_PRINT, "ERR_LOG"},
- {WARN_LOG_PRINT, "WARN_LOG"}, {INFO_LOG_PRINT, "INFO_LOG"}
+ { ALL_LOG_DROP, "ALL_LOG_DROP" },
+ { ERR_LOG_PRINT, "ERR_LOG" },
+ { WARN_LOG_PRINT, "WARN_LOG" },
+ { INFO_LOG_PRINT, "INFO_LOG" }
};
-/* 1) state = 0, do not print logs
- * 2) state = 1, print err logs
- * 3) state = 2, warn logs: include err and warn logs
- * 4) state = 3, info logs: include err, warn, and info logs
+/* 1)state = 0,不打印日志;
+ * 2)state = 1,打印err日志
+ * 3) state = 2,打印err + warn日志
+ * 4)state = 3,打印err + warn + info日志
*/
static int micro_log_state_set(void *hwdev, enum log_level_type state)
{
@@ -54,25 +55,26 @@ static int micro_log_state_set(void *hwdev, enum log_level_type state)
struct card_node *chip_node;
struct micro_log_info *log_info;
- if (!hwdev) {
+ if (hwdev == NULL) {
microlog_err("hwdev is NULL!");
return -ENOMEM;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
- if (!chip_node) {
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ if (chip_node == NULL) {
microlog_err("chip_node is NULL!");
return -ENOMEM;
}
log_info = chip_node->log_info;
- if (!log_info) {
+ if (log_info == NULL) {
microlog_err("log_info is NULL!");
return -ENOMEM;
}
- err = hinic5_microlog_ctrl_info_set(hwdev, log_info->nic_micro_log_enable,
- log_info->all_ci, state);
+ err = hinic5_microlog_ctrl_info_set(
+ hwdev, log_info->nic_micro_log_enable, log_info->all_ci, state);
if (err) {
microlog_err("cmdq return fail(0x%x), state: %u", err, state);
return err;
@@ -88,8 +90,9 @@ static ssize_t log_level_proc_write(struct file *file, const char __user *buff,
char log_level_buffer[LOG_LEVEL_MAX_LEN + 1] = { 0 };
u32 num;
- if (!buff || len == 0) {
- microlog_err("proc parameter incorrect: buff is null or size is zero");
+ if (buff == NULL || len == 0) {
+ microlog_err(
+ "proc parameter incorrect: buff is null or size is zero");
return -EINVAL;
}
@@ -101,37 +104,38 @@ static ssize_t log_level_proc_write(struct file *file, const char __user *buff,
log_level_buffer[wr_len] = '\0';
microlog_info("procfile write: %c, %s, wr_len:0x%x",
- log_level_buffer[0], log_level_buffer, (u32)wr_len);
- /* Convert string to decimal number */
+ log_level_buffer[0], log_level_buffer, (u32)wr_len);
+ /* 将字符串转为十进制数 */
num = simple_strtoul(log_level_buffer, NULL, DEC_CODE);
-
if (num > INFO_LOG_PRINT) {
microlog_err("get wrong log_level:%s", log_level_buffer);
return -EINVAL;
}
- if (micro_log_state_set(g_micro_log_dev, num) != 0)
+ if (micro_log_state_set(g_micro_log_dev, num) != 0) {
return -EINVAL;
+ }
(void)snprintf(log_level_procfs_buffer_rd, PROCFS_RD_BUFFER_SIZE,
"%s\n", log_level_msg[num].level_info);
return wr_len;
}
-static ssize_t log_level_proc_read(struct file *file, char __user *buff, size_t len, loff_t *off)
+static ssize_t log_level_proc_read(struct file *file, char __user *buff,
+ size_t len, loff_t *off)
{
unsigned long plen = strlen(log_level_procfs_buffer_rd);
ssize_t bytes_to_copy;
-
if (*off >= plen) {
- /* If all data has been read, return 0, otherwise keep looping */
+ /* 如果已经读取完所有数据,则返回0, 否则一直循环打印 */
return 0;
}
bytes_to_copy = (len < plen) ? len : plen;
microlog_info("copy_to_user bytes_to_copy:%d.", (u32)bytes_to_copy);
- if (copy_to_user(buff, log_level_procfs_buffer_rd, bytes_to_copy) != 0) {
+ if (copy_to_user(buff, log_level_procfs_buffer_rd, bytes_to_copy) !=
+ 0) {
microlog_err("copy to user failed!");
bytes_to_copy = 0;
}
@@ -158,19 +162,20 @@ static int check_params_valid(void *hwdev)
struct micro_log_info *log_info;
int cpy_len;
- if (!hwdev) {
+ if (hwdev == NULL) {
microlog_err("hwdev is NULL!");
return -ENOMEM;
}
- chip_node = (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
- if (!chip_node) {
+ chip_node =
+ (struct card_node *)(((struct hinic5_hwdev *)hwdev)->chip_node);
+ if (chip_node == NULL) {
microlog_err("chip_node is NULL!");
return -ENOMEM;
}
log_info = chip_node->log_info;
- if (!log_info || !log_info->hinic_micro_log_task.name) {
+ if (log_info == NULL || (log_info->hinic_micro_log_task.name == NULL)) {
microlog_err("log_info is NULL!");
return -ENOMEM;
}
@@ -180,7 +185,8 @@ static int check_params_valid(void *hwdev)
microlog_err("len beyond HINIC_DEV_NAME_LEN");
return -EINVAL;
}
- (void)strscpy(hinic_dev_name, log_info->hinic_micro_log_task.name, HINIC_DEV_NAME_LEN);
+ (void)strncpy(hinic_dev_name, log_info->hinic_micro_log_task.name,
+ HINIC_DEV_NAME_LEN);
hinic_dev_name[cpy_len + 1] = '\0';
return 0;
}
@@ -189,27 +195,31 @@ int micro_log_procfs_init(void *hwdev)
{
int ret = check_params_valid(hwdev);
- if (ret != 0)
+ if (ret != 0) {
return ret;
+ }
proc_micro_log_dir = proc_mkdir(MICRO_LOG_PROCFS_NAME, NULL);
- if (!proc_micro_log_dir) {
- microlog_err("Failed to create /proc/%s directory", MICRO_LOG_PROCFS_NAME);
+ if (proc_micro_log_dir == NULL) {
+ microlog_err("Failed to create /proc/%s directory",
+ MICRO_LOG_PROCFS_NAME);
return -ENOMEM;
}
proc_hinic_dev_dir = proc_mkdir(hinic_dev_name, proc_micro_log_dir);
- if (!proc_hinic_dev_dir) {
- microlog_err("Failed to create /proc/%s directory", MICRO_LOG_PROCFS_NAME);
+ if (proc_hinic_dev_dir == NULL) {
+ microlog_err("Failed to create /proc/%s directory",
+ MICRO_LOG_PROCFS_NAME);
return -ENOMEM;
}
proc_log_level_file = proc_create(LOG_LEVEL_PROCFS_NAME, 0644,
proc_hinic_dev_dir,
&log_level_proc_fops);
- if (!proc_log_level_file) {
+ if (proc_log_level_file == NULL) {
remove_proc_entry(MICRO_LOG_PROCFS_NAME, NULL);
- microlog_err("Failed to create /proc/micro_log/%s file", LOG_LEVEL_PROCFS_NAME);
+ microlog_err("Failed to create /proc/micro_log/%s file",
+ LOG_LEVEL_PROCFS_NAME);
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.h b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.h
index e5a565216..57b6f870b 100644
--- a/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic5/src/tools/micro_log/micro_log_procfs_cmd.h
@@ -1,13 +1,3 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2026-2026, Huawei Tech. Co., Ltd.
- * File Name : micro_log_procfs_cmd.h
- * Version : Initial Draft
- * Created : 2026/5/20
- * Last Modified : 2026/5/20
- * Description : Micro log procfs command header
- */
-
#ifndef MICRO_LOG_PROCFS_CMD_H_
#define MICRO_LOG_PROCFS_CMD_H_
--
2.37.7
2
1
From: Hongye Lin <linhongye(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://atomgit.com/openeuler/kernel/issues/8904
----------------------------------------------------------------------
backport minios patches from linux mainline
Mark Brown (9):
arm64/sysreg: Add definition for ID_AA64PFR2_EL1
arm64/sysreg: Add definition for ID_AA64ISAR3_EL1
arm64/sysreg: Add definition for ID_AA64FPFR0_EL1
arm64/sysreg: Add definition for FPMR
arm64/sysreg: Update SCTLR_EL1 for DDI0601 2023-09
arm64/sysreg: Update ID_AA64ISAR2_EL1 defintion for DDI0601 2023-09
arm64/sysreg: Update ID_AA64SMFR0_EL1 definition for DDI0601 2023-09
arm64/cpufeature: Hook new identification registers up to cpufeature
arm64/hwcap: Define hwcaps for 2023 DPISA features
Documentation/arch/arm64/elf_hwcaps.rst | 48 ++++++++
arch/arm64/include/asm/cpu.h | 3 +
arch/arm64/include/asm/hwcap.h | 15 +++
arch/arm64/include/uapi/asm/hwcap.h | 15 +++
arch/arm64/kernel/cpufeature.c | 63 ++++++++++
arch/arm64/kernel/cpuinfo.c | 3 +
arch/arm64/kernel/hwcap_str.h | 15 +++
arch/arm64/tools/sysreg | 149 ++++++++++++++++++++++--
8 files changed, 304 insertions(+), 7 deletions(-)
--
2.33.0
2
10
[PATCH OLK-5.10] Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
by Chen Jinghuang 03 Aug '26
by Chen Jinghuang 03 Aug '26
03 Aug '26
From: Siwei Zhang <oss(a)fourdim.xyz>
mainline inclusion
from mainline-v7.2-rc3
commit 6fef032af0092ed5ccb767239a9ac1bc38c08a40
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16859
CVE: CVE-2026-64557
Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm…
--------------------------------
l2cap_sock_new_connection_cb() returned l2cap_pi(sk)->chan after
release_sock(parent). Once the parent lock is dropped the newly
enqueued child socket sk is reachable via the accept queue, so another
task can accept and free it before the callback dereferences sk,
resulting in a use-after-free.
Rework the ->new_connection() op so the core, rather than the callback,
owns the child channel's lifetime. The op now receives a pre-allocated
new_chan and returns an errno instead of allocating and returning a
channel. l2cap_new_connection() allocates the child channel and links
it into the conn list via __l2cap_chan_add() before invoking the
callback, so the conn-list reference keeps the channel alive once
release_sock(parent) exposes the socket to other tasks.
Channel configuration that was duplicated in l2cap_sock_init() and the
various new_connection callbacks is consolidated into
l2cap_chan_set_defaults(), which now inherits from the parent channel
when one is supplied.
Fixes: 8ffb929098a5 ("Bluetooth: Remove parent socket usage from l2cap_core.c")
Cc: stable(a)kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Siwei Zhang <oss(a)fourdim.xyz>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Conflicts:
include/net/bluetooth/l2cap.h
net/bluetooth/6lowpan.c
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_core.c
[context conflicts, not merged 0a120d961663("Bluetooth: L2CAP:
Fix null-ptr-deref in l2cap_sock_new_connection_cb()")]
Signed-off-by: Chen Jinghuang <chenjinghuang2(a)huawei.com>
---
include/net/bluetooth/l2cap.h | 10 ++--
net/bluetooth/6lowpan.c | 18 +-----
net/bluetooth/l2cap_core.c | 78 ++++++++++++++++++++-----
net/bluetooth/l2cap_sock.c | 103 ++++++++++++++++------------------
net/bluetooth/smp.c | 27 ++-------
5 files changed, 126 insertions(+), 110 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 678394d95321..541c3c5c6079 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -650,7 +650,8 @@ struct l2cap_chan {
struct l2cap_ops {
char *name;
- struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan);
+ int (*new_connection)(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan);
int (*recv) (struct l2cap_chan * chan,
struct sk_buff *skb);
void (*teardown) (struct l2cap_chan *chan, int err);
@@ -909,9 +910,10 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq)
return (seq + 1) % (chan->tx_win_max + 1);
}
-static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan)
+static inline int l2cap_chan_no_new_connection(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
- return NULL;
+ return -EOPNOTSUPP;
}
static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -986,7 +988,7 @@ int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
-void l2cap_chan_set_defaults(struct l2cap_chan *chan);
+void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan);
int l2cap_ertm_init(struct l2cap_chan *chan);
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 7601ce9143c1..6ee874654794 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -650,7 +650,7 @@ static struct l2cap_chan *chan_create(void)
if (!chan)
return NULL;
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
chan->mode = L2CAP_MODE_LE_FLOWCTL;
@@ -762,21 +762,6 @@ static inline void chan_ready_cb(struct l2cap_chan *chan)
ifup(dev->netdev);
}
-static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan)
-{
- struct l2cap_chan *chan;
-
- chan = chan_create();
- if (!chan)
- return NULL;
-
- chan->ops = pchan->ops;
-
- BT_DBG("chan %p pchan %p", chan, pchan);
-
- return chan;
-}
-
static void delete_netdev(struct work_struct *work)
{
struct lowpan_btle_dev *entry = container_of(work,
@@ -895,7 +880,6 @@ static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
static const struct l2cap_ops bt_6lowpan_chan_ops = {
.name = "L2CAP 6LoWPAN channel",
- .new_connection = chan_new_conn_cb,
.recv = chan_recv_cb,
.close = chan_close_cb,
.state_change = chan_state_change_cb,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3b6e354551c1..b7b4e24f78e1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -537,7 +537,10 @@ void l2cap_chan_put(struct l2cap_chan *c)
}
EXPORT_SYMBOL_GPL(l2cap_chan_put);
-void l2cap_chan_set_defaults(struct l2cap_chan *chan)
+/* Initialise @chan with default values, inheriting from the parent channel
+ * @pchan when it is given.
+ */
+void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan)
{
chan->fcs = L2CAP_FCS_CRC16;
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
@@ -551,6 +554,31 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+ if (pchan) {
+ BT_DBG("chan %p pchan %p", chan, pchan);
+
+ chan->chan_type = pchan->chan_type;
+ chan->imtu = pchan->imtu;
+ chan->omtu = pchan->omtu;
+ chan->mode = pchan->mode;
+ chan->fcs = pchan->fcs;
+ chan->max_tx = pchan->max_tx;
+ chan->tx_win = pchan->tx_win;
+ chan->tx_win_max = pchan->tx_win_max;
+ chan->sec_level = pchan->sec_level;
+ chan->conf_state = pchan->conf_state;
+ chan->flags = pchan->flags;
+ chan->tx_credits = pchan->tx_credits;
+ chan->rx_credits = pchan->rx_credits;
+
+ if (chan->chan_type == L2CAP_CHAN_FIXED) {
+ chan->scid = pchan->scid;
+ chan->dcid = pchan->scid;
+ }
+
+ return;
+ }
+
chan->conf_state = 0;
set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
@@ -4126,6 +4154,38 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
return 0;
}
+/* Allocate and initialise a channel for an incoming connection.
+ *
+ * The channel inherits its configuration from @pchan and is linked into @conn
+ * before ->new_connection() runs, so the conn list reference keeps it alive if
+ * the callback exposes it (e.g. via the socket accept queue) before this
+ * returns. The l2cap_chan_create() reference is taken over by the subsystem on
+ * success and dropped here on failure.
+ */
+static struct l2cap_chan *l2cap_new_connection(struct l2cap_conn *conn,
+ struct l2cap_chan *pchan)
+{
+ struct l2cap_chan *chan;
+
+ chan = l2cap_chan_create();
+ if (!chan)
+ return NULL;
+
+ l2cap_chan_set_defaults(chan, pchan);
+ chan->ops = pchan->ops;
+
+ __l2cap_chan_add(conn, chan);
+
+ if (pchan->ops->new_connection &&
+ pchan->ops->new_connection(pchan, chan) < 0) {
+ l2cap_chan_del(chan, 0);
+ l2cap_chan_put(chan);
+ return NULL;
+ }
+
+ return chan;
+}
+
static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd,
u8 *data, u8 rsp_code, u8 amp_id)
@@ -4173,7 +4233,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
goto response;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan)
goto response;
@@ -4192,8 +4252,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
chan->dcid = scid;
chan->local_amp_id = amp_id;
- __l2cap_chan_add(conn, chan);
-
dcid = chan->scid;
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
@@ -5881,7 +5939,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
goto response_unlock;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
goto response_unlock;
@@ -5896,8 +5954,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
-
l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits));
dcid = chan->scid;
@@ -6099,7 +6155,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
continue;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
continue;
@@ -6114,8 +6170,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
-
l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
/* Init response */
@@ -8352,14 +8406,12 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
goto next;
l2cap_chan_lock(pchan);
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (chan) {
bacpy(&chan->src, &hcon->src);
bacpy(&chan->dst, &hcon->dst);
chan->src_type = bdaddr_src_type(hcon);
chan->dst_type = dst_type;
-
- __l2cap_chan_add(conn, chan);
}
l2cap_chan_unlock(pchan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 644ec4bf06f0..cc06be98f3c0 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -44,7 +44,8 @@ static struct bt_sock_list l2cap_sk_list = {
static const struct proto_ops l2cap_sock_ops;
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern);
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan);
static void l2cap_sock_cleanup_listen(struct sock *parent);
bool l2cap_is_socket(struct socket *sock)
@@ -1215,6 +1216,23 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
return err;
}
+/* Release the sock's ref on chan and clear the pointer so that the ref is
+ * dropped exactly once even if both l2cap_sock_kill() and
+ * l2cap_sock_destruct() run. Setting chan->data to NULL first stops any other
+ * task from dereferencing the now-dead sock pointer.
+ */
+static void l2cap_sock_put_chan(struct sock *sk)
+{
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+
+ if (!chan)
+ return;
+
+ chan->data = NULL;
+ l2cap_pi(sk)->chan = NULL;
+ l2cap_chan_put(chan);
+}
+
/* Kill socket (only if zapped and orphan)
* Must be called on unlocked socket, with l2cap channel lock.
*/
@@ -1225,13 +1243,9 @@ static void l2cap_sock_kill(struct sock *sk)
BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
- /* Sock is dead, so set chan data to NULL, avoid other task use invalid
- * sock pointer.
- */
- l2cap_pi(sk)->chan->data = NULL;
- /* Kill poor orphan */
+ l2cap_sock_put_chan(sk);
- l2cap_chan_put(l2cap_pi(sk)->chan);
+ /* Kill poor orphan */
sock_set_flag(sk, SOCK_DEAD);
sock_put(sk);
}
@@ -1473,7 +1487,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
}
}
-static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
+static int l2cap_sock_new_connection_cb(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
struct sock *sk, *parent = chan->data;
@@ -1483,25 +1498,28 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
release_sock(parent);
- return NULL;
+ return -ENOBUFS;
}
sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
- GFP_ATOMIC, 0);
+ GFP_ATOMIC, 0, new_chan);
if (!sk) {
release_sock(parent);
- return NULL;
- }
+ return -ENOMEM;
+ }
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
l2cap_sock_init(sk, parent);
+ /* The conn list reference taken by l2cap_new_connection() keeps new_chan
+ * alive once release_sock() lets another task free this socket.
+ */
bt_accept_enqueue(parent, sk, false);
release_sock(parent);
- return l2cap_pi(sk)->chan;
+ return 0;
}
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -1770,10 +1788,7 @@ static void l2cap_sock_destruct(struct sock *sk)
{
BT_DBG("sk %p", sk);
- if (l2cap_pi(sk)->chan) {
- l2cap_pi(sk)->chan->data = NULL;
- l2cap_chan_put(l2cap_pi(sk)->chan);
- }
+ l2cap_sock_put_chan(sk);
if (l2cap_pi(sk)->rx_busy_skb) {
kfree_skb(l2cap_pi(sk)->rx_busy_skb);
@@ -1804,30 +1819,12 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
BT_DBG("sk %p", sk);
if (parent) {
- struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
-
sk->sk_type = parent->sk_type;
bt_sk(sk)->flags = bt_sk(parent)->flags;
- chan->chan_type = pchan->chan_type;
- chan->imtu = pchan->imtu;
- chan->omtu = pchan->omtu;
- chan->conf_state = pchan->conf_state;
- chan->mode = pchan->mode;
- chan->fcs = pchan->fcs;
- chan->max_tx = pchan->max_tx;
- chan->tx_win = pchan->tx_win;
- chan->tx_win_max = pchan->tx_win_max;
- chan->sec_level = pchan->sec_level;
- chan->flags = pchan->flags;
- chan->tx_credits = pchan->tx_credits;
- chan->rx_credits = pchan->rx_credits;
-
- if (chan->chan_type == L2CAP_CHAN_FIXED) {
- chan->scid = pchan->scid;
- chan->dcid = pchan->scid;
- }
-
+ /* Channel configuration is inherited from the parent by
+ * l2cap_new_connection().
+ */
security_sk_clone(parent, sk);
} else {
switch (sk->sk_type) {
@@ -1853,7 +1850,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
chan->mode = L2CAP_MODE_BASIC;
}
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
}
/* Default config options */
@@ -1870,10 +1867,10 @@ static struct proto l2cap_proto = {
};
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern)
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan)
{
struct sock *sk;
- struct l2cap_chan *chan;
sk = bt_sock_alloc(net, sock, &l2cap_proto, proto, prio, kern);
if (!sk)
@@ -1882,18 +1879,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
- chan = l2cap_chan_create();
- if (!chan) {
- sk_free(sk);
- if (sock)
- sock->sk = NULL;
- return NULL;
- }
-
- l2cap_chan_hold(chan);
-
- l2cap_pi(sk)->chan = chan;
-
+ /* The sock takes ownership of the caller's reference on chan. */
return sk;
}
@@ -1901,6 +1887,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("sock %p", sock);
@@ -1915,10 +1902,16 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
sock->ops = &l2cap_sock_ops;
- sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
- if (!sk)
+ chan = l2cap_chan_create();
+ if (!chan)
return -ENOMEM;
+ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern, chan);
+ if (!sk) {
+ l2cap_chan_put(chan);
+ return -ENOMEM;
+ }
+
l2cap_sock_init(sk, NULL);
bt_sock_link(&l2cap_sk_list, sk);
return 0;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 081b08c3a6bc..e556550eb139 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -3236,34 +3236,19 @@ static const struct l2cap_ops smp_chan_ops = {
.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
};
-static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
+static inline int smp_new_conn_cb(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
- struct l2cap_chan *chan;
-
- BT_DBG("pchan %p", pchan);
-
- chan = l2cap_chan_create();
- if (!chan)
- return NULL;
-
- chan->chan_type = pchan->chan_type;
- chan->ops = &smp_chan_ops;
- chan->scid = pchan->scid;
- chan->dcid = chan->scid;
- chan->imtu = pchan->imtu;
- chan->omtu = pchan->omtu;
- chan->mode = pchan->mode;
+ new_chan->ops = &smp_chan_ops;
/* Other L2CAP channels may request SMP routines in order to
* change the security level. This means that the SMP channel
* lock must be considered in its own category to avoid lockdep
* warnings.
*/
- atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
-
- BT_DBG("created chan %p", chan);
+ atomic_set(&new_chan->nesting, L2CAP_NESTING_SMP);
- return chan;
+ return 0;
}
static const struct l2cap_ops smp_root_chan_ops = {
@@ -3334,7 +3319,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
l2cap_add_scid(chan, cid);
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
if (cid == L2CAP_CID_SMP) {
u8 bdaddr_type;
--
2.34.1
2
1
From: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
driver inclusion
category: feature
bugzilla: https://atomgit.com/openeuler/kernel/issues/9708
CVE: NA
---------------------------------
Add hiroce5 driver to support hi1825 chip.
Signed-off-by: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
Reviewed-by: Qiujun <roland.qiu(a)huawei.com<mailto:roland.qiu@huawei.com>>
Reviewed-by: chiqijun <chiqijun(a)huawei.com<mailto:chiqijun@huawei.com>>
---
.../hw/hiroce5/drv_intf/roce_drv_msg_intf.h | 14 +
.../hw/hiroce5/kernel/CMakeLists.txt | 62 +
drivers/infiniband/hw/hiroce5/kernel/Makefile | 543 ++++
.../hw/hiroce5/kernel/base/cq/roce_cq.h | 230 ++
.../hiroce5/kernel/base/cq/roce_cq_common.c | 299 ++
.../hw/hiroce5/kernel/base/cq/roce_cq_cqe.c | 763 ++++++
.../hiroce5/kernel/base/cq/roce_cq_create.c | 636 +++++
.../hw/hiroce5/kernel/base/cq/roce_cq_ctrl.c | 964 +++++++
.../hiroce5/kernel/base/cq/roce_cq_destroy.c | 304 +++
.../hiroce5/kernel/base/cq/roce_cq_format.h | 29 +
.../hiroce5/kernel/base/cq/roce_cq_intern.c | 98 +
.../hiroce5/kernel/base/cq/roce_cq_intern.h | 24 +
.../hw/hiroce5/kernel/base/event/roce_event.c | 437 +++
.../hw/hiroce5/kernel/base/event/roce_event.h | 25 +
.../base/extension/roce_event_extension.c | 56 +
.../base/extension/roce_main_extension.c | 170 ++
.../kernel/base/extension/roce_mr_extension.c | 40 +
.../kernel/base/extension/roce_qp_extension.c | 222 ++
.../base/extension/roce_srq_extension.c | 55 +
.../hw/hiroce5/kernel/base/mr/roce_mr.c | 1281 +++++++++
.../hw/hiroce5/kernel/base/mr/roce_mr.h | 113 +
.../hw/hiroce5/kernel/base/qp/roce_post.h | 171 ++
.../hw/hiroce5/kernel/base/qp/roce_qp.h | 317 +++
.../hiroce5/kernel/base/qp/roce_qp_create.c | 1506 +++++++++++
.../kernel/base/qp/roce_qp_ctx_format.h | 278 ++
.../hiroce5/kernel/base/qp/roce_qp_destroy.c | 342 +++
.../hw/hiroce5/kernel/base/qp/roce_qp_exp.h | 80 +
.../hw/hiroce5/kernel/base/qp/roce_qp_ext.c | 39 +
.../hw/hiroce5/kernel/base/qp/roce_qp_ext.h | 19 +
.../hw/hiroce5/kernel/base/qp/roce_qp_inner.h | 17 +
.../hiroce5/kernel/base/qp/roce_qp_modify.c | 2398 +++++++++++++++++
.../kernel/base/qp/roce_qp_post_recv.c | 238 ++
.../kernel/base/qp/roce_qp_post_send.c | 1205 +++++++++
.../hw/hiroce5/kernel/base/qp/roce_qp_query.c | 543 ++++
.../hw/hiroce5/kernel/base/rdma/rdma_comp.c | 22 +
.../hw/hiroce5/kernel/base/rdma/rdma_comp.h | 166 ++
.../hiroce5/kernel/base/rdma/rdma_comp_gid.c | 489 ++++
.../hiroce5/kernel/base/rdma/rdma_comp_init.c | 443 +++
.../kernel/base/rdma/rdma_comp_mw_mr.c | 120 +
.../kernel/base/rdma/rdma_comp_mw_mr.h | 12 +
.../hiroce5/kernel/base/rdma/rdma_comp_pd.c | 51 +
.../hiroce5/kernel/base/rdma/rdma_comp_res.c | 140 +
.../hw/hiroce5/kernel/base/rdma/roce_com.h | 78 +
.../hw/hiroce5/kernel/base/rdma/roce_mix.c | 1594 +++++++++++
.../hw/hiroce5/kernel/base/rdma/roce_mix.h | 269 ++
.../hw/hiroce5/kernel/base/rdma/roce_pd.c | 138 +
.../hw/hiroce5/kernel/base/rdma/roce_pd.h | 15 +
.../hw/hiroce5/kernel/base/srq/roce_srq.h | 191 ++
.../hiroce5/kernel/base/srq/roce_srq_comm.c | 116 +
.../hiroce5/kernel/base/srq/roce_srq_create.c | 712 +++++
.../hiroce5/kernel/base/srq/roce_srq_ctrl.c | 635 +++++
.../hiroce5/kernel/base/srq/roce_srq_format.h | 36 +
.../hw/hiroce5/kernel/base/uld/roce_uld_api.c | 729 +++++
.../hiroce5/kernel/base/uld/roce_uld_inner.h | 77 +
.../hw/hiroce5/kernel/base/xrc/roce_xrc.c | 169 ++
.../hw/hiroce5/kernel/base/xrc/roce_xrc.h | 17 +
.../hw/hiroce5/kernel/dev/card/roce_card.c | 162 ++
.../hw/hiroce5/kernel/dev/card/roce_card.h | 27 +
.../hw/hiroce5/kernel/dev/cmd/roce_cmd.c | 1270 +++++++++
.../hw/hiroce5/kernel/dev/cmd/roce_cmd.h | 82 +
.../hw/hiroce5/kernel/dev/db/roce_db.c | 86 +
.../hw/hiroce5/kernel/dev/db/roce_db.h | 30 +
.../hw/hiroce5/kernel/dev/init/roce_main.c | 1701 ++++++++++++
.../hiroce5/kernel/dev/netdev/roce_netdev.c | 1082 ++++++++
.../hiroce5/kernel/dev/netdev/roce_netdev.h | 70 +
.../hiroce5/kernel/dev/netlink/roce_netlink.c | 413 +++
.../hiroce5/kernel/dev/netlink/roce_netlink.h | 53 +
.../kernel/dev/netlink/roce_netlink_process.c | 832 ++++++
.../kernel/dev/netlink/roce_netlink_process.h | 133 +
.../hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.c | 74 +
.../hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.h | 21 +
.../kernel/dev/sysfs/roce_multipath_sysfs.c | 240 ++
.../kernel/dev/sysfs/roce_multipath_sysfs.h | 30 +
.../hw/hiroce5/kernel/dev/sysfs/roce_sysfs.c | 2157 +++++++++++++++
.../hw/hiroce5/kernel/dev/sysfs/roce_sysfs.h | 241 ++
.../hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.c | 472 ++++
.../hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.h | 73 +
.../extern/chip_ext/roce_main_chip_ext.c | 13 +
.../extern/chip_ext/roce_main_chip_ext.h | 17 +
.../kernel/extern/chip_ext/roce_mr_chip_ext.c | 348 +++
.../kernel/extern/chip_ext/roce_mr_chip_ext.h | 24 +
.../kernel/extern/chip_ext/roce_qp_chip_ext.c | 44 +
.../extern/chip_ext/roce_srq_chip_ext.c | 26 +
.../extern/hyper_roce/hyper_roce_common.h | 13 +
.../extern/hyper_roce/hyper_roce_netlink.c | 511 ++++
.../extern/hyper_roce/hyper_roce_netlink.h | 82 +
.../kernel/extern/hyper_roce/hyper_roce_qp.c | 29 +
.../kernel/extern/hyper_roce/hyper_roce_qp.h | 35 +
.../extern/hyper_roce/tool/hyper_roce_tool.c | 60 +
.../extern/hyper_roce/tool/hyper_roce_tool.h | 21 +
.../hyper_roce/tool/hyper_roce_tool_pktdrop.c | 142 +
.../hyper_roce/tool/hyper_roce_tool_pktdrop.h | 23 +
.../hw/hiroce5/kernel/include/roce.h | 665 +++++
.../hw/hiroce5/kernel/include/roce_compat.h | 87 +
.../kernel/include/roce_event_extension.h | 17 +
.../hw/hiroce5/kernel/include/roce_gid.h | 48 +
.../hw/hiroce5/kernel/include/roce_infra.h | 77 +
.../kernel/include/roce_kernel_compat_gen.h | 6 +
.../kernel/include/roce_main_extension.h | 77 +
.../kernel/include/roce_mr_extension.h | 14 +
.../hiroce5/kernel/include/roce_os_compat.h | 237 ++
.../kernel/include/roce_qp_extension.h | 61 +
.../hw/hiroce5/kernel/include/roce_restore.h | 88 +
.../kernel/include/roce_srq_extension.h | 38 +
.../hw/hiroce5/kernel/include/roce_user.h | 100 +
.../kernel/include/roce_verbs_compat.h | 24 +
.../hw/hiroce5/kernel/util/bond/roce_bond.h | 79 +
.../hiroce5/kernel/util/bond/roce_bond_cfm.c | 490 ++++
.../kernel/util/bond/roce_bond_device.c | 490 ++++
.../kernel/util/bond/roce_bond_internal.h | 97 +
.../hiroce5/kernel/util/bond/roce_bond_mac.c | 260 ++
.../kernel/util/bond/roce_bond_slave.c | 459 ++++
.../hiroce5/kernel/util/bond/roce_bond_tx.c | 94 +
.../hw/hiroce5/kernel/util/debug/roce_debug.h | 25 +
.../hw/hiroce5/kernel/util/dfx/roce_dfx.c | 375 +++
.../hw/hiroce5/kernel/util/dfx/roce_dfx.h | 378 +++
.../hiroce5/kernel/util/dfx/roce_dfx_attack.c | 828 ++++++
.../hiroce5/kernel/util/dfx/roce_dfx_debug.c | 35 +
.../hiroce5/kernel/util/dfx/roce_dfx_query.c | 851 ++++++
.../kernel/util/obj_ext/roce_obj_ext.c | 83 +
.../kernel/util/obj_ext/roce_obj_ext.h | 40 +
.../hiroce5/kernel/util/option/roce_option.c | 125 +
.../hiroce5/kernel/util/option/roce_option.h | 30 +
123 files changed, 36652 insertions(+)
create mode 100644 drivers/infiniband/hw/hiroce5/drv_intf/roce_drv_msg_intf.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/CMakeLists.txt
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/Makefile
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_common.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_cqe.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_create.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_ctrl.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_destroy.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_format.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_event_extension.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_main_extension.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_mr_extension.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_qp_extension.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_srq_extension.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_post.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_create.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ctx_format.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_destroy.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_exp.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_inner.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_modify.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_recv.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_send.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_query.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_gid.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_init.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_pd.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_res.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_com.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_comm.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_create.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_ctrl.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_format.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_api.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_inner.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/init/roce_main.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_qp_chip_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_srq_chip_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_common.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_compat.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_event_extension.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_gid.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_infra.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_kernel_compat_gen.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_main_extension.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_mr_extension.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_os_compat.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_qp_extension.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_restore.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_srq_extension.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_user.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/include/roce_verbs_compat.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_cfm.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_device.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_internal.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_mac.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_slave.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_tx.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/debug/roce_debug.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_attack.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_debug.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_query.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.h
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.c
create mode 100644 drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.h
diff --git a/drivers/infiniband/hw/hiroce5/drv_intf/roce_drv_msg_intf.h b/drivers/infiniband/hw/hiroce5/drv_intf/roce_drv_msg_intf.h
new file mode 100644
index 000000000..4875a1f1a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/drv_intf/roce_drv_msg_intf.h
@@ -0,0 +1,14 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+#ifndef ROCE_DRV_MSG_INTF_H
+#define ROCE_DRV_MSG_INTF_H
+
+#include "udk_usrnl.h"
+
+typedef struct {
+ usrnl_drv_msg_hdr_s common_hdr;
+ unsigned long long card_id;
+} roce5_drv_msg_hdr_s;
+
+#endif /* ROCE_DRV_MSG_INTF_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/CMakeLists.txt b/drivers/infiniband/hw/hiroce5/kernel/CMakeLists.txt
new file mode 100644
index 000000000..e67756615
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/CMakeLists.txt
@@ -0,0 +1,62 @@
+option(ENABLE_DEBUG "Enable debug in RoCE kernel driver" OFF)
+option(ENABLE_HYPER_ROCE "Enable hyper roce" OFF)
+
+if("${BUILD_VERSION}" MATCHES "_debug$")
+ set(ENABLE_DEBUG ON)
+endif()
+
+# ubx kernel hyper_roce使能宏
+if (DEFINED ENV{build_roce_mode})
+ if ($ENV{build_roce_mode} STREQUAL "hyperroce")
+ set(ENABLE_HYPER_ROCE ON)
+ endif()
+endif()
+
+if("${BUILD_VERSION}" MATCHES "ub_ascend")
+ set(UMMU_CORE_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ummu-core-v1)
+elseif("${PRODUCT}" STREQUAL "ascend910D" OR "${PRODUCT}" STREQUAL "ascend910Desl")
+ set(UBUS_DIR ${TOP_DIR}/drivers/ubus)
+ set(KDIR ${KERNEL_WORK_DIR}/../linux-4.19)
+ set(UMMU_CORE_BUILD_DIR ${UBUS_DIR}/kernel/ummu-core-v1)
+else()
+ set(UMMU_CORE_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ummu-core)
+endif()
+
+set(UBUS_UBC_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ubus)
+set(HISDK5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/sdk/knldk/lld)
+set(HINIC5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/service/nic/linux)
+set(HIROCE5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/service/roce/linux/kernel)
+
+if("${PRODUCT}" STREQUAL "ascend910D" OR "${PRODUCT}" STREQUAL "ascend910Desl")
+ set(hiroce5_depends hisdk hinic)
+ add_device_ko(LOCAL_MODULE hiroce5
+ KO_SRC_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}
+ MAKE_ARGS "IS_ASCEND=true"
+ TARGETE_DPENDS "${hiroce5_depends}")
+else()
+ add_custom_target(hiroce5_ko
+ COMMENT echo "build ${CMAKE_CURRENT_SOURCE_DIR} start."
+ COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/Makefile ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${MAKE} -j64
+ -C ${KDIR}
+ M=${CMAKE_CURRENT_BINARY_DIR}
+ src=${CMAKE_CURRENT_SOURCE_DIR}
+ UBUS_UBC_BUILD_DIR=${UBUS_UBC_BUILD_DIR}
+ HI1823_TRUNK_DIR=${TOP_DIR}/ChipSolution
+ HI1823_BUILD_DIR=${TOP_DIR}/ChipSolution/build
+ CONFIG_UBUS_DEVICE=y
+ HI1823_OS_TYPE=openEuler24.03
+ VERBOSE=1
+ HISDK5_SYMVERS=${HISDK5_BUILD_DIR}/Module.symvers
+ HINIC5_SYMVERS=${HINIC5_BUILD_DIR}/Module.symvers
+ CHIP_VERSION=hi1825v100
+ VERSION=ROCE_STANDARD
+ ENABLE_DEBUG=${ENABLE_DEBUG}
+ ENABLE_HYPER_ROCE=${ENABLE_HYPER_ROCE}
+ COMMAND cp -f *.ko ${CMAKE_INSTALL_PREFIX}/ko
+ DEPENDS kernel
+ )
+ add_dependencies(hiroce5_ko hisdk5_ko)
+ add_dependencies(hiroce5_ko hinic5_ko)
+ add_dependencies(hiroce5_ko ubus_ko)
+endif()
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/Makefile b/drivers/infiniband/hw/hiroce5/kernel/Makefile
new file mode 100644
index 000000000..0527b1b8a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/Makefile
@@ -0,0 +1,543 @@
+ifeq ($(KERNELRELEASE), )
+
+.PHONY: all kernel install_kernel install clean clean_kernel
+
+CWD=$(shell pwd)
+TOP_DIR=$(CWD)/../../../../../../..
+INSTALL_MOD_PATH=$(TOP_DIR)/ci/bin
+
+KERN_VERSION=$(shell uname -r)
+KSRC=/lib/modules/$(shell uname -r)/build
+ifeq ($(CONFIG_UB_UNIFIED_UBUS), y)
+ KERN_VERSION ?= 6.6.0-132.0.0.111.oe2403sp3.aarch64
+ KSRC=${UBUS_BUILD_KERNEL_DIR}
+endif
+
+ENABLE_DEBUG ?= OFF
+ENABLE_HYPER_ROCE ?= ON
+
+PANGEA_EULER_2107=4.19.90-vhulk2107.1.0.h699.eulerosv2r10.aarch64
+PANGEA_EULER_2108=4.19.90-vhulk2108.6.0.h832.eulerosv2r10.aarch64
+PANGEA_EULER_2202=4.19.90-vhulk2202.2.0.h1064.eulerosv2r10.aarch64
+EULER_V2R12_H1032=5.10.0-136.12.0.86.h1032.eulerosv2r12.x86_64
+EULER_V2R12_ARM_H1032=5.10.0-136.12.0.86.h1032.eulerosv2r12.aarch64
+EULER_V2R12_ARM_H1258=5.10.0-136.12.0.86.h1258.eulerosv2r12.aarch64
+EULER_V2R11_X86=5.10.0-60.18.0.50.h509.eulerosv2r11.x86_64
+EULER_V2R11_ARM=5.10.0-60.18.0.50.h665.eulerosv2r11.aarch64
+HCE_2_ARM_R865_35=5.10.0-60.18.0.50.r865_35.hce2.aarch64
+HCE_2_ARM_R1526_92=5.10.0-136.12.0.86.r1526_92.hce2.aarch64
+HCE_3_ARM_R1040_72=6.6.0-72.0.0.76.r1040_72.hce3.aarch64
+HCE_3_ARM_R1245_84=6.6.0-72.0.0.76.r1245_84.hce3.aarch64
+OPEN_EULER_153_2203_ARM=5.10.0-153.12.0.92.oe2203sp2.aarch64
+OPEN_EULER_136_2203_ARM=5.10.0-136.12.0.86.oe2203sp1.aarch64
+OPEN_EULER_2403_X86=6.6.0-28.0.0.34.oe2403.x86_64
+OPEN_EULER_2403_ARM=6.6.0-28.0.0.34.oe2403.aarch64
+OPEN_EULER_2403_SP1_ARM=6.6.0-72.0.0.76.oe2403sp1.aarch64
+OPEN_EULER_2403_SP2_ARM=6.6.0-98.0.0.103.oe2403sp2.aarch64
+OPEN_EULER_2403_SP3_ARM=6.6.0-132.0.0.111.oe2403sp3.aarch64
+EULER_V2R9_ARM=4.19.90-vhulk2009.2.0.h310.eulerosv2r9.aarch64
+
+OS_NAME := $(shell grep -E '^NAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
+OS_VERSION_ID := $(shell grep -E '^VERSION_ID=' /etc/os-release | cut -d= -f2 | tr -d '"')
+OS_VERSION := $(shell grep -E '^VERSION=' /etc/os-release | cut -d= -f2 | tr -d '"')
+
+KBUILD_EXTRA_SYMBOLS+=$(TOP_DIR)/ci/lib/SDK_Module.symvers
+KBUILD_EXTRA_SYMBOLS+=$(TOP_DIR)/ci/lib/NIC_Module.symvers
+
+# Set CFLAGS based on public macro definations
+CFLAGS += -DHW_CONVERT_ENDIAN
+CFLAGS += -DROCE_SERVICE
+CFLAGS += -DROCE_DRIVER_COMPILE
+CFLAGS += -D__ROCE_DFX__
+CFLAGS += -DROCE_CC_EN
+CFLAGS += -DRDMA_ROCE_MODULE
+CFLAGS += $(HI1823_FLAGS)
+CFLAGS += -Werror -Wall
+CFLAGS += -DROCE_DWQE_EN
+
+# Set CFLAGS, KBUILD_EXTRA_SYMBOLS and other THIRDPARTY* variables
+# from OS and kernel version information
+ifeq ($(OFED_VERSION), MLNX_OFED)
+ THIRDPARTY = /opt/buildtools/mlnx-ofa_kernel-5.8
+ KBUILD_EXTRA_SYMBOLS+=/opt/buildtools/mlnx-ofa_kernel-5.8/Module.symvers
+else ifeq ($(KERN_VERSION),$(filter $(KERN_VERSION), $(PANGEA_EULER_2107) $(PANGEA_EULER_2108) $(PANGEA_EULER_2202)))
+ KBUILD_EXTRA_SYMBOLS += $(TOP_DIR)/pangea/output/aarch64/euleros/ofed_knl/include/Module.symvers
+ THIRDPARTY_INC = $(TOP_DIR)/pangea/output/aarch64/euleros/ofed_knl/
+ CFLAGS += -DCONFIG_INFINIBAND_USER_MEM
+ CFLAGS += -DHAVE_GET_USER_PAGES_GUP_FLAGS
+ CFLAGS += -DCONFIG_MODULE_UPGRADE
+ CFLAGS += -DCONFIG_NVMF_AA
+else ifeq ($(KERN_VERSION),$(filter $(KERN_VERSION), $(EULER_V2R12_H1032) $(EULER_V2R12_ARM_H1032) $(EULER_V2R12_ARM_H1258) \
+ $(EULER_V2R11_ARM) $(OPEN_EULER_153_2203_ARM) $(HCE_2_ARM_R865_35) $(HCE_2_ARM_R1526_92) $(OPEN_EULER_136_2203_ARM) \
+ $(EULER_V2R9_ARM) $(OPEN_EULER_2403_X86) $(OPEN_EULER_2403_ARM) $(OPEN_EULER_2403_SP1_ARM) $(OPEN_EULER_2403_SP2_ARM) $(OPEN_EULER_2403_SP3_ARM) \
+ $(HCE_3_ARM_R1040_72) $(HCE_3_ARM_R1245_84)))
+ THIRDPARTY_INC = /usr/src/kernels/$(KERN_VERSION)/include
+else ifeq ($(OS_NAME),openEuler)
+ ifeq ($(OS_VERSION_ID),24.03)
+ ifneq (,$(findstring SP4,$(OS_VERSION)))
+ THIRDPARTY_INC = /usr/src/kernels/$(KERN_VERSION)/include
+ endif
+ endif
+else ifeq ($(KERN_VERSION), $(filter $(KERN_VERSION), $(EULER_V2R11_X86)))
+ THIRDPARTY =/usr/src/compat-rdma-4.17
+ KBUILD_EXTRA_SYMBOLS+=/usr/src/compat-rdma/Module.symvers
+ THIRDPARTY_INC = /usr/src/compat-rdma
+else
+ ifeq ($(CROSS_COMPILE),)
+ THIRDPARTY =/usr/src/compat-rdma-4.17
+ KBUILD_EXTRA_SYMBOLS+=/usr/src/compat-rdma/Module.symvers
+ THIRDPARTY_INC = /usr/src/compat-rdma
+# centos compat 417 need 6 para
+ CFLAGS += -DHAVE_NLA_PARSE_6_PARAMS
+ else
+ THIRDPARTY =/arm/cross_compile/install/sysroot/usr/src/compat-rdma-4.8
+ KBUILD_EXTRA_SYMBOLS+=/arm/cross_compile/install/sysroot/usr/src/compat-rdma/Module.symvers
+ THIRDPARTY_INC = /arm/cross_compile/install/sysroot/usr/src/compat-rdma
+ endif
+endif
+
+# Set CFLAGS from compiled driver version
+ifeq ($(VERSION),ROCE_STANDARD)
+ CFLAGS += -DROCE_STANDARD
+ CFLAGS += -DROCE_BONDING_EN
+ CFLAGS += -DSIGN_MTT_EN
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/bond
+ CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/include/cfm/bond
+ # CFLAGS += -DROCE_LATENCY_PROF_EN # 时延统计工具,需手动开启
+else ifeq ($(VERSION),ROCE_VBS)
+ CFLAGS += -DROCE_STANDARD
+ CFLAGS += -DROCE_BONDING_EN
+ CFLAGS += -DSIGN_MTT_EN
+ CFLAGS += -DROCE_VBS_EN
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/bond
+ CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/include/cfm/bond
+ CFLAGS += -I$(TOP_DIR)/test/at_test/host/service/vbs/extend/roce_kernel/
+else ifeq ($(VERSION),CHIP_TEST)
+ CFLAGS += -DROCE_CHIP_TEST
+ CFLAGS += -DSIGN_MTT_EN
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/extern/chip_ext
+else ifeq ($(VERSION),ROCE_COMPUTE)
+ CFLAGS += -DROCE_STANDARD
+ CFLAGS += -DROCE_COMPUTE
+else ifeq ($(VERSION),ROCE_VROCE)
+ CFLAGS += -DROCE_VROCE_EN
+ CFLAGS += -I$(TOP_DIR)/src/dpu_extended_library/host/service/roce/linux/kernel/extern/vroce/include
+endif
+
+ifeq ($(ENABLE_DEBUG),ON)
+ CFLAGS += -DENABLE_DEBUG
+endif
+
+ifeq ($(ENABLE_HYPER_ROCE),ON)
+ CFLAGS += -DENABLE_HYPER_ROCE
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/extern/hyper_roce
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/extern/hyper_roce/tool
+ CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/cqm
+endif
+
+# Set CFLAGS from default file directories
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/roce
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma/hi182x
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/include
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/drv_intf
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/cq
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/event
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/mr
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/qp
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/rdma
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/srq
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/xrc
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/uld
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/card
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/cmd
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/db
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/netdev
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/netlink
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/sdk_api
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/sysfs
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/include
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/dfx
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/option
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/debug
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/obj_ext
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_cfm_intf/hmm
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/cfm/hmm
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/urts
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/include/sdk/knldk
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/crm
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/include
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/host/cfm/rdma
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/ccp
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/public
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/nic
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/nic
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mag
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/include
+CFLAGS += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_tool_msg
+CFLAGS += -I$(TOP_DIR)/platform/huawei_secure_c/include
+CFLAGS += -I$(TOP_DIR)/platform/huawei_secure_c/src
+CFLAGS += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/roce
+CFLAGS += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
+
+##Safe compilation options
+ifneq ($(HI1823_OS_TYPE), BCLINUX)
+ CFLAGS += -fstack-protector-all -Wl,-z,noexecstack
+endif
+
+# Set CFLAGS from Driver version info,
+# Currently not in use.
+CFLAGS += -D HIROCE5_DRV_VER=\"$(HIROCE5_DRV_VERSION)\"
+
+export KERN_VERSION
+export KBUILD_EXTRA_SYMBOLS
+
+DEPMOD = /sbin/depmod
+INSTALL_MOD_DIR ?= $(shell test -f /etc/redhat-release && echo extra/ofa_kernel || echo updates)
+
+##Define compilation target
+all: kernel
+
+install: install_kernel
+install_kernel: install_modules
+
+##Test whether there are autoconf.h, kconfig.h files in the kernel directory, and if so, refer to the header file later
+autoconf_h=$(shell /bin/ls -1 $(KSRC)/include/*/autoconf.h 2> /dev/null | head -1)
+kconfig_h=$(shell /bin/ls -1 $(KSRC)/include/*/kconfig.h 2> /dev/null | head -1)
+
+ifneq ($(kconfig_h),)
+ KCONFIG_H = -include $(kconfig_h)
+endif
+
+##Test whether V variable is defined. If so, "make" will print some information during subsequent compilation
+V ?= 0
+
+##KBUILD_NOCMDDEP=1, when "make" again after "make", it will not recompile
+##LINUXINCLUDE, reconfigure kernel module compilation options
+##__OFED_BUILD__, use macro definition configured by OFED instead of that configured by kernel
+
+linux_include := -include $(autoconf_h) \
+ $(KCONFIG_H) \
+ $(BACKPORT_INCLUDES) \
+ -I$(THIRDPARTY)/include \
+ -I$(THIRDPARTY)/include/uapi \
+ $$(if $$(CONFIG_XEN),-I$$(srctree)/arch/x86/include/mach-xen) \
+ $$(if $$(CONFIG_XEN),-D__XEN_INTERFACE_VERSION__=$$(CONFIG_XEN_INTERFACE_VERSION)) \
+ -I$$(srctree)/arch/$$(SRCARCH)/include \
+ -I$$(srctree)/arch/$$(SRCARCH)/include/uapi \
+ -Iarch/$$(SRCARCH)/include/generated \
+ -Iarch/$$(SRCARCH)/include/generated/uapi \
+ -Iinclude \
+ $$(if $$(KBUILD_SRC),-Iinclude2 -I$$(srctree)/include) \
+ -I$$(srctree)/include/uapi \
+ -I$$(srctree)/arch/$$(SRCARCH)/include \
+ -Iinclude/generated/uapi \
+ -Iarch/$$(SRCARCH)/include/generated
+
+#########################
+# make kernel #
+#########################
+#NB: The LINUXINCLUDE value comes from main kernel Makefile
+# with local directories prepended. This eventually affects
+# CPPFLAGS in the kernel Makefile
+kernel: $(COMPAT_CONFIG) $(COMPAT_AUTOCONF)
+ @echo '============== INFO =============='
+ @echo 'Building kernel modules'
+ @echo 'Driver Version: $(VERSION)'
+ @echo 'Kernel Version: $(KERN_VERSION)'
+ @echo 'Modules Directory: $(INSTALL_MOD_PATH)/$(MODULES_DIR)'
+ @echo 'Kernel Sources: $(KSRC)'
+ @echo 'Thirdparty Source: $(THIRDPARTY)'
+ @echo 'Thirdparty Symbols: $(KBUILD_EXTRA_SYMBOLS)'
+ @echo 'TOP_DIR: $(TOP_DIR)'
+ @echo 'HI1823_TRUNK_DIR: $(HI1823_TRUNK_DIR)'
+ @echo '=================================='
+ $(MAKE) -C $(KSRC) M="$(CWD)" V=$(V) KBUILD_NOCMDDEP=1 $(WITH_MAKE_PARAMS) EXTRA_CFLAGS="$(CFLAGS)" \
+ LINUXINCLUDE='$(linux_include)' ENABLE_DEBUG=$(ENABLE_DEBUG) ENABLE_HYPER_ROCE=$(ENABLE_HYPER_ROCE) modules
+
+#########################
+# Install kernel #
+#########################
+install_modules:
+ @echo "Installing kernel modules"
+
+ $(MAKE) -C $(KSRC) M="$(CWD)" \
+ INSTALL_MOD_PATH=$(INSTALL_MOD_PATH) \
+ INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) \
+ $(WITH_MAKE_PARAMS) modules_install;
+ if [ ! -n "$(INSTALL_MOD_PATH)" ]; then $(DEPMOD) $(KERN_VERSION);fi;
+
+clean: clean_kernel
+
+clean_kernel:
+ @echo "clean kernel modules"
+ $(MAKE) -C $(KSRC) M="$(CWD)" $(WITH_MAKE_PARAMS) clean
+ @/bin/rm -f $(clean-files)
+
+clean-files := Module.symvers modules.order Module.markers compat/modules.order
+clean-files += $(COMPAT_CONFIG) $(COMPAT_AUTOCONF)
+
+help:
+ @echo
+ @echo "kernel: build kernel modules"
+ @echo "all: build kernel modules"
+ @echo
+ @echo "install_kernel: install kernel modules under $(INSTALL_MOD_PATH)/$(MODULES_DIR)"
+ @echo "install: run install_kernel"
+ @echo
+ @echo "clean: delete kernel modules binaries"
+ @echo "clean_kernel: delete kernel modules binaries"
+ @echo
+
+else
+
+obj-m += hiroce5.o
+
+ENABLE_DEBUG ?= OFF
+$(info kernel ENABLE_DEBUG: $(ENABLE_DEBUG))
+
+ifeq ($(CONFIG_UBUS_DEVICE), y)
+TOP_DIR=$(HI1823_TRUNK_DIR)
+
+GLOBAL_VERSION=$(shell cat $(HI1823_TRUNK_DIR)/src/GLOBAL_VERSION_NEW | grep driver | awk -F ':' '{print $$2}')
+ccflags-y += -DGLOBAL_VERSION_STR=\"$(GLOBAL_VERSION)\"
+ccflags-y += -DHW_CONVERT_ENDIAN
+ccflags-y += -DROCE_SERVICE
+ccflags-y += -DROCE_DRIVER_COMPILE
+ccflags-y += -D__ROCE_DFX__
+ccflags-y += -DROCE_CC_EN
+ccflags-y += -DRDMA_ROCE_MODULE
+ccflags-y += $(HI1823_FLAGS)
+# ccflags-y += -Werror -Wall
+ccflags-y += -Wall
+ccflags-y += -DROCE_DWQE_EN
+
+KBUILD_EXTRA_SYMBOLS += $(HISDK5_SYMVERS)
+KBUILD_EXTRA_SYMBOLS += $(HINIC5_SYMVERS)
+# ccflags-y = /usr/src/kernels/$(KERN_VERSION)/include
+
+ccflags-y += -DROCE_STANDARD
+ccflags-y += -DROCE_BONDING_EN
+ccflags-y += -DSIGN_MTT_EN
+
+ifeq ($(ENABLE_DEBUG),ON)
+ ccflags-y += -DENABLE_DEBUG
+endif
+ifeq ($(ENABLE_HYPER_ROCE),ON)
+ ccflags-y += -DENABLE_HYPER_ROCE
+ ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/extern/hyper_roce
+ ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/extern/hyper_roce/tool
+ ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/cqm
+endif
+
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/bond
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/bond
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/include/cfm/bond
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/roce
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/roce/hi182x
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma/hi182x
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/include
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/drv_intf
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/cq
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/event
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/mr
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/qp
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/rdma
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/srq
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/xrc
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/base/uld
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/card
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/cmd
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/db
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/netdev
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/netlink
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/sdk_api
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/dev/sysfs
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/include
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/dfx
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/option
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/debug
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/service/roce/linux/kernel/util/obj_ext
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_cfm_intf/hmm
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/cfm/hmm
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/urts
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/include/hwsdk
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/include/
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/cfm/rdma
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/crm
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/sdk/knldk/include
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/include/sdk/knldk
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/ccp
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/public
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/nic
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/nic
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/roce
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mag
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/include
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/include/drv_tool_msg
+ccflags-y += -I$(TOP_DIR)/platform/huawei_secure_c/include
+ccflags-y += -I$(TOP_DIR)/platform/huawei_secure_c/src
+ccflags-y += -I$(TOP_DIR)/src/dpu_platform_library/host/knldk/rdma
+ccflags-y += -I$(TOP_DIR)/..//opensource/openeuler/kernel/olk-6.6/include/linux/
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface
+ccflags-y += -I$(TOP_DIR)/../opensource/openeuler/kernel/olk-6.6/include
+ccflags-y += -nostdinc
+endif
+
+# List files of release here.
+ccflags-y += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
+hiroce5-y := ../../../../../../../platform/huawei_secure_c/src/securecutil.o \
+ ../../../../../../../platform/huawei_secure_c/src/secureinput_a.o \
+ ../../../../../../../platform/huawei_secure_c/src/secureprintoutput_a.o \
+ ../../../../../../../platform/huawei_secure_c/src/memset_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/memcpy_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/strncpy_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/strncat_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/sprintf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/vsprintf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/vsnprintf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/snprintf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/vsscanf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/sscanf_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/memmove_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/strcpy_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/strcat_s.o \
+ ../../../../../../../platform/huawei_secure_c/src/strtok_s.o \
+ ../../../../cfm/hmm/hmm_buddy.o \
+ ../../../../cfm/hmm/hmm_common.o \
+ ../../../../cfm/hmm/hmm_em.o \
+ ../../../../cfm/hmm/hmm_init.o \
+ ../../../../cfm/hmm/hmm_mpt.o \
+ ../../../../cfm/hmm/hmm_mr.o \
+ ../../../../cfm/hmm/hmm_mtt.o \
+ ../../../../cfm/hmm/hmm_umem.o \
+ ../../../../cfm/rdma/rdma_bitmap.o \
+ base/cq/roce_cq_common.o \
+ base/cq/roce_cq_cqe.o \
+ base/cq/roce_cq_create.o \
+ base/cq/roce_cq_ctrl.o \
+ base/cq/roce_cq_destroy.o \
+ base/cq/roce_cq_intern.o \
+ base/extension/roce_event_extension.o \
+ base/extension/roce_main_extension.o \
+ base/extension/roce_mr_extension.o \
+ base/extension/roce_qp_extension.o \
+ base/extension/roce_srq_extension.o \
+ base/mr/roce_mr.o \
+ base/qp/roce_qp_create.o \
+ base/qp/roce_qp_destroy.o \
+ base/qp/roce_qp_ext.o \
+ base/qp/roce_qp_modify.o \
+ base/qp/roce_qp_post_recv.o \
+ base/qp/roce_qp_post_send.o \
+ base/qp/roce_qp_query.o \
+ base/rdma/rdma_comp.o \
+ base/rdma/rdma_comp_res.o \
+ base/rdma/rdma_comp_gid.o \
+ base/rdma/rdma_comp_init.o \
+ base/rdma/rdma_comp_pd.o \
+ base/rdma/rdma_comp_mw_mr.o \
+ base/rdma/roce_pd.o \
+ base/rdma/roce_mix.o \
+ base/srq/roce_srq_comm.o \
+ base/srq/roce_srq_create.o \
+ base/srq/roce_srq_ctrl.o \
+ base/xrc/roce_xrc.o \
+ base/event/roce_event.o \
+ base/uld/roce_uld_api.o \
+ dev/card/roce_card.o \
+ dev/db/roce_db.o \
+ dev/cmd/roce_cmd.o \
+ dev/init/roce_main.o \
+ dev/netdev/roce_netdev.o \
+ dev/netlink/roce_netlink_process.o \
+ dev/netlink/roce_netlink.o \
+ dev/sdk_api/roce_cqm_cmd.o \
+ dev/sysfs/roce_sysfs.o \
+ dev/sysfs/roce_ucc_sysfs.o \
+ dev/sysfs/roce_multipath_sysfs.o \
+ util/dfx/roce_dfx.o \
+ util/dfx/roce_dfx_query.o \
+ util/option/roce_option.o \
+ util/obj_ext/roce_obj_ext.o
+
+ifeq ($(ENABLE_DEBUG),ON)
+ # List debug files here.
+ hiroce5-y += util/dfx/roce_dfx_debug.o
+ hiroce5-y += util/dfx/roce_dfx_attack.o
+endif
+
+ifeq ($(ENABLE_HYPER_ROCE),ON)
+ # List hyper roce files here.
+ hiroce5-y += extern/hyper_roce/hyper_roce_netlink.o
+ hiroce5-y += extern/hyper_roce/hyper_roce_qp.o
+ hiroce5-y += extern/hyper_roce/tool/hyper_roce_tool.o
+ hiroce5-y += extern/hyper_roce/tool/hyper_roce_tool_pktdrop.o
+endif
+
+# Add hiroce5 objects from compiled driver version
+# from dpu_extended_library directories
+ifeq ($(VERSION),ROCE_STANDARD)
+ hiroce5-y +=util/bond/roce_bond_mac.o
+ hiroce5-y +=util/bond/roce_bond_slave.o
+ hiroce5-y +=util/bond/roce_bond_cfm.o
+ hiroce5-y +=util/bond/roce_bond_device.o
+ hiroce5-y +=util/bond/roce_bond_tx.o
+else ifeq ($(VERSION),ROCE_COMPUTE)
+ # hiroce5-y +=util/bond/roce_bond_common.o
+else ifeq ($(VERSION),CHIP_TEST)
+# CHIP_TEST or ROCE_VBS, as VBS driver currently runs on chip test
+ hiroce5-y +=extern/chip_ext/roce_main_chip_ext.o
+ hiroce5-y +=extern/chip_ext/roce_mr_chip_ext.o
+ hiroce5-y +=extern/chip_ext/roce_qp_chip_ext.o
+ hiroce5-y +=extern/chip_ext/roce_srq_chip_ext.o
+else ifeq ($(VERSION),ROCE_VROCE)
+ hiroce5-y +=util/bond/roce_bond_mac.o
+ hiroce5-y +=util/bond/roce_bond_slave.o
+ hiroce5-y +=util/bond/roce_bond_cfm.o
+ hiroce5-y +=util/bond/roce_bond_device.o
+ hiroce5-y +=util/bond/roce_bond_tx.o
+ hiroce5-y +=../../../../../../../src/dpu_extended_library/host/roce/vroce/roce_cmd_ext.o
+else ifeq ($(VERSION),ROCE_VBS)
+ hiroce5-y +=util/bond/roce_bond_mac.o
+ hiroce5-y +=util/bond/roce_bond_slave.o
+ hiroce5-y +=util/bond/roce_bond_cfm.o
+ hiroce5-y +=util/bond/roce_bond_device.o
+ hiroce5-y +=util/bond/roce_bond_tx.o
+ hiroce5-y +=../../../../../../../test/at_test/host/service/vbs/extend/roce_kernel/roce_vbs_qp.o
+endif
+
+# Driver Extension
+# DPU_HIROCE5_DRV_EXTEND_MK, DPU_DRV_MK_DIR, DPU_DRV_HIROCE5_EXTEND_OBJS对外提供用户使用,修改需要评审
+ifneq ($(DPU_HIROCE5_DRV_EXTEND_MK),)
+ $(info Using roce extension $(DPU_HIROCE5_DRV_EXTEND_MK))
+ export DPU_DRV_MK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+ include $(DPU_HIROCE5_DRV_EXTEND_MK)
+ hiroce5-y += $(DPU_DRV_HIROCE5_EXTEND_OBJS)
+endif
+
+build_info:
+ mkdir -p build
+ @echo "CURDIR=$(CURDIR)" > build/build_src.txt
+ @for obj in $(hiroce5-y); do \
+ echo $$(realpath $$obj) >> build/build_src.txt; \
+ done
+
+endif
+
+include $(HI1823_BUILD_DIR)/host/linux/Makefile.ko
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq.h b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq.h
new file mode 100644
index 000000000..37562da9c
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq.h
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_CQ_H
+#define ROCE_CQ_H
+
+#include <rdma/ib_verbs.h>
+#include <linux/slab.h>
+
+#include "hinic5_hw.h"
+#include "hinic5_rdma.h"
+
+#include "roce.h"
+#include "roce_srq.h"
+
+#include "roce_option.h"
+#include "hinic5_hmm.h"
+
+#include "securec.h"
+
+/* DB type of ARM_CQ */
+enum { ROCE_CQ_DB_REQ_NOT_SOL = 1, ROCE_CQ_DB_REQ_NOT = 2 };
+
+#define CQ_DW_TO_BYTE 4
+#define ROCE_CQE_UP_THRESHOLD 1024
+
+/*
+1.Same type of operation as SQ WQE
+8'h00-Send
+8'h01-Send with Invalidate
+8'h02-Send with Immediate Data
+8'h03-reserved
+
+8'h04-RDMA Write
+8'h05-RDMA Write with Immediate Data
+8'h06-reserved
+8'h07-reserved
+
+8'h08-RDMA Read
+8'h09-reserved
+8'h0a-reserved
+8'h0b-reserved
+
+8'h0c-Atomic Compare & Swap
+8'h0d-Atomic Fetch & Add
+8'h0e-Atomic Masked Compare & Swap (Extended Atomic operation)
+8'h0f-Atomic Masked Fetch & Add (Extended Atomic operation)
+
+8'h10-Fast Register PMR
+8'h11-Local Invalidate
+8'h12-Bind Memory Window Type1/2
+8'h13-Local opreation(Extended for further local opreation)
+other-Reserved
+
+2.Receive
+00000 - RDMA Write with Immediate
+00001 - Send
+00010 - Send with Immediate
+00011 - Send & Invalidate
+
+3.The following are general
+11110 Error coding
+10110 Resize coding
+*/
+enum roce5_cqe_send_opcode {
+ ROCE_OPCODE_SEND = 0x0,
+ ROCE_OPCODE_SEND_WITH_INV = 0x1,
+ ROCE_OPCODE_SEND_WITH_IMM = 0x2,
+ /* 0x3 reserved */
+
+ ROCE_OPCODE_RDMA_WRITE = 0x4,
+ ROCE_OPCODE_RDMA_WRITE_WITH_IMM = 0x5,
+ /* 0x6 and 0x7 reserved */
+
+ ROCE_OPCODE_RDMA_READ = 0x8,
+ /* 0x9~0xb reserved */
+
+ ROCE_OPCODE_ATOMIC_COMP_AND_SWP = 0xc,
+ ROCE_OPCODE_ATOMIC_FETCH_AND_ADD = 0xd,
+ ROCE_OPCODE_ATOMIC_MASKED_COMP_AND_SWP = 0xe,
+ ROCE_OPCODE_ATOMIC_MASKED_FETCH_AND_ADD = 0xf,
+
+ ROCE_OPCODE_FAST_REG_PMR = 0x10,
+ ROCE_OPCODE_LOCAL_INV = 0x11,
+ ROCE_OPCODE_BIND_TYPE2_MW = 0x12,
+ ROCE_OPCODE_REG_SIG_MR = 0x13,
+
+ ROCE_OPCODE_RESIZE_CQE = 0x16,
+ ROCE_OPCODE_ERR = 0x1e,
+ ROCE_OPCODE_CQE_UNUSED = 0x1f /* Be used in new CQ buf when reszie cq */
+};
+
+enum roce5_cqe_recv_opcode {
+ ROCE_RECV_OPCODE_RDMA_WRITE_WITH_IMM = 0x0,
+ ROCE_RECV_OPCODE_SEND = 0x1,
+ ROCE_RECV_OPCODE_SEND_WITH_IMM = 0x2,
+ ROCE_RECV_OPCODE_SEND_WITH_INV = 0x3
+};
+
+/* Define the state type of the CQ */
+enum cq_state {
+ ROCE_CQ_STATE_INVALID = 0x0,
+ ROCE_CQ_STATE_ERR = 0x1,
+ ROCE_CQ_STATE_OVERFLOW = 0x2,
+ ROCE_CQ_STATE_VALID = 0xf,
+ ROCE_CQ_STATE_MEM_INIT = 0xa /* Initial value of Host Memory */
+};
+
+#define ROCE_CQ_TIME_OUT_CHECK_VALUE 0xe
+#define ROCE_CQ_STATE_CHECK_VALUE 0x0
+
+#define ROCE_CQE_RQ_INLINE 1
+#define ROCE_CQE_RQ_NORMAL 0
+#define ROCE_CQE_SEND_COMP 1
+#define ROCE_CQE_RECV_COMP 0
+
+#define ATOMIC_DATA_LEN 8 /* Specified as 8B by protocol */
+
+#define ROCE_CQE_INVALID_VALUE 0xff
+#define ROCE_CQ_RESIZE_POLL_TIMES 100
+
+/* roce Commands, bufs and data structures related to cq */
+struct roce5_cq_buf {
+ struct tag_cqm_buf *buf; /* pointer to describe the buf structure b cqm */
+ struct mtt
+ mtt; /* the mtt struct used by kernel mode and user mode to discribe buf */
+ int entry_size; /* the size of cqe */
+ int buf_size; /* the size of cq_buf */
+};
+
+struct roce5_cq_resize_buf {
+ struct roce5_cq_buf buf; /* the size of buf that was resized */
+ int cqe; /* the number of resized cqe */
+};
+
+#define ROCE_RCQ_ULD_DEF_LEN 64
+#define ROCE_RCQ_MAGIC 0x5a5ae0e0
+struct roce5_rcq_uld_def {
+ u8 uld_def[ROCE_RCQ_ULD_DEF_LEN];
+};
+
+struct roce5_cq {
+ struct ib_cq ibcq;
+ cqm_queue_s *cqm_cq; /* Save the handle obtained from cqm */
+ struct roce5_db
+ db; /* The address information of the software DB that stores the CI user mode/kernel mode */
+ __be32 *set_ci_db; /* Kernel-mode software DB */
+ u32 cons_index; /* consumer pointer */
+
+ u32 arm_sn; /* the serial number of arm */
+ int arm_flag; /* Used to determine whether the arm command has been sent, to avoid repeated sending */
+ u32 cqn;
+ unsigned int vector; /* associated to the eq used */
+ struct roce5_cq_buf buf; /* pointer describing the buf structure of cqm */
+ struct roce5_cq_resize_buf *resize_buf; /* resize buf struction */
+
+ spinlock_t lock; /* Need to lock when operating cq */
+ struct mutex resize_mutex; /* resize the mutex of cq */
+ struct ib_umem *umem; /* record the infomation mapped by User-mode buf */
+ struct ib_umem *
+ resize_umem; /* record the infomation mapped by buf which the User-mode resized */
+
+ struct list_head send_qp_list; /* send queue qp */
+ struct list_head recv_qp_list; /* receive queue qp */
+
+ int reset_notify_added;
+ struct list_head reset_notify;
+ u32 cqe_mask; /* mask of the cq size */
+
+ /*
+ * 'left_num' and 'wqebb_index' are only valid in the merged CQE within the RQ.
+ * 'left_num' records the remaining count of the last merged CQE.
+ * 'wqebb_index' records the wqebb index of the current CQE.
+ */
+ u32 left_num;
+ u32 wqebb_index;
+ struct roce5_option *opt;
+ u8 shadow;
+ u32 shadow_vfid;
+
+ void (*reset_flow_comp)(struct roce5_cq *);
+
+ struct roce5_rcq_uld_def
+ uld_def; /* must placed at cq_magic before, preventstop uld access memory stomping, support up to 64B space */
+ u32 rcq_magic;
+};
+
+/* Used when destroy QP */
+void roce5_cq_clean(struct roce5_cq *cq, u32 qpn, struct roce5_srq *srq);
+void roce5_cq_async_event(struct roce5_device *rdev, struct roce5_cq *cq,
+ int type);
+void roce5_cq_clean_process(struct roce5_cq *cq, u32 qpn,
+ struct roce5_srq *srq);
+void roce5_cq_put_umem(struct roce5_device *rdev, struct roce5_cq_buf *buf,
+ struct ib_umem **umem, u8 shadow_cq);
+int roce5_create_cq_common(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata, struct roce5_cq *rcq,
+ u32 index);
+int roce5_cq_get_umem(struct roce5_device *rdev, struct ib_ucontext *context,
+ struct roce5_cq *rcq, u64 buf_addr, int cqe,
+ bool is_resize);
+void *roce5_get_sw_cqe(struct roce5_cq *cq, unsigned int n);
+void *roce5_get_cqe_from_buf(struct roce5_cq_buf *buf, unsigned int n);
+void roce5_cq_set_ci(struct roce5_cq *cq);
+void roce5_cq_buf_init(struct roce5_cq_buf *buf);
+void *roce5_get_cqe(struct roce5_cq *cq, unsigned int n);
+void roce5_reset_flow_comp(struct roce5_cq *rcq);
+
+void roce5_lock_cqs(struct roce5_cq *roce5_send_cq,
+ struct roce5_cq *roce5_recv_cq)
+ __acquires(&roce5_send_cq->lock) __acquires(&roce5_recv_cq->lock);
+void roce5_unlock_cqs(struct roce5_cq *roce5_send_cq,
+ struct roce5_cq *roce5_recv_cq)
+ __releases(&roce5_send_cq->lock) __releases(&roce5_recv_cq->lock);
+
+struct roce5_cq *roce5_get_rcq_by_cqn(struct roce5_device *rdev, u32 cqn);
+void roce5_cq_completion(void *svc_hd, u32 cqn, void *cq_handler);
+
+static inline void roce5_rcq_put(struct roce5_cq *rcq)
+{
+ if (rcq == NULL) {
+ return;
+ }
+ roce5_option_put_value(rcq->opt);
+ cqm5_object_put(&rcq->cqm_cq->object);
+}
+
+#endif // ROCE_CQ_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_common.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_common.c
new file mode 100644
index 000000000..f212acecc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_common.c
@@ -0,0 +1,299 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "hinic5_hw.h"
+
+#include "roce.h"
+#include "roce_srq.h"
+#include "roce_qp.h"
+#include "roce_mix.h"
+#include "roce_xrc.h"
+#include "roce_user.h"
+#include "roce_cq.h"
+#include "roce_xqe_format.h"
+#include "roce_option.h"
+#include "hinic5_hmm.h"
+#include "securec.h"
+#include "roce_os_compat.h"
+#include "roce_aeq_format.h"
+
+/* ****************************************************************************
+ Prototype : roce5_cq_async_event
+ Description : roce5_cq_async_event
+ Input : struct roce5_device *rdev
+ struct roce5_cq *cq
+ int type
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_cq_async_event(struct roce5_device *rdev, struct roce5_cq *cq,
+ int type)
+{
+ struct ib_cq *ibcq = &cq->ibcq;
+ struct ib_event event;
+ int ret;
+
+ ret = memset_s(&event, sizeof(event), 0, sizeof(event));
+ if (ret != 0) {
+ ROCE_DEV_ERR_LIMIT(rdev, "Failed to memset event.(ret:%d)",
+ ret);
+ }
+ if (type != ROCE_EVENT_TYPE_CQ_ERROR) {
+ ROCE_DEV_WARN_LIMIT(
+ rdev,
+ "Unexpected event type(0x%x) on CQ(%06x), func_id(%d)",
+ type, cq->cqn, rdev->glb_func_id);
+ return;
+ }
+
+ if (ibcq->event_handler) {
+ event.device = ibcq->device;
+ event.event = IB_EVENT_CQ_ERR;
+ event.element.cq = ibcq;
+ ibcq->event_handler(&event, ibcq->cq_context);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_buf_init
+ Description : roce5_cq_buf_init
+ Input : struct roce5_cq_buf *buf
+ Output : None
+
+ 1.Date : 2015/11/9
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_cq_buf_init(struct roce5_cq_buf *buf)
+{
+ /* optype was initialized into ROCE_OPCODE_CQE_UNUSED(0x1f) */
+ int ret;
+ ret = memset_s(buf->buf->direct.va,
+ (unsigned long)((unsigned)buf->buf_size),
+ ROCE_CQE_INVALID_VALUE,
+ (unsigned long)((unsigned)buf->buf_size));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset va.(ret:%d)", ret);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_put_umem
+ Description : Release umem and corresponding mtt, corresponding to put
+ Input : struct roce5_device *rdev
+ struct roce5_cq_buf *buf
+ struct ib_umem **umem
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_cq_put_umem(struct roce5_device *rdev, struct roce5_cq_buf *buf,
+ struct ib_umem **umem, u8 shadow_cq)
+{
+ if (shadow_cq != 0) {
+ return;
+ }
+ /* free MTT of Buffer */
+ hmm_mtt_free(rdev->hwdev, &buf->mtt, SERVICE_T_ROCE);
+
+ /* release umem */
+ ib_umem_release(*umem);
+}
+
+static void *roce5_cq_buf_offset(struct tag_cqm_buf *buf, unsigned int offset)
+{
+ return (void *)((char *)buf->direct.va + offset);
+}
+
+void *roce5_get_cqe_from_buf(struct roce5_cq_buf *buf, unsigned int n)
+{
+ return roce5_cq_buf_offset(buf->buf, (n * buf->entry_size));
+}
+
+void *roce5_get_cqe(struct roce5_cq *cq, unsigned int n)
+{
+ return roce5_get_cqe_from_buf(&cq->buf, n);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_get_sw_cqe
+ Description : roce5_get_sw_cqe
+ Input : struct roce5_cq *cq
+ unsigned int n
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void *roce5_get_sw_cqe(struct roce5_cq *cq, unsigned int n)
+{
+ struct roce_cqe *cqe = NULL;
+ struct roce_cqe tmp_cqe;
+ unsigned int tmp_val;
+
+ cqe = (struct roce_cqe *)roce5_get_cqe(
+ cq, (n & ((unsigned int)cq->cqe_mask)));
+ if (cqe == NULL) {
+ ROCE_ERR("Get sw cqe failed.");
+ return NULL;
+ }
+ tmp_cqe.dw0.value = roce5_convert_cpu32(cqe->dw0.value);
+ tmp_cqe.dw1.value = roce5_convert_cpu32(cqe->dw1.value);
+
+ /* Add judgment condition: the optype of CQE cannot be UNUSED, UNUSED means that it has been initialized in resize
+ cq */
+ tmp_val = ((n & ((unsigned int)cq->ibcq.cqe + ROCE_CQE_UP_THRESHOLD)) ==
+ 0) ?
+ 1 :
+ 0;
+ if ((ROCE_LIKELY(tmp_cqe.dw1.bs.op_type != ROCE_OPCODE_CQE_UNUSED)) &&
+ ((tmp_cqe.dw0.bs.owner ^ tmp_val) != 0)) {
+ return cqe;
+ }
+
+ return NULL;
+}
+
+int roce5_cq_get_umem(struct roce5_device *rdev, struct ib_ucontext *context,
+ struct roce5_cq *rcq, u64 buf_addr, int cqe,
+ bool is_resize)
+{
+ int ret = 0;
+ u32 npages = 0;
+ int page_shift = 0;
+ int cqe_size = (int)rdev->rdma_cap.cqe_size;
+ struct roce5_cq_buf *buf = NULL;
+ struct ib_umem **umem = NULL;
+
+ if (rcq->shadow != 0) {
+ return 0;
+ }
+ if (is_resize) {
+ buf = &rcq->resize_buf->buf;
+ umem = &rcq->resize_umem;
+ } else {
+ buf = &rcq->buf;
+ umem = &rcq->umem;
+ }
+
+ *umem = roce5_umem_get(&rdev->ib_dev, context, buf_addr,
+ (unsigned long)(cqe * cqe_size),
+ IB_ACCESS_LOCAL_WRITE, 1);
+ if (IS_ERR(*umem)) {
+ ROCE_DEV_ERR(rdev, "Failed to get ib_umem, func_id(%d)",
+ rdev->glb_func_id);
+ return (int)PTR_ERR(*umem);
+ }
+
+ page_shift = (int)roce5_umem_get_buf_page_shift(rdev, *umem, buf_addr);
+ npages = roce5_umem_get_mtt_npages(rdev, *umem, page_shift);
+
+ buf->mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, npages, (u32)page_shift, &buf->mtt,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma_mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_buf;
+ }
+
+ ret = roce5_umem_write_mtt(rdev, &buf->mtt, *umem, true);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt for umem, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_mtt;
+ }
+
+ return 0;
+
+err_mtt:
+ hmm_mtt_free(rdev->hwdev, &buf->mtt, SERVICE_T_ROCE);
+
+err_buf:
+ ib_umem_release(*umem);
+
+ return ret;
+}
+
+void roce5_reset_flow_comp(struct roce5_cq *rcq)
+{
+ struct ib_cq *ibcq = &rcq->ibcq;
+
+ ibcq->comp_handler(ibcq, ibcq->cq_context);
+}
+
+/**
+ * @brief Get roce cq by cqn. When querying succeeded, you have to call roce5_rcq_put() to free
+ the cqm_obj and opt. But there is no need to call roce5_rcq_put() if querying failed.
+ * @return Success: return the roce cq. Failure: return NULL.
+ */
+struct roce5_cq *roce5_get_rcq_by_cqn(struct roce5_device *rdev, u32 cqn)
+{
+ cqm_object_s *cqm_obj = NULL;
+ cqm_queue_s *cqm_queue = NULL;
+ struct roce5_option *opt = NULL;
+ struct roce5_cq *rcq = NULL;
+
+ cqm_obj = cqm5_object_get(rdev->hwdev, CQM_OBJECT_RDMA_SCQ, cqn, false);
+ if (cqm_obj == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't find rcq according to cqn(0x%x), func_id(%d)",
+ cqn, rdev->glb_func_id);
+ goto err_out;
+ }
+
+ cqm_queue = container_of(cqm_obj, cqm_queue_s, object);
+ opt = (struct roce5_option *)cqm_queue->priv;
+ if (opt == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to get option, priv ptr is NULL.");
+ goto err_out_cqm_put;
+ }
+
+ rcq = (struct roce5_cq *)roce5_option_get_value(opt);
+ if (rcq == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to get rcq from option.");
+ goto err_out_cqm_put;
+ }
+
+ return rcq;
+
+err_out_cqm_put:
+ cqm5_object_put(cqm_obj);
+err_out:
+ return NULL;
+}
+
+void roce5_cq_completion(void *svc_hd, u32 cqn, void *cq_handler)
+{
+ struct roce5_option *opt = NULL;
+ struct roce5_cq *rcq = NULL;
+
+ if (cq_handler == NULL) {
+ ROCE_ERR("Cq_handler is null");
+ return;
+ }
+
+ opt = (struct roce5_option *)cq_handler;
+ rcq = (struct roce5_cq *)roce5_option_get_value(opt);
+ if (rcq == NULL) {
+ ROCE_WARN("Failed to get rcq from option.");
+ return;
+ }
+
+ ++rcq->arm_sn;
+ rcq->arm_flag = 0;
+
+ rcq->ibcq.comp_handler(&rcq->ibcq, rcq->ibcq.cq_context);
+
+ roce5_option_put_value(opt);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_cqe.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_cqe.c
new file mode 100644
index 000000000..b79aad2dc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_cqe.c
@@ -0,0 +1,763 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "hinic5_hw.h"
+#include "securec.h"
+
+#include "roce.h"
+#include "roce_srq.h"
+#include "roce_qp.h"
+#include "roce_mix.h"
+#include "roce_xrc.h"
+#include "roce_cq.h"
+#include "roce_restore.h"
+#include "roce_aeq_format.h"
+#include "roce_xqe_format.h"
+
+#include "roce_main_extension.h"
+
+/* ****************************************************************************
+ Prototype : roce5_next_cqe_sw
+ Description : roce5_next_cqe_sw
+ Input : struct roce5_cq *cq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static struct roce_cqe *roce5_next_cqe_sw(struct roce5_cq *cq)
+{
+ return (struct roce_cqe *)roce5_get_sw_cqe(cq, cq->cons_index);
+}
+
+static int g_error_cqe_to_wc[ROCE_COMPLETE_EVENT_MAX] = {
+ [ROCE_COMPLETE_EVENT_LOC_LEN_ERR] = IB_WC_LOC_LEN_ERR,
+ [ROCE_COMPLETE_EVENT_LOC_QP_OPERATION_ERR] = IB_WC_LOC_QP_OP_ERR,
+ [ROCE_COMPLETE_EVENT_LOC_PROTECTION_ERR] = IB_WC_LOC_PROT_ERR,
+ [ROCE_COMPLETE_EVENT_WR_FLUSH_ERR] = IB_WC_WR_FLUSH_ERR,
+
+ [ROCE_COMPLETE_EVENT_MW_BIND_ERR] = IB_WC_MW_BIND_ERR,
+ [ROCE_COMPLETE_EVENT_BAD_RESP_ERR] = IB_WC_BAD_RESP_ERR,
+
+ [ROCE_COMPLETE_EVENT_LOC_ACCESS_ERR] = IB_WC_LOC_ACCESS_ERR,
+ [ROCE_COMPLETE_EVENT_REM_INV_REQ_ERR] = IB_WC_REM_INV_REQ_ERR,
+ [ROCE_COMPLETE_EVENT_REM_ACCESS_ERR] = IB_WC_REM_ACCESS_ERR,
+ [ROCE_COMPLETE_EVENT_REM_OPERATION_ERR] = IB_WC_REM_OP_ERR,
+ [ROCE_COMPLETE_EVENT_RETRY_CTR_EXCEED_ERR] = IB_WC_RETRY_EXC_ERR,
+
+ [ROCE_COMPLETE_EVENT_RNR_RETRY_CTR_EXCEED_ERR] =
+ IB_WC_RNR_RETRY_EXC_ERR,
+
+ [ROCE_COMPLETE_EVENT_REM_ABORTED_ERR] = IB_WC_REM_ABORT_ERR,
+ [ROCE_COMPLETE_EVENT_XRC_VIOLATION_ERR] = IB_WC_REM_INV_RD_REQ_ERR,
+};
+
+/* ****************************************************************************
+ Prototype : roce5_handle_error_cqe
+ Description : roce5_handle_error_cqe
+ Input : struct roce_err_cqe *cqe
+ struct ib_wc *wc
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_handle_error_cqe(struct roce_err_cqe *cqe, struct ib_wc *wc)
+{
+ if (cqe->dw7.bs.syndrome >= ROCE_COMPLETE_EVENT_MAX) {
+ wc->status = IB_WC_GENERAL_ERR;
+ } else if (cqe->dw7.bs.syndrome > 0) {
+ wc->status = g_error_cqe_to_wc[cqe->dw7.bs.syndrome];
+ if (wc->status == 0) {
+ wc->status = IB_WC_GENERAL_ERR;
+ }
+ }
+
+ wc->vendor_err = cqe->dw7.bs.vendor_err;
+}
+
+static void roce5_get_local_opcode_from_cqe(const struct roce_cqe *cqe,
+ struct ib_wc *wc)
+{
+ switch (cqe->dw1.bs.op_type) {
+ case ROCE_OPCODE_LOCAL_INV:
+ wc->opcode = IB_WC_LOCAL_INV;
+ break;
+ case ROCE_OPCODE_REG_SIG_MR:
+ wc->opcode = IB_WC_REG_MR;
+ break;
+
+ default:
+ ROCE_WARN("Unknown cqe optype");
+ break;
+ }
+}
+
+static void roce5_get_opcode_type_part_1(struct roce_cqe *cqe, struct ib_wc *wc)
+{
+ switch (cqe->dw1.bs.op_type) {
+ case ROCE_OPCODE_RDMA_WRITE_WITH_IMM:
+ wc->opcode = IB_WC_RDMA_WRITE;
+ wc->wc_flags = (int)((u32)wc->wc_flags | IB_WC_WITH_IMM);
+ break;
+
+ case ROCE_OPCODE_RDMA_WRITE:
+ wc->opcode = IB_WC_RDMA_WRITE;
+ break;
+
+ case ROCE_OPCODE_SEND_WITH_IMM:
+ wc->opcode = IB_WC_SEND;
+ wc->wc_flags = (int)((u32)wc->wc_flags | IB_WC_WITH_IMM);
+ break;
+
+ case ROCE_OPCODE_SEND:
+ wc->opcode = IB_WC_SEND;
+ break;
+
+ case ROCE_OPCODE_SEND_WITH_INV:
+ wc->opcode = IB_WC_SEND;
+ break;
+ default:
+ roce5_get_local_opcode_from_cqe(cqe, wc);
+ break;
+ }
+}
+
+static void roce5_get_opcode_type_part_2(struct roce_cqe *cqe, struct ib_wc *wc)
+{
+ switch (cqe->dw1.bs.op_type) {
+ case ROCE_OPCODE_RDMA_READ:
+ wc->opcode = IB_WC_RDMA_READ;
+ wc->byte_len = cqe->byte_cnt;
+ break;
+
+ case ROCE_OPCODE_ATOMIC_COMP_AND_SWP:
+ wc->opcode = IB_WC_COMP_SWAP;
+ wc->byte_len = ATOMIC_DATA_LEN;
+ break;
+
+ case ROCE_OPCODE_ATOMIC_FETCH_AND_ADD:
+ wc->opcode = IB_WC_FETCH_ADD;
+ wc->byte_len = ATOMIC_DATA_LEN;
+ break;
+
+ case ROCE_OPCODE_ATOMIC_MASKED_COMP_AND_SWP:
+ wc->opcode = IB_WC_MASKED_COMP_SWAP;
+ wc->byte_len = ATOMIC_DATA_LEN;
+ break;
+
+ case ROCE_OPCODE_ATOMIC_MASKED_FETCH_AND_ADD:
+ wc->opcode = IB_WC_MASKED_FETCH_ADD;
+ wc->byte_len = ATOMIC_DATA_LEN;
+ break;
+ case ROCE_OPCODE_FAST_REG_PMR:
+ wc->opcode = IB_WC_REG_MR;
+ break;
+
+ default:
+ roce5_get_local_opcode_from_cqe(cqe, wc);
+ break;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_get_opcode_from_scqe
+ Description : Set the opcode/flag/byte_len of wc according to the opcode of send_cqe
+ Input : struct roce_cqe *cqe
+ struct ib_wc *wc
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_get_opcode_from_scqe(struct roce_cqe *cqe, struct ib_wc *wc)
+{
+ wc->wc_flags = 0;
+
+ if (cqe->dw1.bs.op_type < ROCE_OPCODE_RDMA_READ) {
+ roce5_get_opcode_type_part_1(cqe, wc);
+ } else {
+ roce5_get_opcode_type_part_2(cqe, wc);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_get_opcode_from_rcqe
+ Description : Set the opcode/flag/byte_len of wc according to the opcode of send_cqe
+ Input : struct roce_cqe *cqe
+ struct ib_wc *wc
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_get_opcode_from_rcqe(struct roce_cqe *cqe, struct ib_wc *wc)
+{
+ wc->byte_len = cqe->byte_cnt;
+
+ switch (cqe->dw1.bs.op_type) {
+ case ROCE_RECV_OPCODE_RDMA_WRITE_WITH_IMM:
+ wc->opcode = IB_WC_RECV_RDMA_WITH_IMM;
+ wc->wc_flags = IB_WC_WITH_IMM;
+ /* The driver does not perform big or small endian conversion for immediate data, but the incoming CQE
+ has been converted to the CPU endian, so it needs to be converted back */
+ wc->ex.imm_data = roce5_convert_be32(cqe->imm_invalid_rkey);
+ break;
+
+ case ROCE_RECV_OPCODE_SEND_WITH_INV:
+ wc->opcode = IB_WC_RECV;
+ wc->wc_flags = IB_WC_WITH_INVALIDATE;
+ wc->ex.invalidate_rkey =
+ roce5_convert_be32(cqe->imm_invalid_rkey);
+ break;
+
+ case ROCE_RECV_OPCODE_SEND:
+ wc->opcode = IB_WC_RECV;
+ wc->wc_flags = 0;
+ break;
+
+ case ROCE_RECV_OPCODE_SEND_WITH_IMM:
+ wc->opcode = IB_WC_RECV;
+ wc->wc_flags = IB_WC_WITH_IMM;
+ /* The driver does not perform big or small endian conversion for immediate data, but the incoming CQE
+ has been converted to the CPU endian, so it needs to be converted back */
+ wc->ex.imm_data = roce5_convert_be32(cqe->imm_invalid_rkey);
+ break;
+
+ default:
+ ROCE_WARN("Not supported");
+ break;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_poll_and_resize
+ Description : roce5_cq_poll_and_resize
+ Input : struct roce5_cq *cq
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_cq_poll_and_resize(struct roce5_device *rdev,
+ struct roce5_cq *cq)
+{
+ if (ROCE_LIKELY(cq->resize_buf != NULL)) {
+ /* Release the original Buffer of CQ */
+ cqm5_object_resize_free_old(&cq->cqm_cq->object);
+ cq->buf = cq->resize_buf->buf;
+ cq->ibcq.cqe = cq->resize_buf->cqe;
+
+ kfree(cq->resize_buf);
+ cq->resize_buf = NULL;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_get_cur_qp
+ Description : roce5_cq_get_cur_qp
+ Input : struct roce5_cq *cq
+ struct roce5_qp **cur_qp
+ struct roce_cqe *cqe
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_get_cur_qp(struct roce5_cq *cq, struct roce5_qp **cur_qp,
+ struct roce_cqe *cqe)
+{
+ struct roce5_device *rdev = to_roce5_dev(cq->ibcq.device);
+
+ if ((*cur_qp == NULL) || (cqe->dw0.bs.qpn != (u32)(*cur_qp)->qpn)) {
+ if (*cur_qp != NULL) {
+ roce5_rqp_put(*cur_qp);
+ }
+
+ *cur_qp = roce5_get_rqp_by_qpn(rdev, cqe->dw0.bs.qpn);
+ if (*cur_qp == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "CQ(%06x) with entry for unknown QPN(%06x), func_id(%d)",
+ cq->cqn, cqe->dw0.bs.qpn, rdev->glb_func_id);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_get_xrc_srq
+ Description : roce5_cq_get_xrc_srq
+ Input : struct roce5_cq *cq
+ struct roce5_srq **srq
+ struct roce_cqe *cqe
+ u32 qp_type
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_get_xrc_srq(struct roce5_cq *cq, struct roce5_srq **srq,
+ struct roce_cqe *cqe, u32 qp_type)
+{
+ u32 srqn = cqe->dw6.bs.srqn_rqpn;
+ struct roce5_device *rdev = to_roce5_dev(cq->ibcq.device);
+
+ if (qp_type == IB_QPT_XRC_TGT) {
+ if (*srq != NULL) {
+ roce5_rsrq_put(*srq);
+ }
+
+ *srq = roce5_get_rsrq_by_srqn(rdev, cqe->dw6.bs.srqn_rqpn);
+ if (*srq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "CQ(%06x) with entry for unknown SRQN(%06x), func_id(%d)",
+ cq->cqn, srqn, rdev->glb_func_id);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int roce5_poll_recv_cqe(struct roce5_cq *rcq, struct roce5_qp *cur_qp,
+ struct roce5_srq *srq, struct ib_wc *wc)
+{
+ u32 wqe_ctr = rcq->wqebb_index;
+ unsigned int tail = 0;
+ struct roce5_srq *srq_tmp = NULL;
+
+ if (cur_qp->ibqp.srq) {
+ srq_tmp = to_roce5_srq(cur_qp->ibqp.srq);
+ /* Determine whether to overflow */
+ if (wqe_ctr > (int)srq_tmp->max_depth) {
+ ROCE_ERR("Get wqe index(0x%x) from cqe", wqe_ctr);
+ return -EINVAL;
+ }
+
+ wc->wr_id = srq_tmp->wrid[wqe_ctr];
+ roce5_free_srq_wqe(srq_tmp, wqe_ctr);
+ } else if (srq != NULL) {
+ /* Determine whether to overflow */
+ if (wqe_ctr > srq->max_depth) {
+ ROCE_ERR("Get wqe index(0x%x) from cqe", wqe_ctr);
+ return -EINVAL;
+ }
+
+ wc->wr_id = srq->wrid[wqe_ctr];
+ roce5_free_srq_wqe(srq, wqe_ctr);
+ } else {
+ struct roce5_wq *wq = &(cur_qp->rq);
+ tail = (u32)(wq->tail & ((unsigned int)wq->wqebb_cnt - 1));
+ wc->wr_id = wq->wrid[tail];
+ ++wq->tail;
+ }
+
+ return 0;
+}
+
+static void roce5_poll_move_tail(const struct roce5_qp *cur_qp,
+ struct roce5_wq *wq,
+ struct roce_cqe *trans_cqe)
+{
+ u16 wqe_ctr = 0;
+ if (cur_qp->sq_signal_bits == 0) {
+ wqe_ctr = trans_cqe->dw7.bs.wqe_cnt;
+ wq->tail += (u16)(wqe_ctr - (u16)wq->tail);
+ }
+}
+
+static void roce5_poll_one_get_av_info(const struct roce5_qp *cur_qp,
+ struct ib_wc *wc,
+ struct roce_cqe trans_cqe,
+ struct roce_cqe *cqe)
+{
+ int ret;
+
+ if ((cur_qp->qp_type == IB_QPT_UD) || (cur_qp->qp_type == IB_QPT_GSI)) {
+ wc->sl = trans_cqe.dw4.bs.vlan_pri;
+ wc->src_qp = trans_cqe.dw6.bs.srqn_rqpn;
+ wc->network_hdr_type = trans_cqe.dw6.bs.stp;
+ wc->smac[0] =
+ (u8)(trans_cqe.dw4.bs.smac_h >>
+ 8); /* Take the first Byte data, shift 8bit */
+ wc->smac[1] = (u8)(trans_cqe.dw4.bs.smac_h & 0xff);
+ ret = memcpy_s(&wc->smac[2], sizeof(cqe->smac_l), &cqe->smac_l,
+ sizeof(cqe->smac_l)); //2 : smac array idx
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy smac.(ret:%d)", ret);
+ }
+ wc->wc_flags = (int)((u32)wc->wc_flags | IB_WC_WITH_SMAC);
+ if (trans_cqe.dw6.bs.vlan_pre != 0) {
+ wc->vlan_id = trans_cqe.dw4.bs.vlan_id;
+ wc->wc_flags =
+ (int)((u32)wc->wc_flags | IB_WC_WITH_VLAN);
+ }
+ }
+}
+
+static int roce5_poll_one_get_qp_and_srq(struct roce5_cq *cq,
+ struct roce5_qp **cur_qp,
+ struct ib_wc *wc,
+ struct roce_cqe *trans_cqe,
+ struct roce5_srq **srq)
+{
+ int ret = 0;
+ ret = roce5_cq_get_cur_qp(cq, cur_qp, trans_cqe);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get current qp");
+ return ret;
+ }
+
+ wc->qp = &((*cur_qp)->ibqp);
+
+ ret = roce5_cq_get_xrc_srq(cq, srq, trans_cqe, wc->qp->qp_type);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get xrc srq");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void roce5_bytes_trans(u32 *addr, int dw_num)
+{
+ u32 *dw = addr;
+ int i = 0;
+
+ for (i = 0; i < dw_num; i++) {
+ *dw = roce5_convert_cpu32(*dw);
+ dw++;
+ }
+}
+
+static int roce5_get_and_trans_cqe(struct roce5_device *rdev,
+ struct roce5_cq *cq,
+ struct roce_cqe *trans_cqe, int *is_send,
+ struct roce_cqe **cqe)
+{
+ int ret;
+
+ do {
+ *cqe = roce5_next_cqe_sw(cq);
+ if (*cqe == NULL) {
+ return -EAGAIN;
+ }
+
+ /* Later, it is necessary to perform big and small end conversion on CQE.
+ In order to avoid turning back after processing, copy a copy */
+ ret = memcpy_s((void *)trans_cqe, sizeof(struct roce_cqe),
+ (void *)*cqe, sizeof(struct roce_cqe));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy trans_cqe.(ret:%d).", ret);
+ return -ENOMEM;
+ }
+
+ /*
+ * Make sure we read CQ entry contents after we've checked the
+ * ownership bit.
+ */
+ rmb();
+
+ /* Convert the CQE into the CPU endian corresponding to the running environment */
+ roce5_bytes_trans(
+ (u32 *)(void *)trans_cqe,
+ (int)(sizeof(struct roce_cqe) / CQ_DW_TO_BYTE));
+
+ *is_send = trans_cqe->dw1.bs.s_r;
+ /* Resize CQ operation in progress */
+ if (ROCE_UNLIKELY(trans_cqe->dw1.bs.op_type ==
+ ROCE_OPCODE_RESIZE_CQE)) {
+ roce5_cq_poll_and_resize(rdev, cq);
+ }
+ } while (ROCE_UNLIKELY(trans_cqe->dw1.bs.op_type ==
+ ROCE_OPCODE_RESIZE_CQE));
+
+ return 0;
+}
+
+static void roce5_poll_send_cqe(struct roce5_qp *cur_qp,
+ struct roce_cqe *trans_cqe, struct ib_wc *wc)
+{
+ struct roce5_wq *wq = &(cur_qp->sq);
+ /* QP of type IB_SIGNAL_REQ_WR, tail needs to skip several WRs that do not generate CQE */
+ roce5_poll_move_tail(cur_qp, wq, trans_cqe);
+
+ wc->wr_id = wq->wrid[wq->tail & ((unsigned int)wq->wqebb_cnt - 1)];
+ ++wq->tail;
+
+ if (trans_cqe->dw1.bs.op_type == ROCE_OPCODE_ERR) {
+ roce5_handle_error_cqe((struct roce_err_cqe *)(void *)trans_cqe,
+ wc);
+ return;
+ }
+
+ roce5_get_opcode_from_scqe(trans_cqe, wc);
+}
+
+static void roce5_init_wc(struct roce_cqe *trans_cqe, struct ib_wc *wc)
+{
+ roce5_get_opcode_from_rcqe(trans_cqe, wc);
+ wc->wc_flags = (int)((unsigned int)wc->wc_flags | IB_WC_GRH);
+ wc->pkey_index = 0;
+ wc->vlan_id = 0xffff;
+ wc->sl = 0;
+ /* avoid cm_req_handler()->ib_lid_be16() trigger call trace */
+ wc->slid = 0;
+ return;
+}
+
+static int roce5_poll_one_cqe(struct roce5_cq *rcq, struct roce5_qp *cur_qp,
+ int is_send, struct roce_cqe *trans_cqe,
+ struct roce_cqe *cqe, struct roce5_srq *srq,
+ struct ib_wc *wc)
+{
+ int ret = 0;
+
+ wc->status = IB_WC_SUCCESS;
+ if (is_send != 0) {
+ roce5_poll_send_cqe(cur_qp, trans_cqe, wc);
+ return 0;
+ }
+
+ ret = roce5_poll_recv_cqe(rcq, cur_qp, srq, wc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (trans_cqe->dw1.bs.op_type == ROCE_OPCODE_ERR) {
+ roce5_handle_error_cqe((struct roce_err_cqe *)(void *)trans_cqe,
+ wc);
+ return 0;
+ }
+
+ roce5_init_wc(trans_cqe, wc);
+
+ roce5_poll_one_get_av_info((cur_qp), wc, *trans_cqe, cqe);
+
+ /* Kernel mode does not support receiving inline */
+ if (trans_cqe->dw1.bs.inline_r == ROCE_CQE_RQ_INLINE) {
+ ROCE_ERR("Receive inline not supported in kernel space");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_update_cons_index(struct roce5_device *rdev,
+ struct roce5_cq *rcq,
+ struct roce_cqe *trans_cqe)
+{
+ if (trans_cqe->dw1.bs.flush_op != 0) {
+ if (trans_cqe->dw1.bs.s_r == ROCE_CQE_SEND_COMP) {
+ ROCE_DEV_ERR(rdev, "Unexpected flush operation in SQ.");
+ ++rcq->cons_index;
+ return -EBADE;
+ }
+
+ if (rcq->left_num == 0) {
+ rcq->left_num = trans_cqe->wqe_num;
+ rcq->wqebb_index = trans_cqe->dw1.bs.wqebb_cnt;
+ }
+ } else {
+ rcq->left_num = 1;
+ rcq->wqebb_index = trans_cqe->dw1.bs.wqebb_cnt;
+ }
+
+ if (rcq->left_num == 1) {
+ ++rcq->cons_index;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_poll_one
+ Description : roce5_poll_one
+ Input : struct roce5_cq *cq
+ struct roce5_qp **cur_qp
+ struct ib_wc *wc
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_poll_one(struct roce5_device *rdev, struct roce5_cq *cq,
+ struct roce5_qp **cur_qp, struct ib_wc *wc)
+{
+ int ret = 0;
+ struct roce_cqe *cqe = NULL;
+ struct roce_cqe trans_cqe;
+ struct roce5_srq *srq = NULL;
+ int is_send = 0;
+ bool need_poll = true;
+
+ while (need_poll) {
+ ret = roce5_get_and_trans_cqe(rdev, cq, &trans_cqe, &is_send,
+ &cqe);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ ret = roce5_update_cons_index(rdev, cq, &trans_cqe);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ ret = roce5_poll_one_get_qp_and_srq(cq, cur_qp, wc, &trans_cqe,
+ &srq);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ /* Poll cq exception handling, generally cq judges user state information, xrc judges wrid */
+ if ((*cur_qp) == NULL) {
+ ROCE_ERR("cur_qp is NULL when poll cq");
+ ret = -EACCES;
+ goto err_out;
+ }
+ if ((*cur_qp)->umem ||
+ ((*cur_qp)->ibqp.xrcd && srq != NULL && !(srq->wrid))) {
+ ROCE_ERR(
+ "qp(%u) create in user space , but poll cq in kernel. NOT PERMIT!",
+ (*cur_qp)->qpn);
+ ret = -EACCES;
+ goto err_out;
+ }
+
+ if (trans_cqe.dw1.bs.fake != 0) {
+ ROCE_INFO("Fake cqe go repoll.");
+ continue;
+ }
+
+ ret = roce5_poll_one_cqe(cq, *cur_qp, is_send, &trans_cqe, cqe,
+ srq, wc);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ --cq->left_num;
+ need_poll = false;
+ }
+
+err_out:
+ roce5_rsrq_put(srq);
+ return ret;
+}
+
+/* the format of cq_ci DB:the bits of ci less than 24bit */
+void roce5_cq_set_ci(struct roce5_cq *cq)
+{
+ *cq->set_ci_db = cpu_to_be32(cq->cons_index & 0xffffff);
+}
+
+int roce5_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_cq *rcq = to_roce5_cq(ibcq);
+ struct roce5_qp *cur_qp = NULL;
+ unsigned long flags = 0; /* type required by kernel API */
+ int npolled = 0;
+ int ret = 0;
+
+ spin_lock_irqsave(&rcq->lock, flags);
+
+ rdev = to_roce5_dev(ibcq->device);
+
+ for (npolled = 0; npolled < num_entries; ++npolled) {
+ ret = roce5_poll_one(rdev, rcq, &cur_qp, wc + npolled);
+ if (ret != 0) {
+ break;
+ }
+ }
+
+ roce5_cq_set_ci(rcq);
+
+ spin_unlock_irqrestore(&rcq->lock, flags);
+
+ if ((ret == 0) || (ret == -EAGAIN)) {
+ ret = npolled;
+ goto err_out;
+ }
+
+err_out:
+ roce5_rqp_put(cur_qp);
+ return ret;
+}
+
+static void roce5_cq_arm(struct roce5_cq *cq, u32 cmd, void __iomem *uar_page)
+{
+ struct roce_db_cq_arm db_value;
+ int ret;
+
+ ret = memset_s(&db_value, sizeof(db_value), 0, sizeof(db_value));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset db_value.(ret:%d)", ret);
+ }
+
+ db_value.dw0.bs.type = 3;
+ db_value.dw0.bs.cos = 0; /* arm_cq don't need cos */
+ db_value.dw0.bs.cp = 1; /* 1 for cp */
+ db_value.dw0.bs.non_filter = 1;
+ db_value.dw0.bs.cqc_type = 0;
+ db_value.dw0.bs.cqn = cq->cqn;
+ db_value.dw0.value = roce5_convert_be32(db_value.dw0.value);
+
+ db_value.dw1.bs.cmd_sn = cq->arm_sn;
+ db_value.dw1.bs.cmd = cmd;
+ db_value.dw1.bs.ci = cq->cons_index;
+ db_value.dw1.value = roce5_convert_be32(db_value.dw1.value);
+
+ /*
+ * Make sure that the doorbell record in host memory is
+ * written before ringing the doorbell via PCI MMIO.
+ */
+ wmb();
+
+ roce5_write64((u32 *)(void *)&db_value, uar_page);
+}
+
+int roce5_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
+{
+ unsigned long lock_flags = 0; /* type required by kernel API */
+ struct roce5_cq *rcq = NULL;
+
+ if (CHECK_2LAYER_IS_NULL(ibcq, device)) {
+ return -EINVAL;
+ }
+
+ rcq = to_roce5_cq(ibcq);
+
+ spin_lock_irqsave(&rcq->lock, lock_flags);
+ if (rcq->arm_flag != 0) {
+ spin_unlock_irqrestore(&rcq->lock, lock_flags);
+ return 0;
+ }
+
+ rcq->arm_flag = 1;
+ spin_unlock_irqrestore(&rcq->lock, lock_flags);
+
+ /* Only 64-bit is supported, 64-bit writes are atomic, no need to lock */
+ roce5_cq_arm(rcq,
+ (((unsigned int)flags & IB_CQ_SOLICITED_MASK) ==
+ IB_CQ_SOLICITED) ?
+ ROCE_CQ_DB_REQ_NOT_SOL :
+ ROCE_CQ_DB_REQ_NOT,
+ to_roce5_dev(ibcq->device)->kernel_db_map);
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_create.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_create.c
new file mode 100644
index 000000000..0df5d34e4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_create.c
@@ -0,0 +1,636 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "comm_defs.h"
+#include "roce_cq.h"
+#include "roce_npu_cmd.h"
+#include "roce_cqm_cmd.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_os_compat.h"
+#include "roce_user.h"
+#include "roce_option.h"
+#include "roce_cq_intern.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_uld_inner.h"
+
+#define ROCE_CQE_BASE_SIZE_BYTES 16
+
+/* ****************************************************************************
+ Prototype :roce5_cq_attr_assign
+ Description : Assign value to CQC
+ Input : struct roce_cq_attr *cq_attr
+ struct roce5_cq *rcq
+ int eqn
+ int page_shift
+ Output : None
+
+ 1.Date : 2019/10/13
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_cq_attr_assign(roce_verbs_cq_attr_s *cq_attr,
+ struct roce5_cq *rcq, int eqn, int page_shift)
+{
+ /* Assign value to CQ */
+ /* dw0 */
+ cq_attr->dw0.bs.size = (u32)ROCE_ILOG2(
+ (unsigned)(rcq->ibcq.cqe + ROCE_CQE_UP_THRESHOLD));
+ cq_attr->dw0.bs.page_size = (u32)page_shift;
+ cq_attr->dw0.bs.cqe_size = (u32)ROCE_ILOG2(
+ (unsigned)(rcq->buf.entry_size / ROCE_CQE_BASE_SIZE_BYTES));
+ cq_attr->dw0.bs.mtt_page_size =
+ rcq->buf.mtt.mtt_page_shift - PAGE_SHIFT_4K;
+ cq_attr->dw0.bs.tss_timer_num =
+ 7; /* 7 : The maximum number of timers supported by cq */
+ cq_attr->dw0.bs.arm_timer_en = 0;
+ cq_attr->dw0.bs.timer_mode = 0;
+ cq_attr->dw0.bs.cnt_adjust_en = 1;
+ cq_attr->dw0.bs.cnt_clear_en = 1;
+ cq_attr->dw0.bs.ci_on_chip = 0;
+ cq_attr->dw0.value = cpu_to_be32(cq_attr->dw0.value);
+
+ /* dw1 */
+ cq_attr->dw1.bs.dma_attr_idx = 0;
+ cq_attr->dw1.bs.so_ro = 0;
+ cq_attr->dw1.bs.state = ROCE_CQ_STATE_VALID;
+ cq_attr->dw1.value = cpu_to_be32(cq_attr->dw1.value);
+
+ /* dw2 */
+ cq_attr->dw2.bs.idle_max_count = 0;
+ cq_attr->dw2.bs.cqecnt_lth = 10; /* update ci threshhold: 2^10=1024 */
+ cq_attr->dw2.bs.cqecnt_rctl_en = 0;
+ cq_attr->dw2.bs.ceqe_en = 1;
+ cq_attr->dw2.bs.arm_ceqe_en = 1;
+ cq_attr->dw2.bs.ceqn = (u8)eqn;
+ cq_attr->dw2.value = cpu_to_be32(cq_attr->dw2.value);
+
+ /* dw3 */
+ cq_attr->dw3.bs.timeout =
+ 0; /* The timeout mechanism is disabled by default when CQ is created */
+ cq_attr->dw3.bs.max_cnt =
+ 0; /* The overtime mechanism is disabled by default when CQ is created */
+ cq_attr->dw3.value = cpu_to_be32(cq_attr->dw3.value);
+
+ /* dw4 - dw5 */
+ cq_attr->cqc_l0mtt_gpa = rcq->buf.mtt.mtt_paddr;
+ cq_attr->cqc_l0mtt_gpa = cpu_to_be64(cq_attr->cqc_l0mtt_gpa);
+
+ /* dw6 - dw7 */
+ cq_attr->ci_record_gpa_at_hop_num = cpu_to_be64(
+ (rcq->db.dma & (~0x3uLL)) | rcq->buf.mtt.mtt_layers);
+}
+
+static int roce5_cq_fill_create_inbuf(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int vector,
+ int page_shift,
+ cqm_cmd_buf_s *cqm_cmd_inbuf)
+{
+ int eqn = 0;
+ roce_verbs_cq_attr_s *cq_attr = NULL;
+ roce_uni_cmd_create_cq_s *cq_sw2hw_inbuf = NULL;
+
+ cq_sw2hw_inbuf = (roce_uni_cmd_create_cq_s *)cqm_cmd_inbuf->buf;
+ cq_sw2hw_inbuf->com.index = cpu_to_be32(rcq->cqn);
+ cq_sw2hw_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_CQ_BITMASK));
+ if (rcq->shadow != 0) {
+ cq_sw2hw_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_sw2hw_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rcq->shadow_vfid);
+ }
+ cq_attr = &cq_sw2hw_inbuf->cq_attr;
+
+ /* Get the EQN of the CEQ based on the Vector index */
+ eqn = hinic5_vector_to_eqn(rdev->hwdev, SERVICE_T_ROCE, vector);
+ if (eqn < 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to get eqn from hinic vector, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ roce5_cq_attr_assign(cq_attr, rcq, eqn, page_shift);
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_sw2hw
+ Description : Send the cqc configuration command
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int vector
+ int page_shift
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_sw2hw(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int vector, int page_shift)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_create_cq_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ ret = roce5_cq_fill_create_inbuf(rdev, rcq, vector, page_shift,
+ cqm_cmd_inbuf);
+ if (ret != 0) {
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE, ROCE_CMD_SW2HW_CQ,
+ cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send SW2HW_CQ command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+
+ /* CMDq times out or CMDq does not work, update the device status, notify the PCIe module to reset
+ the device through OFED */
+ if ((ret == -ETIMEDOUT) || (ret == -EPERM)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+
+ ret = -1;
+ goto err_send_cmd;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ rcq->cons_index = 0;
+ rcq->arm_sn = 1;
+ rcq->arm_flag = 0;
+ rcq->vector = (u32)vector;
+
+ return 0;
+
+err_send_cmd:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_cq_check
+ Description : roce5_create_cq_check
+ Input : struct ib_device *ibdev
+ int entries
+ int vector
+ struct ib_ucontext *ibcontext
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_cq_check(struct ib_device *ibdev, int entries,
+ int vector)
+{
+ struct roce5_device *rdev = NULL;
+
+ if (ibdev == NULL) {
+ ROCE_ERR("Ibdev is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+ if ((entries < 1) || (entries > (int)rdev->rdma_cap.max_cqes)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Cqe number invalid, entries(%d), max_cqes(%d), func_id(%d)",
+ entries, (int)rdev->rdma_cap.max_cqes,
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if (vector > (int)rdev->rdma_cap.num_comp_vectors) {
+ ROCE_DEV_ERR(rdev, "Vector over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_check_cq_create_flags(u32 flags)
+{
+ /*
+ * It returns non-zero value for unsupported CQ
+ * create flags, otherwise it returns zero.
+ */
+ return (int)(flags & ~(IB_UVERBS_CQ_FLAGS_IGNORE_OVERRUN |
+ IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION));
+}
+
+static int roce5_cq_cqc_cfg(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int vector, struct ib_udata *udata, u64 cq_buf_addr)
+{
+ int ret = 0;
+ int page_shift = (int)roce5_umem_get_buf_page_shift(rdev, rcq->umem,
+ cq_buf_addr) -
+ PAGE_SHIFT_4K;
+
+ /* configurate CQC */
+ ret = roce5_cq_sw2hw(rdev, rcq, vector, page_shift);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to handle cq sw2hw, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ /* User mode requires outgoing CQN */
+ if (ib_copy_to_udata(udata, &rcq->cqn, sizeof(u32)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy data to user space, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EFAULT;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int roce5_create_user_cq(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int cqe_num, const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ int vector = attr->comp_vector;
+ struct roce5_create_cq_cmd ucmd = { 0 };
+ roce_user_handle_t hdl = { 0 };
+
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy from user space, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EFAULT;
+ goto err_out;
+ }
+
+ ROCE_CONSTUCT_ULD_HDL_RCQ(&hdl, rdev, rcq, udata, &rcq->buf.mtt,
+ &rcq->db.dma, cqe_num);
+ ROCE_CONSTUCT_ULD_HDL_SHADOW(&hdl, &rcq->shadow, &rcq->shadow_vfid,
+ NULL);
+ ret = roce5_uld_cq_create((roce_uld_handle)&hdl);
+ if (ret != 0) {
+ ROCE_ERR("Failed to execute uld cq create, ret(%d)", ret);
+ goto err_out;
+ }
+ /* Entries has been decreased by one when it was input by User Mode, and it is the expected value exactly
+ after increased by one by Kernel Mode */
+ ret = roce5_cq_get_umem(rdev, ibcontext, rcq, ucmd.buf_addr, cqe_num,
+ false);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get umem, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_destroy_uld;
+ }
+
+ ret = roce5_db_map_user(to_roce5_ucontext(ibcontext),
+ (unsigned long)ucmd.db_addr, &rcq->db,
+ rcq->shadow);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to map kernel_mem to user_mem, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_mtt;
+ }
+
+ ret = roce5_cq_cqc_cfg(rdev, rcq, vector, udata, ucmd.buf_addr);
+ if (ret != 0) {
+ goto err_unmap_db;
+ }
+
+ return 0;
+
+err_unmap_db:
+ roce5_db_unmap_user(to_roce5_ucontext(ibcontext), &rcq->db,
+ rcq->shadow);
+
+err_free_mtt:
+ roce5_cq_put_umem(rdev, &rcq->buf, &rcq->umem, rcq->shadow);
+ rcq->umem = NULL;
+
+err_destroy_uld:
+ roce5_uld_cq_destroy((roce_uld_handle)&hdl);
+
+err_out:
+
+ return ret;
+}
+
+static void roce5_fill_rcq_info(struct roce5_cq *rcq)
+{
+ rcq->cqn = rcq->cqm_cq->index;
+ rcq->buf.buf = &rcq->cqm_cq->q_room_buf_1;
+
+ /* Initialize buf to unused */
+ roce5_cq_buf_init(&rcq->buf);
+
+ /* Software DB assignment */
+ rcq->set_ci_db = (__be32 *)(void *)(&rcq->cqm_cq->q_header_vaddr
+ ->doorbell_record);
+ *rcq->set_ci_db = 0;
+ rcq->db.db_record = (__be32 *)(void *)(&rcq->cqm_cq->q_header_vaddr
+ ->doorbell_record);
+ rcq->db.dma = rcq->cqm_cq->q_header_paddr;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_kernel_cq
+ Description : roce5_create_kernel_cq
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ int vector
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_kernel_cq(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int entries, int vector,
+ u32 index)
+{
+ int ret = 0;
+ int page_shift = 0;
+
+ rcq->buf.buf_size = entries * (int)rdev->rdma_cap.cqe_size;
+ rcq->cqm_cq = cqm5_object_rdma_queue_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_RDMA_SCQ,
+ (u32)rcq->buf.buf_size, rcq->opt, true, index, 0, 0);
+ if (rcq->cqm_cq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create rdma_queue from cqm_object, func_id(%d), index(%d)",
+ rdev->glb_func_id, index);
+ return (-ENOMEM);
+ }
+
+ /* Buffer is obtained from room1 when the queue is just created */
+ if (rcq->cqm_cq->current_q_room != CQM_RDMA_Q_ROOM_1) {
+ ROCE_DEV_ERR(rdev, "Not use CQM_RDMA_Q_ROOM_1, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EINVAL;
+ goto err_free_cqm_cq;
+ }
+
+ roce5_fill_rcq_info(rcq);
+
+ page_shift = ROCE_ILOG2(rcq->cqm_cq->q_room_buf_1.buf_size);
+
+ /* allocate MTT */
+ rcq->buf.mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, rcq->buf.buf->buf_number,
+ (u32)page_shift, &rcq->buf.mtt, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_cqm_cq;
+ }
+
+ /* Write the PA of the CQ Buffer to the MTT */
+ ret = roce5_buf_write_mtt(rdev, &rcq->buf.mtt, rcq->buf.buf);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_mtt;
+ }
+
+ page_shift = (int)ROCE_ILOG2(rcq->cqm_cq->q_room_buf_1.buf_size) -
+ PAGE_SHIFT_4K;
+
+ /* configurate CQC */
+ ret = roce5_cq_sw2hw(rdev, rcq, vector, page_shift);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to configure CQC, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_mtt;
+ }
+
+ return 0;
+
+err_free_mtt:
+ hmm_mtt_free(rdev->hwdev, &rcq->buf.mtt, SERVICE_T_ROCE);
+
+err_free_cqm_cq:
+ cqm5_object_delete(&rcq->cqm_cq->object);
+
+ return ret;
+}
+
+static int roce5_cq_depth_init(struct roce5_device *rdev, struct roce5_cq *rcq,
+ const struct ib_cq_init_attr *attr, int *cqe_num)
+{
+ u32 entries = (u32)attr->cqe;
+
+ /* The CQE queue should reserve four special CQE for the HOST CI can be updated to the CQC CI */
+ entries += ROCE_CQE_UP_THRESHOLD;
+ entries = ROCE_ROUNDUP_POW_OF_TWO(entries) & 0xffffffff;
+ /* Chip Constraints: Minimum queue depth needs to be page-aligned */
+ if ((entries * rdev->rdma_cap.cqe_size) < PAGE_SIZE) {
+ entries = (PAGE_SIZE >> ROCE_ILOG2(rdev->rdma_cap.cqe_size));
+ }
+ if (entries == 0) {
+ ROCE_DEV_ERR(rdev, "Invalid entries after align, func_id(%u)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+ rcq->cqe_mask = entries - 1;
+ /* Check if max spec is exceeded */
+ if (rdev->rdma_cap.max_cqes > UINT_MAX - ROCE_CQE_UP_THRESHOLD) {
+ ROCE_DEV_ERR(
+ rdev,
+ "max_cqes overflow detected, max_cqes(%u), func_id(%u)",
+ rdev->rdma_cap.max_cqes, rdev->glb_func_id);
+ return -EINVAL;
+ }
+ if (entries > (rdev->rdma_cap.max_cqes + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Over range after align, entries(%u), max_cqes(%u), func_id(%u)",
+ entries,
+ rdev->rdma_cap.max_cqes + ROCE_CQE_UP_THRESHOLD,
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if ((int)entries > INT_MAX) {
+ ROCE_DEV_ERR(rdev, "Bug detected: Int Overflow!");
+ return -EINVAL;
+ }
+
+ *cqe_num = (int)entries;
+ rcq->ibcq.cqe = (int)entries - ROCE_CQE_UP_THRESHOLD;
+ return 0;
+}
+
+static int roce5_do_create_cq(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata, struct roce5_cq *rcq,
+ u32 index)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_ucontext *context = NULL;
+ int ret = 0;
+ int vector = attr->comp_vector;
+ int cqe_num = 0;
+
+ rdev = to_roce5_dev(ibdev);
+ ret = roce5_cq_depth_init(rdev, rcq, attr, &cqe_num);
+ if (ret != 0) {
+ return ret;
+ }
+
+ mutex_init(&rcq->resize_mutex);
+ spin_lock_init(&rcq->lock);
+ rcq->resize_buf = NULL;
+ rcq->resize_umem = NULL;
+ rcq->buf.entry_size = (int)rdev->rdma_cap.cqe_size;
+ rcq->rcq_magic = ROCE_RCQ_MAGIC;
+
+ rcq->opt = roce5_some(rcq);
+ if (rcq->opt == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to init some, cqn(%u).", rcq->cqn);
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&rcq->send_qp_list);
+ INIT_LIST_HEAD(&rcq->recv_qp_list);
+ if (udata != NULL) {
+ ret = roce5_create_cq_alloc_cqn(rdev, rcq, index);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm cq resource, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+ context = roce5_queue_to_ucontext((void *)(&rcq->ibcq), udata,
+ ROCE_Q_TYPE_CQ);
+ ret = roce5_create_user_cq(rdev, rcq, cqe_num, attr,
+ &context->ibucontext, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create user_cq, func_id(%d)",
+ rdev->glb_func_id);
+ cqm5_object_delete(&rcq->cqm_cq->object);
+ return ret;
+ }
+ } else {
+ ret = roce5_create_kernel_cq(rdev, rcq, cqe_num, vector, index);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create kernel_cq, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+ rcq->reset_flow_comp = roce5_reset_flow_comp;
+
+ return 0;
+}
+
+int roce5_create_cq_common(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata, struct roce5_cq *rcq,
+ u32 index)
+{
+ int ret;
+ int vector = attr->comp_vector;
+ int entries = (int)attr->cqe;
+
+ if (roce5_check_cq_create_flags(attr->flags) != 0) {
+ ROCE_ERR("Not support the cq_create flag(%x)", attr->flags);
+ return -EOPNOTSUPP;
+ }
+
+ ret = roce5_create_cq_check(ibdev, entries, vector);
+ if (ret != 0) {
+ ROCE_ERR("Failed to check cq information");
+ return ret;
+ }
+
+ return roce5_do_create_cq(ibdev, attr, udata, rcq, index);
+}
+
+int roce5_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata)
+{
+ struct roce5_cq *rcq = NULL;
+
+ if ((ibcq == NULL) || (attr == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ rcq = to_roce5_cq(ibcq);
+ return roce5_create_cq_common(ibcq->device, attr, udata, rcq,
+ ROCE_CQN_INVLD);
+}
+
+struct ib_cq *roce5_create_cq_ofa(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_cq *rcq = NULL;
+ struct ib_uobject uobject;
+
+ if ((ibdev == NULL) || (attr == NULL)) {
+ ROCE_ERR("ibdev or attr is NULL");
+ return ERR_PTR(-EINVAL);
+ }
+
+ uobject.context = ibcontext;
+
+ rcq = (struct roce5_cq *)kzalloc(sizeof(*rcq), GFP_KERNEL);
+ if (rcq == NULL) {
+ ret = -ENOMEM;
+ ROCE_ERR("Failed to alloc rcq");
+ goto out;
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ rcq->ibcq.device = ibdev;
+#if defined(IB_CQ_HAVE_UOBJECT)
+ rcq->ibcq.uobject = ((udata != NULL) ? &uobject : NULL);
+#endif
+ ret = roce5_create_cq(&rcq->ibcq, attr, udata);
+ if (ret != 0) {
+ kfree(rcq);
+ rcq = NULL;
+ goto out;
+ }
+
+out:
+ /* disassociate anyway */
+ if (rcq != NULL) {
+ rcq->ibcq.uobject = NULL;
+ }
+ return ((ret != 0) ? (struct ib_cq *)ERR_PTR((long)ret) : &rcq->ibcq);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_ctrl.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_ctrl.c
new file mode 100644
index 000000000..eaf8e22f4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_ctrl.c
@@ -0,0 +1,964 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "comm_defs.h"
+#include "roce_cq.h"
+#include "roce_cqm_cmd.h"
+#include "roce_npu_cmd.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_infra.h"
+#include "roce_compat.h"
+#include "roce_os_compat.h"
+#include "roce_cqe_format.h"
+#include "roce_user.h"
+#include "roce_com.h"
+
+/* and above next is V100 adaptation data structure */
+typedef struct tag_roce_cmd_resize_cq {
+ roce_verbs_cmd_com_s com;
+
+ u32 rsvd;
+ u32 page_size; /* Size of the resize buf page. */
+ u32 log_cq_size; /* Cq depth after resize */
+ u32 mtt_layer_num; /* Number of mtt levels after resize */
+ /* DW4~5 */
+ union {
+ u64 mtt_base_addr; /* Start address of mr or mw */
+ u32 cqc_l0mtt_gpa[2];
+ };
+ u32 mtt_page_size; /* Size of the mtt page after resize. */
+ roce_xq_mtt_info_s mtt_info;
+} roce_cmd_resize_cq_s;
+
+typedef struct tag_roce_cmd_modify_cq {
+ roce_verbs_cmd_com_s com;
+ u32 max_cnt;
+ u32 timeout;
+} roce_cmd_modify_cq_s;
+
+static int roce5_uni_cmd_cq_modify(struct roce5_device *rdev,
+ struct roce5_cq *cq, u32 cnt, u32 period)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_modify_cq_s *cq_modify_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_modify_cq_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ cq_modify_inbuf = (roce_uni_cmd_modify_cq_s *)cqm_cmd_inbuf->buf;
+ cq_modify_inbuf->com.index = cpu_to_be32(cq->cqn);
+ cq_modify_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_CQ_BITMASK);
+ if (cq->shadow != 0) {
+ cq_modify_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_modify_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(cq->shadow_vfid);
+ }
+ cq_modify_inbuf->cq_modify.max_cnt = cpu_to_be32(cnt);
+ cq_modify_inbuf->cq_modify.timeout = cpu_to_be32(period);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_MODIFY_CQ, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send MODIFY_CQ, cqn(0x%x), ret(%d), func_id(%hu)",
+ cq->cqn, ret, rdev->glb_func_id);
+ /* CMDq may return a positive number, so its return value cannot be used directly */
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int roce5_cq_modify(struct roce5_device *rdev, struct roce5_cq *cq,
+ u32 cnt, u32 period)
+{
+ if (ROCE5_SUPPORT_CQ_MODIFY_MSG_V2(rdev) != 0) {
+ return roce5_uni_cmd_cq_modify(rdev, cq, cnt, period);
+ }
+ return -EINVAL;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_modify_cq
+ Description : OFED_3_12
+ Input : struct ib_cq *ibcq
+ u16 cq_count
+ u16 cq_period
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_modify_cq(struct ib_cq *ibcq, u16 cq_count, u16 cq_period)
+{
+ int ret = 0;
+ struct roce5_cq *cq = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (ibcq == NULL) {
+ ROCE_ERR(" Ibcq is null");
+ return -EINVAL;
+ }
+
+ cq = to_roce5_cq(ibcq);
+ rdev = to_roce5_dev(ibcq->device);
+
+ ret = roce5_cq_modify(rdev, cq, cq_count, cq_period);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to modify cq, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_alloc_resize_buf
+ Description : Kernel mode applies for resize_buf, and its corresponding MTT
+ When there is an error in execution, this function ensures that all intermediate resources are released;
+ when the execution is successful, this function can confirm that all resources are acquired.
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_alloc_resize_buf(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int entries)
+{
+ int ret = 0;
+ int page_shift = 0;
+
+ if (rcq->resize_buf != NULL) {
+ ROCE_DEV_ERR(rdev, "Resize buffer is busy, func_id(%d)",
+ rdev->glb_func_id);
+ return -EBUSY;
+ }
+
+ /* Apply for resize_buf and assign it */
+ rcq->resize_buf = (struct roce5_cq_resize_buf *)kmalloc(
+ sizeof(*rcq->resize_buf), GFP_ATOMIC);
+ if (rcq->resize_buf == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc resize buffer, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ rcq->resize_buf->buf.entry_size = rcq->buf.entry_size;
+ rcq->resize_buf->buf.buf_size = entries * rcq->buf.entry_size;
+ ret = cqm5_object_resize_alloc_new(&rcq->cqm_cq->object,
+ (u32)rcq->resize_buf->buf.buf_size);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to resize cq buffer, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_resize_buf_alloc;
+ }
+
+ /* If the application is successful, record the buffer information of the new buffer */
+ rcq->resize_buf->cqe = entries - ROCE_CQE_UP_THRESHOLD;
+ rcq->resize_buf->buf.buf = &rcq->cqm_cq->q_room_buf_2;
+
+ /* Initialize new buf to unused state */
+ roce5_cq_buf_init(&rcq->resize_buf->buf);
+
+ page_shift = (int)ROCE_ILOG2(rcq->resize_buf->buf.buf->buf_size);
+
+ /* Apply MTT for resize_buf */
+ rcq->buf.mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, rcq->resize_buf->buf.buf->buf_number,
+ (u32)page_shift, &rcq->resize_buf->buf.mtt,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_mtt_alloc;
+ }
+
+ /* configurate MTT, write PA of resize_buf to MTT */
+ ret = roce5_buf_write_mtt(rdev, &rcq->resize_buf->buf.mtt,
+ rcq->resize_buf->buf.buf);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_mtt_write;
+ }
+
+ return 0;
+
+err_mtt_write:
+ hmm_mtt_free(rdev->hwdev, &rcq->buf.mtt, SERVICE_T_ROCE);
+
+err_mtt_alloc:
+ /* free resize_buf */
+ cqm5_object_resize_free_new(&rcq->cqm_cq->object);
+
+err_resize_buf_alloc:
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_free_resize_buf
+ Description : Kernel Mode releases resize_buf and its corresponding MTT
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_cq_free_resize_buf(struct roce5_device *rdev,
+ struct roce5_cq *rcq)
+{
+ /* Release the MTT of resize_buf first */
+ hmm_mtt_free(rdev->hwdev, &(rcq->resize_buf->buf.mtt), SERVICE_T_ROCE);
+
+ /* free resize_buf */
+ cqm5_object_resize_free_new(&(rcq->cqm_cq->object));
+
+ /* free the resize_buf pointer itself */
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_alloc_resize_umem
+ Description : User mode applies for umem of resize_buf, and MTT corresponding to user mode buf
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_alloc_resize_umem(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int entries,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_resize_cq_cmd ucmd = { 0 };
+ struct roce5_ucontext *context = roce5_queue_to_ucontext(
+ (void *)(&rcq->ibcq), udata, ROCE_Q_TYPE_CQ);
+
+ /* If a resize is being executed, it is not allowed to execute another resize at the same time */
+ if (rcq->resize_umem != NULL) {
+ ROCE_DEV_ERR(rdev, "Resize_umem is busy, func_id(%d)",
+ rdev->glb_func_id);
+ return -EBUSY;
+ }
+
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy from user space, func_id(%d)",
+ rdev->glb_func_id);
+ return -EFAULT;
+ }
+
+ rcq->resize_buf = (struct roce5_cq_resize_buf *)kmalloc(
+ sizeof(*rcq->resize_buf), GFP_ATOMIC);
+ if (rcq->resize_buf == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc cq resize buffer, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ ret = roce5_cq_get_umem(rdev, &context->ibucontext, rcq, ucmd.buf_addr,
+ entries, true);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get umem, func_id(%d)",
+ rdev->glb_func_id);
+
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+
+ return ret;
+ }
+
+ rcq->resize_buf->buf.entry_size = rcq->buf.entry_size;
+ rcq->resize_buf->buf.buf_size = entries * rcq->buf.entry_size;
+ rcq->resize_buf->cqe = entries - ROCE_CQE_UP_THRESHOLD;
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_free_resize_umem
+ Description : User mode applies for umem of resize_buf, and MTT corresponding to user mode buf
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_cq_free_resize_umem(struct roce5_device *rdev,
+ struct roce5_cq *rcq)
+{
+ /* Free MTT and umem of resize_buf */
+ roce5_cq_put_umem(rdev, &rcq->resize_buf->buf, &rcq->resize_umem, 0);
+ rcq->resize_umem = NULL;
+
+ /* free resize_buf itself */
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_get_outstanding_cqes
+ Description : roce5_cq_get_outstanding_cqes
+ Input : struct roce5_cq *cq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_get_outstanding_cqes(struct roce5_cq *cq)
+{
+ u32 i = 0;
+
+ i = cq->cons_index;
+ while (roce5_get_sw_cqe(cq, i)) {
+ ++i;
+ }
+
+ return (int)(i - cq->cons_index);
+}
+
+static int roce5_cq_get_next_cqe(struct roce_cqe **cqe, struct roce5_cq *cq,
+ unsigned int *i, u32 *times,
+ const struct roce_cqe *start_cqe)
+{
+ do {
+ *cqe = (struct roce_cqe *)roce5_get_sw_cqe(cq, ++(*i));
+ if (*cqe == NULL) {
+ ROCE_DELAY();
+ --(*times);
+ }
+ } while ((*cqe == NULL) && (*times != 0));
+
+ if ((*cqe == start_cqe) || (*cqe == NULL)) {
+ ROCE_ERR("Failed to get resize CQE, CQN(0x%x)", cq->cqn);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_resize_copy_cqes
+ Description : roce5_cq_resize_copy_cqes
+ Input : struct roce5_cq *cq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_cq_resize_copy_cqes(struct roce5_cq *cq)
+{
+ struct roce_cqe *cqe = NULL;
+ struct roce_cqe *new_cqe = NULL;
+ struct roce_cqe *start_cqe = NULL;
+ u32 times;
+ unsigned int i = 0;
+ int ret = 0;
+
+ i = cq->cons_index;
+
+ times = ROCE_CQ_RESIZE_POLL_TIMES;
+ do {
+ cqe = (struct roce_cqe *)roce5_get_sw_cqe(cq, i);
+ if (cqe == NULL) {
+ ROCE_DELAY();
+ --times;
+ }
+ } while ((cqe == NULL) && (times != 0));
+
+ if (cqe == NULL) {
+ ROCE_ERR("Failed to get resize CQE, CQN(0x%x)", cq->cqn);
+ return -ENOMEM;
+ }
+
+ start_cqe = cqe;
+
+ /* r_cqe:resize_cqe
+ CI
+ +--------+-----+-----+-----+----------+
+ old_buf: | | CQE | CQE |R_CQE| |
+ +--------+-----+-----+-----+----------+
+ | |
+ | |
+ +--------+-----+-----+-----+----------+
+ new_buf: | | CQE | CQE | | |
+ +--------+-----+-----+-----+----------+
+ */
+ /* Convert the fields needed by CQE to little endian */
+ cqe->dw0.value = roce5_convert_cpu32(cqe->dw0.value);
+ cqe->dw1.value = roce5_convert_cpu32(cqe->dw1.value);
+ while (cqe->dw1.bs.op_type != ROCE_OPCODE_RESIZE_CQE) {
+ /* The resized PI can be inherited, and the index of the original CQE remains unchanged in resize_buf */
+ new_cqe = (struct roce_cqe *)roce5_get_cqe_from_buf(
+ &cq->resize_buf->buf,
+ (i & ((unsigned)cq->resize_buf->cqe)));
+
+ ret = memcpy_s((void *)new_cqe, sizeof(struct roce_cqe),
+ (void *)cqe, sizeof(struct roce_cqe));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy new_cqe.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ /* If the CQE has been wrapped in resize_buf, the corresponding Owner bit needs to be modified
+ to be owned by the software.
+ * The rule is: when the owner bit is owned by CQE software, the O bit is opposite to the high bit of ci;
+ when the owner bit is owned by hardware, the O bit is the same as the high bit of CI.
+ */
+ new_cqe->dw0.bs.owner = ((i & ((unsigned)cq->resize_buf->cqe +
+ ROCE_CQE_UP_THRESHOLD)) != 0) ?
+ 1 :
+ 0;
+
+ /* After processing, turn the DW0/DW1 of CQE back to big endian */
+ cqe->dw0.value = roce5_convert_be32(cqe->dw0.value);
+ cqe->dw1.value = roce5_convert_be32(cqe->dw1.value);
+
+ /* Convert DW0/DW1 of the CQE in the new queue back to big endian */
+ new_cqe->dw0.value = roce5_convert_be32(new_cqe->dw0.value);
+ new_cqe->dw1.value = roce5_convert_be32(new_cqe->dw1.value);
+
+ /* Get the next CQE */
+ ret = roce5_cq_get_next_cqe(&cqe, cq, &i, ×, start_cqe);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Convert DW0/DW1 of CQE to little endian */
+ cqe->dw0.value = roce5_convert_cpu32(cqe->dw0.value);
+ cqe->dw1.value = roce5_convert_cpu32(cqe->dw1.value);
+ }
+
+ return 0;
+}
+
+static int roce5_uni_cmd_cq_resize_inbuf_fill(struct roce5_device *rdev,
+ struct roce5_cq *rcq,
+ int page_shift,
+ cqm_cmd_buf_s **cqm_cmd_inbuf)
+{
+ int ret = 0;
+ struct dev_roce_svc_own_cap *rdma_own_cap = NULL;
+ u32 cq_size = 0;
+ u32 mtt_layer = 0;
+ u64 mtt_paddr = 0;
+ u32 mtt_page_size = 0;
+ roce_uni_cmd_resize_cq_s *cq_resize_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_resize_cq_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ rdma_own_cap = &rdev->rdma_cap.dev_rdma_cap.roce_own_cap;
+ cq_size = (u32)rcq->resize_buf->cqe + ROCE_CQE_UP_THRESHOLD;
+ cq_size = (u32)ROCE_ILOG2(cq_size);
+ mtt_layer = rcq->resize_buf->buf.mtt.mtt_layers;
+ mtt_paddr = rcq->resize_buf->buf.mtt.mtt_paddr;
+ mtt_page_size = rcq->resize_buf->buf.mtt.mtt_page_shift - PAGE_SHIFT_4K;
+
+ cq_resize_inbuf = (roce_uni_cmd_resize_cq_s *)(*cqm_cmd_inbuf)->buf;
+ cq_resize_inbuf->com.index = cpu_to_be32(rcq->cqn);
+ cq_resize_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_CQ_BITMASK));
+ if (rcq->shadow != 0) {
+ cq_resize_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_resize_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rcq->shadow_vfid);
+ }
+ cq_resize_inbuf->cq_resize.page_size = cpu_to_be32((u32)page_shift);
+ cq_resize_inbuf->cq_resize.log_cq_size = cpu_to_be32(cq_size);
+ cq_resize_inbuf->cq_resize.mtt_layer_num = cpu_to_be32(mtt_layer);
+ cq_resize_inbuf->cq_resize.mtt_base_addr = mtt_paddr;
+ cq_resize_inbuf->cq_resize.mtt_base_addr =
+ cpu_to_be64(cq_resize_inbuf->cq_resize.mtt_base_addr);
+ cq_resize_inbuf->cq_resize.mtt_page_size = cpu_to_be32(mtt_page_size);
+
+ cq_resize_inbuf->cq_resize.cmtt_cache.mtt_flags = 0;
+ cq_resize_inbuf->cq_resize.cmtt_cache.mtt_num = 0;
+ cq_resize_inbuf->cq_resize.cmtt_cache.mtt_cache_line_start =
+ cpu_to_be32(rdma_own_cap->cmtt_cl_start);
+ cq_resize_inbuf->cq_resize.cmtt_cache.mtt_cache_line_end =
+ cpu_to_be32(rdma_own_cap->cmtt_cl_end);
+ cq_resize_inbuf->cq_resize.cmtt_cache.mtt_cache_line_size =
+ cpu_to_be32(rdma_own_cap->cmtt_cl_sz);
+ return 0;
+}
+
+static int roce5_cq_resize(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int page_shift)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+
+ if (ROCE5_SUPPORT_IB_CMD_RESIZE_CQ_MSG_V2(rdev) != 0) {
+ ret = roce5_uni_cmd_cq_resize_inbuf_fill(rdev, rcq, page_shift,
+ &cqm_cmd_inbuf);
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_RESIZE_CQ, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RESIZE_CQ command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+
+ /* When CMDq times out or CMDq cannot work, update the device status and notify the PCIe module to reset
+ the device through OFED */
+ if ((ret == -ETIMEDOUT) || (ret == -EPERM)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_user_cq_resize
+ Description : roce5_user_cq_resize
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_user_cq_resize(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int entries, struct ib_udata *udata)
+{
+ int page_shift = 0;
+ int ret = 0;
+
+ /* Cannot exceed max size after power-of-2 alignment */
+ if (entries > ((int)rdev->rdma_cap.max_cqes + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(rdev, "Over range after align, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ ret = roce5_cq_alloc_resize_umem(rdev, rcq, entries, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc resize_umem, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+#if defined(UMEM_HAVE_PAGE_SHIFT)
+ page_shift = rcq->resize_umem->page_shift - PAGE_SHIFT_4K;
+#else
+ page_shift = PAGE_SHIFT - PAGE_SHIFT_4K;
+#endif
+
+ /* Send the cq_resize command to configure CQC. After the configuration is successful, the new CQE is written to
+ resize_buf, and the old buffer may still retain the old CQE. */
+ ret = roce5_cq_resize(rdev, rcq, page_shift);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to resize cq, func_id(%d)",
+ rdev->glb_func_id);
+ roce5_cq_free_resize_umem(rdev, rcq);
+ return ret;
+ }
+
+ rcq->ibcq.cqe = rcq->resize_buf->cqe;
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_resize_user_cq
+ Description : roce5_resize_user_cq
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_resize_user_cq(struct roce5_device *rdev, struct roce5_cq *rcq,
+ int entries, struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_resize_cq_cmd ucmd = { 0 };
+ int cqe_entries = entries;
+
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy from user space, func_id(%d)",
+ rdev->glb_func_id);
+ return -EFAULT;
+ }
+
+ mutex_lock(&rcq->resize_mutex);
+
+ if (ucmd.stage == 1) {
+ goto release_flow;
+ }
+
+ /* The CQE queue should reserve four special CQE for the HOST CI can be updated to the CQC CI */
+ cqe_entries += ROCE_CQE_UP_THRESHOLD;
+ cqe_entries =
+ (int)(ROCE_ROUNDUP_POW_OF_TWO((u32)cqe_entries) & 0xffffffff);
+ //Minimum queue depth needs to be aligned by page
+ if ((u32)(cqe_entries * (int)rdev->rdma_cap.cqe_size) < PAGE_SIZE) {
+ cqe_entries =
+ (int)(PAGE_SIZE >> (unsigned int)ROCE_ILOG2(
+ rdev->rdma_cap.cqe_size));
+ }
+ if (cqe_entries == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid cqe_entries after align, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EINVAL;
+ goto out;
+ }
+ rcq->cqe_mask = cqe_entries - 1;
+
+ /* The new depth of CQ cannot be the same as the old depth. Four special CQE space is reserved when CQ is created,
+ so the value of ibcq->cqe is 4 smaller than the actual value */
+ if (cqe_entries == (rcq->ibcq.cqe + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(rdev, "No need to resize cq, func_id(%d)",
+ rdev->glb_func_id);
+ ret = 0;
+ goto out;
+ }
+
+ ret = roce5_user_cq_resize(rdev, rcq, cqe_entries, udata);
+ if (ret != 0) {
+ goto out;
+ }
+
+ mutex_unlock(&rcq->resize_mutex);
+
+ return 0;
+
+release_flow:
+ /* free old MTT */
+ hmm_mtt_free(rdev->hwdev, &rcq->buf.mtt, SERVICE_T_ROCE);
+
+ rcq->buf = rcq->resize_buf->buf;
+ ib_umem_release(rcq->umem);
+ rcq->umem = rcq->resize_umem;
+
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+ rcq->resize_umem = NULL;
+
+out:
+ mutex_unlock(&rcq->resize_mutex);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_kernel_cq_resize
+ Description : roce5_kernel_cq_resize
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_kernel_cq_resize(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int entries)
+{
+ int outst_cqe = 0;
+ int page_shift = 0;
+ int ret = 0;
+
+ /* Cannot exceed max size after power-of-2 alignment */
+ if (entries > ((int)rdev->rdma_cap.max_cqes + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(rdev, "Over range after align, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ /* The number of resized CQEs cannot be smaller than the number of outstanding CQEs */
+ outst_cqe = roce5_cq_get_outstanding_cqes(rcq);
+ if (entries < (outst_cqe + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't resize, because smaller than the number of outstanding CQES, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ ret = roce5_cq_alloc_resize_buf(rdev, rcq, entries);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc resize buffer, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ page_shift = (int)ROCE_ILOG2(rcq->cqm_cq->q_room_buf_2.buf_size) -
+ PAGE_SHIFT_4K;
+
+ /* Send the cq_resize command to configure CQC. After the configuration is successful, the new CQE is written to
+ resize_buf, and the old buffer may still retain the old CQE. */
+ ret = roce5_cq_resize(rdev, rcq, page_shift);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to resize cq, func_id(%d)",
+ rdev->glb_func_id);
+ roce5_cq_free_resize_buf(rdev, rcq);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_resize_kernel_cq
+ Description : roce5_resize_kernel_cq
+ Input : struct roce5_device *rdev
+ struct roce5_cq *rcq
+ int entries
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_resize_kernel_cq(struct roce5_device *rdev,
+ struct roce5_cq *rcq, int entries)
+{
+ int ret = 0;
+ int old_cqe = 0;
+ struct mtt old_mtt;
+ int cqe_entries = entries;
+
+ mutex_lock(&rcq->resize_mutex);
+
+ cqe_entries += ROCE_CQE_UP_THRESHOLD;
+ cqe_entries =
+ (int)(ROCE_ROUNDUP_POW_OF_TWO((u32)cqe_entries) & 0xffffffff);
+ /* Minimum queue depth needs to be aligned by page */
+ if ((u32)(cqe_entries * (int)rdev->rdma_cap.cqe_size) < PAGE_SIZE) {
+ cqe_entries = (PAGE_SIZE >> (unsigned int)ROCE_ILOG2(
+ rdev->rdma_cap.cqe_size));
+ }
+
+ /* The new depth of CQ cannot be the same as the old depth. Four special CQE space is reserved when CQ is created,
+ so the value of ibcq->cqe is four smaller than the actual value */
+ if (cqe_entries == (rcq->ibcq.cqe + ROCE_CQE_UP_THRESHOLD)) {
+ ROCE_DEV_ERR(rdev, "No need to resize cq, func_id(%d)",
+ rdev->glb_func_id);
+ mutex_unlock(&rcq->resize_mutex);
+ return 0;
+ }
+
+ ret = roce5_kernel_cq_resize(rdev, rcq, cqe_entries);
+ if (ret != 0) {
+ goto out;
+ }
+
+ /* free old MTT */
+ old_mtt = rcq->buf.mtt;
+
+ /* When copying CQE from the old buffer to resize_buf, the user may be polling cqe from the old buf, so
+ it needs to be locked.If CQE of the old buffer has been polled in the polling process, polling process will
+ free old buffer and switch to new buffer.
+ */
+ spin_lock_irq(&rcq->lock);
+
+ /* If the new buf has been switched to, nothing needs to be done */
+ if (rcq->resize_buf != NULL) {
+ ret = roce5_cq_resize_copy_cqes(rcq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Have not polled resize cqe(fuc:%d, cqn:%u, ret:%d)",
+ rdev->glb_func_id, rcq->cqn, ret);
+ roce5_cq_free_resize_buf(rdev, rcq);
+ spin_unlock_irq(&rcq->lock);
+ mutex_unlock(&rcq->resize_mutex);
+ return ret;
+ }
+ old_cqe = rcq->ibcq.cqe;
+ rcq->buf = rcq->resize_buf->buf;
+ rcq->ibcq.cqe = rcq->resize_buf->cqe;
+
+ kfree(rcq->resize_buf);
+ rcq->resize_buf = NULL;
+ }
+
+ spin_unlock_irq(&rcq->lock);
+
+ /* Non-0 means that the above resize_buf non-empty branch has been entered, the old buffer needs to be released */
+ if (old_cqe != 0) {
+ hmm_mtt_free(rdev->hwdev, &old_mtt, SERVICE_T_ROCE);
+ cqm5_object_resize_free_old(&rcq->cqm_cq->object);
+ }
+
+out:
+ mutex_unlock(&rcq->resize_mutex);
+
+ return ret;
+}
+
+static int roce5_resize_cq_check(struct ib_cq *ibcq, int entries,
+ const struct ib_udata *udata)
+{
+ struct roce5_device *rdev = NULL;
+
+ if (ibcq == NULL) {
+ ROCE_ERR("Ibcq is null");
+ return -EINVAL;
+ }
+
+ if ((ibcq->uobject != NULL) && (udata == NULL)) {
+ ROCE_ERR("Udata is null, but uobject is not null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibcq->device);
+ if ((entries < 1) || (entries > (int)rdev->rdma_cap.max_cqes)) {
+ ROCE_DEV_ERR(rdev,
+ "Resize CQEs invalid. entries(%d), func_id(%d)",
+ entries, rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_resize_cq
+ Description : roce5_resize_cq
+ Input : struct ib_cq *ibcq
+ int entries
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_cq *rcq = NULL;
+ struct roce5_device *rdev = NULL;
+
+ ret = roce5_resize_cq_check(ibcq, entries, udata);
+ if (ret != 0) {
+ ROCE_ERR("Failed to check resize_cq");
+ return ret;
+ }
+
+ rcq = to_roce5_cq(ibcq);
+ rdev = to_roce5_dev(ibcq->device);
+
+ if (ibcq->uobject) {
+ ret = roce5_resize_user_cq(rdev, rcq, entries, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to resize user cq, func_id(%u) ret(%d)",
+ (u32)rdev->glb_func_id, ret);
+ return ret;
+ }
+ } else {
+ ret = roce5_resize_kernel_cq(rdev, rcq, entries);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to resize kernel cq, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void roce5_lock_cqs(struct roce5_cq *roce5_send_cq,
+ struct roce5_cq *roce5_recv_cq)
+ __acquires(&roce5_send_cq->lock) __acquires(&roce5_recv_cq->lock)
+{
+ if (roce5_send_cq == roce5_recv_cq) {
+ spin_lock_irq(&roce5_send_cq->lock);
+ __acquire(&roce5_recv_cq->lock);
+ } else if (roce5_send_cq->cqn < roce5_recv_cq->cqn) {
+ spin_lock_irq(&roce5_send_cq->lock);
+ spin_lock_nested(&roce5_recv_cq->lock, SINGLE_DEPTH_NESTING);
+ } else {
+ spin_lock_irq(&roce5_recv_cq->lock);
+ spin_lock_nested(&roce5_send_cq->lock, SINGLE_DEPTH_NESTING);
+ }
+}
+
+void roce5_unlock_cqs(struct roce5_cq *roce5_send_cq,
+ struct roce5_cq *roce5_recv_cq)
+ __releases(&roce5_send_cq->lock) __releases(&roce5_recv_cq->lock)
+{
+ if (roce5_send_cq == roce5_recv_cq) {
+ __release(&roce5_recv_cq->lock);
+ spin_unlock_irq(&roce5_send_cq->lock);
+ } else if (roce5_send_cq->cqn < roce5_recv_cq->cqn) {
+ spin_unlock(&roce5_recv_cq->lock);
+ spin_unlock_irq(&roce5_send_cq->lock);
+ } else {
+ spin_unlock(&roce5_send_cq->lock);
+ spin_unlock_irq(&roce5_recv_cq->lock);
+ }
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_destroy.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_destroy.c
new file mode 100644
index 000000000..c4e442598
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_destroy.c
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+
+#include "roce.h"
+#include "roce_srq.h"
+#include "roce_qp.h"
+#include "roce_mix.h"
+#include "roce_xrc.h"
+#include "roce_cq.h"
+#include "roce_cqm_cmd.h"
+#include "roce_npu_cmd.h"
+#include "hinic5_hmm.h"
+#include "securec.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_compat.h"
+#include "roce_os_compat.h"
+#include "roce_cq_intern.h"
+#include "roce_com.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_uld_inner.h"
+
+/* and above next is V100 adaptation data structure */
+typedef struct tag_roce_cmd_cq_cache_invalidate {
+ roce_verbs_cmd_com_s com;
+ roce_xq_mtt_info_s mtt_info;
+} roce_cmd_cq_cache_invalidate_s;
+#define CQC_CHECK_RESCHED_LOOP_TIMES 0xffffU
+static int roce5_check_cqc_data_state(struct roce5_device *rdev,
+ const struct roce5_cq *cq,
+ struct roce5_cq_context *cqc_data,
+ u32 check_state)
+{
+ int read_back_flag = 0;
+ u32 times = (u32)rdev->try_times;
+ struct roce5_cq_context check_cqc_data;
+ while ((times--) != 0) {
+ check_cqc_data.dw2.value = be32_to_cpu(cqc_data->dw2.value);
+ if (check_cqc_data.dw2.bs.state == check_state) {
+ read_back_flag = 1;
+ break;
+ }
+ ROCE_DELAY();
+
+ // limit schedule cond_resched count, preventstop thread schedule frequency past high
+ if ((times & CQC_CHECK_RESCHED_LOOP_TIMES) == 0) {
+ cond_resched();
+ }
+ }
+
+ if (read_back_flag == 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to read back after try %d times, Cqn(0x%x), CQ state(0x%x), func_id(%u)",
+ rdev->try_times, cq->cqn, cqc_data->dw2.value,
+ (u32)rdev->glb_func_id);
+ return -1;
+ }
+
+ return 0;
+}
+/* ****************************************************************************
+ Prototype : roce5_cq_hw2sw
+ Description : roce5_cq_hw2sw
+ Input : struct roce5_device *rdev
+ struct roce5_cq *cq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_cq_hw2sw(struct roce5_device *rdev, struct roce5_cq *cq)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ struct roce5_cq_context *cqc_data = NULL;
+ roce_uni_cmd_cq_hw2sw_s *cq_hw2sw_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_cq_hw2sw_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ cq_hw2sw_inbuf = (roce_uni_cmd_cq_hw2sw_s *)cqm_cmd_inbuf->buf;
+ cq_hw2sw_inbuf->com.index = cpu_to_be32((u32)cq->cqn);
+ cq_hw2sw_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_CQ_BITMASK);
+ if (cq->shadow != 0) {
+ cq_hw2sw_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_hw2sw_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(cq->shadow_vfid);
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE, ROCE_CMD_HW2SW_CQ,
+ cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send HW2SW_CQ command, func_id(%u), cqn(0x%x), (ret:%d)",
+ (u32)rdev->glb_func_id, cq->cqn, ret);
+
+ ret = (-EINVAL);
+
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Card not present, return OK, func_id(%d)",
+ rdev->glb_func_id);
+ ret = 0;
+ }
+
+ /* CMDq may return a positive number, so its return value cannot be used directly */
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ /* HI1825_V100 will retry load cqc in cmdq */
+ if (ROCE5_SUPPORT_RETRY_LOAD_CQC_MSG_FEATURE(rdev) != 0) {
+ cqc_data = (struct roce5_cq_context *)((void *)cq->cqm_cq
+ ->q_ctx_vaddr);
+ return roce5_check_cqc_data_state(rdev, cq, cqc_data,
+ ROCE_CQ_TIME_OUT_CHECK_VALUE);
+ }
+ return 0;
+}
+
+static int roce5_uni_cmd_cq_cache_out(struct roce5_device *rdev,
+ struct roce5_cq *cq,
+ cqm_cmd_buf_s **cqm_cmd_inbuf)
+{
+ int ret = 0;
+ struct dev_roce_svc_own_cap *roce_own_cap = NULL;
+ roce_uni_cmd_cq_hw2sw_s *cq_cache_invld_inbuf = NULL;
+
+ /* Send the cache out command */
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_cq_hw2sw_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ roce_own_cap = &rdev->rdma_cap.dev_rdma_cap.roce_own_cap;
+ cq_cache_invld_inbuf = (roce_uni_cmd_cq_hw2sw_s *)(*cqm_cmd_inbuf)->buf;
+ cq_cache_invld_inbuf->com.index = cpu_to_be32((u32)cq->cqn);
+ cq_cache_invld_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_CQ_BITMASK));
+ if (cq->shadow != 0) {
+ cq_cache_invld_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_cache_invld_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(cq->shadow_vfid);
+ }
+ cq_cache_invld_inbuf->cmtt_cache.mtt_flags = 0;
+ cq_cache_invld_inbuf->cmtt_cache.mtt_num = 0;
+ cq_cache_invld_inbuf->cmtt_cache.mtt_cache_line_start =
+ cpu_to_be32(roce_own_cap->cmtt_cl_start);
+ cq_cache_invld_inbuf->cmtt_cache.mtt_cache_line_end =
+ cpu_to_be32(roce_own_cap->cmtt_cl_end);
+ cq_cache_invld_inbuf->cmtt_cache.mtt_cache_line_size =
+ cpu_to_be32(roce_own_cap->cmtt_cl_sz);
+
+ return 0;
+}
+
+static int roce5_cq_cache_out(struct roce5_device *rdev, struct roce5_cq *cq)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+
+ if (ROCE5_SUPPORT_CQ_CACHE_OUT_MSG_V2(rdev) != 0) {
+ ret = roce5_uni_cmd_cq_cache_out(rdev, cq, &cqm_cmd_inbuf);
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_MISC_CQ_CACHE_INVLD, cqm_cmd_inbuf,
+ NULL, NULL, ROCE_CMD_TIME_CLASS_A,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send CQ_CACHE_INVLD command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Card not present, return OK, func_id(%d)",
+ rdev->glb_func_id);
+ return 0;
+ }
+
+ return -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return 0;
+}
+
+int roce5_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_device *rdev = NULL;
+ struct roce5_cq *rcq = NULL;
+ struct roce5_ucontext *ucontext = NULL;
+ char waiting_msg[ROCE_WAITING_MSG_MAX_SIZE];
+ roce_user_handle_t hdl = { 0 };
+
+ if (ibcq == NULL) {
+ ROCE_ERR("Ibcq is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibcq->device);
+ rcq = to_roce5_cq(ibcq);
+
+ ret = sprintf_s(waiting_msg, ROCE_WAITING_MSG_MAX_SIZE,
+ "Waiting for roce cq(%u) release...", rcq->cqn);
+ if (ret < 0) {
+ ROCE_DEV_WARN(rdev, "Failed to setup waiting message, ret(%d).",
+ ret);
+ }
+
+ roce5_option_unset(rcq->opt, waiting_msg, sizeof(waiting_msg));
+
+ /* Modify CQC to be owned by the software */
+ ret = roce5_cq_hw2sw(rdev, rcq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify CQC, ret(%d), func_id(%d), cqn(0x%x)",
+ ret, rdev->glb_func_id, rcq->cqn);
+ return ret;
+ }
+
+ /* Send the cache out command */
+ ret = roce5_cq_cache_out(rdev, rcq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send cache out command, ret(%d), func_id(%hu)",
+ ret, rdev->glb_func_id);
+ return ret;
+ }
+
+ ROCE_CONSTUCT_ULD_HDL_RCQ(&hdl, rdev, rcq, NULL, NULL, NULL, 0);
+ roce5_uld_cq_destroy((roce_uld_handle)&hdl);
+
+ /* If it is user mode, you also need to cancel the mapping of the corresponding software DB */
+ if (ibcq->uobject != NULL) {
+ ucontext = roce5_queue_to_ucontext((void *)ibcq, udata,
+ ROCE_Q_TYPE_CQ);
+ roce5_db_unmap_user(ucontext, &rcq->db, rcq->shadow);
+ roce5_cq_put_umem(rdev, &rcq->buf, &rcq->umem, rcq->shadow);
+ } else {
+ hmm_mtt_free(rdev->hwdev, &rcq->buf.mtt, SERVICE_T_ROCE);
+ }
+
+ roce5_destroy_cq_dealloc_cqn(rdev, rcq);
+ return 0;
+}
+
+int roce5_destroy_cq_ofa(struct ib_cq *ibcq)
+{
+ int ret = 0;
+ struct roce5_cq *rcq = NULL;
+
+ if (ibcq == NULL) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ ret = roce5_destroy_cq(ibcq, NULL);
+ if (ret == 0) {
+ rcq = to_roce5_cq(ibcq);
+ kfree(rcq);
+ }
+
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_format.h b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_format.h
new file mode 100644
index 000000000..3c1cb6640
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_format.h
@@ -0,0 +1,29 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_CQ_FORMAT_H
+#define ROCE_CQ_FORMAT_H
+
+#include <linux/types.h>
+
+#include "roce_qp_ctx_format.h"
+
+typedef struct roce5_cq_context {
+ u32 rsvd[2];
+ union {
+ struct {
+ u32 rsvd : 28;
+ u32 state : 4;
+ } bs;
+ u32 value;
+ } dw2;
+
+ u32 rsvd1[12];
+
+ struct roce5_qpc_timer_seg timer_seg;
+
+ u32 rsvd2[8];
+} roce5_cq_context_s;
+
+#endif /* ROCE_CQ_FORMAT_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.c b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.c
new file mode 100644
index 000000000..119fafba9
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.c
@@ -0,0 +1,98 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "hinic5_hw.h"
+#include "securec.h"
+
+#include "roce.h"
+#include "roce_user.h"
+#include "roce_cq.h"
+#include "roce_os_compat.h"
+#include "roce_cq_intern.h"
+
+/*
+ * high performance cq, based on reserved of cq, first to firstget get.
+ * 特 point: supports 23V200 & 25V100 two types NIC, according to device type different to allocate different of cq.
+ * later get of cq so bind qp performance will has so next decrease.
+*/
+
+#define ROCE_CQN_PERF_BASE 1
+
+int roce5_create_cq_alloc_cqn(struct roce5_device *rdev, struct roce5_cq *rcq,
+ u32 index)
+{
+ u32 cqn = index;
+ u32 offset = ROCE_CQN_PERF_BASE;
+ u32 step = rdev->cqn_ctrl.rsvd_cq_step;
+ u32 rsvd_cqs = rdev->rdma_cap.dev_rdma_cap.roce_own_cap.reserved_cqs;
+
+ mutex_lock(&rdev->cqn_ctrl.cq_ctrl_mutex);
+
+ if (rdev->cqn_ctrl.alloc_cq_cnt == rdev->cqn_ctrl.high_perf_cq_cnt) {
+ /* The reserved high performance CQs have been fully allocated. */
+ goto cqn_alloc;
+ }
+
+ while (rdev->cqn_ctrl.alloc_cq_cnt < rdev->cqn_ctrl.high_perf_cq_cnt &&
+ (offset < rsvd_cqs)) {
+ if (test_and_set_bit(offset, &rdev->cqn_ctrl.cq_bitmap) != 0) {
+ offset += step;
+ continue;
+ }
+ cqn = offset;
+ rdev->cqn_ctrl.alloc_cq_cnt++;
+ ROCE_DEV_INFO(
+ rdev,
+ "Alloc High performance CQ, func_id(%d), total_high_perf_cq(%u), cqn(%d)",
+ rdev->glb_func_id, rdev->cqn_ctrl.alloc_cq_cnt, cqn);
+ break;
+ }
+
+cqn_alloc:
+ mutex_unlock(&rdev->cqn_ctrl.cq_ctrl_mutex);
+
+ rcq->cqm_cq = cqm5_object_rdma_queue_create(rdev->hwdev, SERVICE_T_ROCE,
+ CQM_OBJECT_RDMA_SCQ, 0,
+ rcq->opt, false, cqn, 0, 0);
+ if (rcq->cqm_cq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create rdma queue from cqm object, func_id(%d), index(%d)",
+ rdev->glb_func_id, index);
+ return -ENOMEM;
+ }
+
+ rcq->cqn = rcq->cqm_cq->index;
+
+ return 0;
+}
+
+void roce5_destroy_cq_dealloc_cqn(struct roce5_device *rdev,
+ struct roce5_cq *rcq)
+{
+ u32 cqn = rcq->cqn;
+ u32 rsvd_cqs = rdev->rdma_cap.dev_rdma_cap.roce_own_cap.reserved_cqs;
+ /* Call the CQM interface to release CQN and CQC. Since there is no cq_buf and software DB in user mode,
+ it does not need to be released; since kernel mode has both, it needs to be released */
+ cqm5_object_delete(&rcq->cqm_cq->object);
+ kfree(rcq->opt);
+ rcq->opt = NULL;
+
+ mutex_lock(&rdev->cqn_ctrl.cq_ctrl_mutex);
+
+ if ((cqn < rsvd_cqs) &&
+ test_and_clear_bit(cqn, &rdev->cqn_ctrl.cq_bitmap) != 0 &&
+ rdev->cqn_ctrl.alloc_cq_cnt > 0) {
+ rdev->cqn_ctrl.alloc_cq_cnt--;
+ ROCE_DEV_INFO(
+ rdev,
+ "Dealloc High performance CQ, func_id(%d), total_high_perf_cq(%u), cqn(%d)",
+ rdev->glb_func_id, rdev->cqn_ctrl.alloc_cq_cnt, cqn);
+ }
+ mutex_unlock(&rdev->cqn_ctrl.cq_ctrl_mutex);
+
+ return;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.h b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.h
new file mode 100644
index 000000000..a2cb56943
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/cq/roce_cq_intern.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_CQ_INTERN_H
+#define ROCE_CQ_INTERN_H
+
+#include <rdma/ib_verbs.h>
+
+#include "hinic5_hw.h"
+#include "hinic5_rdma.h"
+#include "hinic5_cqm.h"
+
+#include "roce.h"
+#include "roce_cq.h"
+
+#define ROCE_CQN_INVLD CQM_INDEX_INVALID
+
+int roce5_create_cq_alloc_cqn(struct roce5_device *rdev, struct roce5_cq *rcq,
+ u32 index);
+void roce5_destroy_cq_dealloc_cqn(struct roce5_device *rdev,
+ struct roce5_cq *rcq);
+
+#endif //ROCE_CQ_INTERN_H
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.c b/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.c
new file mode 100644
index 000000000..0ce3ffb25
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.c
@@ -0,0 +1,437 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_event_extension.h"
+#include "roce_aeq_format.h"
+#include "hinic5_mt.h"
+#include "roce_restore.h"
+#include "roce_infra.h"
+#include "roce_cq.h"
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+#include "roce_event.h"
+
+static void roce5_event_report_common(const struct roce5_device *rdev,
+ int event_str_index)
+{
+ switch (event_str_index) {
+ case OFED_ET_PATH_MIG:
+ ROCE_DEV_INFO_LIMIT(rdev,
+ "OFED event: Path mig. function id: %hu",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_COMM_EST:
+ ROCE_INFO_ONCE(
+ "OFED event: Communication establish. function id: %hu",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_SQ_DRAINED:
+ ROCE_DEV_ERR_LIMIT(rdev,
+ "OFED event: Sq drained. function id: %hu",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_SRQ_QP_LAST_WQE:
+ ROCE_ERR_ONCE("OFED event: Srq/qp last wqe. function id: %hu",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_WQ_CATAS_ERR:
+ ROCE_DEV_ERR_LIMIT(
+ rdev, "OFED event: Wq catas error. function id: %hu",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_PATH_MIG_FAILED:
+ ROCE_DEV_ERR_LIMIT(
+ rdev, "OFED event: Path mig failed. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_WQ_INVAL_REQ_ERR:
+ ROCE_DEV_ERR_LIMIT(
+ rdev, "OFED event: Wq inval req error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_WQ_ACCESS_ERR:
+ ROCE_DEV_ERR_LIMIT(
+ rdev, "OFED event: Wq access error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_CQ_ERR:
+ ROCE_DEV_ERR_LIMIT(rdev,
+ "OFED event: Cq error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_SRQ_LIMIT:
+ ROCE_DEV_ERR_LIMIT(rdev,
+ "OFED event: Srq limit. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case OFED_ET_SRQ_CATAS_ERR:
+ ROCE_DEV_ERR_LIMIT(
+ rdev, "OFED event: Srq catas error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case NON_OFED_ET_QPC_LOOKUP_ERR:
+ ROCE_DEV_ERR_LIMIT(
+ rdev,
+ "[non ofed event type] Qpc lookup error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ case NON_OFED_ET_OTHER_TYPE_ERR:
+ ROCE_ERR_ONCE(
+ "[non ofed event type] other type error. function id: %u",
+ rdev->glb_func_id);
+ break;
+ default:
+ break;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_event_report
+ Description : roce5_event_report
+ Input : struct roce5_device *rdev
+ int event_str_index
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_event_report(struct roce5_device *rdev, u8 *val,
+ int event_str_index)
+{
+ if (event_str_index <= NON_OFED_ET_OTHER_TYPE_ERR) {
+ roce5_event_report_common(rdev, event_str_index);
+ } else {
+ roce5_event_report_extend(rdev, val, event_str_index);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : to_qp_event_str_index
+ Description : to_qp_event_str_index
+ Input : u8 event_type
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int to_qp_event_str_index(u8 event_type)
+{
+ switch (event_type) {
+ case ROCE_EVENT_TYPE_PATH_MIG:
+ return OFED_ET_PATH_MIG;
+
+ case ROCE_EVENT_TYPE_COMM_EST:
+ return OFED_ET_COMM_EST;
+
+ case ROCE_EVENT_TYPE_SQ_DRAINED:
+ return OFED_ET_SQ_DRAINED;
+
+ case ROCE_EVENT_TYPE_SRQ_QP_LAST_WQE:
+ return OFED_ET_SRQ_QP_LAST_WQE;
+
+ case ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+ return OFED_ET_WQ_CATAS_ERR;
+
+ case ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+ return OFED_ET_PATH_MIG_FAILED;
+
+ case ROCE_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+ return OFED_ET_WQ_INVAL_REQ_ERR;
+
+ default:
+ return OFED_ET_WQ_ACCESS_ERR;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_handle_qp_async_event
+ Description : roce5_handle_qp_async_event
+ Input : struct roce5_device *rdev
+ u32 qpn
+ u8 event_type
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_handle_qp_async_event(struct roce5_device *rdev, u32 qpn,
+ u8 event_type)
+{
+ struct roce5_qp *rqp = NULL;
+ cqm_object_s *cqm_obj_queue = NULL;
+
+ cqm_obj_queue = cqm5_object_get(rdev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ qpn, false);
+ if (cqm_obj_queue == NULL) {
+ ROCE_DEV_ERR_LIMIT(
+ rdev,
+ "Failed to get cqm obj queue, func_id(%d), qpn:%u, event_type:%u",
+ rdev->glb_func_id, qpn, event_type);
+ return;
+ }
+
+ rqp = cqmobj_to_roce_qp(cqm_obj_queue);
+ roce5_qp_async_event(rdev, rqp, (int)event_type);
+ cqm5_object_put(cqm_obj_queue);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_handle_cq_async_event
+ Description : roce5_handle_cq_async_event
+ Input : struct roce5_device *rdev
+ u32 cqn
+ u8 event_type
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_handle_cq_async_event(struct roce5_device *rdev, u32 cqn,
+ u8 event_type)
+{
+ struct roce5_cq *rcq = NULL;
+
+ rcq = roce5_get_rcq_by_cqn(rdev, cqn);
+ if (rcq == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to get roce cq by cqn(%u).", cqn);
+ return;
+ }
+
+ roce5_cq_async_event(rdev, rcq, (int)event_type);
+ roce5_rcq_put(rcq);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_handle_srq_async_event
+ Description : roce5_handle_srq_async_event
+ Input : struct roce5_device *rdev
+ u32 srqn
+ u8 event_type
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_handle_srq_async_event(struct roce5_device *rdev, u32 srqn,
+ u8 event_type)
+{
+ struct roce5_srq *rsrq = NULL;
+ cqm_object_s *cqm_obj_queue = NULL;
+
+ cqm_obj_queue =
+ cqm5_object_get(rdev->hwdev, CQM_OBJECT_RDMA_SRQ, srqn, false);
+ if (cqm_obj_queue == NULL) {
+ ROCE_DEV_ERR_LIMIT(
+ rdev,
+ "Failed to get cqm obj queue, func_id(%d), srqn:%u, event_type:%u",
+ rdev->glb_func_id, srqn, event_type);
+ return;
+ }
+
+ rsrq = cqmobj_to_roce5_srq(cqm_obj_queue);
+ roce5_srq_async_event(rdev, rsrq, (int)event_type);
+ cqm5_object_put(cqm_obj_queue);
+}
+
+static bool roce5_async_event_need_reset(u8 event_status)
+{
+ if ((event_status == API_FORMAT_ERROR) ||
+ (event_status == UNKNOWN_RESERVED_ERROR1)) {
+ return true;
+ }
+
+ return false;
+}
+
+u8 roce5_async_event_level(void *svc_hd, u8 event_type, u8 *val)
+{
+ u8 event_level = FAULT_LEVEL_MAX;
+ u8 event_status;
+ u64 param = *((u64 *)val);
+
+ if (svc_hd == NULL) {
+ ROCE_ERR_LIMIT("Svc_hd is null");
+ return FAULT_LEVEL_SUGGESTION;
+ }
+
+ event_status = param & 0xff;
+
+ switch (event_type) {
+ case ROCE_EVENT_TYPE_PATH_MIG:
+ case ROCE_EVENT_TYPE_COMM_EST:
+ case ROCE_EVENT_TYPE_SQ_DRAINED:
+ case ROCE_EVENT_TYPE_SRQ_QP_LAST_WQE:
+ case ROCE_EVENT_TYPE_SRQ_LIMIT:
+ case ROCE_EVENT_TYPE_DEBUG:
+ event_level = FAULT_LEVEL_SUGGESTION;
+ break;
+
+ case ROCE_EVENT_TYPE_LOCAL_CATAS_ERROR:
+ case ROCE_EVENT_TYPE_WQ_INVAL_REQ_ERROR: //ROCE_AEQE_EVENT_QP_REQ_ERR
+ if (event_status == API_FORMAT_ERROR) {
+ return FAULT_LEVEL_SERIOUS_RESET;
+ }
+ break;
+
+ case ROCE_EVENT_TYPE_WQ_CATAS_ERROR: //ROCE_AEQE_EVENT_WQE_CATAS
+ if (roce5_async_event_need_reset(event_status)) {
+ return FAULT_LEVEL_SERIOUS_RESET;
+ }
+ break;
+
+ case ROCE_EVENT_TYPE_CQ_ERROR: //CQ ERR
+ if (roce5_async_event_need_reset(event_status)) {
+ return FAULT_LEVEL_SERIOUS_RESET;
+ }
+ break;
+
+ default:
+ event_level = FAULT_LEVEL_GENERAL;
+ break;
+ }
+
+ return event_level;
+}
+
+static int roce5_async_event_handle_common(u8 event_type, u8 *val,
+ struct roce5_device *rdev)
+{
+ u32 xid = 0;
+ int event_str_index = 0;
+
+ switch (event_type) {
+ case ROCE_EVENT_TYPE_PATH_MIG:
+ case ROCE_EVENT_TYPE_COMM_EST:
+ case ROCE_EVENT_TYPE_SQ_DRAINED:
+ case ROCE_EVENT_TYPE_SRQ_QP_LAST_WQE:
+ case ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+ case ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+ case ROCE_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+ case ROCE_EVENT_TYPE_WQ_ACCESS_ERROR:
+ xid = *((u32 *)val);
+ roce5_handle_qp_async_event(rdev, xid, event_type);
+ event_str_index = to_qp_event_str_index(event_type);
+ break;
+
+ case ROCE_EVENT_TYPE_CQ_ERROR:
+ xid = *((u32 *)val);
+ roce5_handle_cq_async_event(rdev, xid, event_type);
+ event_str_index = OFED_ET_CQ_ERR;
+ break;
+
+ case ROCE_EVENT_TYPE_SRQ_LIMIT:
+ xid = *((u32 *)val);
+ roce5_handle_srq_async_event(rdev, xid, event_type);
+ event_str_index = OFED_ET_SRQ_LIMIT;
+ break;
+
+ case ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
+ xid = *((u32 *)val);
+ roce5_handle_srq_async_event(rdev, xid, event_type);
+ event_str_index = OFED_ET_SRQ_CATAS_ERR;
+ break;
+
+ default:
+ event_str_index = to_unkown_event_str_index(event_type, val);
+ break;
+ }
+
+ return event_str_index;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_async_event
+ Description : roce5_async_event
+ Input : void *svc_hd
+ u8 event_type
+ u64 val
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_async_event(void *svc_hd, u8 event_type, u8 *val)
+{
+ int event_str_index = 0;
+ struct roce5_device *rdev = NULL;
+
+ if (svc_hd == NULL) {
+ ROCE_ERR_LIMIT("Svc_hd is null");
+ return;
+ }
+
+ rdev = (struct roce5_device *)svc_hd;
+ if (event_type <= ROCE_EVENT_TYPE_ODP_PAGE_FAULT) {
+ event_str_index =
+ roce5_async_event_handle_common(event_type, val, rdev);
+ } else {
+ event_str_index =
+ roce5_async_event_handle_extend(event_type, val, rdev);
+ }
+
+ roce5_event_report(rdev, val, event_str_index);
+}
+
+#ifdef ROCE_BONDING_EN
+void roce5_handle_bonded_port_state_event(struct roce5_device *rdev)
+{
+ struct net_device *master = netdev_master_upper_dev_get_rcu(rdev->ndev);
+ enum ib_port_state bonded_port_state = IB_PORT_NOP;
+ struct roce5_bond_device *bond_dev = NULL;
+ enum ib_port_state curr_port_state;
+ enum ib_event_type event;
+ struct roce5_bond_slave *slave = NULL;
+ u32 i;
+
+ bond_dev = rdev->bond_dev;
+ if (bond_dev == NULL) {
+ ROCE_DEV_ERR(rdev, "No bond_dev found");
+ return;
+ }
+
+ if (master == NULL) {
+ bonded_port_state = IB_PORT_DOWN;
+ } else {
+ if (netif_running(master) != 0) {
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ slave = &bond_dev->slaves[i];
+ if (slave->netdev == NULL) {
+ continue;
+ }
+
+ curr_port_state =
+ (netif_running(slave->netdev) &&
+ netif_carrier_ok(slave->netdev)) ?
+ IB_PORT_ACTIVE :
+ IB_PORT_DOWN;
+ bonded_port_state =
+ (bonded_port_state != IB_PORT_ACTIVE) ?
+ curr_port_state :
+ IB_PORT_ACTIVE;
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ } else {
+ bonded_port_state = IB_PORT_DOWN;
+ }
+ }
+
+ if (rdev->port_state != bonded_port_state) {
+ event = (bonded_port_state == IB_PORT_ACTIVE) ?
+ IB_EVENT_PORT_ACTIVE :
+ IB_EVENT_PORT_ERR;
+ if (rdev->port_state != IB_PORT_NOP) {
+ roce5_ifconfig_up_down_event_report(rdev, event);
+ }
+ rdev->port_state = bonded_port_state;
+ }
+}
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.h b/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.h
new file mode 100644
index 000000000..b5acc9b15
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/event/roce_event.h
@@ -0,0 +1,25 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_EVENT_H
+#define ROCE_EVENT_H
+
+#include <linux/types.h>
+
+#define ROCE_M_DELAY 100
+#define API_FORMAT_ERROR 0x2
+#define UNKNOWN_RESERVED_ERROR1 0xe
+#define QPC_LOOKUP_ERR_VALUE 0x300d00016
+
+struct roce5_aeqe_event_data {
+ u32 xid;
+
+ //microcode side by ROCE_AEQE_EVENT construct, driver side byte order differs from microcode side
+ u32 err_code : 8;
+ u32 type : 12;
+ u32 subtype : 8;
+ u32 module_type : 4;
+};
+
+#endif /* ROCE_EVENT_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_event_extension.c b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_event_extension.c
new file mode 100644
index 000000000..c33bab11a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_event_extension.c
@@ -0,0 +1,56 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+
+
+#include <linux/types.h>
+
+#include "roce_event_extension.h"
+#include "roce_aeq_format.h"
+
+int to_unkown_event_str_index(uint8_t event_type, const uint8_t *val)
+{
+ switch (event_type) {
+ case ROCE_EVENT_TYPE_OFED_NO_DEF:
+ if (*((u64 *)val) == QPC_LOOKUP_ERR_VALUE) {
+ return NON_OFED_ET_QPC_LOOKUP_ERR;
+ }
+ return NON_OFED_ET_OTHER_TYPE_ERR;
+
+ case ROCE_EVENT_TYPE_LOCAL_CATAS_ERROR:
+ return NON_OFED_ET_OTHER_TYPE_ERR;
+
+ case ROCE_EVENT_TYPE_DEBUG:
+ return NON_OFED_ET_DEBUG_ERR;
+
+ default:
+ return INVAL_ET_ERR;
+ }
+}
+
+void roce5_event_report_extend(const struct roce5_device *rdev, u8 *val,
+ int event_str_index)
+{
+ if (event_str_index == NON_OFED_ET_DEBUG_ERR) {
+ struct roce5_aeqe_event_data *data =
+ (struct roce5_aeqe_event_data *)val;
+ /* debug subtype according to ROCE_AEQE_DEBUG_SUBTYPE_E */
+ ROCE_ERR_ONCE(
+ "[non ofed event type] Debug extend event subtype 0x%x. function id: %u",
+ data->subtype, rdev->glb_func_id);
+ return;
+ }
+
+ ROCE_ERR_ONCE(
+ "[non ofed event type] Invalid extend event type error. function id: %u",
+ rdev->glb_func_id);
+}
+
+int roce5_async_event_handle_extend(u8 event_type, u8 *val,
+ struct roce5_device *rdev)
+{
+ int event_str_index = 0;
+
+ event_str_index = to_unkown_event_str_index(event_type, val);
+
+ return event_str_index;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_main_extension.c b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_main_extension.c
new file mode 100644
index 000000000..759ba598f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_main_extension.c
@@ -0,0 +1,170 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_main_extension.h"
+#include "roce_infra.h"
+#include "roce_os_compat.h"
+#include "roce_kernel_compat_gen.h"
+
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+
+static struct mutex g_rdev_mutex;
+#endif
+
+void roce5_service_init_pre(void)
+{
+#ifdef ROCE_BONDING_EN
+ mutex_init(&g_rdev_mutex);
+#endif
+
+ return;
+}
+
+void roce5_lock_rdev(void)
+{
+#ifdef ROCE_BONDING_EN
+ mutex_lock(&g_rdev_mutex);
+#endif
+}
+
+void roce5_unlock_rdev(void)
+{
+#ifdef ROCE_BONDING_EN
+ mutex_unlock(&g_rdev_mutex);
+#endif
+}
+
+int roce5_get_rdev_by_uld(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ struct roce5_device **rdev,
+ struct hinic5_event_info *event)
+{
+#ifdef ROCE_BONDING_EN
+ int ret;
+
+ ret = roce5_bond_event_cfg_rdev(lld_dev, uld_dev, rdev, false);
+ if (ret != 0) {
+ return -1;
+ }
+#else
+ *rdev = (struct roce5_device *)uld_dev;
+#endif
+ return 0;
+}
+
+#ifndef ROCE_CHIP_TEST
+void roce5_init_dev_ext_handlers(struct roce5_device *rdev)
+{
+ return;
+}
+#endif
+
+int roce5_board_cfg_check(struct roce5_device *rdev)
+{
+ int ret = 0;
+ int port_num = 0;
+ int port_speed = 0;
+
+ port_num = rdev->board_info.port_num;
+ port_speed = rdev->board_info.port_speed;
+ if ((port_num == ROCE5_2_PORT_NUM) &&
+ (port_speed == ROCE5_100G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_2_100G_HCA;
+ } else if ((port_num == ROCE5_4_PORT_NUM) &&
+ (port_speed == ROCE5_25G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_4_25G_HCA;
+ } else if ((port_num == ROCE5_2_PORT_NUM) &&
+ (port_speed == ROCE5_25G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_2_25G_HCA;
+ } else if ((port_num == ROCE5_1_PORT_NUM) &&
+ (port_speed == ROCE5_100G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_1_100G_HCA;
+ } else if ((port_num == ROCE5_2_PORT_NUM) &&
+ (port_speed == ROCE5_200G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_2_200G_HCA;
+ } else if ((port_num == ROCE5_2_PORT_NUM) &&
+ (port_speed == ROCE5_400G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_2_400G_HCA;
+ } else if ((port_num == ROCE5_4_PORT_NUM) &&
+ (port_speed == ROCE5_200G_PORT_SPEED)) {
+ rdev->hw_info.hca_type = ROCE5_4_200G_HCA;
+ } else {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid fw cfg, port_num(%d), port_speed(%d), hca_type(%d)",
+ port_num, port_speed, rdev->hw_info.hca_type);
+ ret = (-EINVAL);
+ }
+
+ return ret;
+}
+
+void *roce5_rdev_alloc_ext(void)
+{
+#if defined(HAVE__IB_ALLOC_DEVICE)
+ return (void *)ib_alloc_device(roce5_device, ib_dev);
+#else
+ return (void *)ib_alloc_device(sizeof(struct roce5_device));
+#endif
+}
+
+int roce5_set_comm_event(const struct roce5_device *rdev,
+ const struct hinic5_event_info *event)
+{
+ ROCE_DEV_INFO(rdev, "Comm event unsupported, func_id(%d), event(%d)",
+ rdev->glb_func_id, event->type);
+ return -1;
+}
+
+struct roce5_ucontext *
+roce5_queue_to_ucontext(void *ibq, struct ib_udata *udata, int q_type)
+{
+ struct roce5_ucontext *rctx = NULL;
+
+#if defined(UVERBS_IOCTL_HAVE_RDMA_UDATA_TO_DRV_CONTEXT)
+ rctx = rdma_udata_to_drv_context(udata, struct roce5_ucontext,
+ ibucontext);
+#else
+ struct ib_qp *ibqp = NULL;
+ struct ib_cq *ibcq = NULL;
+ struct ib_srq *ibsrq = NULL;
+ switch (q_type) {
+ case ROCE_Q_TYPE_QP:
+ ibqp = (struct ib_qp *)ibq;
+ rctx = to_roce5_ucontext(ibqp->uobject->context);
+ break;
+ case ROCE_Q_TYPE_CQ:
+ ibcq = (struct ib_cq *)ibq;
+ rctx = to_roce5_ucontext(ibcq->uobject->context);
+ break;
+ case ROCE_Q_TYPE_SRQ:
+ ibsrq = (struct ib_srq *)ibq;
+ rctx = to_roce5_ucontext(ibsrq->uobject->context);
+ break;
+ default:
+ ROCE_ERR("Unknown queue type(%d)", q_type);
+ break;
+ }
+#endif
+ return rctx;
+}
+
+#ifndef ROCE_VROCE_EN
+void roce5_fill_gid_entry_ext(const struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ return;
+}
+
+void roce5_cfg_info_update_ext(struct roce5_device *rdev,
+ roce_get_cfg_info_resp_s *resp)
+{
+ return;
+}
+
+int roce5_add_check_ext(const struct hinic5_lld_dev *lld_dev)
+{
+ return 0;
+}
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_mr_extension.c b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_mr_extension.c
new file mode 100644
index 000000000..7f2e14669
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_mr_extension.c
@@ -0,0 +1,40 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+#include "roce_mr.h"
+#include "roce_kernel_compat_gen.h"
+#include "roce_main_extension.h"
+#include "roce_mr_extension.h"
+
+#ifndef ROCE_CHIP_TEST
+int roce5_check_alloc_mr_type(enum ib_mr_type mr_type)
+{
+ int ret = 0;
+
+ if (mr_type != IB_MR_TYPE_MEM_REG) {
+ ret = -EINVAL;
+ ROCE_ERR("mr_type is invalid. mr_type:%u", mr_type);
+ }
+
+ return ret;
+}
+
+enum rdma_mr_type roce5_get_mrtype(enum ib_mr_type ib_mr_type)
+{
+ switch (ib_mr_type) {
+#if defined(IB_MR_TYPE_HAVE_USER) && defined(IB_MR_TYPE_HAVE_INTEGRITY)
+ case IB_MR_TYPE_MEM_REG:
+ return RDMA_FRMR;
+ case IB_MR_TYPE_USER:
+ return RDMA_USER_MR;
+ case IB_MR_TYPE_INTEGRITY:
+ return RDMA_SIG_MR;
+#else
+ case IB_MR_TYPE_MEM_REG:
+ return RDMA_DMA_MR;
+#endif
+ default:
+ return RDMA_DMA_MR;
+ }
+}
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_qp_extension.c b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_qp_extension.c
new file mode 100644
index 000000000..0e0170e9d
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_qp_extension.c
@@ -0,0 +1,222 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_qp_extension.h"
+#include "roce_ctx_format.h"
+#include "roce_restore.h"
+
+#ifdef ROCE_EXTEND
+#include "roce_pd.h"
+#endif
+
+int to_roce5_qp_type(enum ib_qp_type qp_type)
+{
+ switch (qp_type) {
+ case IB_QPT_RC:
+ return ROCE_QP_ST_RC;
+
+ case IB_QPT_UC:
+ return ROCE_QP_ST_UC;
+
+ case IB_QPT_UD:
+ return ROCE_QP_ST_UD;
+
+ case IB_QPT_XRC_INI:
+ case IB_QPT_XRC_TGT:
+ return ROCE_QP_ST_XRC;
+
+ case IB_QPT_GSI:
+ return ROCE_QP_ST_UD;
+
+ default:
+ return -1;
+ }
+}
+
+bool roce5_check_qp_modify_ok(enum ib_qp_state cur_state,
+ enum ib_qp_state next_state, enum ib_qp_type type,
+ enum ib_qp_attr_mask mask,
+ enum rdma_link_layer ll)
+{
+#if defined(IB_MODIFY_QP_IS_OK_HAVE_RDMA_LINK_LAYER)
+ return (bool)ib_modify_qp_is_ok(cur_state, next_state, type, mask, ll);
+#else
+ return (bool)ib_modify_qp_is_ok(cur_state, next_state, type, mask);
+#endif
+}
+
+int roce5_is_qp_normal(struct roce5_qp *rqp, struct ib_qp_init_attr *init_attr)
+{
+ return 1;
+}
+
+#ifdef ROCE_EXTEND
+static struct roce5_qp *
+roce5_cdev_lookup_and_check_rqp(struct roce5_device *rdev, u32 qpn)
+{
+ struct roce5_qp *rqp = NULL;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Can't find rqp according to qpn(0x%x), func_id(%d)",
+ qpn, rdev->glb_func_id);
+ return NULL;
+ }
+
+ if (rqp->qpn >= QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC) {
+ ROCE_DEV_ERR(rdev,
+ "qpn[%u] more than sqpc num offset(%d) for sqpc.",
+ rqp->qpn, QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC);
+ roce5_rqp_put(rqp);
+ return NULL;
+ }
+
+ return rqp;
+}
+
+static int roce5_alloc_sqpc(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct roce5_vbs_qp *vbs_rqp)
+{
+ cqm_qpc_mpt_s *qpc_info = NULL;
+
+ /* Call the CQM interface to allocate QPNs and QPCs */
+ /* For SQPC, do not need to allocate QPN, QPN is directly spcified in rsvd segment */
+ qpc_info = cqm5_object_qpc_mpt_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_SERVICE_CTX,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.qpc_entry_sz, NULL,
+ rqp->qpn + QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC, 0, 0);
+ if (qpc_info == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create qpc by cqm object, func_id(%d), qpn(%u)",
+ rdev->glb_func_id,
+ rqp->qpn + QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC);
+ return -ENOMEM;
+ }
+
+ if (qpc_info->xid != (rqp->qpn + QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Create qpc error, func_id(%d), expect qpn(%d), actual qpn(%d)",
+ rdev->glb_func_id,
+ rqp->qpn + QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC,
+ qpc_info->xid);
+ cqm5_object_delete(&(qpc_info->object));
+ return -EFAULT;
+ }
+
+ vbs_rqp->vbs_sqpc_info = qpc_info;
+ rqp->vbs_qp_ptr = (void *)vbs_rqp;
+
+ return 0;
+}
+
+long roce5_vbs_create_sqpc(struct roce5_device *rdev, void *buf)
+{
+ struct roce5_modify_qp_vbs_cmd cmd;
+ struct roce5_vbs_qp *vbs_rqp = NULL;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_pd *pd = NULL;
+ int ret;
+
+ ret = (int)copy_from_user(&cmd, buf, sizeof(cmd));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to copy data from user");
+ return (long)ret;
+ }
+
+ rqp = roce5_cdev_lookup_and_check_rqp(rdev, cmd.qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp");
+ return -EINVAL;
+ }
+
+ vbs_rqp = (struct roce5_vbs_qp *)kzalloc(sizeof(*vbs_rqp), GFP_KERNEL);
+ if (vbs_rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc vbs_rqp, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -ENOMEM;
+ goto put_rqp;
+ }
+
+ pd = roce5_get_pd(rqp);
+ ret = roce5_db_map_user(to_roce5_ucontext(pd->ibpd.uobject->context),
+ cmd.ci_record_addr, &vbs_rqp->db, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to map db page to user, func_id(%d)",
+ rdev->glb_func_id);
+ goto free_rqp;
+ }
+
+ ret = roce5_alloc_sqpc(rdev, rqp, vbs_rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc sqpc, func_id(%d)",
+ rdev->glb_func_id);
+ goto free_rqp;
+ }
+
+ roce5_rqp_put(rqp);
+ return 0;
+
+free_rqp:
+ kfree(vbs_rqp);
+put_rqp:
+ roce5_rqp_put(rqp);
+ return (long)ret;
+}
+#endif
+
+#ifndef ROCE_CHIP_TEST
+void roce5_set_qp_dif_attr(struct roce5_qp *rqp,
+ const struct ib_qp_init_attr *init_attr,
+ const struct roce5_device *rdev)
+{
+ if (((unsigned int)init_attr->create_flags &
+ IB_QP_CREATE_SIGNATURE_EN) != 0) {
+ rqp->signature_en = true;
+ ROCE_DEV_INFO(rdev,
+ "func(%d) qp(%u) roce5_create_qp signature_en.",
+ rdev->glb_func_id, rqp->qpn);
+ }
+ return;
+}
+#endif
+
+#ifndef ROCE_VBS_EN
+void roce5_set_attr_ext(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr, int attr_mask)
+{
+ return;
+}
+
+void roce5_transmit_ci_record_addr_ext(struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ return;
+}
+#endif
+
+#ifndef ROCE_VBS_EN
+int roce5_modify_qp_pre_ext(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata)
+{
+ return 0;
+}
+
+void roce5_destroy_pcqc_ext(struct roce5_qp *rqp)
+{
+ return;
+}
+
+#endif
+
+#ifndef ROCE_VROCE_EN
+
+void roce5_cos_update_ext(struct roce5_device *rdev, u8 *cos,
+ enum ib_qp_type qp_type)
+{
+ *cos = *cos & 0x7;
+}
+#endif
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_srq_extension.c b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_srq_extension.c
new file mode 100644
index 000000000..7067e8c80
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/extension/roce_srq_extension.c
@@ -0,0 +1,55 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+#include "roce_srq_extension.h"
+
+u8 roce5_get_container_sz(u32 container_mode)
+{
+ switch (container_mode) {
+ case ROCE_SRQ_MODE_0:
+ return ROCE_SRQ_CONT_NUM_MODE0;
+ case ROCE_SRQ_MODE_1:
+ return ROCE_SRQ_CONT_NUM_MODE1;
+ case ROCE_SRQ_MODE_2:
+ return ROCE_SRQ_CONT_NUM_MODE2;
+ case ROCE_SRQ_MODE_3:
+ return ROCE_SRQ_CONT_NUM_MODE3;
+ default:
+ return ROCE_SRQ_CONT_NUM_MODE3;
+ }
+}
+
+u8 roce5_calculate_cont_th(u32 srq_limit)
+{
+ u8 cont_th = 0;
+ u32 srq_limit_tmp = srq_limit;
+
+ srq_limit_tmp >>= 1;
+ while (srq_limit_tmp != 0) {
+ srq_limit_tmp >>= 1;
+ ++cont_th;
+ }
+
+ return cont_th;
+}
+
+#ifndef ROCE_CHIP_TEST
+void roce5_srq_container_init(struct ib_srq_init_attr *init_attr,
+ struct roce5_srq *rsrq, struct roce5_device *rdev)
+{
+ rsrq->xrc_en = (init_attr->srq_type == IB_SRQT_XRC);
+
+ if (rsrq->xrc_en != 0) {
+ rsrq->container_flag = rdev->cfg_info.srq_container_en;
+ }
+ rsrq->container_mode = (rsrq->xrc_en != 0) ?
+ rdev->cfg_info.xrc_srq_container_mode :
+ rdev->cfg_info.srq_container_mode;
+ rsrq->container_warn_th =
+ roce5_calculate_cont_th(init_attr->attr.srq_limit);
+ rsrq->rqe_cnt_th = rdev->cfg_info.warn_th;
+ rsrq->container_size = roce5_get_container_sz(rsrq->container_mode);
+}
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.c b/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.c
new file mode 100644
index 000000000..f7f9117f4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.c
@@ -0,0 +1,1281 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_mr.h"
+#include "roce_mr_extension.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "rdma_comp_mw_mr.h"
+#include "hmm_common.h"
+#include "roce_os_compat.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_uld_inner.h"
+
+/* ****************************************************************************
+ Prototype : get_key_from_index
+ Description : get_key_from_index
+ Input : u32 mpt_index
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static u32 get_key_from_index(u32 mpt_index)
+{
+ /* Algorithm of mr key is obtained by index shift calculation */
+ return (mpt_index >> MR_KEY_RIGHT_SHIFT_OFS) |
+ (mpt_index << MR_KEY_LEFT_SHIFT_OFS);
+}
+
+/* ****************************************************************************
+ Prototype : convert_ib_access
+ Description : convert ib access to rdma comp access
+ Input : int access_flag
+ Output : None
+
+ 1.Date : 2015/7/16
+ Modification : Created function
+
+**************************************************************************** */
+static u32 convert_ib_access(int access_flag)
+{
+ u32 u_access_flag = (u32)access_flag;
+ u32 access;
+
+ access = (u32)((((u_access_flag & IB_ACCESS_REMOTE_ATOMIC) != 0) ?
+ RDMA_IB_ACCESS_REMOTE_ATOMIC :
+ 0) |
+ (((u_access_flag & IB_ACCESS_REMOTE_WRITE) != 0) ?
+ RDMA_IB_ACCESS_REMOTE_WRITE :
+ 0) |
+ (((u_access_flag & IB_ACCESS_REMOTE_READ) != 0) ?
+ RDMA_IB_ACCESS_REMOTE_READ :
+ 0) |
+ (((u_access_flag & IB_ACCESS_LOCAL_WRITE) != 0) ?
+ RDMA_IB_ACCESS_LOCAL_WRITE :
+ 0) |
+ (((u_access_flag & IB_ACCESS_MW_BIND) != 0) ?
+ RDMA_IB_ACCESS_MW_BIND :
+ 0) |
+ (((u_access_flag & IB_ZERO_BASED) != 0) ?
+ RDMA_IB_ACCESS_ZERO_BASED :
+ 0));
+
+ return access;
+}
+
+/* ****************************************************************************
+ Prototype : check_ib_access
+ Description : check remote access without local write
+ Input : int access_flag
+ Output : None
+
+ 1.Date : 2017/11/18
+ Modification : Created function
+
+**************************************************************************** */
+static int check_ib_access(int access_flag)
+{
+ /*
+ * Local write permission is required if remote write or
+ * remote atomic permission is also requested.
+ */
+
+ if (((((u32)access_flag) &
+ (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE)) != 0) &&
+ ((((u32)access_flag) & IB_ACCESS_LOCAL_WRITE) == 0)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+u32 roce5_get_mpt_xid_mode(struct roce5_device *rdev)
+{
+ u8 mode = rdev->mpt_xid_mode;
+
+ if (mode == ROCE_MPT_XID_SEQUENTIAL)
+ return CQM_INDEX_INVALID;
+
+ return CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_ALL, CQM_XID_LOW_BIT_0_0_1,
+ (u32)mode);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_alloc_tpt
+ Description : alloc mpt and mtt
+ Input : struct roce5_device *rdev
+ struct hmm_rdma *mr
+ u32 npages
+ u32 page_shift
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_alloc_tpt(struct roce5_device *rdev, struct hmm_rdma *mr, u32 npages,
+ u32 page_shift, u32 mpt_xid_mode)
+{
+ int ret = 0;
+
+ ret = hmm_mpt_alloc_templated(rdev->hwdev, &mr->mpt, SERVICE_T_ROCE,
+ mpt_xid_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mpt, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ return ret;
+ }
+
+ mr->enabled = RDMA_MPT_EN_SW;
+
+ /* npages = 0 is a legal case, when npages = 0 or npages = 1, MTT does not need to do address translation */
+ ret = hmm_mtt_alloc(rdev->hwdev, npages, page_shift, &mr->mtt,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mtt, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto err_alloc_mtt;
+ }
+
+ return 0;
+
+err_alloc_mtt:
+ hmm_mpt_free(rdev->hwdev, &mr->mpt);
+ mr->enabled = RDMA_MPT_DISABLED;
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_free_tpt
+ Description : free mpt and mtt
+ Input : struct roce5_device *rdev
+ struct hmm_rdma *mr
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_free_tpt(struct roce5_device *rdev, struct hmm_rdma *mr)
+{
+ hmm_mtt_free(rdev->hwdev, &mr->mtt, SERVICE_T_ROCE);
+
+ hmm_mpt_free(rdev->hwdev, &mr->mpt);
+
+ mr->enabled = RDMA_MPT_DISABLED;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_rdma_mr
+ Description : set the member of rdma_mr
+ Input : struct hmm_rdma *mr
+ enum rdma_mr_type mr_type
+ u32 pdn
+ u64 iova
+ u64 size
+ u32 access
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_set_rdma_mr(struct hmm_rdma *mr, enum rdma_mr_type mr_type, u32 pdn,
+ u64 iova, u64 size, u32 access)
+{
+ mr->iova = iova;
+ mr->size = size;
+ mr->pdn = pdn;
+ mr->access = convert_ib_access((
+ int)access); /* Convert ib permissions to rdma component permissions */
+ mr->key = get_key_from_index(
+ mr->mpt.mpt_index); /* Convert from mpt index to key */
+ mr->type = roce5_mr_type2hmm(mr_type);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_rdma_mw
+ Description : set the member of rdma_mw
+ Input : struct rdma_mw *mw
+ u32 pdn
+ enum ib_mw_type type
+ Output : None
+
+ 1.Date : 2016/6/25
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_set_rdma_mw(struct rdma_mw *mw, u32 pdn, enum ib_mw_type type)
+{
+ mw->enabled = RDMA_MPT_EN_SW;
+ mw->pdn = pdn;
+ mw->key = get_key_from_index(mw->mpt.mpt_index);
+ mw->type = (type == IB_MW_TYPE_1 ? RDMA_MW_TYPE_1 : RDMA_MW_TYPE_2);
+}
+#ifdef __ROCE_DFX__
+static void roce5_store_mr_list(struct roce5_device *rdev,
+ struct list_head *node)
+{
+ struct roce5_list *roce_list = NULL;
+
+ if (rdev->device_res == NULL) {
+ ROCE_INFO("Hasn't been created resource, don't need store.");
+ return;
+ }
+
+ roce_list = &rdev->device_res->mr_list;
+ mutex_lock(&roce_list->node_lock);
+ list_add(node, &roce_list->node);
+ mutex_unlock(&roce_list->node_lock);
+}
+
+static void roce5_delete_mr_list(struct roce5_device *rdev,
+ struct list_head *node)
+{
+ struct roce5_list *roce_list = NULL;
+
+ if (rdev->device_res == NULL) {
+ ROCE_INFO("Resource has been release, don't need delete.");
+ return;
+ }
+
+ roce_list = &rdev->device_res->mr_list;
+ mutex_lock(&roce_list->node_lock);
+ list_del(node);
+ mutex_unlock(&roce_list->node_lock);
+}
+#endif //__ROCE_DFX__
+
+/* ****************************************************************************
+ Prototype : roce5_get_dma_mr
+ Description : register DMA_MR
+ Input : struct ib_pd *ibpd
+ int access
+ Output : None
+
+ 1.Date : 2015/4/24
+ Modification : Created function
+
+**************************************************************************** */
+struct ib_mr *roce5_get_dma_mr(struct ib_pd *ibpd, int access)
+{
+ int ret = 0;
+ u32 mpt_xid_mode;
+ struct roce5_mr *mr = NULL;
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if ((ibpd == NULL) || (check_ib_access(access) != 0)) {
+ ret = -EINVAL;
+ ROCE_ERR("Invalid Param.p1:%d", access);
+ goto err_out;
+ }
+
+ pd = to_roce5_pd(ibpd);
+ rdev = to_roce5_dev(ibpd->device);
+
+ mr = (struct roce5_mr *)kzalloc(sizeof *mr, GFP_KERNEL);
+ if (mr == NULL) {
+ ret = -ENOMEM;
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc memory for dma mr, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_out;
+ }
+
+ mr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+ mpt_xid_mode = roce5_get_mpt_xid_mode(rdev);
+ ret = roce5_alloc_tpt(rdev, &mr->rdmamr, 0, 0, mpt_xid_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mpt and mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_alloc_tpt;
+ }
+
+ /* Set the content in rdma_mr */
+ roce5_set_rdma_mr(&mr->rdmamr, RDMA_DMA_MR, pd->pdn, 0ULL,
+ ROCE_DMA_MR_SIZE, (u32)access);
+
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, &(mr->rdmamr),
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to enable mpt of DMA mr, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_enable_mpt;
+ }
+#ifdef __ROCE_DFX__
+ roce5_store_mr_list(rdev, &mr->node);
+#endif
+ mr->ibmr.lkey = mr->rdmamr.key;
+ mr->ibmr.rkey = mr->rdmamr.key;
+ mr->ibmr.device = ibpd->device;
+
+ ROCE_DEV_INFO(rdev, "Roce reg dma mr success, mr mpt index is %u",
+ mr->rdmamr.mpt.mpt_index);
+
+ return &mr->ibmr;
+
+err_enable_mpt:
+ roce5_free_tpt(rdev, &mr->rdmamr);
+
+err_alloc_tpt:
+ kfree(mr);
+
+err_out:
+ return (struct ib_mr *)ERR_PTR((long)ret);
+}
+
+static int roce5_alloc_priv_pages(struct ib_device *ibdev, struct roce5_mr *rmr,
+ u32 max_pages)
+{
+ int ret;
+
+ rmr->page_map_size =
+ roundup(max_pages * sizeof(u64), ROCE5_MR_PAGES_ALIGN);
+ rmr->pages = (__be64 *)(void *)(uintptr_t)get_zeroed_page(GFP_KERNEL);
+ if (rmr->pages == NULL) {
+ ROCE_ERR("Failed to alloc rmr->pages");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ rmr->page_map = dma_map_single(ibdev->dev.parent, rmr->pages,
+ rmr->page_map_size, DMA_TO_DEVICE);
+ if (dma_mapping_error(ibdev->dev.parent, rmr->page_map) != 0) {
+ ROCE_ERR("Failed to do dma mapping");
+ ret = -ENOMEM;
+ goto err_free_pages;
+ }
+
+ return 0;
+
+err_free_pages:
+ free_page((unsigned long)(uintptr_t)(void *)rmr->pages);
+
+err_out:
+ return ret;
+}
+
+void roce5_free_frmr_umem(struct ib_umem **fumem, int fumem_nr)
+{
+ int i;
+
+ ROCE_INFO("%d frmr umems to be free.", fumem_nr);
+ for (i = 0; i < fumem_nr; i++) {
+ ib_umem_release(fumem[i]);
+ }
+}
+
+static void roce5_free_priv_pages(struct roce5_mr *rmr)
+{
+ struct ib_device *ib_dev = rmr->ibmr.device;
+
+ if (rmr->pages != NULL) {
+ ib_dev = rmr->ibmr.device;
+ dma_unmap_single(ib_dev->dev.parent, rmr->page_map,
+ rmr->page_map_size, DMA_TO_DEVICE);
+ free_page((unsigned long)(uintptr_t)(void *)rmr->pages);
+ rmr->pages = NULL;
+ }
+}
+
+static int roce5_alloc_mr_param_validate(const struct ib_pd *ibpd,
+ enum ib_mr_type mr_type,
+ u32 max_num_sg)
+{
+ int ret = 0;
+
+ if (ibpd == NULL) {
+ ret = -EINVAL;
+ ROCE_ERR("Ibpd is null");
+ goto err_out;
+ }
+
+ ret = roce5_check_alloc_mr_type(mr_type);
+ if (ret != 0) {
+ ret = -EINVAL;
+ ROCE_ERR("mr_type is invalid");
+ goto err_out;
+ }
+
+ if (max_num_sg >= ROCE_FRMR_MAX_PAGES) {
+ ROCE_ERR("Invalid max_num_sg(%d)", max_num_sg);
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ return ret;
+}
+
+static int roce5_alloc_mr_param_check(struct roce5_device *rdev,
+ struct roce5_mr **mr, u32 max_num_sg)
+{
+ *mr = (struct roce5_mr *)kzalloc(sizeof(struct roce5_mr), GFP_KERNEL);
+ if ((*mr) == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mr memory, func(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ (*mr)->max_pages = max_num_sg;
+ return 0;
+}
+/* ****************************************************************************
+ Prototype : roce5_alloc_mr
+ Description : register DMA_MR
+ Input : struct ib_pd *ibpd
+ enum ib_mr_type mr_type
+ u32 max_num_sg
+ Output : None
+
+ 1.Date : 2015/4/24
+ Modification : Created function
+
+**************************************************************************** */
+struct ib_mr *roce5_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ u32 max_num_sg)
+{
+ int ret = 0;
+ u16 sign_val = 0;
+ u32 mpt_xid_mode;
+ struct roce5_mr *mr = NULL;
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+
+ ret = roce5_alloc_mr_param_validate(ibpd, mr_type, max_num_sg);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ pd = to_roce5_pd(ibpd);
+ rdev = to_roce5_dev(ibpd->device);
+
+ ret = roce5_alloc_mr_param_check(rdev, &mr, max_num_sg);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ mr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+ mpt_xid_mode = roce5_get_mpt_xid_mode(rdev);
+
+ ret = roce5_alloc_tpt(rdev, &mr->rdmamr, max_num_sg, 0,
+ mpt_xid_mode); //alloc mptc and mtt
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc tpt, func(%d)",
+ rdev->glb_func_id);
+ goto err_alloc_tpt;
+ }
+
+ ret = roce5_alloc_priv_pages(ibpd->device, mr,
+ max_num_sg); //alloc memory to store pa
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc memory, func(%u)",
+ rdev->glb_func_id);
+ goto err_alloc_priv_pages;
+ }
+
+ roce5_set_rdma_mr(&mr->rdmamr, roce5_get_mrtype(mr_type), pd->pdn, 0ULL,
+ max_num_sg * (1 << PAGE_SHIFT),
+ ROCE5_MR_DEFAULT_ACCESS);
+
+#ifdef SIGN_MTT_EN
+ /*
+ MTT table entry of bit[11:2] used for fill in addr_signature, to hardware used for check MTT table entry complete validity. [1:1] is vmr, indicates current page whether be swap out.
+ bit[0:0] is vld bit indicates pointed by of next one level DMTT or Data Buffer of GPA whether valid. use sign_val record [11:0] this 12bit data, exist mr in.
+ send down frmr wqe after chip will do dma use pbl table fill MTT table, here need in advance calculate check value, in roce5_set_page() in write pbl table.
+ */
+ sign_val = (u16)(hmm_gen_mtt_sign(mr->rdmamr.mtt.mtt_paddr,
+ mr->rdmamr.mtt.mtt_type) &
+ 0xffff);
+#endif
+ mr->sign_val = ((sign_val << 1) | MTT_PA_VALID);
+
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, &(mr->rdmamr),
+ HINIC5_CHANNEL_ROCE); // send to chip by cmdq
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to enable mpt, func(%d)",
+ rdev->glb_func_id);
+ goto err_enale_mpt;
+ }
+
+#ifdef __ROCE_DFX__
+ roce5_store_mr_list(rdev, &mr->node);
+#endif
+
+ mr->ibmr.lkey = mr->rdmamr.key;
+ mr->ibmr.rkey = mr->rdmamr.key;
+
+ return &mr->ibmr;
+
+err_enale_mpt:
+ roce5_free_priv_pages(mr);
+
+err_alloc_priv_pages:
+ roce5_free_tpt(rdev, &mr->rdmamr);
+
+err_alloc_tpt:
+ kfree(mr);
+
+err_out:
+ return (struct ib_mr *)ERR_PTR((long)ret);
+}
+
+static int roce5_set_page(struct ib_mr *ibmr, u64 addr)
+{
+ struct roce5_mr *rmr = NULL;
+
+ if (ibmr == NULL) {
+ ROCE_ERR("Ibmr is null");
+ return -EINVAL;
+ }
+
+ rmr = to_roce5_mr(ibmr);
+ if (ROCE_UNLIKELY(rmr->npages >= rmr->max_pages)) {
+ ROCE_ERR("Invalid npages(0x%x), can't set page", rmr->npages);
+ return -ENOMEM;
+ }
+
+ rmr->pages[rmr->npages] = cpu_to_be64(addr | rmr->sign_val);
+ rmr->npages++;
+
+ return 0;
+}
+
+/* RoCE supports FRMR, for at privileged user, can via post send WR of way for at at free status of MR perform fast register.
+ here need in advance via input parameter of sgl available physical page 整 理 in pbl table 里, later via frmr wqe send down. */
+int roce5_map_kernel_frmr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
+ int sg_nents, unsigned int *sg_offset)
+{
+ int ret;
+ struct roce5_mr *rmr = NULL;
+
+ /* sg_offset can be null */
+ if ((ibmr == NULL) || (sg == NULL)) {
+ ROCE_ERR("Ibmr or sg is null");
+ return -EINVAL;
+ }
+
+ rmr = to_roce5_mr(ibmr);
+ rmr->npages = 0;
+
+ if (ROCE_UNLIKELY(((u32)sg_nents) > rmr->max_pages)) {
+ ROCE_ERR("Invalid sg_nents(0x%x), max(0x%x)", sg_nents,
+ rmr->max_pages);
+ return -EINVAL;
+ }
+
+ ib_dma_sync_single_for_cpu(ibmr->device, rmr->page_map,
+ rmr->page_map_size, DMA_TO_DEVICE);
+
+ ret = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, roce5_set_page);
+
+ ib_dma_sync_single_for_device(ibmr->device, rmr->page_map,
+ rmr->page_map_size, DMA_TO_DEVICE);
+
+ return ret;
+}
+
+static int roce5_umem_write_mtt_check(const struct roce5_device *rdev,
+ const struct mtt *mtt,
+ const struct ib_umem *umem)
+{
+ if ((rdev == NULL) || (mtt == NULL) || (umem == NULL)) {
+ ROCE_ERR("Rdev or mtt or umem is null");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_umem_write_mtt_update(struct roce5_device *rdev,
+ struct mtt *mtt, struct ib_umem *umem,
+ u64 *page_list, bool use_huge)
+{
+ int ret = 0;
+ u32 npages = 0; /* The number of recorded pages */
+ u32 start_index = 0; /* page need to be written to mtt */
+ struct ib_block_iter biter;
+
+ rdma_umem_for_each_dma_block(umem, &biter, BIT(mtt->buf_page_shift)) {
+ page_list[npages++] = rdma_block_iter_dma_address(&biter);
+ /* The size of the memory pointed to by page_list is one page, which can store up to PAGE_SIZE / sizeof(u64)
+ pas. After a page is full, mtt needs to be written */
+ if (npages == BIT(mtt->mtt_page_shift) / PA_SIZE) {
+ ret = hmm_mtt_write(rdev->hwdev, mtt, start_index,
+ npages, page_list, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to write mtt, ret(%d), start_index(%u), func_id(%u).",
+ ret, start_index, rdev->glb_func_id);
+ goto out;
+ }
+ start_index += npages;
+ npages = 0;
+ }
+ }
+
+ if (npages != 0) {
+ ret = hmm_mtt_write(rdev->hwdev, mtt, start_index, npages,
+ page_list, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to write mtt, ret(%d), start_index(%u), func_id(%u).",
+ ret, start_index, rdev->glb_func_id);
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int roce5_umem_write_mtt(struct roce5_device *rdev, struct mtt *mtt,
+ struct ib_umem *umem, bool use_huge)
+{
+ int ret = 0;
+ u64 *page_list = NULL; /* page_list to write to mtt */
+
+ ret = roce5_umem_write_mtt_check(rdev, mtt, umem);
+ if (ret != 0) {
+ return ret;
+ }
+
+ page_list = (u64 *)kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (page_list == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc memory for page list, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ ret = roce5_umem_write_mtt_update(rdev, mtt, umem, page_list, use_huge);
+ if (ret != 0) {
+ ROCE_ERR("Failed to write mtt.");
+ }
+
+ kfree(page_list);
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_buf_write_mtt
+ Description : roce5_buf_write_mtt
+ Input : struct roce5_device *rdev
+ struct mtt *mtt
+ struct tag_cqm_buf *buf
+ Output : None
+
+ 1.Date : 2015/4/24
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_buf_write_mtt(struct roce5_device *rdev, struct mtt *mtt,
+ struct tag_cqm_buf *buf)
+{
+ u64 *page_list = NULL;
+ int ret = 0;
+ u32 i = 0;
+
+ if ((rdev == NULL) || (mtt == NULL) || (buf == NULL)) {
+ ROCE_ERR("Rdev or mtt or buf is null");
+ return (-EINVAL);
+ }
+
+ page_list =
+ (u64 *)kzalloc(buf->buf_number * sizeof *page_list, GFP_KERNEL);
+ if (page_list == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc memory for page list, func_id(%d)",
+ rdev->glb_func_id);
+ return (-ENOMEM);
+ }
+
+ /* Each buf is written to MTT as a page, buf_size is 2^n times PAGE_SIZE */
+ for (i = 0; i < buf->buf_number; ++i) {
+ page_list[i] = buf->buf_list[i].pa;
+ }
+
+ ret = hmm_mtt_write(rdev->hwdev, mtt, 0, buf->buf_number, page_list,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d)",
+ rdev->glb_func_id);
+ }
+
+ kfree(page_list);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_is_umem_dma_contiguous
+ Description : Determine whether the input ib_umem occupies a contiguous
+ region in DMA address space, i.e., all scatter-gather entries
+ are adjacent in DMA addresses and the total length matches
+ umem->length.
+ Input : struct roce5_device *rdev
+ struct ib_umem *umem
+ Output : bool - true if the umem is DMA-contiguous, false otherwise
+ 1.Date : 2026/3/12
+ Modification : Created function
+**************************************************************************** */
+static inline bool roce5_is_umem_dma_contiguous(struct roce5_device *rdev,
+ struct ib_umem *umem)
+{
+ struct scatterlist *sg = NULL;
+ int i;
+ dma_addr_t expected_dma, dma;
+ uint64_t total_len = 0, len;
+
+#if defined(IB_UMEM_HAVE_SG_APPEND_TABLE)
+ sg = umem->sgt_append.sgt.sgl;
+#else
+ sg = umem->sg_head.sgl;
+#endif
+
+ expected_dma = sg_dma_address(sg);
+
+#if defined(IB_UMEM_HAVE_SG_APPEND_TABLE)
+ for_each_sg(umem->sgt_append.sgt.sgl, sg, umem->sgt_append.sgt.nents, i)
+#else
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i)
+#endif
+ {
+ dma = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+
+ if (i > 0 && dma != expected_dma) {
+ ROCE_DEV_WARN(
+ rdev,
+ "Enable huge page, but discontinuity at sg[%d]: expected 0x%llx, got 0x%llx\n",
+ i, (u64)expected_dma, (u64)dma);
+ return false;
+ }
+
+ total_len += len;
+ expected_dma = dma + len;
+ }
+
+ /* Check the total length. */
+ if (total_len != umem->length) {
+ ROCE_DEV_WARN(rdev, "Total length %llu != umem length(%zu)\n",
+ total_len, umem->length);
+ return false;
+ }
+
+ return true;
+}
+
+static int roce5_get_page_info(struct roce5_device *rdev, struct ib_umem *umem,
+ u32 *npages, u32 *page_shift, u64 virt_addr)
+{
+ *page_shift = roce5_umem_get_buf_page_shift(rdev, umem, virt_addr);
+ *npages = roce5_umem_get_mtt_npages(rdev, umem, *page_shift);
+
+ if (rdev->huge_page_en && *page_shift > PAGE_SHIFT) {
+ if (*page_shift != PAGE_SHIFT_2MB) {
+ ROCE_DEV_WARN(
+ rdev,
+ "RoCE reg huge MR expect page_size(2MB), but found %lu.",
+ BIT(*page_shift));
+ }
+ ROCE_DEV_INFO(rdev,
+ "RoCE reg huge MR: npages(%u), page_shift(%u).",
+ *npages, *page_shift);
+ return ROCE_USE_HUGEPAGE;
+ }
+
+ return ROCE_NOT_USE_HUGEPAGE;
+}
+
+int roce5_user_mr_reg(struct roce5_device *rdev, struct roce5_mr *mr, u32 pdn,
+ u64 virt_addr, u64 length, int access)
+{
+ int ret = 0;
+ u32 npages = 0;
+ u32 page_shift = PAGE_SHIFT;
+ u32 mpt_xid_mode;
+ int use_huge;
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)rdev->hwdev;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("hwdev is null");
+ return 0;
+ }
+
+ mr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+
+ use_huge = roce5_get_page_info(rdev, mr->umem, &npages, &page_shift,
+ virt_addr);
+ mpt_xid_mode = roce5_get_mpt_xid_mode(rdev);
+
+ ret = roce5_alloc_tpt(rdev, &mr->rdmamr, npages, page_shift,
+ mpt_xid_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mpt and mtt, func_id(%d)",
+ hinic5_global_func_id(hwdev));
+ goto err_alloc_tpt;
+ }
+
+ roce5_set_rdma_mr(&mr->rdmamr, RDMA_USER_MR, pdn, virt_addr, length,
+ (u32)access);
+
+ ret = roce5_umem_write_mtt(rdev, &mr->rdmamr.mtt, mr->umem, use_huge);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d)",
+ hinic5_global_func_id(hwdev));
+ goto err_write_mtt;
+ }
+
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, hwdev, &mr->rdmamr,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to enable mpt of user mr, func_id(%d)",
+ hinic5_global_func_id(hwdev));
+ goto err_write_mtt;
+ }
+
+ return 0;
+
+err_write_mtt:
+ roce5_free_tpt(rdev, &mr->rdmamr);
+
+err_alloc_tpt:
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_reg_user_mr
+ Description : register MR for user
+ Input : struct ib_pd *ibpd
+ u64 start
+ u64 length
+ u64 virt_addr
+ int access
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2015/4/24
+ Modification : Created function
+
+**************************************************************************** */
+struct ib_mr *roce5_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length,
+ u64 virt_addr, int access,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_mr *mr = NULL;
+ struct roce5_device *rdev = NULL;
+ struct roce5_pd *rpd = to_roce5_pd(ibpd);
+ roce_user_handle_t *handle = NULL;
+
+ if (ibpd == NULL) {
+ ret = -EINVAL;
+ ROCE_ERR("Ibpd is null");
+ goto err_out;
+ }
+
+ rdev = to_roce5_dev(ibpd->device);
+
+ mr = (struct roce5_mr *)kzalloc(sizeof(*mr), GFP_KERNEL);
+ if (mr == NULL) {
+ ret = -ENOMEM;
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc memory for roce mr, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_out;
+ }
+#if defined(IB_UMEM_GET_PEER)
+ mr->umem = roce5_mr_umem_get_peer(rdev, (size_t)length, access, start,
+ udata, true);
+#else
+ mr->umem = roce5_umem_get(&rdev->ib_dev, ibpd->uobject->context, start,
+ (size_t)length, access, 0);
+#endif
+ if (IS_ERR(mr->umem)) {
+ handle = (roce_user_handle_t *)kzalloc(
+ sizeof(roce_user_handle_t), GFP_KERNEL);
+ if (handle == NULL) {
+ ret = -ENOMEM;
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc memory for handle, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_get_umem;
+ }
+ handle->magic = ROCE_ULD_HANDLE_MAGIC_NUM;
+ handle->rdev = rdev;
+ handle->mr = mr;
+ handle->virt_addr = virt_addr;
+ handle->length = length;
+ handle->pdn = rpd->pdn;
+ handle->access = access;
+
+ mr->david_en = true;
+ mr->private_data = (void *)handle;
+
+ /* call ULD interface */
+ ret = roce5_uld_reg_user_mr((roce_uld_handle)handle);
+ if (ret != 0) {
+ ROCE_DEV_WARN(
+ rdev,
+ "Failed to reg user mr uld, func_id(%d), ret(%d), err(%d)",
+ rdev->glb_func_id, ret, (int)PTR_ERR(mr->umem));
+ ret = (int)PTR_ERR(mr->umem);
+ kfree(handle);
+ mr->private_data = NULL;
+ goto err_get_umem;
+ }
+
+ mr->umem = NULL;
+ } else {
+ ret = roce5_user_mr_reg(rdev, mr, rpd->pdn, virt_addr, length,
+ access);
+ if (ret != 0) {
+ goto err_mr_update;
+ }
+ }
+#ifdef __ROCE_DFX__
+ roce5_store_mr_list(rdev, &mr->node);
+#endif
+ mr->ibmr.lkey = mr->rdmamr.key;
+ mr->ibmr.rkey = mr->rdmamr.key;
+
+ ROCE_DEV_INFO(rdev, "Roce reg user mr success, mr mpt index is %u",
+ mr->rdmamr.mpt.mpt_index);
+
+ return &mr->ibmr;
+
+err_mr_update:
+ ib_umem_release(mr->umem);
+
+err_get_umem:
+ kfree(mr);
+
+err_out:
+ return (struct ib_mr *)ERR_PTR((long)ret);
+}
+
+int roce5_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_mr *mr = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (ibmr == NULL) {
+ ROCE_ERR("Ibmr is null");
+ return -EINVAL;
+ }
+
+ mr = to_roce5_mr(ibmr);
+ rdev = to_roce5_dev(ibmr->device);
+
+ if (mr->rdmamr.type == HMM_RDMA_FRMR) {
+ roce5_free_priv_pages(mr);
+ }
+
+ if (mr->david_en) {
+ if (mr->private_data == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid parameter, private data is NULL.");
+ return -EINVAL;
+ }
+
+ ret = roce5_uld_dereg_user_mr(
+ (roce_uld_handle)mr->private_data);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "roce dereg user mr uld failed, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ kfree(mr->private_data);
+ mr->private_data = NULL;
+ } else {
+ ret = hmm_rdma_disable_mpt(rdev->lld_dev, rdev->hwdev,
+ &mr->rdmamr, SERVICE_T_ROCE,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Mr may has mw bind on it, ret(%d), mr_key(%#x), func_id(%d)",
+ ret, mr->rdmamr.key, rdev->glb_func_id);
+ if (ret == (-CMDQ_TIMEOUT)) {
+ rdev->dev_status_to_ofed =
+ ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+ return ret;
+ }
+
+ roce5_free_tpt(rdev, &mr->rdmamr);
+
+ ib_umem_release(mr->umem);
+ }
+
+ if (mr->fumem_nr != 0) {
+ roce5_free_frmr_umem(mr->fumem, mr->fumem_nr);
+ mr->fumem_nr = 0;
+ }
+#ifdef __ROCE_DFX__
+ roce5_delete_mr_list(rdev, &mr->node);
+#endif
+
+ kfree(mr);
+
+ return 0;
+}
+
+int roce5_dereg_mr_ofa(struct ib_mr *ibmr)
+{
+ return roce5_dereg_mr(ibmr, NULL);
+}
+
+static void roce5_err_enable_mpt_handler(void *hwdev, struct roce5_mw *mw)
+{
+ hmm_mpt_free(hwdev, &mw->rdmamw.mpt);
+ mw->rdmamw.enabled = RDMA_MPT_DISABLED;
+ return;
+}
+
+static void roce5_mw2hmm_adapter(const struct rdma_mw *rdmamw,
+ struct hmm_rdma *hmmrdma)
+{
+ hmmrdma->mpt = rdmamw->mpt;
+ hmmrdma->key = rdmamw->key;
+ hmmrdma->pdn = rdmamw->pdn;
+ hmmrdma->type = (rdmamw->type == RDMA_MW_TYPE_1) ? HMM_RDMA_MW_TYPE_1 :
+ HMM_RDMA_MW_TYPE_2;
+ hmmrdma->enabled = rdmamw->enabled;
+}
+
+int roce5_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
+{
+ int ret;
+ u32 mpt_xid_mode;
+ struct roce5_mw *mw = NULL;
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+ struct hmm_rdma hmmrdma = { 0 };
+
+ if (ibmw == NULL) {
+ ROCE_ERR("Ibmw is null");
+ return -EINVAL;
+ }
+
+ mw = to_roce5_mw(ibmw);
+ pd = to_roce5_pd(ibmw->pd);
+ rdev = to_roce5_dev(ibmw->device);
+
+ mpt_xid_mode = roce5_get_mpt_xid_mode(rdev);
+ ret = hmm_mpt_alloc_templated(rdev->hwdev, &mw->rdmamw.mpt,
+ SERVICE_T_ROCE, mpt_xid_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mpt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err;
+ }
+
+ roce5_set_rdma_mw(&mw->rdmamw, pd->pdn, ibmw->type);
+ roce5_mw2hmm_adapter(&mw->rdmamw, &hmmrdma);
+
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, &hmmrdma,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to enable mpt of mw, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ if (ret == (-CMDQ_TIMEOUT)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+ goto err_enable_mpt;
+ }
+
+ mw->rdmamw.enabled = hmmrdma.enabled;
+ mw->ibmw.rkey = mw->rdmamw.key;
+ return 0;
+err_enable_mpt:
+ roce5_err_enable_mpt_handler(rdev->hwdev, mw);
+err:
+ return ret;
+}
+
+struct ib_mw *roce5_alloc_mw_ofa(struct ib_pd *ibpd, enum ib_mw_type type,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_mw *mw = NULL;
+
+ if (ibpd == NULL) {
+ ret = -EINVAL;
+ ROCE_ERR("Ibpd is null");
+ goto out;
+ }
+
+ mw = (struct roce5_mw *)kzalloc(sizeof *mw, GFP_KERNEL);
+ if (mw == NULL) {
+ ret = -ENOMEM;
+ ROCE_ERR("Failed to alloc memory for roce mw");
+ goto out;
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ mw->ibmw.pd = ibpd;
+ mw->ibmw.device = ibpd->device;
+ mw->ibmw.type = type;
+ ret = roce5_alloc_mw(&mw->ibmw, udata);
+ if (ret != 0) {
+ kfree(mw);
+ }
+
+out:
+ return (ret != 0 ? (struct ib_mw *)ERR_PTR((long)ret) : &mw->ibmw);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_dealloc_mw
+ Description : dealloc mw and release related resource
+ Input : struct ib_mw *ibmw
+ Output : None
+
+ 1.Date : 2015/4/24
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_dealloc_mw(struct ib_mw *ibmw)
+{
+ int ret = 0;
+ struct roce5_mw *mw = NULL;
+ struct roce5_device *rdev = NULL;
+ struct hmm_rdma hmmrdma;
+
+ if (ibmw == NULL) {
+ ROCE_ERR("Ibmw is null");
+ return -EINVAL;
+ }
+
+ mw = to_roce5_mw(ibmw);
+ rdev = to_roce5_dev(ibmw->device);
+ roce5_mw2hmm_adapter(&mw->rdmamw, &hmmrdma);
+
+ ret = hmm_rdma_disable_mpt(rdev->lld_dev, rdev->hwdev, &hmmrdma,
+ SERVICE_T_ROCE, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to disable mpt of mw, func_id(%d)",
+ rdev->glb_func_id);
+ if (ret == (-CMDQ_TIMEOUT)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+ return ret;
+ }
+ mw->rdmamw.enabled = hmmrdma.enabled;
+
+ hmm_mpt_free(rdev->hwdev, &mw->rdmamw.mpt);
+ mw->rdmamw.enabled = RDMA_MPT_DISABLED;
+
+ return ret;
+}
+
+int roce5_dealloc_mw_ofa(struct ib_mw *ibmw)
+{
+ int ret = 0;
+ struct roce5_mw *mw = NULL;
+
+ ret = roce5_dealloc_mw(ibmw);
+ if (ret == 0) {
+ mw = to_roce5_mw(ibmw);
+ kfree(mw);
+ }
+
+ return ret;
+}
+
+int roce5_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
+ struct ib_mr_status *mr_status)
+{
+ int ret = 0;
+ struct roce5_mr *mr = NULL;
+
+ if ((ibmr == NULL) || (mr_status == NULL)) {
+ ROCE_ERR("ibmr or mr_status is NULL ptr.");
+ return -EINVAL;
+ }
+
+ mr = to_roce5_mr(ibmr);
+ if ((check_mask & (~IB_MR_CHECK_SIG_STATUS)) != 0) {
+ ROCE_ERR("check_mask(%#x) invalid", check_mask);
+ return -EINVAL;
+ }
+
+ if (mr->signature_en == 0) {
+ ROCE_ERR("mr not configure dif info");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ mr->sig.sig_status_checked = true;
+ mr_status->fail_status = 0;
+
+ /* If err does not exist, return 0 */
+ if (!mr->sig.sig_err_exists) {
+ return 0;
+ }
+
+ ret = memcpy_s((void *)&mr_status->sig_err, sizeof(struct ib_sig_err),
+ (void *)&mr->sig.sig_err_item,
+ sizeof(struct ib_sig_err));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy sig_err.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ mr->sig.sig_err_exists = false;
+ mr_status->fail_status |= IB_MR_CHECK_SIG_STATUS;
+
+ return 0;
+}
+
+/**
+ * @brief Get mpt by index. When querying succeeded, you have to call roce5_mpt_put() to free
+ the cqm_obj_mpt. But there is no need to call roce5_mpt_put() if querying failed.
+ * @return Success: return the mpt. Failure: return NULL.
+ */
+struct mpt *roce5_get_mpt_by_index(struct roce5_device *rdev, u32 mpt_index)
+{
+ cqm_object_s *cqm_obj_mpt = NULL;
+ cqm_qpc_mpt_s *cqm_mpt = NULL;
+ struct mpt *mpt = NULL;
+
+ cqm_obj_mpt =
+ cqm5_object_get(rdev->hwdev, CQM_OBJECT_MPT, mpt_index, false);
+ if (cqm_obj_mpt == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't find mpt according to index(0x%x), func_id(%d)",
+ mpt_index, rdev->glb_func_id);
+ return NULL;
+ }
+
+ cqm_mpt = container_of(cqm_obj_mpt, cqm_qpc_mpt_s, object);
+ mpt = (struct mpt *)cqm_mpt->priv;
+ if (mpt == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to convert obj to mpt.");
+ cqm5_object_put(cqm_obj_mpt);
+ }
+
+ return mpt;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.h b/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.h
new file mode 100644
index 000000000..3124c2470
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/mr/roce_mr.h
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_MR_H
+#define ROCE_MR_H
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_umem.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+
+#include "roce.h"
+
+#include "hinic5_hmm.h"
+#include "hinic5_rdma.h"
+#include "rdma_comp.h"
+
+#include "securec.h"
+
+#define ROCE5_MR_DEFAULT_ACCESS \
+ (IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE | \
+ IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_ATOMIC)
+
+#define ROCE5_MR_PAGES_ALIGN 64U
+#define ROCE5_FRMR_UMEM_NUM 512
+#define ROCE5_SIZE_2M (2 * 1024 * 1024)
+
+struct roce5_sig_ctx {
+ struct ib_sig_attrs sig_attrs; /* recorded when submitting WR */
+ struct ib_sig_err
+ sig_err_item; /* Get information configuration from CQE when polling CQE */
+ bool sig_status_checked; /* Indicates whether the status is checked */
+ bool sig_err_exists; /* Indicates if an error exists */
+ u32 sig_err_count; /* Count the number of wrong CQEs */
+};
+
+/* uld service can extension structure space */
+#define ROCE_MR_ULD_DEF_LEN 24
+#define ROCE_NOT_USE_HUGEPAGE 0
+#define ROCE_USE_HUGEPAGE 1
+
+/* used for verify uld access whether memory stomping */
+#define ROCE_RMR_MAGIC 0x1317F73a
+struct roce5_mr_uld_def {
+ u8 self_def[ROCE_MR_ULD_DEF_LEN];
+};
+
+struct roce5_mr {
+ struct ib_mr ibmr; /* mr structure provided by ofed */
+ struct ib_umem *
+ umem; /* Maintain the structure where the user-mode allocated buffer */
+ struct ib_umem **fumem; /* used to frmr only */
+ struct hmm_rdma rdmamr; /* mr structure provided by rdma component */
+ struct roce5_sig_ctx sig; /* Record signature related information */
+ u16 signature_en; /* Whether the logo contains signature information */
+ u16 sign_val; /* MTT entry [11:0] */
+ __be64 *pages;
+ u32 npages;
+ u32 fumem_nr;
+ u32 max_pages;
+ size_t page_map_size;
+ dma_addr_t page_map;
+#ifdef __ROCE_DFX__
+ struct list_head node;
+#endif // __ROCE_DFX__
+ bool david_en; /* Indicate whether the mr is a david mr */
+ void *private_data; /* private data for driver */
+ u32 user_data_len; /* length of user data which stored in struct hmm_rdma */
+ struct roce5_mr_uld_def uld_def;
+ u32 rmr_magic; /* preventstop uld access memory stomping, support up to 24B space */
+};
+
+struct roce5_mw {
+ struct ib_mw ibmw; /* mw structure provided by ofed */
+ struct rdma_mw rdmamw; /* mw structure provided by rdma component */
+};
+
+int roce5_alloc_tpt(struct roce5_device *rdev, struct hmm_rdma *mr, u32 npages,
+ u32 page_shift, u32 mpt_xid_mode);
+void roce5_free_tpt(struct roce5_device *rdev, struct hmm_rdma *mr);
+void roce5_set_rdma_mr(struct hmm_rdma *mr, enum rdma_mr_type mr_type, u32 pdn,
+ u64 iova, u64 size, u32 access);
+void roce5_free_frmr_umem(struct ib_umem **fumem, int fumem_nr);
+struct mpt *roce5_get_mpt_by_index(struct roce5_device *rdev, u32 mpt_index);
+static inline void roce5_mpt_put(struct mpt *rmpt)
+{
+ if (rmpt == NULL) {
+ return;
+ }
+ cqm5_object_put(&((cqm_qpc_mpt_s *)(rmpt->mpt_object))->object);
+}
+
+static inline int roce5_mr_type2hmm(enum rdma_mr_type mr_type)
+{
+ int mr_type_convert_table[] = {
+ [RDMA_DMA_MR] = HMM_RDMA_DMA_MR,
+ [RDMA_USER_MR] = HMM_RDMA_USER_MR,
+ [RDMA_FRMR] = HMM_RDMA_FRMR,
+ [RDMA_FMR] = HMM_RDMA_FMR,
+ [RDMA_PHYS_MR] = HMM_RDMA_PHYS_MR,
+ [RDMA_RSVD_LKEY] = HMM_RDMA_RSVD_LKEY,
+ [RDMA_SIG_MR] = HMM_RDMA_SIG_MR,
+ [RDMA_INDIRECT_MR] = HMM_RDMA_INDIRECT_MR,
+ [RDMA_ODP_IMPLICIT_MR] = HMM_RDMA_ODP_IMPLICIT_MR,
+ [RDMA_ODP_EXPLICIT_MR] = HMM_RDMA_ODP_EXPLICIT_MR,
+ };
+
+ return mr_type_convert_table[mr_type];
+}
+
+#endif // __ROCE_MR_H_
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_post.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_post.h
new file mode 100644
index 000000000..28a092b29
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_post.h
@@ -0,0 +1,171 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+
+
+#ifndef ROCE_POST_H
+#define ROCE_POST_H
+
+#include <linux/types.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_wqe_format.h"
+
+#define ROCE_SQ_DOORBELL_TYPE_2 2
+#define ROCE_SQ_DOORBELL_TYPE_23 23
+#define ROCE_SQ_DOORBELL_TYPE_21 21
+
+#define ROCE_DWQE_DDB_TYPE 3 /* RoCE direct wqe of DDB type */
+
+#define ROCE_IMM_EXT_LEN 4
+#define ROCE_TASK_SEG_ALIGN 8
+
+enum roce_tsl_8_byte_aligned_size_e {
+ ROCE_SEND_LOCAL_WQE_TSL = 2,
+ ROCE_RDMA_WQE_TSL = 4,
+ ROCE_ATOMIC_CWP_WQE_TSL = 6,
+ ROCE_UD_WQE_COM_TSL = 8
+};
+
+enum {
+ ROCE_WQE_OPCODE_SEND = 0x00,
+ ROCE_WQE_OPCODE_SEND_INVAL = 0x01,
+ ROCE_WQE_OPCODE_SEND_IMM = 0x02,
+
+ ROCE_WQE_OPCODE_RDMA_WRITE = 0x04,
+ ROCE_WQE_OPCODE_RDMA_WRITE_IMM = 0x05,
+
+ ROCE_WQE_OPCODE_RDMA_READ = 0x08,
+
+ ROCE_WQE_OPCODE_ATOMIC_CMP_SWP = 0x0c,
+ ROCE_WQE_OPCODE_ATOMIC_FETCH_ADD = 0x0d,
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_CMP_SWP = 0x0e,
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_FETCH_ADD = 0x0f,
+
+ ROCE_WQE_OPCODE_FRMR = 0x10,
+ ROCE_WQE_OPCODE_LOCAL_INVAL = 0x11,
+ ROCE_WQE_OPCODE_BIND_MW = 0x12,
+ ROCE_WQE_OPCODE_REG_SIG_MR =
+ 0x13, /* Extended for further local opreation */
+};
+
+#define ROCE_KERNEL_OPCODE_NUM (ROCE_WQE_OPCODE_REG_SIG_MR + 1)
+
+enum {
+ ROCE_DWQE_DB_SUBTYPE_SEND = 0x1,
+ ROCE_DWQE_DB_SUBTYPE_SEND_IMM = 0x2,
+ ROCE_DWQE_DB_SUBTYPE_RDMA_WRITE = 0x3,
+ ROCE_DWQE_DB_SUBTYPE_RDMA_WRITE_IMM = 0x4,
+ ROCE_DWQE_DB_SUBTYPE_RDMA_READ = 0x5,
+ ROCE_DWQE_DB_SUBTYPE_ATOMIC_CMP_SWP = 0x6,
+ ROCE_DWQE_DB_SUBTYPE_ATOMIC_FETCH_ADD = 0x7
+};
+
+/* UD send WQE task seg1 */
+struct roce_wqe_ud_tsk_seg_cycle1 {
+ roce_wqe_tsk_com_seg_u common;
+
+ /* DW0 */
+ u32 data_len;
+
+ /* DW1 */
+ u32 immdata_invkey;
+
+ /* DW2 */
+ union {
+ struct {
+ u32 pd : 18;
+ u32 rsvd0 : 6;
+ u32 stat_rate : 4; /* 0: No limit on the static rate (100% port speed)
+ 1-6: reserved
+ 7: 2.5 Gb/s. 8: 10 Gb/s. 9: 30 Gb/s. 10: 5 Gb/s. 11: 20 Gb/s.
+ 12: 40 Gb/s. 13: 60 Gb/s. 14: 80 Gb/s.15: 120 Gb/s. */
+ u32 rsvd1 : 3;
+ u32 fl : 1;
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3 */
+ union {
+ struct {
+ u32 hop_limit : 8;
+ u32 sgid_idx : 7;
+ u32 rsvd0 : 1;
+ u32 port : 4;
+ u32 rsvd1 : 4;
+ u32 tc : 8;
+ } bs;
+ u32 value;
+ } dw3;
+
+ /* DW4 */
+ union {
+ struct {
+ u32 flow_label : 20;
+ u32 rsvd0 : 4;
+ u32 smac_index : 3;
+ u32 rsvd1 : 5;
+ } bs;
+ u32 value;
+ } dw4;
+
+ /* DW5~8 */
+ u8 dgid[16];
+
+ /* DW9 */
+ union {
+ struct {
+ u32 dst_qp : 24;
+ u32 rsvd : 8;
+ } bs;
+ u32 value;
+ } dw9;
+
+ /* DW10 */
+ u32 qkey;
+};
+
+/* UD send WQE task seg2; */
+struct roce_wqe_ud_tsk_seg_cycle2 {
+ /* DW0 */
+ union {
+ struct {
+ u32 dmac_h16 : 16;
+ u32 vlan_id : 12;
+ u32 cfi : 1;
+ u32 vlan_prio : 3;
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ u32 dmac_l32;
+};
+
+struct roce5_post_send_normal_param {
+ struct roce5_wqe_ctrl_seg *ctrl_seg;
+ union roce5_wqe_tsk_com_seg *tsk_com_seg;
+ u32 wqe_size;
+ u8 *wqe;
+ struct roce_wqe_data_seg *dseg;
+ u32 wr_num; /* record posted WR numbers */
+ u32 index; /* WQEBB id */
+ int inline_flag; /* Inline flag */
+ u32 data_len;
+ u32 *data_len_addr;
+ u32 sq_rmd_size;
+ s32 opcode;
+ s32 cycle;
+ u32 sq_wqe_ssn;
+ struct roce5_wqe_ctrl_seg ctrl_seg_tmp;
+
+ unsigned long flags; /* type required by kernel API */
+};
+
+typedef struct tag_roce_opcode_attr {
+ uint32_t rsvd : 31;
+ uint32_t remote_opcode : 1;
+} roce_opcode_attr_s;
+
+#endif /* ROCE_POST_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp.h
new file mode 100644
index 000000000..7088cd550
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp.h
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_QP_H
+#define ROCE_QP_H
+
+#include <linux/types.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "hinic5_rdma.h"
+#include "hinic5_cqm.h"
+
+#include "roce.h"
+#include "roce_cq.h"
+#include "roce_db.h"
+#include "roce_pd.h"
+#include "roce_compat.h"
+#include "roce_npu_cmd_qp_defs.h"
+#include "roce_wqe_base_format.h"
+#include "roce_post.h"
+#include "roce_mix.h"
+#include "roce_xqe_format.h"
+#include "roce_qp_ctx_format.h"
+#include "roce_cq_format.h"
+#include "roce_srq_format.h"
+#include "roce_com.h"
+#include "roce_obj_ext.h"
+#include "roce_kernel_compat_gen.h"
+
+#define ROCE_RQ_MIN_SGE 4
+#define ROCE_RQ_MID_SGE 8
+#define ROCE_RQ_MAX_SGE 16
+
+#define ROCE_WQE_NEXT_SGE_INVALID (1UL << 31)
+
+#define ROCE_RDMARC_DESTROY_CHECK_VALUE 0xcece5a5a
+
+#define RDMARC_NUM_PER_CACHELINE 8
+#define RDMARC_TABLE_ENTRY_SIZE 32
+#define ROCE_QP_MAX_PFETCH_MTT_LAYER 3
+#define ROCE_QP_MAX_TIMER_NUM 5
+
+#define ROCE_QP_SMI_QP_NUM 0x0
+#define ROCE_QP_GSI_QP_NUM 0x1
+#define ROCE_QP_INVLID_QP_NUM CQM_INDEX_INVALID
+
+#define ROCE_QP_MAX_DWQE_SIZE 256
+#define ROCE_QP_DEFAULT_WQE_SHIFT 6
+
+#define ROCE_QP_MODIFY_CMD_OUT_BUF_SIZE 512
+
+#define ROCE_QP_STATE_MEM_INIT 0xa
+
+#define ROCE_UD_MAX_INLINE_LEN_SUB 48
+
+#define ROCE_QP_GPA_SIG_LEN 3
+#define ROCE_WR_MIN_NUM 2
+
+#define ROCE_QPC_PMTU_TRANSLATE(pmtu) (((1U << ((pmtu)-1)) - 1) & 0xf)
+
+#define ROCE_QP_OPTPAR_ALT_ADDR_PATH (1 << 0)
+#define ROCE_QP_OPTPAR_RRE (1 << 1)
+#define ROCE_QP_OPTPAR_RAE (1 << 2)
+#define ROCE_QP_OPTPAR_RWE (1 << 3)
+#define ROCE_QP_OPTPAR_PKEY_INDEX (1 << 4)
+#define ROCE_QP_OPTPAR_Q_KEY (1 << 5)
+#define ROCE_QP_OPTPAR_RNR_TIMEOUT (1 << 6)
+#define ROCE_QP_OPTPAR_PRIMARY_ADDR_PATH (1 << 7)
+#define ROCE_QP_OPTPAR_SRA_MAX (1 << 8)
+#define ROCE_QP_OPTPAR_RRA_MAX (1 << 9)
+#define ROCE_QP_OPTPAR_PM_STATE (1 << 10)
+#define ROCE_QP_OPTPAR_RETRY_COUNT (1 << 11)
+#define ROCE_QP_OPTPAR_RNR_RETRY (1 << 12)
+#define ROCE_QP_OPTPAR_ACK_TIMEOUT (1 << 13)
+#define ROCE_QP_OPTPAR_SCHED_QUEUE (1 << 14)
+#define ROCE_QP_OPTPAR_COUNTER_INDEX (1 << 15)
+
+#define roce5_LB1_MASK_1825V100 0x7
+
+enum roce_qp_state {
+ ROCE_QP_STATE_RST = 0,
+ ROCE_QP_STATE_INIT = 1,
+ ROCE_QP_STATE_RTR = 2,
+ ROCE_QP_STATE_RTS = 3,
+ ROCE_QP_STATE_SQER = 4,
+ ROCE_QP_STATE_SQD = 5,
+ ROCE_QP_STATE_ERR = 6,
+ ROCE_QP_STATE_SQ_DRAINING = 7,
+ ROCE_QP_STATE_NUM
+};
+
+enum {
+ ROCE_QP_PM_MIGRATED = 0x3,
+ ROCE_QP_PM_ARMED = 0x0,
+ ROCE_QP_PM_REARM = 0x1
+};
+
+enum { ROCE_QP_NO_SRQ, ROCE_QP_HAS_SRQ };
+
+enum { ROCE_QP = 0, ROCE_QP_EXT };
+
+struct roce5_wq {
+ u64 *wrid;
+ spinlock_t lock;
+ u32 wqebb_cnt;
+ u32 max_post;
+ u32 max_sge;
+ u32 offset;
+ u32 wqe_shift;
+ u32 head;
+ u32 tail;
+};
+
+struct roce5_sqp_attr {
+ int pkey_index;
+ u32 qkey;
+ u32 send_psn;
+};
+
+#define ROCE_RQP_ULD_DEF_LEN 64
+#define ROCE_RQP_MAGIC 0x5a5b5c5d
+struct roce5_rqp_uld_def {
+ u8 uld_def[ROCE_RQP_ULD_DEF_LEN];
+};
+
+struct roce5_qp {
+ struct ib_qp ibqp;
+ u32 qpn;
+ struct roce5_db db;
+ cqm_queue_s *qp_buf_info;
+ cqm_qpc_mpt_s *qpc_info;
+ struct roce5_wq rq;
+ u32 sq_signal_bits;
+ unsigned int sq_next_wqe;
+ u32 sq_max_wqes_per_wr;
+ struct roce5_wq sq;
+ struct ib_umem *umem;
+ struct mtt mtt;
+ struct roce5_buf buf;
+ int buf_size;
+ struct mutex mutex;
+ u32 xrcdn;
+ u8 port;
+ u8 atomic_rd_en;
+ u8 qp_state;
+ u8 qp_ext;
+ u32 qp_type;
+ u32 max_inline_data;
+ int max_dwqe_size;
+ u32 sq_wqe_ssn;
+ struct rdma_rdmarc rdmarc;
+ u16 rsp_depth;
+ u8 sl;
+ bool has_rq;
+ u8 *sq_head_addr;
+ u8 *sq_tail_addr;
+ bool signature_en;
+ u8 pi_on_chip;
+ u8 double_sgl_mode;
+ u8 ext_mtu;
+ u8 ext_mtu_mode;
+
+ u8 db_sgid_index;
+ u8 db_path_mtu;
+ u8 db_cos;
+ u8 shadow;
+
+ struct roce5_sqp_attr *sqp_attr;
+
+ u32 qid;
+ u32 local_comm_id; /* used by NOF AA to reuse qpn when disconnection happens */
+ u32 remote_comm_id;
+ void *wb_va; /* used for xrc */
+ dma_addr_t wb_dma; /* used for xrc */
+ u32 shadow_vfid;
+
+ /* hot-plug record */
+ struct list_head qps_list;
+ struct list_head cq_recv_list;
+ struct list_head cq_send_list;
+#if defined(ROCE_VBS_EN) || defined(ROCE_EXTEND)
+ void *vbs_qp_ptr;
+#endif
+#ifdef ROCE_BONDING_EN
+ u32 tx_hash_value;
+#endif
+
+ struct roce5_obj_ext obj_ext;
+
+ struct roce5_rqp_uld_def
+ uld_def; /* must placed at qp_magic before, preventstop uld access memory stomping, support up to 64B space */
+ u32 rqp_magic;
+};
+
+typedef struct tag_roce_modify_qp_param {
+ u32 optpar;
+ roce_verbs_qp_attr_s qp_attr;
+ roce_verbs_cmd_qp_modify_rsp_s modify_rsp;
+} roce_modify_qp_param_s;
+
+void roce5_qp_async_event(struct roce5_device *rdev, struct roce5_qp *qp,
+ int type);
+
+void roce5_free_opt_rdmarc(struct roce5_qp *rqp);
+void roce5_set_opt_rdmarc(struct rdma_rdmarc *rdmarc, u16 depth,
+ roce_verbs_qp_attr_s *qp_attr);
+void roce5_get_cqs(struct roce5_qp *rqp, struct roce5_cq **send_cq,
+ struct roce5_cq **recv_cq);
+int roce5_qp_modify_2rst_cmd(struct roce5_device *rdev, u32 qpn);
+int roce5_qp_cache_out_cmd(struct roce5_device *rdev, struct roce5_qp *rqp);
+struct roce5_pd *roce5_get_pd(struct roce5_qp *rqp);
+bool roce5_sqp_check(const struct roce5_qp *rqp);
+void *roce5_get_wqe(struct roce5_qp *rqp, u32 offset);
+int roce5_wq_overflow(struct roce5_wq *wq, u32 wr_num, struct ib_cq *ibcq);
+void roce5_set_data_seg(struct roce_wqe_data_seg *dseg, struct ib_sge *sge);
+void roce5_qpc_to_be(roce_verbs_qp_attr_s *qp_attr, struct roce5_qp *rqp,
+ u32 *be_ctx);
+void roce5_qp_rst2init(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr);
+
+int roce5_send_qp_lb_cmd(u32 qpn, struct roce5_device *rdev, u8 cmd,
+ cqm_cmd_buf_s *buf_in, cqm_cmd_buf_s *buf_out,
+ u32 timeout);
+
+int roce5_qp_query(struct roce5_device *rdev, u32 qpn, u32 *context,
+ int qpc_size);
+int roce5_post_send_standard(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr);
+void qpc_seg_to_le32(struct roce5_qp_context *be_ctx,
+ struct roce5_qp_context *le_ctx, u32 srq_vld);
+void roce5_be32_2_le32(void *context, u32 *le_ctx, u32 ctx_size);
+
+int roce5_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr);
+
+int roce5_post_send_ofa(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr);
+struct roce5_qp *roce5_get_rqp_by_qpn(struct roce5_device *rdev, u32 qpn);
+static inline void roce5_rqp_put(struct roce5_qp *rqp)
+{
+ if (rqp == NULL) {
+ return;
+ }
+ cqm5_object_put(&rqp->qpc_info->object);
+}
+
+#define ROCE_UD_MTU_SHIFT 4 /* 4K mtu */
+static inline void roce5_set_sq_db(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ struct roce_sq_db_seg *db,
+ unsigned int index)
+{
+ db->dw0.bs.qpn = rqp->qpn & 0xfffff;
+ db->dw0.bs.ctx_size = 1; /* 512B */
+ db->dw0.bs.cp_flag = 0;
+ db->dw0.bs.cos = rqp->db_cos;
+ if (ROCE5_SUPPORT_SQ_DB_TYPE_21(rdev) != 0) {
+ db->dw0.bs.type = ROCE_SQ_DOORBELL_TYPE_21;
+ } else if (ROCE5_SUPPORT_SQ_DB_TYPE_MSG_V2(rdev) != 0) {
+ db->dw0.bs.type = ROCE_SQ_DOORBELL_TYPE_23;
+ } else {
+ db->dw0.bs.type = ROCE_SQ_DOORBELL_TYPE_2;
+ }
+
+ db->dw1.bs.pi = ((index & 0xffff) >> 8) & 0xff; /* 8bits */
+ db->dw1.bs.sub_type = 0;
+ db->dw1.bs.mtu_shift = rqp->db_path_mtu & 0x7;
+ db->dw1.bs.sgid_index = rqp->db_sgid_index;
+ if (rqp->qp_type == IB_QPT_RC) {
+ } else if (rqp->qp_type == IB_QPT_UD || rqp->qp_type == IB_QPT_GSI) {
+ db->dw1.bs.mtu_shift = ROCE_UD_MTU_SHIFT;
+ } else if (rqp->qp_type == IB_QPT_XRC_INI ||
+ rqp->qp_type == IB_QPT_XRC_TGT) {
+ db->dw1.bs.xrc_vld = 1;
+ }
+
+ db->dw0.value = roce5_convert_be32(db->dw0.value);
+ db->dw1.value = roce5_convert_be32(db->dw1.value);
+}
+
+static inline int roce5_write_sq_db(struct roce5_device *rdev,
+ struct roce5_qp *rqp, u32 index,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ union roce_sq_db sq_db;
+
+ ret = memset_s(&sq_db.sq_db_val, sizeof(u64), 0, sizeof(u64));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memset sq_db.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ roce5_set_sq_db(rdev, rqp, &sq_db.sq_db_seg, index);
+
+ if (udata == NULL) {
+ *(rqp->db.db_record) = cpu_to_be32(index & 0xffff);
+ }
+
+ wmb();
+ ret = cqm5_ring_hardware_db(rdev->hwdev, SERVICE_T_ROCE, index & 0xff,
+ sq_db.sq_db_val);
+
+ /*
+ * Make sure doorbells don't leak out of SQ spinlock
+ * and reach the HCA out of order.
+ */
+ wmb();
+ return ret;
+}
+
+#if defined(IB_QP_CREATE_FLAGS_HAVE_INTEGRITY_EN)
+#define IB_QP_CREATE_SIGNATURE_EN IB_QP_CREATE_INTEGRITY_EN
+#endif
+#endif // ROCE_QP_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_create.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_create.c
new file mode 100644
index 000000000..6adbe787c
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_create.c
@@ -0,0 +1,1506 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_compat.h"
+
+#include "roce.h"
+#include "roce_infra.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_user.h"
+#include "roce_xrc.h"
+#include "roce_pd.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+#include "roce_qp_extension.h"
+#include "roce_main_extension.h"
+#include "roce_aeq_format.h"
+#include "roce_restore.h"
+#include "roce_os_compat.h"
+#include "roce_cc_format.h"
+#include "roce_uld_inner.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_qp_inner.h"
+#include "roce_com.h"
+#include "roce_qp_ext.h"
+
+#include "hinic5_hmm.h"
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+
+#include "securec.h"
+
+/* ****************************************************************************
+ Prototype : roce5_check_rq_size
+ Description : roce5_check_rq_size
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ struct ib_qp_cap *cap
+ bool has_rq
+ Output : None
+
+ 1.Date : 2017/4/27
+ Modification : Created function
+**************************************************************************** */
+static int roce5_check_rq_size(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_init_attr *init_attr, bool has_rq)
+{
+ u32 max_sge_num;
+ struct ib_qp_cap *cap = &init_attr->cap;
+
+ max_sge_num = rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_sg;
+ if ((cap->max_recv_wr >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes) ||
+ (cap->max_recv_sge > max_sge_num)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to check rq size, over range, func_id(%d), attr max_recv_wr(%d), cap max_wqes(%d), \
+ attr max_recv_sge(%d), cap max_sge_num(%d)",
+ rdev->glb_func_id, cap->max_recv_wr,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes,
+ cap->max_recv_sge, max_sge_num);
+ return -EINVAL;
+ }
+
+ if (has_rq && ((cap->max_recv_wr == 0) || (cap->max_recv_sge == 0))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Has rq, cap->max_recv_wr(%d), cap->max_recv_sge(%d), func_id(%d)",
+ cap->max_recv_wr, cap->max_recv_sge, rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if ((!has_rq) && (cap->max_recv_wr != 0)) {
+ ROCE_DEV_ERR(rdev,
+ "Not has rq, cap->max_recv_wr(%d), func_id(%d).",
+ cap->max_recv_wr, rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_rq_size
+ Description : roce5_set_rq_size
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ struct ib_qp_cap *cap
+ bool is_user
+ bool has_rq
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+**************************************************************************** */
+/* ****************************************************************************
+*
+* 1 there is SQ or RQ
+* SQ/RQ depth must be power of 2
+* if max_send_wr=0, no need to alloc buf for SQ/RQ
+
+* RQ WQE SIZE equals 64 or128
+* SQ WQE SIZE equals multi of wqebb size
+
+* SQ max_gs, max 8 and min 0
+* RQ max_gs, can be 4 or 8, but can not be 0.
+
+* 2 there is no SQ or RQ
+* all related params should be 0
+*
+
+**************************************************************************** */
+static int roce5_set_rq_size(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_init_attr *init_attr, bool is_user,
+ bool has_rq)
+{
+ int ret;
+ u32 wqebb_num = 0;
+ u32 sge_total_len = 0;
+ u32 page_size;
+ struct ib_qp_cap *cap = &init_attr->cap;
+
+ page_size = roce5_get_page_size(rdev, true);
+
+ ret = roce5_check_rq_size(rdev, rqp, init_attr, has_rq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to check rq size, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ if (has_rq) {
+ wqebb_num = ROCE_MAX(2U, cap->max_recv_wr);
+ rqp->rq.wqebb_cnt =
+ (u32)(ROCE_ROUNDUP_POW_OF_TWO(wqebb_num) & 0xffffffff);
+
+ /* RQ SGE range [0,4] select 4,[5,8] select 8 */
+ rqp->rq.max_sge =
+ (cap->max_recv_sge <= ROCE_RQ_MIN_SGE) ?
+ ROCE_RQ_MIN_SGE :
+ ((cap->max_recv_sge <= ROCE_RQ_MID_SGE) ?
+ ROCE_RQ_MID_SGE :
+ ROCE_RQ_MAX_SGE);
+
+ sge_total_len = (u32)((u32)rqp->rq.max_sge *
+ sizeof(struct roce_wqe_data_seg));
+ rqp->rq.wqe_shift = (u32)ROCE_ILOG2(sge_total_len);
+
+ if ((u32)((u32)rqp->rq.wqebb_cnt
+ << (unsigned)rqp->rq.wqe_shift) < page_size) {
+ rqp->rq.wqebb_cnt =
+ (page_size >> (unsigned)rqp->rq.wqe_shift);
+ }
+
+ /* leave userspace return values as they were, so as not to break ABI */
+ if (is_user) {
+ rqp->rq.max_post =
+ ROCE_MIN(rdev->rdma_cap.dev_rdma_cap
+ .roce_own_cap.max_wqes,
+ rqp->rq.wqebb_cnt);
+ cap->max_recv_wr = (u32)rqp->rq.max_post;
+ cap->max_recv_sge = (u32)rqp->rq.max_sge;
+ } else {
+ rqp->rq.max_post =
+ ROCE_MIN(rdev->rdma_cap.dev_rdma_cap
+ .roce_own_cap.max_wqes,
+ rqp->rq.wqebb_cnt);
+ cap->max_recv_wr = (u32)rqp->rq.max_post;
+ cap->max_recv_sge =
+ ROCE_MIN((u32)rqp->rq.max_sge,
+ rdev->rdma_cap.dev_rdma_cap
+ .roce_own_cap.max_rq_sg);
+ }
+ } else {
+ rqp->rq.wqebb_cnt = 0;
+ rqp->rq.max_sge = 0;
+ rqp->rq.wqe_shift = ROCE_QP_DEFAULT_WQE_SHIFT;
+ rqp->rq.max_post = 0;
+ cap->max_recv_sge = 0;
+ }
+
+ rqp->rq.head = 0;
+ rqp->rq.tail = 0;
+
+ return 0;
+}
+
+static int roce5_set_user_sq_size_check(struct roce5_device *rdev,
+ const struct ib_qp_cap *cap,
+ const struct roce5_qp *rqp)
+{
+ u32 ud_max_inline_size;
+
+ if (cap->max_send_wr >
+ (rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes)) {
+ ROCE_DEV_ERR(rdev, "Log_sq_bb_count over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if (rqp->qp_type == IB_QPT_UD) {
+ ud_max_inline_size =
+ (rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_sq_inline_data_sz >
+ ROCE_UD_MAX_INLINE_LEN_SUB) ?
+ (rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_sq_inline_data_sz -
+ ROCE_UD_MAX_INLINE_LEN_SUB) :
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_sq_inline_data_sz;
+ } else {
+ ud_max_inline_size = rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_sq_inline_data_sz;
+ }
+
+ /* RC:192B inline data, UD:176B */
+ if (cap->max_inline_data > ud_max_inline_size) {
+ ROCE_DEV_ERR(rdev, "SQ max inline data over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+/* ****************************************************************************
+ Prototype : roce5_set_user_sq_size
+ Description : roce5_set_user_sq_size
+ Input : struct roce5_device *rdev
+ struct ib_qp_cap *cap
+ struct roce5_qp *rqp
+ struct roce5_create_qp *ucmd
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_set_user_sq_size(struct roce5_device *rdev,
+ struct ib_qp_cap *cap, struct roce5_qp *rqp,
+ struct create_qp_cmd *ucmd)
+{
+ u32 tmp_max_sq_wqe_sz = 0;
+ u32 sq_buf_sz = 0;
+ int ret = 0;
+ u32 page_size;
+
+ page_size = roce5_get_page_size(rdev, true);
+
+ ret = roce5_set_user_sq_size_check(rdev, cap, rqp);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ /* between max and min */
+ tmp_max_sq_wqe_sz =
+ (u32)(ROCE_ROUNDUP_POW_OF_TWO(
+ rdev->rdma_cap.max_sq_desc_sz) &
+ 0xffffffff);
+ if ((ucmd->log_sq_stride > ROCE_ILOG2(tmp_max_sq_wqe_sz)) ||
+ (ucmd->log_sq_stride <
+ ROCE_ILOG2(rdev->rdma_cap.wqebb_size))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "WQE size invalid, func_id(%d) log_sq_stride:%d wqebb_size:%d tmp_max_sq_wqe_sz:%d",
+ rdev->glb_func_id, ucmd->log_sq_stride,
+ rdev->rdma_cap.wqebb_size, tmp_max_sq_wqe_sz);
+ return -EINVAL;
+ }
+
+ rqp->sq.wqebb_cnt = (u32)(1U << ucmd->log_sq_bb_count);
+ rqp->sq.wqe_shift = ucmd->log_sq_stride;
+
+ if ((u32)((u64)rqp->sq.wqebb_cnt
+ << (unsigned)rqp->sq.wqe_shift) < page_size) {
+ rqp->sq.wqebb_cnt =
+ (page_size >> (unsigned)rqp->sq.wqe_shift);
+ }
+
+ sq_buf_sz = (u32)ROCE_ALIGN(
+ (u64)rqp->sq.wqebb_cnt << (unsigned)rqp->sq.wqe_shift,
+ page_size);
+ rqp->buf_size =
+ (int)ROCE_ALIGN(((unsigned)sq_buf_sz +
+ ((unsigned)rqp->rq.wqebb_cnt
+ << (unsigned)rqp->rq.wqe_shift)),
+ page_size);
+
+ rqp->sq.offset = 0;
+ rqp->rq.offset = sq_buf_sz;
+
+ rqp->max_inline_data = (u32)cap->max_inline_data;
+ } else {
+ rqp->sq.wqebb_cnt = 0;
+ rqp->sq.wqe_shift = ucmd->log_sq_stride;
+ rqp->buf_size = 0;
+ rqp->sq.offset = 0;
+ rqp->rq.offset = 0;
+ rqp->max_inline_data = 0;
+ cap->max_inline_data = 0;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_send_wqe_overhead
+ Description : roce5_send_wqe_overhead
+ Input : enum ib_qp_type qp_type
+ Output : None
+
+ 1.Date : 2015/5/7
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_send_wqe_overhead(enum ib_qp_type qp_type)
+{
+ switch (qp_type) {
+ case IB_QPT_RC:
+ return sizeof(struct roce5_wqe_ctrl_seg) +
+ sizeof(struct roce_wqe_frmr_tsk_seg);
+
+ case IB_QPT_UC:
+ return sizeof(struct roce5_wqe_ctrl_seg) +
+ sizeof(struct roce_wqe_send_tsk_seg);
+
+ case IB_QPT_UD:
+ return sizeof(struct roce5_wqe_ctrl_seg) +
+ sizeof(struct roce_wqe_ud_tsk_seg);
+
+ case IB_QPT_GSI:
+ return sizeof(struct roce5_wqe_ctrl_seg) +
+ sizeof(struct roce_wqe_ud_tsk_seg);
+
+ case IB_QPT_XRC_TGT:
+ return 0;
+
+ case IB_QPT_XRC_INI:
+ return sizeof(struct roce5_wqe_ctrl_seg) +
+ sizeof(struct roce_wqe_frmr_tsk_seg);
+
+ default:
+ ROCE_ERR("Not supported this qp_type(%d)", qp_type);
+ return -1;
+ }
+}
+
+static int roce5_set_kernel_sq_size_check(const struct roce5_device *rdev,
+ const struct ib_qp_cap *cap,
+ int *sq_max_wqe_size,
+ enum ib_qp_type qp_type)
+{
+ int wqe_overhead = 0;
+ int ret = 0;
+
+ if (cap->max_send_wr >
+ (u32)rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes) {
+ ROCE_DEV_ERR(rdev, "SQ WR over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if (cap->max_send_sge > rdev->rdma_cap.max_sq_sg) {
+ ROCE_DEV_ERR(rdev, "SQ SGE over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if (cap->max_inline_data >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_sq_inline_data_sz) {
+ ROCE_DEV_ERR(rdev, "SQ max inline data over range, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ wqe_overhead = roce5_send_wqe_overhead(qp_type);
+ if (wqe_overhead < 0) {
+ ROCE_DEV_ERR(rdev, "Invalid service type(%d), func_id(%d)",
+ (int)qp_type, rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ *sq_max_wqe_size = ROCE_MAX((int)(cap->max_send_sge *
+ sizeof(struct roce_wqe_data_seg)),
+ (int)cap->max_inline_data) +
+ wqe_overhead;
+ if (*sq_max_wqe_size > (int)rdev->rdma_cap.max_sq_desc_sz) {
+ ROCE_DEV_ERR(
+ rdev,
+ "SQ WQE size over range, func_id(%d) max_send_sge:%u,max_inline_data:%u,"
+ "wqe_overhead:%d,sq_max_wqe_size:%d,max_sq_desc_sz:%u",
+ rdev->glb_func_id, cap->max_send_sge,
+ cap->max_inline_data, wqe_overhead, *sq_max_wqe_size,
+ rdev->rdma_cap.max_sq_desc_sz);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+/* ****************************************************************************
+ Prototype : roce5_set_kernel_sq_size
+ Description : roce5_set_kernel_sq_size
+ Input : struct roce5_device *rdev
+ struct ib_qp_cap *cap
+ enum roce5_qp_type qp_type
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_set_kernel_sq_size(struct roce5_device *rdev,
+ struct ib_qp_cap *cap,
+ enum ib_qp_type qp_type,
+ struct roce5_qp *rqp)
+
+{
+ u32 sq_buf_sz = 0;
+ int sq_max_wqe_size = 0;
+ int ret = 0;
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ ret = roce5_set_kernel_sq_size_check(rdev, cap,
+ &sq_max_wqe_size, qp_type);
+ if (ret != 0) {
+ return ret;
+ }
+
+ rqp->sq.wqe_shift = (u32)ROCE_ILOG2(rdev->rdma_cap.wqebb_size);
+ rqp->sq_max_wqes_per_wr = (u32)ROCE_DIV_ROUND_UP(
+ (unsigned)sq_max_wqe_size,
+ (u32)(1UL << (unsigned)rqp->sq.wqe_shift));
+
+ /*
+ * As one wqebb ought to be reserved for invalidate wqebb, 1 is added to sq.wqebb_cnt here
+ * to satisfy the actual IB_MAD_QP_SEND_SIZE set by applications
+ */
+ rqp->sq.wqebb_cnt =
+ (u32)((u32)cap->max_send_wr * rqp->sq_max_wqes_per_wr +
+ 1);
+ rqp->sq.wqebb_cnt =
+ (u32)(ROCE_ROUNDUP_POW_OF_TWO(rqp->sq.wqebb_cnt) &
+ 0xffffffff);
+
+ if ((u32)((u64)rqp->sq.wqebb_cnt << (u32)rqp->sq.wqe_shift) <
+ PAGE_SIZE) {
+ rqp->sq.wqebb_cnt =
+ (PAGE_SIZE >> ((u32)rqp->sq.wqe_shift));
+ }
+
+ rqp->sq.max_sge =
+ (u32)(((u64)rqp->sq_max_wqes_per_wr
+ << (unsigned)rqp->sq.wqe_shift) -
+ (unsigned)roce5_send_wqe_overhead(qp_type));
+ rqp->sq.max_sge = (u32)ROCE_MIN(rdev->rdma_cap.max_sq_desc_sz,
+ rqp->sq.max_sge) /
+ (u32)sizeof(struct roce_wqe_data_seg);
+
+ sq_buf_sz = (u32)ALIGN((u64)rqp->sq.wqebb_cnt
+ << (unsigned)rqp->sq.wqe_shift,
+ PAGE_SIZE);
+ rqp->buf_size = (int)ALIGN(((unsigned)sq_buf_sz +
+ ((unsigned)rqp->rq.wqebb_cnt
+ << (unsigned)rqp->rq.wqe_shift)),
+ PAGE_SIZE);
+
+ rqp->sq.offset = 0u;
+ rqp->rq.offset = sq_buf_sz;
+
+ if (((rqp->sq.wqebb_cnt - 1) / rqp->sq_max_wqes_per_wr) == 1) {
+ ROCE_DEV_ERR(rdev,
+ "Only one WR,please check,func_id(%d)",
+ rdev->glb_func_id);
+ rqp->sq.max_post = ROCE_WR_MIN_NUM;
+ cap->max_send_wr = rqp->sq.max_post;
+ } else {
+ rqp->sq.max_post = (rqp->sq.wqebb_cnt - 1) /
+ rqp->sq_max_wqes_per_wr;
+ cap->max_send_wr = (u32)rqp->sq.max_post;
+ }
+
+ cap->max_send_sge = (u32)ROCE_MIN(rqp->sq.max_sge,
+ rdev->rdma_cap.max_sq_sg);
+ rqp->max_inline_data = (u32)cap->max_inline_data;
+ } else {
+ rqp->sq.wqebb_cnt = 0;
+ rqp->sq.wqe_shift = ROCE_QP_DEFAULT_WQE_SHIFT;
+ rqp->buf_size = 0;
+ rqp->sq.offset = 0;
+ rqp->rq.offset = 0;
+ rqp->max_inline_data = 0;
+ cap->max_inline_data = 0;
+ }
+
+ rqp->sq.head = 0;
+ rqp->sq.tail = 0;
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_async_event
+ Description : roce5_qp_async_event
+ Input : struct roce5_device *rdev
+ struct roce5_qp *qp
+ int type
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_qp_async_event(struct roce5_device *rdev, struct roce5_qp *qp,
+ int type)
+{
+ struct ib_event event;
+ struct ib_qp *ibqp = &qp->ibqp;
+ int ret;
+
+ ret = memset_s(&event, sizeof(event), 0, sizeof(event));
+ if (ret != 0) {
+ ROCE_DEV_ERR_LIMIT(rdev, "Failed to memset dmac.(ret:%d)", ret);
+ return;
+ }
+
+ if (ibqp->event_handler) {
+ event.device = ibqp->device;
+ event.element.qp = ibqp;
+
+ switch (type) {
+ case ROCE_EVENT_TYPE_COMM_EST:
+ event.event = IB_EVENT_COMM_EST;
+ break;
+
+ case ROCE_EVENT_TYPE_SQ_DRAINED:
+ event.event = IB_EVENT_SQ_DRAINED;
+ break;
+
+ case ROCE_EVENT_TYPE_SRQ_QP_LAST_WQE:
+ event.event = IB_EVENT_QP_LAST_WQE_REACHED;
+ break;
+
+ case ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+ event.event = IB_EVENT_QP_FATAL;
+ break;
+
+ case ROCE_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+ event.event = IB_EVENT_QP_REQ_ERR;
+ break;
+
+ case ROCE_EVENT_TYPE_WQ_ACCESS_ERROR:
+ event.event = IB_EVENT_QP_ACCESS_ERR;
+ break;
+
+ default:
+ return;
+ }
+
+ ibqp->event_handler(&event, ibqp->qp_context);
+ }
+}
+
+static void *roce5_buf_offset(struct roce5_buf *buf, u32 offset)
+{
+ return (void *)((char *)buf->direct.buf + offset);
+}
+
+void *roce5_get_wqe(struct roce5_qp *rqp, u32 offset)
+{
+ return roce5_buf_offset(&rqp->buf, offset);
+}
+
+static void *roce5_get_send_wqe_head(struct roce5_qp *rqp)
+{
+ return roce5_get_wqe(rqp, rqp->sq.offset);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_get_send_wqe_tail
+ Description : roce5_get_send_wqe_tail
+ Input : struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2015/8/8
+ Modification : Created function
+
+**************************************************************************** */
+static void *roce5_get_send_wqe_tail(struct roce5_qp *rqp)
+{
+ return roce5_get_wqe(rqp, rqp->sq.offset + (rqp->sq.wqebb_cnt
+ << (u32)rqp->sq.wqe_shift));
+}
+
+/* ****************************************************************************
+ Prototype : roce5_sq_buf_init
+ Description : roce5_sq_buf_init
+ Input : struct roce5_qp *qp
+ Output : None
+
+ 1.Date : 2015/11/9
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_sq_buf_init(struct roce5_qp *qp)
+{
+ u32 entries = qp->rq.offset / (1U << qp->sq.wqe_shift);
+ u8 *wqe = NULL;
+ struct roce5_wqe_ctrl_seg *wqe_ctrl = NULL;
+ u32 i;
+
+ for (i = 0; i < entries; i++) {
+ wqe = (u8 *)qp->buf.direct.buf +
+ (u32)(i * (1U << ((u32)qp->sq.wqe_shift)));
+ wqe_ctrl = (struct roce5_wqe_ctrl_seg *)((void *)wqe);
+ wqe_ctrl->dw0.value = be32_to_cpu(wqe_ctrl->dw0.value);
+ wqe_ctrl->dw0.bs.owner = 1;
+ wqe_ctrl->dw0.value = cpu_to_be32(wqe_ctrl->dw0.value);
+ }
+}
+
+static int roce5_check_qp_udata(struct roce5_device *rdev,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata, struct roce5_qp *rqp,
+ struct create_qp_cmd *ucmd)
+{
+ int ret = 0;
+
+ if ((udata == NULL) ||
+ (ib_copy_from_udata(ucmd, udata, sizeof(*ucmd)) != 0)) {
+ ret = -EFAULT;
+ return ret;
+ }
+
+ ret = roce5_set_user_sq_size(rdev, &init_attr->cap, rqp, ucmd);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to set user sq_size, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return ret;
+}
+
+static bool
+roce5_need_qpn_lb1_consistent_srqn(const struct roce5_qp *rqp,
+ const struct roce5_device *rdev,
+ const struct ib_qp_init_attr *init_attr)
+{
+ if ((init_attr->srq == NULL) || (rdev->cfg_info.lb_en == 0)) {
+ return false;
+ }
+
+ if (ROCE5_SUPPORT_QP_SRQN_LB_MSG_V2(rdev) != 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+roce5_need_qpn_lb1_consistent_scqn(struct roce5_device *rdev,
+ struct ib_qp_init_attr *init_attr)
+{
+ if ((init_attr->send_cq == NULL) || (rdev->cfg_info.lb_en == 0)) {
+ return false;
+ }
+
+ if (ROCE5_SUPPORT_ALLOC_QPC_MSG_FEATURE(rdev) != 0) {
+ return false;
+ }
+ return true;
+}
+
+static int roce5_find_free_lb_qpn(struct roce5_device *rdev)
+{
+ int idx = 0;
+ for (; idx < ROCE_LB_QPN_MAX; idx++) {
+ if (rdev->qp_lb_scqn_ctrl.qp[idx] == 0) {
+ return idx;
+ }
+ }
+ return -1;
+}
+
+static int roce5_alloc_qpc(struct roce5_qp *rqp, struct roce5_device *rdev,
+ u32 qpn, struct ib_qp_init_attr *init_attr)
+{
+ struct roce5_srq *rsrq = NULL;
+ struct roce5_cq *rcq = NULL;
+ u32 qpn_tmp = qpn;
+ u32 roce_lb_mask = 0;
+ u32 cqm_lb_mode = 0;
+ int idx = -1;
+
+ if ((rqp == NULL) || (rdev == NULL) || (init_attr == NULL)) {
+ ROCE_ERR("rqp, rdev or init_attr is NULL");
+ return -EINVAL;
+ }
+
+ if (ROCE_IS_DEV_1825V100(rdev)) {
+ cqm_lb_mode = CQM_XID_LOW_BIT_1_1_1;
+ roce_lb_mask = roce5_LB1_MASK_1825V100;
+ } else {
+ ROCE_DEV_ERR(rdev, "Unknown device type(%u), func_id(%u).",
+ rdev->device_type, rdev->glb_func_id);
+ return -EINVAL;
+ }
+ mutex_lock(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+
+ if (roce5_need_qpn_lb1_consistent_srqn(rqp, rdev, init_attr)) {
+ rsrq = to_roce5_srq(init_attr->srq);
+ qpn_tmp = CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_ALL, cqm_lb_mode,
+ rsrq->srqn);
+ } else if ((qpn != ROCE_QP_GSI_QP_NUM) &&
+ roce5_need_qpn_lb1_consistent_scqn(rdev, init_attr)) {
+ rcq = to_roce5_cq(init_attr->send_cq);
+ //if not found free of qpn, idx return -1, not need do LB
+ idx = roce5_find_free_lb_qpn(rdev);
+ if (idx >= 0) {
+ qpn_tmp = CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_ALL,
+ cqm_lb_mode, rcq->cqn);
+ }
+ }
+
+ rqp->qpc_info = cqm5_object_qpc_mpt_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_SERVICE_CTX,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.qpc_entry_sz, rqp,
+ qpn_tmp, 0, 0);
+
+ if (rqp->qpc_info == NULL && rdev->full_qp_spec) {
+ /* For subsequent QPs, XID alignment is not mandatory. */
+ rqp->qpc_info = cqm5_object_qpc_mpt_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_SERVICE_CTX,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.qpc_entry_sz,
+ rqp, qpn, 0, 0);
+ } else if (rqp->qpc_info != NULL) {
+ if (idx >= 0) { //idx >= 0 indicates has emptyremaining of lb qpn bit position
+ rdev->qp_lb_scqn_ctrl.qp[idx] = rqp->qpc_info->xid;
+ ROCE_DEV_INFO(
+ rdev,
+ "RoCE create lb qpn func_id(%d), qpn(%d), idx(%d)",
+ rdev->glb_func_id, rqp->qpc_info->xid, idx);
+ }
+ }
+ mutex_unlock(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+ if (rqp->qpc_info == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create qpc mpt by cqm object, func_id(%d), qpn(%u)",
+ rdev->glb_func_id, qpn_tmp);
+ return -ENOMEM;
+ }
+
+ rqp->qpn = rqp->qpc_info->xid;
+ if (roce5_need_qpn_lb1_consistent_srqn(rqp, rdev, init_attr)) {
+ if (rsrq != NULL && ((rsrq->srqn & roce_lb_mask) !=
+ (rqp->qpn & roce_lb_mask))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create qpc LB srqn, func_id(%d), qpn(%u) srqn(%u) mask:0x%x",
+ rdev->glb_func_id, rqp->qpn, rsrq->srqn,
+ roce_lb_mask);
+ }
+ }
+
+ return 0;
+}
+
+static int roce5_create_qp_user_umem_mtt(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ struct ib_pd *ibpd,
+ struct create_qp_cmd *ucmd)
+{
+ u32 npages = 0;
+ int ret;
+
+ if (rqp->shadow != 0) {
+ return 0;
+ }
+ rqp->umem = roce5_umem_get(&rdev->ib_dev, ibpd->uobject->context,
+ ucmd->buf_addr, (size_t)rqp->buf_size, 0, 0);
+ if (IS_ERR(rqp->umem)) {
+ ROCE_DEV_ERR(rdev, "Failed to get ib_umem, func_id(%d)",
+ rdev->glb_func_id);
+ ret = (int)PTR_ERR(rqp->umem);
+ return ret;
+ }
+
+ rqp->buf.page_shift = (int)roce5_umem_get_buf_page_shift(
+ rdev, rqp->umem, ucmd->buf_addr);
+ npages = roce5_umem_get_mtt_npages(rdev, rqp->umem,
+ (u32)rqp->buf.page_shift);
+
+ rqp->mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, npages, (u32)rqp->buf.page_shift,
+ &rqp->mtt, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc rdma_mtt, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_umem;
+ }
+
+ ret = roce5_umem_write_mtt(rdev, &rqp->mtt, rqp->umem, 1);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_write_mtt;
+ }
+
+ return 0;
+
+err_write_mtt:
+ hmm_mtt_free(rdev->hwdev, &rqp->mtt, SERVICE_T_ROCE);
+err_umem:
+ ib_umem_release(rqp->umem);
+ return ret;
+}
+
+void roce5_destroy_qp_user_umem_mtt(struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ if (rqp->shadow != 0) {
+ return;
+ }
+ hmm_mtt_free(rdev->hwdev, &rqp->mtt, SERVICE_T_ROCE);
+ ib_umem_release(rqp->umem);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_qp_user
+ Description : create qp resource for user space qp
+ Input : struct roce5_device *rdev
+ struct ib_pd *ibpd
+ struct ib_qp_init_attr *init_attr
+ struct ib_udata *udata
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2016/01/30
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_qp_user(struct roce5_device *rdev, struct ib_pd *ibpd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata, struct roce5_qp *rqp)
+{
+ int ret = 0;
+ struct roce5_ucontext *roce5_uctx = NULL;
+ struct create_qp_cmd ucmd = { 0 };
+ u32 qpn = ROCE_QP_INVLID_QP_NUM;
+
+ roce5_uctx = to_roce5_ucontext(ibpd->uobject->context);
+
+ ret = roce5_check_qp_udata(rdev, init_attr, udata, rqp, &ucmd);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = roce5_create_qp_user_umem_mtt(rdev, rqp, ibpd, &ucmd);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (init_attr->qp_type != IB_QPT_XRC_TGT) {
+ ret = roce5_db_map_user(roce5_uctx, ucmd.db_addr, &rqp->db,
+ rqp->shadow);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to map db page to user, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_map_db;
+ }
+ }
+
+ ret = roce5_alloc_qpc(rqp, rdev, qpn, init_attr);
+ if (ret != 0) {
+ goto err_alloc_qpc;
+ }
+
+ return 0;
+
+err_alloc_qpc:
+ if (init_attr->qp_type != IB_QPT_XRC_TGT) {
+ roce5_db_unmap_user(roce5_uctx, &rqp->db, rqp->shadow);
+ }
+
+err_map_db:
+ roce5_destroy_qp_user_umem_mtt(rdev, rqp);
+
+ return ret;
+}
+
+static void roce5_free_wrid(struct roce5_qp *rqp)
+{
+ if (rqp->rq.wrid) {
+ kvfree(rqp->rq.wrid);
+ }
+
+ if (rqp->sq.wrid) {
+ kvfree(rqp->sq.wrid);
+ }
+}
+
+static int roce5_get_wrid(struct roce5_qp *rqp, struct roce5_device *rdev)
+{
+ int ret = 0;
+
+ rqp->sq.wrid = (u64 *)kzalloc((unsigned)rqp->sq.wqebb_cnt * sizeof(u64),
+ GFP_KERNEL);
+ if (rqp->sq.wrid == NULL) {
+ rqp->sq.wrid = (u64 *)(void *)vzalloc(
+ (size_t)(rqp->sq.wqebb_cnt * sizeof(u64)));
+ }
+
+ rqp->rq.wrid = (u64 *)kzalloc((unsigned)rqp->rq.wqebb_cnt * sizeof(u64),
+ GFP_KERNEL);
+ if (rqp->rq.wrid == NULL) {
+ rqp->rq.wrid = (u64 *)(void *)vzalloc(
+ (size_t)(rqp->rq.wqebb_cnt * sizeof(u64)));
+ }
+
+ if ((rqp->sq.wrid == NULL) || (rqp->rq.wrid == NULL)) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc wrid of sq or rq, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+static void roce5_create_qp_kernel_set_attr(struct roce5_qp *rqp,
+ cqm_queue_s *qp_buf_info)
+{
+ int ret;
+ ret = memset_s(qp_buf_info->q_room_buf_1.direct.va,
+ (size_t)((unsigned)rqp->buf_size), 0,
+ (size_t)((unsigned)rqp->buf_size));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset qp_buf_info.(ret:%d)", ret);
+ return;
+ }
+ rqp->buf.direct.buf = qp_buf_info->q_room_buf_1.direct.va;
+ rqp->buf.direct.map = qp_buf_info->q_room_buf_1.direct.pa;
+ rqp->buf.page_shift =
+ (int)ROCE_ILOG2(qp_buf_info->q_room_buf_1.buf_size);
+
+ roce5_sq_buf_init(rqp);
+
+ rqp->db.db_record = (__be32 *)(void *)(&qp_buf_info->q_header_vaddr
+ ->doorbell_record);
+ rqp->db.dma = qp_buf_info->q_header_paddr;
+
+ qp_buf_info->q_header_vaddr->doorbell_record = 0;
+
+ rqp->qp_buf_info = qp_buf_info;
+
+ rqp->sq_head_addr = (u8 *)roce5_get_send_wqe_head(rqp);
+ rqp->sq_tail_addr = (u8 *)roce5_get_send_wqe_tail(rqp);
+ rqp->max_dwqe_size = 0;
+ rqp->sq_wqe_ssn = 0;
+
+ if (rqp->max_inline_data != 0) {
+ rqp->max_dwqe_size = ROCE_QP_MAX_DWQE_SIZE;
+ }
+}
+
+static int roce5_create_qp_kernel_normal(struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ int ret;
+ cqm_queue_s *qp_buf_info = NULL;
+
+ qp_buf_info = cqm5_object_rdma_queue_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_RDMA_QP,
+ (u32)rqp->buf_size, rqp, true, ROCE_QP_INVLID_QP_NUM, 0, 0);
+ if (qp_buf_info == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create rdma queue by cqm object, func_id(%d)",
+ rdev->glb_func_id);
+ return -1;
+ }
+
+ roce5_create_qp_kernel_set_attr(rqp, qp_buf_info);
+
+ rqp->mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, qp_buf_info->q_room_buf_1.buf_number,
+ (u32)rqp->buf.page_shift, &rqp->mtt,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_alloc_mtt;
+ }
+ ret = roce5_buf_write_mtt(rdev, &rqp->mtt,
+ &rqp->qp_buf_info->q_room_buf_1);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write rdma mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_write_mtt;
+ }
+
+ ret = roce5_get_wrid(rqp, rdev);
+ if (ret != 0) {
+ goto err_alloc_wrid;
+ }
+
+ return 0;
+
+err_alloc_wrid:
+ roce5_free_wrid(rqp);
+
+err_write_mtt:
+ hmm_mtt_free(rdev->hwdev, &rqp->mtt, SERVICE_T_ROCE);
+
+err_alloc_mtt:
+ cqm5_object_delete(&rqp->qp_buf_info->object);
+
+ return ret;
+}
+
+static void roce5_destroy_qp_kernel_normal(struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ roce5_free_wrid(rqp);
+ hmm_mtt_free(rdev->hwdev, &rqp->mtt, SERVICE_T_ROCE);
+ cqm5_object_delete(&rqp->qp_buf_info->object);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_qp_kernel
+ Description : create qp resource for kernel space qp
+ Input : struct roce5_device *rdev
+ struct ib_qp_init_attr *init_attr
+ struct roce5_qp *rqp
+ u32 qpn
+ Output : None
+
+ 1.Date : 2016/01/30
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_qp_kernel(struct roce5_device *rdev,
+ struct ib_qp_init_attr *init_attr,
+ struct roce5_qp *rqp, u32 qpn)
+{
+ int ret = 0;
+
+ ret = roce5_set_kernel_sq_size(rdev, &init_attr->cap,
+ (enum ib_qp_type)rqp->qp_type, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set sq buffer size in kernel, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ ret = roce5_create_qp_kernel_normal(rdev, rqp);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ ret = roce5_alloc_qpc(rqp, rdev, qpn, init_attr);
+ if (ret != 0) {
+ goto err_alloc_qpc;
+ }
+
+ return 0;
+
+err_alloc_qpc:
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ roce5_destroy_qp_kernel_normal(rdev, rqp);
+ }
+
+ return ret;
+}
+
+static void roce5_qp_add_cq_list(struct ib_qp_init_attr *init_attr,
+ struct roce5_qp *rqp,
+ struct roce5_device *rdev)
+{
+ struct roce5_cq *send_rcq = to_roce5_cq(init_attr->send_cq);
+ struct roce5_cq *recv_rcq = to_roce5_cq(init_attr->recv_cq);
+ unsigned long flags = 0; /* type required by kernel API */
+
+ spin_lock_irqsave(&rdev->reset_flow_resource_lock, flags);
+ roce5_lock_cqs(send_rcq, recv_rcq);
+ list_add_tail(&rqp->qps_list, &rdev->qp_list);
+ list_add_tail(&rqp->cq_send_list, &send_rcq->send_qp_list);
+ list_add_tail(&rqp->cq_recv_list, &recv_rcq->recv_qp_list);
+ roce5_unlock_cqs(send_rcq, recv_rcq);
+ spin_unlock_irqrestore(&rdev->reset_flow_resource_lock, flags);
+}
+
+static int roce5_alloc_xrc_extra_dma(const struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ dma_addr_t wb_dma = 0;
+ void *wb_va = NULL;
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ return 0;
+ }
+
+ wb_va = dma_alloc_coherent(rdev->dev, (size_t)4UL, &wb_dma, GFP_KERNEL);
+ if (wb_va == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc wb_va, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ rqp->wb_dma = wb_dma;
+ rqp->wb_va = wb_va;
+
+ return 0;
+}
+
+#define ROCE_MAX_PI_ON_CHIP_QPN 1024 /* temporarily when set PI is 1024(count word), later debug add */
+static int roce5_set_pi_on_chip(const struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ /* shadow scenario next, actual use of is vf, and pi on chip function in shadow scenario not already verify, default disable */
+ if (ROCE5_SUPPORT_SET_PI_ON_CHIP_MSG_V2(rdev) != 0 &&
+ rqp->shadow == 0) {
+ /* becauseslice on store pi resource has limit, disable VF of pi_on_chip, such as need enabled, need modify configuration file in chip store store PI data, Note 审monitorslice on resource whether satisfy requirement */
+ rqp->pi_on_chip = (roce5_func_is_vf(rdev->hwdev) == false) &&
+ (rqp->qpn < ROCE_MAX_PI_ON_CHIP_QPN);
+ }
+
+ return 0;
+}
+
+static int roce5_do_create_qp(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_pd *ibpd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+
+ mutex_init(&rqp->mutex);
+
+ spin_lock_init(&rqp->sq.lock);
+ spin_lock_init(&rqp->rq.lock);
+
+ rqp->qp_state = IB_QPS_RESET;
+ rqp->qp_type = init_attr->qp_type;
+ rqp->sq_signal_bits = (u32)(init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
+
+ ret = roce5_alloc_xrc_extra_dma(rdev, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc xrc extra dma, func_id(%d), ret(%d).",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ if (ibpd != NULL && ibpd->uobject) {
+ ret = roce5_set_rq_size(rdev, rqp, init_attr, true,
+ rqp->has_rq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set rq size, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto create_qp_err;
+ }
+
+ ret = roce5_create_qp_user(rdev, ibpd, init_attr, udata, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create qp user, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto create_qp_err;
+ }
+ } else {
+ ret = roce5_set_rq_size(rdev, rqp, init_attr, false,
+ rqp->has_rq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set rq size, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto create_qp_err;
+ }
+
+ ret = roce5_create_qp_kernel(rdev, init_attr, rqp,
+ ROCE_QP_INVLID_QP_NUM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create qp kernel, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto create_qp_err;
+ }
+
+ roce5_qp_add_cq_list(init_attr, rqp, rdev);
+ }
+
+ ret = roce5_set_pi_on_chip(rdev, rqp);
+ if (ret != 0) {
+ goto create_qp_err;
+ }
+
+ ret = roce5_create_qp_ext_init(rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init qp extension, ret(%d).",
+ ret);
+ goto create_qp_err;
+ }
+
+ return ret;
+create_qp_err:
+ if (rqp->wb_va != NULL) {
+ dma_free_coherent(rdev->dev, sizeof(u32), rqp->wb_va,
+ rqp->wb_dma);
+ }
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_qp_gsi
+ Description : roce5_create_qp_gsi
+ Input : struct roce5_device *rdev
+ struct ib_pd *ibpd
+ struct ib_qp_init_attr *init_attr
+ Output : None
+
+ 1.Date : 2017/04/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_qp_gsi(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_init_attr *init_attr)
+{
+ int ret = 0;
+
+ rqp->sqp_attr = (struct roce5_sqp_attr *)kzalloc(
+ sizeof(struct roce5_sqp_attr), GFP_KERNEL);
+ if (rqp->sqp_attr == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to allocate memory for sqp attribute.");
+ return -ENOMEM;
+ }
+
+ mutex_init(&rqp->mutex);
+
+ spin_lock_init(&rqp->sq.lock);
+ spin_lock_init(&rqp->rq.lock);
+
+ rqp->qp_state = (u8)IB_QPS_RESET;
+ rqp->qp_type = init_attr->qp_type;
+ rqp->sq_signal_bits = (u32)(init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
+ rqp->has_rq = !init_attr->srq;
+
+ ret = roce5_set_rq_size(rdev, rqp, init_attr, false, rqp->has_rq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set rq size, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_out;
+ }
+
+ ret = roce5_create_qp_kernel(rdev, init_attr, rqp, ROCE_QP_GSI_QP_NUM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create qp kernel, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_out;
+ }
+
+ rqp->qpn = ROCE_QP_GSI_QP_NUM;
+
+ roce5_qp_add_cq_list(init_attr, rqp, rdev);
+
+ return 0;
+
+err_out:
+ kfree(rqp->sqp_attr);
+
+ return ret;
+}
+
+static int roce5_create_check_init_attr(const struct ib_pd *ibpd,
+ const struct ib_qp_init_attr *init_attr,
+ const struct ib_udata *udata)
+{
+ if (init_attr == NULL) {
+ ROCE_ERR("init_attr is null");
+ return (-EINVAL);
+ }
+
+ if ((ibpd == NULL) && (init_attr->qp_type != IB_QPT_XRC_TGT)) {
+ ROCE_ERR(
+ "Ibpd is null and qp_type is not IB_QPT_XRC_TGT, qp_type(0x%x)",
+ init_attr->qp_type);
+ return (-EINVAL);
+ }
+
+ if ((udata) && (init_attr->qp_type == IB_QPT_GSI)) {
+ ROCE_ERR("Udata is not null and qp_type is IB_QPT_GSI");
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+static int roce5_set_qp_attr(struct ib_qp_init_attr *init_attr,
+ struct roce5_qp *rqp, struct roce5_device *rdev,
+ struct ib_pd **ibpd, int qp_ext)
+{
+ u16 xrcdn = 0;
+
+ rqp->qp_ext = (u8)qp_ext;
+ if (init_attr->qp_type == IB_QPT_XRC_TGT) {
+ *ibpd = to_roce5_xrcd(init_attr->xrcd)->pd;
+ xrcdn = (u16)to_roce5_xrcd(init_attr->xrcd)->xrcdn;
+ init_attr->send_cq = to_roce5_xrcd(init_attr->xrcd)->cq;
+ init_attr->recv_cq = init_attr->send_cq;
+
+ rqp->has_rq = false;
+ rqp->xrcdn = xrcdn;
+ } else if (init_attr->qp_type == IB_QPT_XRC_INI) {
+ init_attr->recv_cq = init_attr->send_cq;
+ rqp->has_rq = false;
+ } else if ((init_attr->qp_type == IB_QPT_RC) ||
+ (init_attr->qp_type == IB_QPT_UC) ||
+ (init_attr->qp_type == IB_QPT_UD)) {
+ rqp->has_rq = !init_attr->srq;
+ } else {
+ ROCE_DEV_ERR(rdev, "Unknown QP Type(%u), func_id(%d)",
+ init_attr->qp_type, rdev->glb_func_id);
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+static int roce5_create_gsi_qp_result(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ struct ib_qp_init_attr *init_attr)
+{
+ int ret;
+
+ ret = roce5_create_qp_gsi(rdev, rqp, init_attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create gsi qp, func_id(%d), ret(%d).",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ rqp->ibqp.qp_num = rqp->qpn;
+ return 0;
+}
+
+static int roce5_create_qp_common(struct roce5_qp *rqp,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata, int qp_ext)
+{
+ int ret;
+ int uld_ret;
+ //when init_attr->qp_type == IB_QPT_XRC_TGT, ibpd is NULL.
+ struct ib_pd *ibpd = rqp->ibqp.pd;
+ struct roce5_device *rdev =
+ to_roce5_dev(ibpd ? ibpd->device : init_attr->xrcd->device);
+ roce_user_handle_t hdl = { 0 };
+
+ if (rdev->ecn_ctx.cc_algo == ROCE_CC_LDCP_ALGO &&
+ (init_attr->qp_type == IB_QPT_XRC_TGT ||
+ init_attr->qp_type == IB_QPT_XRC_INI)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "XRC QP cant be created when LDCP is enabled, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ if (init_attr->qp_type == IB_QPT_GSI) {
+ return roce5_create_gsi_qp_result(rdev, rqp, init_attr);
+ }
+
+ rqp->rqp_magic = ROCE_RQP_MAGIC;
+ ret = roce5_set_qp_attr(init_attr, rqp, rdev, &ibpd, qp_ext);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to set qp attribute, ret(%d).", ret);
+ goto err_set_attr;
+ }
+
+ ROCE_CONSTUCT_ULD_HDL_RQP(&hdl, rdev, rqp, NULL, udata, &rqp->mtt,
+ &rqp->db.dma);
+ ROCE_CONSTUCT_ULD_HDL_SHADOW(&hdl, &rqp->shadow, &rqp->shadow_vfid,
+ NULL);
+ ret = roce5_uld_qp_create((roce_uld_handle)&hdl);
+ if (ret != 0) {
+ ROCE_ERR("Failed to execute uld qp creation, ret(%d)", ret);
+ goto err_set_attr;
+ }
+ ret = roce5_do_create_qp(rdev, rqp, ibpd, init_attr, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create qp in common process, ret(%d).",
+ ret);
+ goto err_create_qp;
+ }
+
+ roce5_set_qp_dif_attr(rqp, init_attr, rdev);
+ rqp->ibqp.qp_num = rqp->qpn;
+ rqp->rsp_depth = 0;
+
+ mutex_lock(&rdev->qp_cnt.cur_qps_mutex);
+ rdev->qp_cnt.alloc_qp_cnt++;
+ mutex_unlock(&rdev->qp_cnt.cur_qps_mutex);
+
+ return 0;
+
+err_create_qp:
+ uld_ret = roce5_uld_qp_destroy((roce_uld_handle)&hdl);
+ if (uld_ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to destroy uld qp in common process, uld_ret(%d).",
+ uld_ret);
+ }
+err_set_attr:
+ return ret;
+}
+
+struct ib_qp *roce5_create_qp_compat(struct ib_pd *ibpd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret;
+
+ ret = roce5_create_check_init_attr(ibpd, init_attr, udata);
+ if (ret != 0) {
+ ROCE_ERR("Failed to check init attr");
+ return (struct ib_qp *)ERR_PTR((long)ret);
+ }
+
+ rqp = (struct roce5_qp *)kzalloc(sizeof(*rqp), GFP_KERNEL);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to alloc roce qp.");
+ return (struct ib_qp *)ERR_PTR((long)-ENOMEM);
+ }
+
+ rqp->ibqp.pd = ibpd;
+
+ ret = roce5_create_qp_common(rqp, init_attr, udata, ROCE_QP);
+ if (ret != 0) {
+ ROCE_ERR("Failed to execute common qp creation, ret(%d)", ret);
+ goto err_create_qp;
+ }
+
+ return &(rqp->ibqp);
+err_create_qp:
+ kfree(rqp);
+ return (struct ib_qp *)ERR_PTR((long)-ENOMEM);
+}
+
+int roce5_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_qp *rqp = NULL;
+
+ if (ibqp == NULL) {
+ ROCE_ERR("Invalid parameter, ibqp is NULL.");
+ return -EINVAL;
+ }
+
+ ret = roce5_create_check_init_attr(ibqp->pd, init_attr, udata);
+ if (ret != 0) {
+ ROCE_ERR("Failed to check init attr");
+ return ret;
+ }
+
+ rqp = to_roce5_qp(ibqp);
+ ret = roce5_create_qp_common(rqp, init_attr, udata, ROCE_QP);
+ if (ret != 0) {
+ ROCE_ERR("Failed to execute common qp creation, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ctx_format.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ctx_format.h
new file mode 100644
index 000000000..c435e7090
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ctx_format.h
@@ -0,0 +1,278 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_QP_CTX_FOMRAT_H
+#define ROCE_QP_CTX_FOMRAT_H
+
+#include <linux/types.h>
+
+/* Align each field with 4bytes. */
+#pragma pack(push)
+#pragma pack(4)
+
+struct roce5_chip_seg_rrwc {
+ u32 dw0;
+
+ union {
+ u64 rrw_curt_sge_va;
+ struct {
+ u32 rrw_curt_sge_va_hi;
+ u32 rrw_curt_sge_va_lo;
+ } dw1;
+ };
+
+ u32 rsvd[5];
+};
+
+struct roce5_chip_seg_rcc {
+ u32 dw0;
+
+ union {
+ u64 rc_curt_sge_va;
+ struct {
+ u32 rc_curt_sge_va_hi;
+ u32 rc_curt_sge_va_lo;
+ } dw1;
+ };
+
+ u32 rsvd[5];
+};
+
+struct roce5_chip_seg_sqc {
+ u32 rsvd[9];
+
+ union {
+ u64 sq_curt_sge_va;
+ struct {
+ u32 sq_curt_sge_va_hi;
+ u32 sq_curt_sge_va_lo;
+ } dw9;
+ };
+
+ u32 rsvd1[5];
+};
+
+struct roce5_chip_seg_sqac {
+ u32 rsvd[9];
+
+ union {
+ u64 sqa_curt_sge_va;
+ struct {
+ u32 sqa_curt_sge_va_hi;
+ u32 sqa_curt_sge_va_lo;
+ } dw9;
+ };
+
+ u32 rsvd1[5];
+};
+
+struct roce5_chip_seg_rqc {
+ u32 rsvd[9];
+
+ union {
+ u64 rq_curt_sge_va;
+ struct {
+ u32 rq_curt_sge_va_hi;
+ u32 rq_curt_sge_va_lo;
+ } dw9;
+ };
+
+ u32 rsvd1[5];
+};
+
+struct roce5_chip_seg_srqc {
+ u32 rsvd[9];
+
+ union {
+ u64 srq_curt_sge_va;
+ struct {
+ u32 srq_curt_sge_va_hi;
+ u32 srq_curt_sge_va_lo;
+ } dw9;
+ };
+
+ u32 rsvd1[5];
+};
+
+struct roce5_chip_seg_qpcc {
+ union {
+ u64 sq_rq_l0mtt_gpa;
+ struct {
+ u32 sq_rq_l0mtt_gpa_hi;
+ u32 sq_rq_l0mtt_gpa_lo;
+ } dw0;
+ };
+
+ union {
+ u64 sq_rq_pi_record_gpa_at_hop_num;
+ struct {
+ u32 sq_rq_pi_record_gpa_hi;
+ u32 sq_rq_pi_record_gpa_lo_at_hop_num;
+ } dw2;
+ };
+
+ u32 dw4;
+
+ union {
+ struct {
+ u32 rsvd1 : 22;
+ u32 qp_rre : 1;
+ u32 qp_rae : 1;
+ u32 qp_rwe : 1;
+ u32 rsvd : 7;
+ } bs;
+ u32 value;
+ } dw5;
+
+ u32 rsvd[2];
+};
+
+typedef struct roce5_qpc_chip_seg {
+ struct roce5_chip_seg_rrwc rrwc;
+ struct roce5_chip_seg_rcc rcc;
+ struct roce5_chip_seg_sqc sqc;
+ struct roce5_chip_seg_sqac sqac;
+ union {
+ struct roce5_chip_seg_rqc rqc;
+ struct roce5_chip_seg_srqc srqc;
+ };
+ struct roce5_chip_seg_qpcc qpcc;
+} roce5_qpc_chip_seg_s;
+
+struct roce5_qpc_timer_seg {
+ u32 rsvd[8];
+};
+
+typedef struct roce5_qpc_drv_seg {
+ union {
+ struct {
+ u32 dest_qp : 24;
+ u32 state : 4;
+ u32 rsvd : 4;
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 dw1;
+
+ union {
+ struct {
+ u32 pmtu : 3;
+ u32 rsvd : 13;
+ u32 to_retry_limit : 3;
+ u32 rnr_retry_limit : 3;
+ u32 min_rnr_nak : 5;
+ u32 ack_to : 5;
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+ u32 rsvd : 26;
+ u32 rra_max : 3;
+ u32 sra_max : 3;
+ } bs;
+ u32 value;
+ } dw3;
+} roce5_qpc_drv_seg_s;
+
+typedef struct roce5_drv_path_info {
+ u32 rsvd[2];
+
+ u8 dgid[16];
+
+ union {
+ struct {
+ u32 flow_label : 20;
+ u32 tclass : 8;
+ u32 rsvd : 4;
+ } bs;
+ u32 value;
+ } dw6;
+
+ union {
+ struct {
+ u32 hoplmt : 8;
+ u32 sgid_index : 7;
+ u32 rsvd : 14;
+ u32 sl : 3;
+ } bs;
+ u32 value;
+ } dw7;
+} roce5_drv_path_info_s;
+
+typedef struct roce5_ucode_common_ctx {
+ union {
+ struct {
+ u32 rsvd1 : 20;
+ u32 port : 2;
+ u32 rsvd : 10;
+ } bs;
+ u32 value;
+ } dw0;
+
+ u32 dw1;
+
+ union {
+ u32 qkey;
+ u32 value;
+ } dw2;
+
+ u32 dw3;
+} roce5_ucode_common_ctx_s;
+
+typedef struct roce5_ucode_sq_ctx {
+ union {
+ struct {
+ u32 next_send_psn : 24;
+ u32 rsvd : 8;
+ } bs;
+ u32 value;
+ } dw8;
+
+ u32 rsvd[12];
+} roce5_ucode_sq_ctx_s;
+
+typedef struct roce5_ucode_rq_ctx {
+ union {
+ struct {
+ u32 next_rcv_psn : 24;
+ u32 rsvd : 8;
+ } bs;
+ u32 value;
+ } dw20;
+
+ u32 rsvd[9];
+} roce5_ucode_rq_ctx_s;
+
+typedef struct roce5_drv_ucode_all_info {
+ /* DW0~DW3 */
+ roce5_ucode_common_ctx_s common;
+
+ /* DW4~DW16 */
+ roce5_ucode_sq_ctx_s sq_ctx;
+
+ /* DW17~DW26 */
+ roce5_ucode_rq_ctx_s rq_ctx;
+
+ u32 rsvd;
+} roce5_drv_ucode_all_info_s;
+
+typedef struct roce5_qpc_sw_seg {
+ roce5_qpc_drv_seg_s drv_seg;
+ roce5_drv_path_info_s path_seg;
+ roce5_drv_ucode_all_info_s ucode_seg;
+ u32 rsvd[8];
+} roce5_qpc_sw_seg_s;
+
+typedef struct roce5_qp_context {
+ struct roce5_qpc_chip_seg chip_seg;
+ struct roce5_qpc_timer_seg timer_seg;
+ struct roce5_qpc_sw_seg sw_seg;
+} roce5_qp_context_s;
+
+#pragma pack(pop)
+
+#endif /* ROCE_QP_CTX_FOMRAT_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_destroy.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_destroy.c
new file mode 100644
index 000000000..71a77ada0
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_destroy.c
@@ -0,0 +1,342 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_compat.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_xrc.h"
+#include "roce_pd.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+#include "roce_qp_ext.h"
+#include "roce_qp_extension.h"
+#include "roce_restore.h"
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+#include "hinic5_hmm.h"
+#include "securec.h"
+#include "roce_os_compat.h"
+#include "roce_uld_inner.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_qp_inner.h"
+
+static void roce5_clear_lb_qpn(struct roce5_device *rdev, u32 qpn)
+{
+ int idx = 0;
+ mutex_lock(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+ for (; idx < ROCE_LB_QPN_MAX; idx++) {
+ if (rdev->qp_lb_scqn_ctrl.qp[idx] == qpn) {
+ rdev->qp_lb_scqn_ctrl.qp[idx] = 0;
+ ROCE_DEV_INFO(
+ rdev,
+ "RoCE destroy lb qpn func_id(%d), qpn(%d), idx(%d)",
+ rdev->glb_func_id, qpn, idx);
+ break;
+ }
+ }
+ mutex_unlock(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+}
+
+static void roce5_clean_qp_user(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_udata *udata)
+{
+ struct roce5_ucontext *ucontext = NULL;
+
+ roce5_free_opt_rdmarc(rqp);
+
+ cqm5_object_delete(&(rqp->qpc_info->object));
+
+ roce5_clear_lb_qpn(rdev, rqp->qpn);
+
+ roce5_destroy_pcqc_ext(rqp);
+
+ ucontext = roce5_queue_to_ucontext((void *)(&rqp->ibqp), udata,
+ ROCE_Q_TYPE_QP);
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ roce5_db_unmap_user(ucontext, &rqp->db, rqp->shadow);
+ }
+
+ roce5_destroy_qp_user_umem_mtt(rdev, rqp);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_cq_clean_process
+ Description : roce5_cq_clean_process
+ Input : struct roce5_cq *cq
+ u32 qpn
+ struct roce5_srq *srq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_cq_clean_process(struct roce5_cq *cq, u32 qpn, struct roce5_srq *srq)
+{
+ u32 prod_index = 0;
+ int nfreed = 0;
+ struct roce_cqe *cqe = NULL;
+ struct roce_cqe *dest = NULL;
+ u8 owner_bit = 0;
+ int ret;
+
+ /*
+ * First we need to find the current producer index, so we
+ * know where to start cleaning from. It doesn't matter if HW
+ * adds new entries after this loop -- the QP we're worried
+ * about is already in RESET, so the new entries won't come
+ * from our QP and therefore don't need to be checked.
+ */
+ for (prod_index = cq->cons_index; roce5_get_sw_cqe(cq, prod_index);
+ ++prod_index) {
+ if (prod_index == (u32)((int)cq->cons_index + cq->ibcq.cqe)) {
+ break;
+ }
+ }
+
+ /*
+ * Now sweep backwards through the CQ, removing CQ entries
+ * that match our QP by copying older entries on top of them.
+ */
+ /* xcqe:qpn's cqe.
+ CI
+ +--------+------+------+------+----------+
+ b4_clean: | | cqe1 | xcqe2| cqe3 | |
+ +--------+------+------+------+----------+
+ \
+ \
+ +---------------+------+------+----------+
+ af_clean: | | cqe1 | cqe3 | |
+ +---------------+------+------+----------+
+ */
+ while ((int)--prod_index - (int)cq->cons_index >= 0) {
+ cqe = (struct roce_cqe *)roce5_get_cqe(
+ cq, prod_index & (u32)cq->cqe_mask);
+
+ cqe->dw0.value = roce5_convert_cpu32(cqe->dw0.value);
+ cqe->dw1.value = roce5_convert_cpu32(cqe->dw1.value);
+ cqe->dw7.value = roce5_convert_cpu32(cqe->dw7.value);
+
+ if (cqe->dw0.bs.qpn == qpn) {
+ if (srq && (cqe->dw1.bs.s_r == ROCE_CQE_RECV_COMP)) {
+ roce5_free_srq_wqe(srq, cqe->dw7.bs.wqe_cnt);
+ }
+
+ ++nfreed;
+ } else if (nfreed != 0) {
+ dest = (struct roce_cqe *)roce5_get_cqe(
+ cq, (unsigned int)((int)prod_index + nfreed) &
+ (unsigned int)cq->cqe_mask);
+ dest->dw0.value = roce5_convert_cpu32(dest->dw0.value);
+ owner_bit = dest->dw0.bs.owner;
+ ret = memcpy_s((void *)dest, sizeof(struct roce_cqe),
+ (void *)cqe, sizeof(struct roce_cqe));
+ if (ret != 0) {
+ ROCE_ERR("[Failed to memcpy dest.(ret:%d)",
+ ret);
+ return;
+ }
+ dest->dw0.bs.owner = owner_bit;
+ dest->dw0.value = roce5_convert_be32(dest->dw0.value);
+ dest->dw1.value = roce5_convert_be32(dest->dw1.value);
+ dest->dw7.value = roce5_convert_be32(dest->dw7.value);
+ } else {
+ ROCE_INFO("Nothing need to do");
+ }
+
+ cqe->dw0.value = roce5_convert_be32(cqe->dw0.value);
+ cqe->dw1.value = roce5_convert_be32(cqe->dw1.value);
+ cqe->dw7.value = roce5_convert_be32(cqe->dw7.value);
+ }
+
+ if (nfreed != 0) {
+ cq->cons_index += (u32)nfreed;
+ /*
+ * Make sure update of buffer contents is done before
+ * updating consumer index.
+ */
+ wmb();
+
+ roce5_cq_set_ci(cq);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_clean_qp_kernel
+ Description : roce5_clean_qp_kernel
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2017/04/26
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_clean_qp_kernel(struct roce5_device *rdev,
+ struct roce5_qp *rqp)
+{
+ struct roce5_cq *send_cq = NULL;
+ struct roce5_cq *recv_cq = NULL;
+ unsigned long flags = 0; /* type required by kernel API */
+
+ roce5_free_opt_rdmarc(rqp);
+
+ roce5_get_cqs(rqp, &send_cq, &recv_cq);
+
+ spin_lock_irqsave(&rdev->reset_flow_resource_lock, flags);
+ roce5_lock_cqs(send_cq, recv_cq);
+ /* del from lists under both locks above to protect reset flow paths */
+ list_del(&rqp->qps_list);
+ list_del(&rqp->cq_send_list);
+ list_del(&rqp->cq_recv_list);
+
+ roce5_cq_clean_process(recv_cq, rqp->qpn,
+ rqp->ibqp.srq ? to_roce5_srq(rqp->ibqp.srq) :
+ NULL);
+
+ if (send_cq != recv_cq) {
+ roce5_cq_clean_process(send_cq, rqp->qpn, NULL);
+ }
+
+ roce5_unlock_cqs(send_cq, recv_cq);
+ spin_unlock_irqrestore(&rdev->reset_flow_resource_lock, flags);
+
+ cqm5_object_delete(&(rqp->qpc_info->object));
+
+ roce5_clear_lb_qpn(rdev, rqp->qpn);
+
+ if (rqp->sq.wrid) {
+ kvfree(rqp->sq.wrid);
+ rqp->sq.wrid = NULL;
+ }
+
+ if (rqp->rq.wrid) {
+ kvfree(rqp->rq.wrid);
+ rqp->rq.wrid = NULL;
+ }
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ cqm5_object_delete(&(rqp->qp_buf_info->object));
+ }
+
+ hmm_mtt_free(rdev->hwdev, &rqp->mtt, SERVICE_T_ROCE);
+}
+
+static int roce5_qp_destroy(struct roce5_qp *rqp, struct roce5_device *rdev)
+{
+ int ret = 0;
+
+ ret = roce5_qp_modify_2rst_cmd(rdev, rqp->qpn);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify QP(0x%06x) to RESET, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_qp_cache_out_cmd(rdev, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "QP(0x%06x) cache invalid, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_destroy_qp_common(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_pd *pd = roce5_get_pd(rqp);
+ roce_user_handle_t hdl = { 0 };
+
+ roce5_destroy_qp_ext_deinit(rqp);
+
+ if (rqp->wb_va != NULL) {
+ dma_free_coherent(rdev->dev, sizeof(u32), rqp->wb_va,
+ rqp->wb_dma);
+ rqp->wb_va = NULL;
+ }
+
+ if (rqp->qp_state != IB_QPS_RESET) {
+ ret = roce5_qp_destroy(rqp, rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to destroy qp, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ rqp->qp_state = IB_QPS_RESET;
+ }
+
+ if (pd->ibpd.uobject) {
+ roce5_clean_qp_user(rdev, rqp, udata);
+ } else {
+ roce5_clean_qp_kernel(rdev, rqp);
+
+ if (roce5_sqp_check(rqp) != 0 && rqp->sqp_attr != NULL) {
+ kfree(rqp->sqp_attr);
+ rqp->sqp_attr = NULL;
+ }
+ }
+
+ ROCE_CONSTUCT_ULD_HDL_RQP(&hdl, rdev, rqp, NULL, NULL, NULL, NULL);
+ ret = roce5_uld_qp_destroy((roce_uld_handle)&hdl);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to destroy uld qp, ret(%d).", ret);
+ return ret;
+ }
+
+ mutex_lock(&rdev->qp_cnt.cur_qps_mutex);
+ rdev->qp_cnt.del_qp_cnt++;
+ mutex_unlock(&rdev->qp_cnt.cur_qps_mutex);
+ return 0;
+}
+
+int roce5_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
+{
+ struct roce5_qp *rqp = NULL;
+ struct roce5_device *rdev = NULL;
+ int ret;
+
+ if (ibqp == NULL) {
+ ROCE_ERR("Ibqp is null");
+ return -EINVAL;
+ }
+
+ rqp = to_roce5_qp(ibqp);
+ rdev = to_roce5_dev(ibqp->device);
+
+ ret = roce5_destroy_qp_common(rdev, rqp, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Error occur when destroy qp! ret(%d).",
+ ret);
+ return ret;
+ }
+
+#if !defined(IB_DEVICE_OPS_HAVE_IB_QP_OBJ)
+ kfree(rqp);
+#endif
+ return 0;
+}
+
+int roce5_destroy_qp_ofa(struct ib_qp *ibqp)
+{
+ return roce5_destroy_qp(ibqp, NULL);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_exp.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_exp.h
new file mode 100644
index 000000000..646717c2a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_exp.h
@@ -0,0 +1,80 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_QP_EXP_H
+#define ROCE_QP_EXP_H
+
+#include <linux/io-mapping.h>
+#include <linux/list.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "hinic5_rdma.h"
+#include "hinic5_cqm.h"
+
+#include "roce.h"
+#include "roce_db.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+
+#define EXP_OK (0)
+#define EXP_PARAM_ERR (1)
+#define EXP_FUNC_ERR (2)
+
+#define QPC_MIN_SIZE (512)
+#define CONTX_SZ (sizeof(struct roce_qp_context) / QPC_MIN_SIZE)
+
+#define BUFFER_SZ (sizeof(struct roce_qp_context) / sizeof(u32))
+
+#define TYPE_LEN (8)
+#define DEV_NUM (32)
+#define QPN_MAX (0xFFFFF)
+#define QPN_MIN (0)
+#define IB_QP_EXP_CMD (1 << 23)
+#define ROCE_OPTPAR_EXP (1 << 16)
+#define VA_OFFSET (8)
+
+struct roce5_device_list {
+ struct ib_device *ib_dev[DEV_NUM];
+ int ib_dev_num;
+ struct mutex mutex;
+};
+
+struct ib_qp_info {
+ dma_addr_t sq_pg_base_addr[64];
+ dma_addr_t hw_doorbell_addr;
+ dma_addr_t sw_doorbell_addr;
+
+ u32 sq_depth;
+ u32 qpn;
+ u8 sq_pg_cnt;
+ u8 qp_cos;
+ u8 cntx_sz;
+ u8 sq_wqe_size;
+};
+
+struct ib_qp_attr_data {
+ u32 data_type; //plog:1
+ u32 data_len;
+ u8 *data_buf;
+};
+
+struct ib_qp_attr_exp {
+ struct ib_qp_attr qp_attr;
+ struct ib_qp_attr_data qp_attr_data;
+};
+
+struct roce5_device_list *roce5_get_plog_device_info(void);
+
+int ib_get_qp_info(char *dev_name, int qpn, struct ib_qp_info *qp_info);
+struct ib_qp *ib_get_qp(const char *dev_name, int qpn);
+int ib_put_qp(struct ib_qp *ibqp);
+int roce5_qp_modify_exp(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask,
+ enum ib_qp_state cur_state, enum ib_qp_state new_state,
+ u16 vlan_id);
+int roce5_modify_extend_qp(struct ib_qp_attr *attr, int attr_mask,
+ struct ib_qp *ibqp);
+
+#endif //ROCE_QP_EXP_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.c
new file mode 100644
index 000000000..a548667ee
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.c
@@ -0,0 +1,39 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include "roce_qp.h"
+#include "roce_infra.h"
+#include "roce_obj_ext.h"
+#ifdef ENABLE_HYPER_ROCE
+#include "hyper_roce_qp.h"
+#endif
+
+const struct roce5_ext_reg g_rqp_exts[] = {
+#ifdef ENABLE_HYPER_ROCE
+ {
+ .ext_id = ROCE_EXT_HYPER_ROCE,
+ .data_size = sizeof(struct roce5_qp_hyper_extend),
+ .init_func = roce5_hyper_qp_init,
+ .cleanup_func = roce5_hyper_qp_cleanup,
+ },
+#endif
+};
+
+const u8 g_rqp_exts_num = sizeof(g_rqp_exts) / sizeof(struct roce5_ext_reg);
+
+int roce5_create_qp_ext_init(struct roce5_qp *rqp)
+{
+ int ret = roce5_obj_ext_init((void *)rqp, g_rqp_exts, g_rqp_exts_num,
+ &rqp->obj_ext);
+ if (ret != 0) {
+ ROCE_ERR("Failed to init qp extension, ret(%d).", ret);
+ return ret;
+ }
+ return 0;
+}
+
+void roce5_destroy_qp_ext_deinit(struct roce5_qp *rqp)
+{
+ roce5_obj_ext_deinit((void *)rqp, g_rqp_exts, g_rqp_exts_num,
+ &rqp->obj_ext);
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.h
new file mode 100644
index 000000000..8b3e95565
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_ext.h
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_QP_EXT_H
+#define ROCE_QP_EXT_H
+
+#include "roce_qp.h"
+#include "roce_obj_ext.h"
+
+static inline void *roce5_qp_get_ext_buf(struct roce5_qp *rqp,
+ enum ROCE_EXT_ID ext_id)
+{
+ return roce5_obj_ext_get_buf(&rqp->obj_ext, ext_id);
+}
+
+int roce5_create_qp_ext_init(struct roce5_qp *rqp);
+void roce5_destroy_qp_ext_deinit(struct roce5_qp *rqp);
+
+#endif /* ROCE_QP_EXT_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_inner.h b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_inner.h
new file mode 100644
index 000000000..c757ce2ba
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_inner.h
@@ -0,0 +1,17 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef ROCE_QP_INNER_H
+#define ROCE_QP_INNER_H
+
+#include <rdma/ib_verbs.h>
+#include "roce.h"
+#include "roce_qp.h"
+
+int roce5_destroy_qp_common(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_udata *udata);
+void roce5_destroy_qp_user_umem_mtt(struct roce5_device *rdev,
+ struct roce5_qp *rqp);
+
+#endif /* ROCE_QP_INNER_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_modify.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_modify.c
new file mode 100644
index 000000000..5a6a4ec7b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_modify.c
@@ -0,0 +1,2398 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <rdma/ib_verbs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+
+#include "comm_defs.h"
+#include "roce_compat.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_user.h"
+#include "roce_xrc.h"
+#include "roce_pd.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_cqm_cmd.h"
+#include "roce_qp.h"
+#include "roce_qp_exp.h"
+#include "roce_qp_extension.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "securec.h"
+#include "roce_ctx_format.h"
+#include "roce_npu_cmd.h"
+#include "roce_npu_cmd_qp_defs.h"
+#include "roce_npu_cmd_ext_defs.h"
+#include "roce_cmd.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_uld_inner.h"
+#include "roce_netdev.h"
+#include "roce_os_compat.h"
+
+#ifdef ROCE_ANTI_ATTACK
+#include "roce_anti_attack.h"
+#endif
+
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+
+#define ROCE_MTT_GPA_VALID 0x1
+#define ROCE_WQE_PREFETCH_MAXNUM 5 //5: 8(count word) WQEBB
+#define ROCE_SQ_WQEBB_SIZE_SHIFT 4
+#define ROCE_SQ_WQEBB_SIZE_MASK 0x7
+#define ROCE_SQ_PD_MASK 0x3ffff
+#define ROCE_SQ_PAGE_SIZE_MASK 0xf
+#define ROCE_SQ_WQECNT_LTH 4
+#define ROCE_SQ_PREFETCH_MINNUM 2
+#define ROCE_SQ_PREFETCH_MAXNUM 4
+#define ROCE_SQ_SIZE_MASK 0x1f
+#define ROCE_SQ_CQN_MASK 0xfffff
+#define ROCE_RQ_WQECNT_LTH 0xe
+#define ROCE_RQ_MTT_PREFETCH_MAXLEN0 3
+#define ROCE_RQ_MTT_PREFETCH_MAXWQE 7
+#define ROCE_RQ_WQE_PREFETCH_MAXNUM 7
+#define ROCE_SRQ_INIT_STATE 0xf
+#define ROCE_MAX_PI_ON_CHIP_QPN 1024
+
+enum {
+ BIT_LENGTH_IB_MTU_256 = 8,
+ BIT_LENGTH_IB_MTU_512,
+ BIT_LENGTH_IB_MTU_1024,
+ BIT_LENGTH_IB_MTU_2048,
+ BIT_LENGTH_IB_MTU_4096,
+ BIT_LENGTH_IB_MTU_8192,
+};
+
+enum {
+ CACHE_INVLAID_ALLOC,
+ CACHE_INVLAID_CMDQ,
+ CACHE_INVLAID_RDMARC_CHECK,
+ CACHE_INVLAID_QP_CHECK,
+ MODIFY_2RST_CMDQ,
+ CMDQ_SDKCALL_BUTT
+};
+
+#define ROCE_CMDQ_TIMEOUT 1000
+#define ROCE_CMDQ_TIMEOUT_10MS 10
+
+#ifdef ROCE_SIGN_EN
+enum mtt_check_type_e { MTT_CHECK_TYPE_0 = 0, MTT_CHECK_TYPE_1 };
+
+#define ROCE_QP_QPCC_SIGN_WIDTH 5
+#define ROCE_QP_QPCC_SIGN_SPLITNUM 4
+#define ROCE_QP_QPCC_SIGN_CHECKBITS \
+ (ROCE_QP_QPCC_SIGN_WIDTH * ROCE_QP_QPCC_SIGN_SPLITNUM)
+
+#define ROCE_QP_SUB_SIGN_WIDTH 3
+#define ROCE_QP_SUB_SIGN_SPLITNUM 5
+#define ROCE_QP_SUB_SIGN_CHECKBITS \
+ (ROCE_QP_SUB_SIGN_WIDTH * ROCE_QP_SUB_SIGN_SPLITNUM)
+
+#define ROCE_QP_GPA_SIGN_WIDTH 3
+#define ROCE_QP_GPA_SIGN_SPLITNUM 11
+#define ROCE_QP_GPA_SIGN_CHECKBITS \
+ (ROCE_QP_GPA_SIGN_WIDTH * ROCE_QP_GPA_SIGN_SPLITNUM)
+
+#define ROCE_SQ_WQE_SIGN_WIDTH 8
+#define ROCE_SQ_WQE_SIGN_SPLITNUM 9
+#define ROCE_SQ_WQE_SIGN_CHECKBITS_1 32
+#define ROCE_SQ_WQE_SIGN_CHECKBITS_2 20
+#define ROCE_SQ_WQE_SIGN_CHECKBITS_12 \
+ (ROCE_SQ_WQE_SIGN_CHECKBITS_2 + ROCE_SQ_WQE_SIGN_CHECKBITS_1)
+#define ROCE_SQ_WQE_SIGN_CHECKBITS_3 20
+#define ROCE_SQ_WQE_SIGN_CHECKBITS_123 \
+ (ROCE_SQ_WQE_SIGN_CHECKBITS_3 + ROCE_SQ_WQE_SIGN_CHECKBITS_12)
+#define ROCE_SQ_WQE_SIGN_CHECKBITS \
+ (ROCE_SQ_WQE_SIGN_WIDTH * ROCE_SQ_WQE_SIGN_SPLITNUM)
+
+#define ROCE_MTT_SIGN_WIDTH 11
+#define ROCE_MTT_SIGN_SPLITNUM 5
+#define ROCE_MTT_SIGN_CHECKBITS_1 22
+#define ROCE_MTT_SIGN_CHECKBITS_2 33
+#define ROCE_MTT_SIGN_CHECKBITS_12 \
+ (ROCE_MTT_SIGN_CHECKBITS_1 + ROCE_MTT_SIGN_CHECKBITS_2)
+#define ROCE_MTT_SIGN_CHECKBITS (ROCE_MTT_SIGN_WIDTH * ROCE_MTT_SIGN_SPLITNUM)
+
+#define ROCE_MTT_BLOCK_SIGN_WIDTH 5
+#define ROCE_MTT_BLOCK_SIGN_SPLITNUM 11
+
+/* ****************************************************************************
+ Prototype : roce5_calculate_sign_bit
+ Description : roce5_calculate_signature
+ Input : u32 *check_bit
+ u32 sign_width
+ u32 sign_split
+ u32 *sign_bit
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_calculate_sign_bit(u32 *check_bit, u32 sign_width,
+ u32 sign_split, u32 *sign_bit)
+{
+ u32 i = 0;
+ u32 j = 0;
+
+ for (i = 0; i < sign_width; i++) {
+ sign_bit[i] = 0;
+ for (j = 0; j < sign_split; j++) {
+ sign_bit[i] = sign_bit[i] ^
+ check_bit[i + sign_width * j];
+ }
+
+ sign_bit[i] = (~sign_bit[i]) & 0x1;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_calculate_signature
+ Description : roce5_calculate_signature
+ Input : u32 *sign_bit
+ u32 sign_width
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_calculate_signature(u32 *sign_bit, u32 sign_width)
+{
+ u32 i = 0;
+ u32 signature = 0;
+
+ for (i = 0; i < sign_width; i++) {
+ signature |= sign_bit[i] << i;
+ }
+
+ return (signature & ((1U << sign_width) - 1));
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_qp_rcc_sign
+ Description : Signature 3bit
+ CheckedBits = QPn[14:0]
+ Input : u32 qpn
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_qp_rcc_sign(u32 qpn)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_QP_SUB_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_QP_SUB_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_QP_SUB_SIGN_CHECKBITS; i++) {
+ if (qpn & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_QP_SUB_SIGN_WIDTH,
+ ROCE_QP_SUB_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_QP_SUB_SIGN_WIDTH);
+
+ return signature;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_qp_sqc_sign
+ Description : Signature 3bit
+ CheckedBits = QPn[14:0]
+ Input : u32 qpn
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_qp_sqc_sign(u32 qpn)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_QP_SUB_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_QP_SUB_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_QP_SUB_SIGN_CHECKBITS; i++) {
+ if (qpn & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_QP_SUB_SIGN_WIDTH,
+ ROCE_QP_SUB_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_QP_SUB_SIGN_WIDTH);
+
+ return signature;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_qp_sqac_sign
+ Description : Signature 3bit
+ CheckedBits = QPn[14:0]
+ Input : u32 qpn
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_qp_sqac_sign(u32 qpn)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_QP_SUB_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_QP_SUB_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_QP_SUB_SIGN_CHECKBITS; i++) {
+ if (qpn & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_QP_SUB_SIGN_WIDTH,
+ ROCE_QP_SUB_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_QP_SUB_SIGN_WIDTH);
+
+ return signature;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_qp_rqc_sign
+ Description : Signature 3bit
+ CheckedBits = QPn[14:0]
+ Input : u32 qpn
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_qp_rqc_sign(u32 qpn)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_QP_SUB_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_QP_SUB_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_QP_SUB_SIGN_CHECKBITS; i++) {
+ if (qpn & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_QP_SUB_SIGN_WIDTH,
+ ROCE_QP_SUB_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_QP_SUB_SIGN_WIDTH);
+
+ return signature;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_qp_rrwc_sign
+ Description : Signature 3bit
+ CheckedBits = QPn[14:0]
+ Input : u32 qpn
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_qp_rrwc_sign(u32 qpn)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_QP_SUB_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_QP_SUB_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_QP_SUB_SIGN_CHECKBITS; i++) {
+ if (qpn & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_QP_SUB_SIGN_WIDTH,
+ ROCE_QP_SUB_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_QP_SUB_SIGN_WIDTH);
+
+ return signature;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_gen_sq_wqe_sign
+ Description : Signature 8bit
+ CheckedBits = {QPn[19:0], WQECI[19:0], WQE.Header[31:0]}
+ Input : u32 qpn
+ u32 wqe_ci
+ u32 wqe_header
+ Output : None
+
+ 1.Date : 2017/4/1
+ Modification : Created function
+
+**************************************************************************** */
+static u32 roce5_gen_sq_wqe_sign(u32 qpn, u32 wqe_ci, u32 wqe_header)
+{
+ u32 i;
+ u32 signature = 0;
+ u32 sign_bit[ROCE_SQ_WQE_SIGN_WIDTH] = { 0 };
+ u32 check_bit[ROCE_SQ_WQE_SIGN_CHECKBITS] = { 0 };
+
+ for (i = 0; i < ROCE_SQ_WQE_SIGN_CHECKBITS_1; i++) {
+ if (wqe_header & (1U << i)) {
+ check_bit[i] = 1;
+ }
+ }
+
+ for (i = ROCE_SQ_WQE_SIGN_CHECKBITS_1;
+ i < ROCE_SQ_WQE_SIGN_CHECKBITS_12; i++) {
+ if (wqe_ci & (1U << (i - ROCE_SQ_WQE_SIGN_CHECKBITS_1))) {
+ check_bit[i] = 1;
+ }
+ }
+
+ for (i = ROCE_SQ_WQE_SIGN_CHECKBITS_12;
+ i < ROCE_SQ_WQE_SIGN_CHECKBITS_123; i++) {
+ if (qpn & (1U << (i - ROCE_SQ_WQE_SIGN_CHECKBITS_12))) {
+ check_bit[i] = 1;
+ }
+ }
+
+ roce5_calculate_sign_bit(check_bit, ROCE_SQ_WQE_SIGN_WIDTH,
+ ROCE_SQ_WQE_SIGN_SPLITNUM, sign_bit);
+
+ signature = roce5_calculate_signature(sign_bit, ROCE_SQ_WQE_SIGN_WIDTH);
+
+ return signature;
+}
+#endif
+
+#define ROCE_BASE_GID_IDX \
+ 1 /* current IP mode supports precise push GID, reserved this field compatible old version firmware */
+static void roce5_qp_set_path(const struct roce5_qp *rqp,
+ struct rdma_ah_attr *ah_attr,
+ roce_verbs_qpc_attr_path_s *path_info)
+{
+ u8 *dmac = ah_attr->roce.dmac;
+ int ret;
+
+ path_info->dw7.bs.hoplmt = (u8)ah_attr->grh.hop_limit;
+ path_info->dw6.bs.tclass =
+ (u8)(ah_attr->grh.traffic_class | IP_ECN_PERMIT);
+ path_info->dw6.bs.flow_label = ah_attr->grh.flow_label &
+ 0xfffff; /* flow_label: 20bit */
+ path_info->dw7.bs.sgid_index = ah_attr->grh.sgid_index &
+ 0x7f; /* sgid_index: 7bit */
+
+ path_info->dw7.bs.base_sgid_n =
+ (path_info->dw7.bs.sgid_index != ROCE_BASE_GID_IDX);
+
+ ret = memcpy_s((void *)path_info->dgid, sizeof(path_info->dgid),
+ (void *)ah_attr->grh.dgid.raw, sizeof(path_info->dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ }
+
+ ret = memcpy_s((void *)&path_info->dmac_l32,
+ sizeof(path_info->dmac_l32),
+ (void *)&dmac[ROCE_RAH_DMAC_L32_START],
+ sizeof(path_info->dmac_l32));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dmac_l32.(ret:%d)", ret);
+ }
+ path_info->dmac_l32 = cpu_to_be32(path_info->dmac_l32);
+ path_info->dw0.bs.dmac_h16 = (dmac[0] << ROCE_RAH_DMAC_H16_SHIFT) |
+ dmac[1]; //shift dmac[0] left by 8 bits
+ path_info->dw7.bs.sl = (ah_attr->sl & 0x7); /* sl: 3bit */
+ path_info->dw0.bs.udp_src_port_h =
+ ((rqp->qpn >> ROCE_UDP_SRC_PORT_H8_SHIFT) & 0xff);
+ path_info->dw7.bs.udp_src_port = (rqp->qpn & 0xff);
+#ifdef ROCE_BONDING_EN
+ path_info->dw0.bs.bond_tx_hash_value = (rqp->tx_hash_value & 0xf);
+#endif
+}
+
+struct roce5_pd *roce5_get_pd(struct roce5_qp *rqp)
+{
+ if (rqp->qp_type == IB_QPT_XRC_TGT) {
+ return to_roce5_pd(to_roce5_xrcd(rqp->ibqp.xrcd)->pd);
+ } else {
+ return to_roce5_pd(rqp->ibqp.pd);
+ }
+}
+
+void roce5_get_cqs(struct roce5_qp *rqp, struct roce5_cq **send_cq,
+ struct roce5_cq **recv_cq)
+{
+ switch (rqp->qp_type) {
+ case IB_QPT_XRC_TGT:
+ *send_cq = to_roce5_cq(to_roce5_xrcd(rqp->ibqp.xrcd)->cq);
+ *recv_cq = *send_cq;
+ break;
+
+ case IB_QPT_XRC_INI:
+ *send_cq = to_roce5_cq(rqp->ibqp.send_cq);
+ *recv_cq = *send_cq;
+ break;
+
+ default:
+ *send_cq = to_roce5_cq(rqp->ibqp.send_cq);
+ *recv_cq = to_roce5_cq(rqp->ibqp.recv_cq);
+ break;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_access_flags
+ Description : roce5_set_access_flags
+ Input : struct roce5_qp *rqp
+ roce_verbs_qp_attr_s *qp_attr
+ struct ib_qp_attr *attr
+ int attr_mask
+ Output : None
+
+ 1.Date : 2015/5/26
+ Modification : Created function
+ 2.Date : 2016/2/26
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_set_access_flags(struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr,
+ struct ib_qp_attr *attr, int attr_mask)
+{
+ u16 dest_rd_atomic = 0;
+ u32 access_flags = 0;
+
+ if ((((u32)attr_mask) & IB_QP_MAX_DEST_RD_ATOMIC) != 0) {
+ dest_rd_atomic = attr->max_dest_rd_atomic;
+ } else {
+ dest_rd_atomic = rqp->rsp_depth;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_ACCESS_FLAGS) != 0) {
+ access_flags = (u32)attr->qp_access_flags;
+ } else {
+ access_flags = rqp->atomic_rd_en;
+ }
+
+ if (dest_rd_atomic == 0) {
+ access_flags &= IB_ACCESS_REMOTE_WRITE;
+ }
+
+ if ((access_flags & IB_ACCESS_REMOTE_READ) != 0) {
+ qp_attr->com_info.dw0.bs.rre = 1; /* rc_rre: 1bits */
+ }
+
+ if ((access_flags & IB_ACCESS_REMOTE_ATOMIC) != 0) {
+ qp_attr->com_info.dw0.bs.rae = 1; /* rc_rae: 1bits */
+ }
+
+ if ((access_flags & IB_ACCESS_REMOTE_WRITE) != 0) {
+ qp_attr->com_info.dw0.bs.rwe = 1; /* rrw_rwe: 1bits */
+ }
+}
+
+bool roce5_sqp_check(const struct roce5_qp *rqp)
+{
+ if (((rqp->qp_type == IB_QPT_GSI) &&
+ (rqp->qpn == ROCE_QP_SMI_QP_NUM)) ||
+ (rqp->qpn == ROCE_QP_GSI_QP_NUM)) {
+ return true;
+ }
+
+ return false;
+}
+
+/* ****************************************************************************
+ Prototype : store_sqp_attrs
+ Description : save the special
+ Input : struct roce5_qp *rqp
+ const struct ib_qp_attr *attr
+ int attr_mask
+ Output : int status
+
+ 1.Date : 2015/7/24
+ Modification : Created function
+
+**************************************************************************** */
+static int store_sqp_attrs(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ int attr_mask)
+{
+ if (rqp->sqp_attr == NULL) {
+ ROCE_ERR("Error! sqp attribute is NULL, qpn(%u).", rqp->qpn);
+ return -EINVAL;
+ }
+
+ if (((u32)attr_mask & IB_QP_PKEY_INDEX) != 0) {
+ rqp->sqp_attr->pkey_index = attr->pkey_index;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_QKEY) != 0) {
+ rqp->sqp_attr->qkey = attr->qkey;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_SQ_PSN) != 0) {
+ rqp->sqp_attr->send_psn = attr->sq_psn;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : qpc_seg_to_be
+ Input : struct roce_qp_context *be_ctx
+ struct roce_qp_context *le_ctx
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2015/7/29
+ Author : zhaoxinteng
+ Modification : Created function
+
+**************************************************************************** */
+static void qpc_seg_to_be(roce_verbs_qp_attr_s *be_ctx,
+ roce_verbs_qp_attr_s *le_ctx, struct roce5_qp *rqp)
+{
+ /* DRV Seg */
+ int ret;
+
+ ret = memcpy_s((void *)be_ctx->path_info.dgid,
+ sizeof(le_ctx->path_info.dgid),
+ (void *)le_ctx->path_info.dgid,
+ sizeof(le_ctx->path_info.dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ }
+
+ /* CHIP Seg */
+ be_ctx->chip_seg.dw0.sq_rq_l0mtt_gpa =
+ cpu_to_be64(le_ctx->chip_seg.dw0.sq_rq_l0mtt_gpa);
+
+ be_ctx->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num = cpu_to_be64(
+ le_ctx->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qpc_to_be
+ Description : translate big endian
+ Input : roce_verbs_qp_attr_s *qp_attr
+ struct roce5_qp *rqp
+ u32 *be_ctx
+ Output : None
+
+ 1.Date : 2015/7/29
+ Author : zhaoxinteng
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_qpc_to_be(roce_verbs_qp_attr_s *qp_attr, struct roce5_qp *rqp,
+ u32 *be_ctx)
+{
+ u32 *ctx = NULL;
+ u32 *ctx1 = NULL;
+ u32 i = 0;
+ u32 ctx_size = 0;
+
+ ctx = be_ctx;
+ ctx1 = (u32 *)qp_attr;
+ ctx_size = sizeof(roce_verbs_qp_attr_s) / sizeof(u32);
+
+ for (i = 0; i < ctx_size; ++i, ++ctx1, ++ctx) {
+ *ctx = cpu_to_be32(*ctx1);
+ }
+
+ qpc_seg_to_be((roce_verbs_qp_attr_s *)((void *)be_ctx), qp_attr, rqp);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_alloc_opt_rdmarc
+ Description : alloc rdmarc when modify qp
+ Input : struct roce5_qp *rqp
+ struct ib_qp_attr *attr
+ int attr_mask
+ Output : None
+
+ 1.Date : 2016/01/30
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_alloc_opt_rdmarc(struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr, int attr_mask)
+{
+ int ret = 0;
+ struct roce5_device *rdev = NULL;
+ u32 response_depth = 0;
+
+ rdev = to_roce5_dev(rqp->ibqp.device);
+ response_depth = (attr->max_dest_rd_atomic == 0) ?
+ 1 :
+ (u32)ROCE_ROUNDUP_POW_OF_TWO(
+ (u32)attr->max_dest_rd_atomic);
+ if (rqp->rsp_depth != response_depth) {
+ if (rqp->rsp_depth > 0) {
+ roce5_rdma_rdmarc_free(rdev->hwdev, &rqp->rdmarc);
+ }
+
+ ret = roce5_rdma_rdmarc_alloc(rdev->hwdev, response_depth,
+ &rqp->rdmarc);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc rdma rdmarc, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ rqp->rsp_depth = (u16)response_depth;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_free_opt_rdmarc
+ Description : free rdmarc when modify qp failed or destory qp
+ Input : struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2016/01/30
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_free_opt_rdmarc(struct roce5_qp *rqp)
+{
+ struct roce5_device *rdev = NULL;
+
+ rdev = to_roce5_dev(rqp->ibqp.device);
+
+ if (rqp->rsp_depth > 0) {
+ roce5_rdma_rdmarc_free(rdev->hwdev, &rqp->rdmarc);
+ }
+
+ rqp->rsp_depth = 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_opt_rdmarc
+ Description : set opt rdmarc field
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ roce_verbs_qp_attr_s *qp_attr
+ Output : None
+
+ 1.Date : 2017/04/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_set_opt_rdmarc(struct rdma_rdmarc *rdmarc, u16 depth,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ qp_attr->chip_seg.dw10.bs.rc_page_gpa_h =
+ (rdmarc->dma_addr >> ROCE5_RDMARC_GPA_H_SHIFT) &
+ 0xffffff; /* high:24bit, 64-24= 40 */
+ qp_attr->chip_seg.rc_page_gpa_l =
+ (u32)(rdmarc->dma_addr >>
+ ROCE5_RDMARC_GPA_L_SHIFT); //bit[39:8]
+ qp_attr->chip_seg.dw4.bs.rc_size = rdmarc->order;
+ qp_attr->com_info.dw1.bs.rra_max =
+ ((u8)fls(depth - 1)) &
+ ROCE5_RDMARC_RRA_MAX_MASK; /* rra_max:3bit */
+ qp_attr->chip_seg.dw4.bs.rc_max_size =
+ rdmarc->ext_order - ROCE5_RDMARC_EXT_ORDER_SHIFT;
+}
+
+static int roce5_set_opt_mtu(struct roce5_device *rdev,
+ roce_verbs_qp_attr_s *qp_attr,
+ const struct ib_qp_attr *attr)
+{
+ enum roce5_mtu rmtu = (enum roce5_mtu)attr->path_mtu;
+ if (rmtu == ROCE_MTU_8192 && ROCE5_SUPPORT_8K_MTU(rdev) == 0) {
+ ROCE_DEV_ERR(rdev, "Not support 8K MTU.");
+ return -EINVAL;
+ }
+
+ qp_attr->com_info.dw3.bs.pmtu = (u32)rmtu & 0x7; /* 1,2,3,4,5 */
+ qp_attr->com_info.dw5.bs.mtu_code =
+ ROCE_QPC_PMTU_TRANSLATE(rmtu); /* 0,1,3,7,15 */
+ if (qp_attr->com_info.dw3.bs.pmtu == IB_MTU_1024) {
+ qp_attr->com_info.dw3.bs.base_mtu_n = 0;
+ } else {
+ qp_attr->com_info.dw3.bs.base_mtu_n = 1;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_opt_sra
+ Description : set opt sra
+ Input : roce_verbs_qp_attr_s *qp_attr
+ struct ib_qp_attr *attr
+ Output : None
+
+ 1.Date : 2017/04/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_set_opt_sra(roce_verbs_qp_attr_s *qp_attr,
+ struct ib_qp_attr *attr)
+{
+ u8 initiator_depth;
+
+ initiator_depth =
+ (attr->max_rd_atomic == 0) ?
+ 1 :
+ (u8)ROCE_ROUNDUP_POW_OF_TWO((u32)attr->max_rd_atomic);
+ qp_attr->com_info.dw1.bs.sra_max =
+ ((u32)ROCE_FLS(initiator_depth - 1)) & 0x7;
+}
+
+static void roce5_set_opt_attr_av(struct roce5_qp *rqp,
+ struct roce5_device *rdev,
+ struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr, u32 *optpar)
+{
+ u8 cos;
+ roce5_get_cos_inbuf_s inbuf = { 0 };
+
+ roce5_qp_set_path(rqp, &attr->ah_attr, &qp_attr->path_info);
+ qp_attr->com_info.dw3.bs.ext_mtu = rqp->ext_mtu & 0x1;
+ qp_attr->com_info.dw3.bs.ext_md = rqp->ext_mtu_mode & 0x1;
+ *optpar |= ROCE_QP_OPTPAR_PRIMARY_ADDR_PATH;
+
+ inbuf.sl = attr->ah_attr.sl;
+ inbuf.sgid_index = attr->ah_attr.grh.sgid_index;
+ inbuf.port_num = attr->ah_attr.port_num;
+ inbuf.traffic_class = attr->ah_attr.grh.traffic_class;
+
+ (void)roce5_get_dcb_cfg_cos(rdev, &inbuf, &cos, rqp->qp_type);
+
+ qp_attr->com_info.dw5.bs.cos = cos;
+
+ rqp->db_sgid_index = attr->ah_attr.grh.sgid_index & 0x7f;
+ rqp->db_cos = cos;
+}
+
+static void roce5_set_opt_field_attr(struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr,
+ int attr_mask,
+ roce_verbs_qp_attr_s *qp_attr, u32 *optpar)
+{
+ /* RTR2RTS/SQD2SQD RETRY_CNT */
+ if ((((u32)attr_mask) & IB_QP_RETRY_CNT) != 0) {
+ qp_attr->com_info.dw1.bs.to_retry_limit =
+ attr->retry_cnt & 0x7; /* to_retry_limit:3 */
+ *optpar |= ROCE_QP_OPTPAR_RETRY_COUNT;
+ }
+
+ /* RTR2RTS/SQD2SQD RNR_RETRY */
+ if ((((u32)attr_mask) & IB_QP_RNR_RETRY) != 0) {
+ qp_attr->com_info.dw1.bs.rnr_retry_limit =
+ attr->rnr_retry & 0x7; /* rnr_retry_limit:3bits */
+ *optpar |= ROCE_QP_OPTPAR_RNR_RETRY;
+ }
+
+ /* INIT2RTR/SQD2SQD/RTR2RTS/RTS2RTS MIN_RNR_TIMER */
+ if ((((u32)attr_mask) & IB_QP_MIN_RNR_TIMER) != 0) {
+ qp_attr->com_info.dw2.bs.min_rnr_nak =
+ attr->min_rnr_timer & 0x1f; /* min_rnr_nak:5bits */
+ *optpar |= ROCE_QP_OPTPAR_RNR_TIMEOUT;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_SQ_PSN) != 0) {
+ qp_attr->com_info.dw8.bs.next_send_psn =
+ attr->sq_psn & 0xffffff; /* next_rcv_psn:24bit */
+ }
+
+ if ((((u32)attr_mask) & IB_QP_RQ_PSN) != 0) {
+ qp_attr->com_info.dw9.bs.next_rcv_psn =
+ attr->rq_psn & 0xffffff; /* next_rcv_psn:24bit */
+ }
+
+ if ((((u32)attr_mask) & IB_QP_DEST_QPN) != 0) {
+ qp_attr->com_info.dw0.bs.dest_qp = attr->dest_qp_num &
+ 0xffffff; /* dest_qp:24bit */
+ }
+
+ roce5_set_attr_ext(rqp, attr, qp_attr, attr_mask);
+}
+
+static s32 roce5_set_db_path_mtu(const struct ib_qp_attr *attr,
+ struct roce5_qp *rqp,
+ struct roce5_device *rdev)
+{
+ switch ((enum roce5_mtu)attr->path_mtu) {
+ case ROCE_MTU_256:
+ case ROCE_MTU_512:
+ ROCE_DEV_ERR(
+ rdev,
+ "Only support mtu larger than 1K.func_id(%d) mtu:%u",
+ rdev->glb_func_id, attr->path_mtu);
+ return -EINVAL;
+ case ROCE_MTU_1024:
+ rqp->db_path_mtu = BIT_LENGTH_IB_MTU_1024;
+ break;
+ case ROCE_MTU_2048:
+ rqp->db_path_mtu = BIT_LENGTH_IB_MTU_2048;
+ break;
+ case ROCE_MTU_4096:
+ rqp->db_path_mtu = BIT_LENGTH_IB_MTU_4096;
+ break;
+ case ROCE_MTU_8192:
+ if (ROCE5_SUPPORT_8K_MTU(rdev) != 0) {
+ rqp->db_path_mtu = BIT_LENGTH_IB_MTU_8192;
+ break;
+ }
+
+ ROCE_DEV_ERR(rdev, "Not support 8K MTU.");
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_set_opt_field(struct roce5_qp *rqp, struct ib_qp_attr *attr,
+ int attr_mask,
+ roce_modify_qp_param_s *modify_para)
+{
+ int ret = 0;
+ roce_verbs_qp_attr_s *qp_attr = &modify_para->qp_attr;
+ u32 *optpar = &modify_para->optpar;
+ struct roce5_device *rdev = to_roce5_dev(rqp->ibqp.device);
+
+ if ((((u32)attr_mask) & IB_QP_QKEY) != 0) {
+ qp_attr->com_info.q_key = attr->qkey;
+ *optpar |= ROCE_QP_OPTPAR_Q_KEY;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_AV) != 0) {
+ roce5_set_opt_attr_av(rqp, rdev, attr, qp_attr, optpar);
+ }
+
+ if ((((u32)attr_mask) & IB_QP_PORT) != 0) {
+ qp_attr->com_info.dw5.bs.port = attr->port_num &
+ 0x7; /* port: 3bits */
+ *optpar |= ROCE_QP_OPTPAR_SCHED_QUEUE;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_MAX_DEST_RD_ATOMIC) != 0) {
+ roce5_set_opt_rdmarc(&rqp->rdmarc, rqp->rsp_depth, qp_attr);
+ *optpar |= ROCE_QP_OPTPAR_RRA_MAX;
+ }
+
+ /* RTR2RTS/SQD2SQD SRA_MAX */
+ if ((((u32)attr_mask) & IB_QP_MAX_QP_RD_ATOMIC) != 0) {
+ roce5_set_opt_sra(qp_attr, attr);
+ *optpar |= ROCE_QP_OPTPAR_SRA_MAX;
+ }
+
+ /* RWE/RRE/RAE,RST2INIT */
+ if ((((u32)attr_mask) &
+ (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) != 0) {
+ roce5_set_access_flags(rqp, qp_attr, attr, attr_mask);
+ *optpar |= ROCE_QP_OPTPAR_RWE | ROCE_QP_OPTPAR_RRE |
+ ROCE_QP_OPTPAR_RAE;
+ }
+
+ /* RTR2RTS/SQD2SQD ACK TIMEOUT */
+ if ((((u32)attr_mask) & IB_QP_TIMEOUT) != 0) {
+ qp_attr->com_info.dw2.bs.ack_to = attr->timeout &
+ 0x1f; /* ack_to:5bits */
+ *optpar |= ROCE_QP_OPTPAR_ACK_TIMEOUT;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_PATH_MTU) != 0) {
+ ret = roce5_set_db_path_mtu(attr, rqp, rdev);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = roce5_set_opt_mtu(rdev, qp_attr, attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to set MTU.");
+ return ret;
+ }
+ }
+
+ roce5_set_opt_field_attr(rqp, attr, attr_mask, qp_attr, optpar);
+ return ret;
+}
+
+static void roce5_set_qp_srq_attr(struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr,
+ struct roce5_pd *pd,
+ const struct roce5_cq *recv_cq)
+{
+ struct roce5_srq *rsrq = to_roce5_srq(rqp->ibqp.srq);
+ struct roce5_srq_context temp;
+
+ if (rsrq->container_flag != 0) {
+ struct roce5_srq_context *srqc =
+ (struct roce5_srq_context *)((void *)rsrq->cqm_srq
+ ->q_ctx_vaddr);
+ temp.dw0.value = be32_to_cpu(srqc->dw0.value);
+ qp_attr->chip_seg.dw12.bs.srq_pd = temp.dw0.bs.pdn &
+ 0x3ffff; /* srq_pd:18bits */
+ qp_attr->chip_seg.dw12.bs.srq_wqebb_size =
+ temp.dw0.bs.wqebb_size;
+ qp_attr->chip_seg.dw12.bs.srq_page_size = temp.dw0.bs.page_size;
+ qp_attr->chip_seg.dw12.bs.srq_size = temp.dw0.bs.size;
+
+ temp.dw1.value = be32_to_cpu(srqc->dw1.value);
+ qp_attr->com_info.dw5.bs.so_ro = temp.dw1.bs_c.so_ro;
+ qp_attr->com_info.dw5.bs.dma_attr_idx =
+ temp.dw1.bs_c.dma_attr_idx;
+
+ qp_attr->chip_seg.dw9.bs.container_sz =
+ MAX_SUPPORT_CONTAINER_MODE - rsrq->container_mode;
+ qp_attr->chip_seg.dw9.bs.container_en = 1;
+
+ qp_attr->com_info.dw3.bs.srq_container = 1;
+
+ if (rsrq->rqe_cnt_th > 0) {
+ qp_attr->chip_seg.dw9.bs.srq_warth_flag = 1;
+ qp_attr->chip_seg.dw8.bs.srq_rqecnt_th =
+ rsrq->rqe_cnt_th &
+ 0xf; /* srq_rqecnt_th:4bits */
+ }
+
+ qp_attr->chip_seg.dw7.bs.srqn = rsrq->srqn &
+ 0x3ffff; /* srqn:18bits */
+ } else {
+ qp_attr->chip_seg.dw7.bs.srqn = rsrq->srqn &
+ 0x3ffff; /* srqn:18bits */
+ }
+
+ qp_attr->com_info.dw2.bs.srq_en = 1;
+ qp_attr->chip_seg.dw12.bs.srq_rkey_en = 1;
+ qp_attr->com_info.dw0.bs.rkey_en = 1;
+ qp_attr->chip_seg.dw13.bs.srq_cqn = recv_cq->cqn &
+ 0xfffff; /* rq_cqn:20bits */
+ qp_attr->chip_seg.dw9.bs.srq_mtt_prefetch_maxlen1 = 1;
+}
+
+static void roce5_set_qp_rst2init_attr(struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr,
+ struct roce5_pd *pd,
+ struct roce5_cq *recv_cq)
+{
+ qp_attr->chip_seg.dw4.bs.rq_base_ci =
+ (u32)(ROCE_ILOG2(rqp->rq.offset >> rqp->rq.wqe_shift));
+ qp_attr->chip_seg.dw19.bs.qp_pd = pd->pdn & 0x3ffff; /* pd:18bits */
+ qp_attr->com_info.dw3.bs.dsgl_en = rqp->double_sgl_mode & 0x1;
+
+ if (rqp->ibqp.srq != NULL) {
+ roce5_set_qp_srq_attr(rqp, qp_attr, pd, recv_cq);
+ } else {
+ qp_attr->chip_seg.dw15.bs.rq_size =
+ (rqp->rq.wqebb_cnt > 0) ?
+ (((u32)ROCE_ILOG2(rqp->rq.wqebb_cnt)) & 0x1f) :
+ 0;
+ qp_attr->chip_seg.dw15.bs.rq_page_size =
+ ((u32)((u32)rqp->buf.page_shift - PAGE_SHIFT_4K)) &
+ ROCE_SQ_PAGE_SIZE_MASK;
+ qp_attr->chip_seg.dw15.bs.rq_pd = pd->pdn &
+ 0x3ffff; /* pd:18bits */
+ qp_attr->chip_seg.dw8.bs.rq_wqebb_size =
+ (u32)(rqp->rq.wqe_shift - BYTES_TO_16B_SHIFT) & 0x7;
+ qp_attr->com_info.dw7.bs.rq_cqn = recv_cq->cqn &
+ 0xfffff; /* rq_cqn:20bits */
+ qp_attr->chip_seg.dw15.bs.rq_rkey_en = 1;
+
+ qp_attr->chip_seg.dw8.bs.rq_pi_on_chip = 0;
+ qp_attr->chip_seg.dw7.bs.rq_wqecnt_lth = ROCE_RQ_WQECNT_LTH;
+ qp_attr->chip_seg.dw7.bs.rq_wqecnt_rctl_en = 0;
+ qp_attr->chip_seg.dw7.bs.rq_wqe_cache_thd_sel = 0;
+ qp_attr->chip_seg.dw7.bs.rq_wqecnt_rctl = 0;
+ qp_attr->chip_seg.dw9.bs.rq_mtt_prefetch_maxlen0 =
+ ROCE_RQ_MTT_PREFETCH_MAXLEN0;
+ qp_attr->chip_seg.dw9.bs.rq_mtt_prefetch_maxlen1 = 0;
+ qp_attr->chip_seg.dw9.bs.rq_mtt_prefetch_maxwqe =
+ ROCE_RQ_MTT_PREFETCH_MAXWQE;
+ qp_attr->chip_seg.dw7.bs.rq_wqe_prefetch_minnum = 0;
+ qp_attr->chip_seg.dw7.bs.rq_wqe_prefetch_maxnum =
+ ROCE_RQ_WQE_PREFETCH_MAXNUM;
+ }
+}
+
+static void roce5_qp_rst2init_set_qpcc(roce_verbs_qp_attr_s *qp_attr,
+ struct roce5_qp *rqp,
+ const struct roce5_device *rdev)
+{
+ qp_attr->chip_seg.dw0.sq_rq_l0mtt_gpa = rqp->mtt.mtt_paddr;
+ qp_attr->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num =
+ rqp->db.dma & (~0x3ULL); /* bits:63-2 */
+ qp_attr->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num |=
+ rqp->mtt.mtt_layers & 0x3; /* bits:1-0 */
+ if (rqp->qp_type == IB_QPT_XRC_TGT) {
+ qp_attr->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num =
+ rqp->wb_dma;
+ }
+
+ qp_attr->chip_seg.dw4.bs.sq_rq_mtt_page_size =
+ rqp->mtt.mtt_page_shift - PAGE_SHIFT_4K;
+ /* rc_entry_size:2bits */
+ qp_attr->chip_seg.dw10.bs.rc_entry_size =
+ ((u32)ROCE_ILOG2(rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .rdmarc_entry_sz >>
+ BYTES_TO_16B_SHIFT) &
+ 0x3);
+ qp_attr->chip_seg.dw14.bs.qp_rkey_en = 1;
+ qp_attr->chip_seg.dw10.bs.rc_entry_prefetch_maxnum = 0;
+}
+
+static void roce5_qp_rst2init_set_sqc_sqac(roce_verbs_qp_attr_s *qp_attr,
+ const struct roce5_qp *rqp,
+ const struct roce5_pd *pd,
+ const struct roce5_cq *send_cq)
+{
+ qp_attr->chip_seg.dw5.bs.sq_pi_on_chip = rqp->pi_on_chip;
+ qp_attr->chip_seg.dw16.bs.sq_wqebb_size =
+ ((u32)(rqp->sq.wqe_shift - ROCE_SQ_WQEBB_SIZE_SHIFT)) &
+ ROCE_SQ_WQEBB_SIZE_MASK;
+ qp_attr->chip_seg.dw16.bs.sq_pd = ((u32)pd->pdn) &
+ 0x3ffff; /* pd:18bits */
+ qp_attr->chip_seg.dw16.bs.sq_page_size =
+ ((u32)(rqp->buf.page_shift - PAGE_SHIFT_4K)) &
+ ROCE_SQ_PAGE_SIZE_MASK;
+ qp_attr->chip_seg.dw5.bs.sq_inline_en = (rqp->max_inline_data > 0) ? 1 :
+ 0;
+
+ qp_attr->chip_seg.dw16.bs.sq_rkey_en = 1;
+
+ qp_attr->chip_seg.dw5.bs.sq_wqecnt_lth = ROCE_SQ_WQECNT_LTH;
+ qp_attr->chip_seg.dw5.bs.sq_wqecnt_rctl_en = 0;
+ qp_attr->chip_seg.dw5.bs.sq_wqecnt_rctl = 0;
+ qp_attr->chip_seg.dw5.bs.sq_wqe_prefetch_minnum =
+ ROCE_SQ_PREFETCH_MINNUM;
+ qp_attr->chip_seg.dw5.bs.sq_wqe_prefetch_maxnum =
+ ROCE_SQ_PREFETCH_MAXNUM;
+ qp_attr->chip_seg.dw5.bs.sq_wqe_cache_thd_sel = 0;
+ qp_attr->chip_seg.dw6.bs.sq_wqe_prefetch_mode = 0;
+ qp_attr->chip_seg.dw6.bs.sq_mtt_prefetch_maxlen = 0;
+
+ if (rqp->sq.wqebb_cnt != 0) {
+ qp_attr->chip_seg.dw5.bs.sq_size =
+ (u32)(ROCE_ILOG2((u32)rqp->sq.wqebb_cnt)) &
+ ROCE_SQ_SIZE_MASK;
+ }
+
+ qp_attr->chip_seg.dw17.bs.sqa_cqn = send_cq->cqn & ROCE_SQ_CQN_MASK;
+
+ qp_attr->chip_seg.dw5.bs.sqa_wqe_prefetch_minnum =
+ ROCE_SQ_PREFETCH_MINNUM;
+ qp_attr->chip_seg.dw5.bs.sqa_wqe_prefetch_maxnum =
+ ROCE_WQE_PREFETCH_MAXNUM;
+ qp_attr->chip_seg.dw6.bs.sqa_mtt_prefetch_maxlen = 0;
+ qp_attr->chip_seg.dw5.bs.sqa_wqe_cache_thd_sel = 0;
+}
+
+static void roce5_qp_rst2init_set_drv(roce_verbs_qp_attr_s *qp_attr,
+ struct roce5_qp *rqp,
+ struct roce5_device *rdev)
+{
+ qp_attr->com_info.dw0.bs.service_type =
+ (u32)to_roce5_qp_type((enum ib_qp_type)rqp->qp_type) & 0x7;
+ qp_attr->com_info.dw3.bs.dif_en = (u32)rqp->signature_en;
+
+ if (!rqp->ibqp.uobject) {
+ qp_attr->com_info.dw0.bs.fre = 1;
+ }
+
+ qp_attr->com_info.dw3.bs.xrc_vld =
+ (u32)(rqp->qp_type == IB_QPT_XRC_INI);
+ qp_attr->com_info.dw1.bs.local_qp = rqp->qpn &
+ 0xffffff; /* local_qp:24bits */
+ qp_attr->com_info.dw5.bs.ep = rdev->hw_info.ep_id;
+ qp_attr->chip_seg.dw4.bs.dsgl = rqp->double_sgl_mode & 0x1;
+}
+
+static void roce5_qp_rst2init_set_common(roce_verbs_qp_attr_s *qp_attr,
+ const struct roce5_pd *pd,
+ const struct roce5_qp *rqp,
+ const struct roce5_cq *recv_cq,
+ const struct roce5_cq *send_cq)
+{
+ qp_attr->chip_seg.dw18.bs.ud_pd = pd->pdn & 0x3ffff; /* pd:18bits */
+
+ if (rqp->shadow != 0) {
+ qp_attr->com_info.dw11.bs.shadow = 1;
+ if (recv_cq != NULL) {
+ qp_attr->com_info.dw11.bs.shadow_vfid =
+ recv_cq->shadow_vfid;
+ }
+
+ if (send_cq != NULL) {
+ qp_attr->com_info.dw11.bs.shadow_cq_vfid =
+ send_cq->shadow_vfid;
+ }
+ }
+}
+
+static void roce5_qp_rst2init_set_xrc_attr(const struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr,
+ const struct roce5_device *rdev,
+ const struct roce5_cq *recv_cq)
+{
+ qp_attr->com_info.dw2.bs.xrc_srq_en = 1;
+
+ if ((((u32)attr->qp_access_flags & XRC_CONTAINER_FLAG) != 0) ||
+ (rdev->cfg_info.srq_container_en != 0)) {
+ qp_attr->chip_seg.dw9.bs.container_en = 1;
+ qp_attr->com_info.dw3.bs.srq_container = 1;
+ qp_attr->chip_seg.dw8.bs.xrcd = rqp->xrcdn &
+ 0xffff; /* xrcd:16bits */
+ qp_attr->com_info.dw2.bs.srq_en = 1;
+ qp_attr->chip_seg.dw8.bs.srq_rqecnt_th = 1;
+ qp_attr->com_info.dw3.bs.xrc_vld = 1;
+ qp_attr->chip_seg.dw13.bs.srq_state = ROCE_SRQ_INIT_STATE;
+ } else {
+ qp_attr->chip_seg.dw12.bs.srq_rkey_en = 1;
+ qp_attr->com_info.dw2.bs.srq_en = 1;
+ qp_attr->chip_seg.dw8.bs.xrcd = rqp->xrcdn &
+ 0xffff; /* xrcd:16bits */
+ qp_attr->chip_seg.dw9.bs.srq_mtt_prefetch_maxlen1 = 1;
+ qp_attr->com_info.dw3.bs.xrc_vld = 1;
+ qp_attr->chip_seg.dw14.bs.srq_xrcd = rqp->xrcdn &
+ 0xffff; /* xrcd:16bits */
+ }
+ if (recv_cq != NULL) {
+ qp_attr->chip_seg.dw13.bs.srq_cqn = recv_cq->cqn &
+ 0xfffff; /* rq_cqn:20bits */
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_rst2init
+ Description : parameter set when QP is from RESET to INIT
+ Input : struct roce5_qp *rqp
+ const struct ib_qp_attr *attr
+ roce_verbs_qp_attr_s *qp_attr
+ Output : None
+
+ 1.Date : 2015/8/6
+ Author : zhaoxinteng
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_qp_rst2init(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ struct roce5_pd *pd = NULL;
+ struct roce5_cq *send_cq = NULL;
+ struct roce5_cq *recv_cq = NULL;
+ struct roce5_device *rdev = NULL;
+
+ rdev = to_roce5_dev(rqp->ibqp.device);
+ pd = roce5_get_pd(rqp);
+ roce5_get_cqs(rqp, &send_cq, &recv_cq);
+
+ /* CHIP_SEG: QPCC */
+ roce5_qp_rst2init_set_qpcc(qp_attr, rqp, rdev);
+
+ /* CHIP_SEG: SQC & SQAC */
+ roce5_qp_rst2init_set_sqc_sqac(qp_attr, rqp, pd, send_cq);
+
+ /* RRWC */
+ qp_attr->chip_seg.dw4.bs.rrw_mtt_prefetch_maxlen = 0;
+
+ /* RCC */
+ qp_attr->chip_seg.dw10.bs.rc_mtt_prefetch_maxlen =
+ ROCE_QP_MAX_PFETCH_MTT_LAYER;
+
+ /* TIMER_SEG */
+ qp_attr->com_info.dw3.bs.tss_timer_num = ROCE_QP_MAX_TIMER_NUM;
+
+ /* DRV_SEG */
+ roce5_qp_rst2init_set_drv(qp_attr, rqp, rdev);
+
+ /* UCODE COM_SEG */
+ roce5_qp_rst2init_set_common(qp_attr, pd, rqp, recv_cq, send_cq);
+
+ if (rqp->qp_type == IB_QPT_XRC_TGT) {
+ roce5_qp_rst2init_set_xrc_attr(rqp, attr, qp_attr, rdev,
+ recv_cq);
+ } else {
+ roce5_set_qp_rst2init_attr(rqp, qp_attr, pd, recv_cq);
+ }
+
+#ifdef ROCE_BONDING_EN
+ roce5_bond_rr_set_flow(rdev, rqp, qp_attr);
+#endif
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_init2rtr
+ Description : init2rtr attributes modify
+ Input : struct roce5_qp *rqp
+ const struct ib_qp_attr *attr
+ roce_verbs_qp_attr_s *qp_attr
+ Output : None
+
+ 1.Date : 2015/8/1
+ Author : zhaoxinteng
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_qp_init2rtr(struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ if (rqp->ibqp.srq || (rqp->qp_type == IB_QPT_XRC_TGT) ||
+ (rqp->qp_type == IB_QPT_XRC_INI) || (rqp->qp_type == IB_QPT_UD) ||
+ (rqp->qp_type == IB_QPT_UC) || (rqp->qp_type == IB_QPT_GSI)) {
+ qp_attr->com_info.dw3.bs.invalid_credit = 1;
+ }
+
+ if ((rqp->qp_type == IB_QPT_GSI) || (rqp->qp_type == IB_QPT_UD)) {
+ qp_attr->com_info.dw3.bs.pmtu = IB_MTU_4096 &
+ 0x7; /* for UD, mtu = 4096 */
+ qp_attr->com_info.dw5.bs.mtu_code = ROCE_MTU_CODE_4K;
+ }
+
+ qp_attr->com_info.dw2.bs.ack_to = 0xf; /* ack_to:5bits */
+ qp_attr->com_info.dw0.bs.service_type =
+ (u32)to_roce5_qp_type((enum ib_qp_type)rqp->qp_type) &
+ 0x7; /* service_type: 3bit */
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_rtr2rts
+ Description : roce5_qp_rtr2rts
+ Input : struct roce5_qp *rqp
+ const struct ib_qp_attr *attr
+ roce_verbs_qp_attr_s *qp_attr
+ Output : None
+
+ 1.Date : 2015/8/2
+ Author : zhaoxinteng
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_qp_rtr2rts(struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+}
+
+static void roce5_qp_2err(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_abs_field
+ Description : set abs field to qpc
+ Input : struct roce5_qp *rqp
+ struct ib_qp_attr *attr
+ roce_verbs_qp_attr_s *qp_attr
+ enum ib_qp_state cur_state
+ enum ib_qp_state new_state
+ Output : None
+
+ 1.Date : 2016/01/30
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_set_abs_field(struct roce5_qp *rqp, struct ib_qp_attr *attr,
+ int attr_mask, roce_verbs_qp_attr_s *qp_attr)
+{
+ enum ib_qp_state cur_state, new_state;
+
+ cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ new_state = ((((u32)attr_mask) & IB_QP_STATE) != 0) ? attr->qp_state :
+ cur_state;
+ if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT)) {
+ roce5_qp_rst2init(rqp, attr, qp_attr);
+ }
+
+ if ((cur_state == IB_QPS_INIT) && (new_state == IB_QPS_RTR)) {
+ roce5_qp_init2rtr(rqp, attr, qp_attr);
+ }
+
+ if ((cur_state == IB_QPS_RTR) && (new_state == IB_QPS_RTS)) {
+ roce5_qp_rtr2rts(rqp, attr, qp_attr);
+ }
+
+ if (new_state == IB_QPS_ERR) {
+ roce5_qp_2err(rqp, attr, qp_attr);
+ }
+ return;
+}
+
+#ifdef ROCE_LATENCY_PROF_EN
+#define ROCE_SET_LATENCY_PROF_EN 5
+static int roce5_latency_prof_en_check(struct roce5_device *rdev,
+ u32 *latency_prof_en,
+ u32 *frequency_reduction_ratio)
+{
+ roce_dfx_set_inbuf_s buf_in = { 0 };
+ roce_dfx_set_outbuf_s buf_out = { 0 };
+ u32 out_size = sizeof(buf_out);
+ int ret = 0;
+ buf_in.show = 1;
+ buf_in.cmd_type = ROCE_CMD_ROCE_SET;
+ buf_in.sub_cmd_type = ROCE_SET_LATENCY_PROF_EN;
+ ret = roce5_adm_dfx_roce_set(rdev, &buf_in, sizeof(buf_in), &buf_out,
+ &out_size);
+ if (ret != 0) {
+ ROCE_ERR("latency prof query l2d err");
+ return ret;
+ }
+ *latency_prof_en = buf_out.sub_param.latency_prof.latency_prof_en;
+ *frequency_reduction_ratio =
+ buf_out.sub_param.latency_prof.frequency_reduction_ratio;
+ return 0;
+}
+
+static int
+roce5_latency_prof_time_get(struct roce5_device *rdev,
+ struct roce5_modify_qp_ex_resp_data *resp)
+{
+ struct hinic5_hwdev *hwdev = (struct hinic5_hwdev *)rdev->hwdev;
+ u32 latency_prof_en = 0;
+ u32 frequency_reduction_ratio = 1;
+ u64 time_diff = 0;
+ int ret = 0;
+ if (hwdev == NULL) {
+ ROCE_ERR("latency prof hwdev is null");
+ return (-EINVAL);
+ }
+ ret = roce5_latency_prof_en_check(rdev, &latency_prof_en,
+ &frequency_reduction_ratio);
+ if (ret != 0) {
+ return ret;
+ }
+ if (latency_prof_en == 0) {
+ resp->latency_prof_en = 0;
+ resp->non_ptp_time_diff = 0;
+ return 0;
+ }
+ //get clock time and non_ptp_chip time of difference value, convenient at later calculate timestamp
+ ret = hinic5_get_non_ptp_time_diff(hwdev, &time_diff);
+ if (ret != 0) {
+ ROCE_ERR("Failed to read n_ptp time, ret(%d)\n", ret);
+ return ret;
+ }
+ resp->latency_prof_en = 1;
+ resp->non_ptp_time_diff = time_diff;
+ resp->frequency_reduction_ratio = frequency_reduction_ratio;
+ return 0;
+}
+#endif
+static int roce5_record_opt_field(struct roce5_qp *rqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata,
+ roce_verbs_cmd_qp_modify_rsp_s *modify_rsp)
+{
+ int ret = 0;
+ int rsp_vld = 0;
+ enum ib_qp_state cur_state, new_state;
+ struct roce5_modify_qp_ex_resp_data resp = { 0 };
+ struct roce5_device *rdev = NULL;
+
+ cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ new_state = ((((u32)attr_mask) & IB_QP_STATE) != 0) ? attr->qp_state :
+ cur_state;
+ rqp->qp_state = new_state;
+
+ if ((((u32)attr_mask) & IB_QP_AV) != 0) {
+ rqp->sl = attr->ah_attr.sl & 0x7;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_ACCESS_FLAGS) != 0) {
+ rqp->atomic_rd_en = (u8)attr->qp_access_flags;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_PORT) != 0) {
+ rqp->port = attr->port_num;
+ }
+
+ if (roce5_sqp_check(rqp) != 0) {
+ ret = store_sqp_attrs(rqp, attr, attr_mask);
+ if (ret != 0) {
+ ROCE_ERR("Failed to store sqp attribute.");
+ return ret;
+ }
+ }
+
+ rdev = to_roce5_dev(rqp->ibqp.device);
+
+ /*
+ * TGT QP no has update pi requirement, and db trigger microcode thread and driver no has strict timing disable system, one general in init status trigger microcode,
+ * but if XRC TGT QP migration 至 rts after again trigger microcode thread, SQ hardware none permission, fetch wqe will exception, because this TGT QP not next db
+ * but non- TGT QP i.e. make in qp rst status trigger, will go via wqe empty 终结, not will exception
+ */
+ if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT) &&
+ (rqp->pi_on_chip != 0) && (rqp->qp_type != IB_QPT_XRC_TGT)) {
+ /* avoid PI on chip when PI 残keep, primary dynamic clear to zero */
+ ret = roce5_write_sq_db(rdev, rqp, 0, udata);
+ if (ret != 0) {
+ ROCE_ERR("Failed to clear PI on chip");
+ return -1;
+ }
+ }
+
+ if ((udata != NULL) && (udata->outbuf != NULL)) {
+ if ((cur_state == IB_QPS_INIT) && (new_state == IB_QPS_RTR) &&
+ (((u32)attr_mask & IB_QP_AV) != 0)) {
+ resp.cos = rqp->db_cos;
+ resp.is_cos_valid = 1;
+ rsp_vld = 1;
+ }
+
+#ifdef ROCE_LATENCY_PROF_EN
+ if (ROCE_IS_DEV_1825V100(rdev) && (cur_state == IB_QPS_RTR) &&
+ (new_state == IB_QPS_RTS)) {
+ ret = roce5_latency_prof_time_get(rdev, &resp);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get time diff, ret(%d).",
+ ret);
+ return -1;
+ }
+ }
+#endif
+ /* compatible old card not will return ssn value, driver not perform update */
+ if (modify_rsp != NULL &&
+ modify_rsp->magic == ROCE_VERBS_MODIFY_RSP_MAGIC) {
+ resp.is_ssn_valid = modify_rsp->dw1.bs.is_ssn_vld;
+ resp.ssn = modify_rsp->dw1.bs.ssn;
+ rqp->sq_wqe_ssn = resp.ssn;
+ rsp_vld = 1;
+ }
+
+ if (rsp_vld != 0) {
+ ret = ib_copy_to_udata(
+ udata, &resp,
+ sizeof(struct roce5_modify_qp_ex_resp_data));
+ if (ret != 0) {
+ ROCE_ERR("Failed to copy data to user");
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_modify_2rst_cmd
+ Description : cache out qpc mtt
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2016/6/17
+ Modification : Created function
+
+ 2.Date : 2017/04/26
+ Modification : Modify function
+
+**************************************************************************** */
+int roce5_qp_modify_2rst_cmd(struct roce5_device *rdev, u32 qpn)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_qp_modify2rst_s *qp_moidfy2rst_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_qp_modify2rst_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ qp_moidfy2rst_inbuf =
+ (roce_uni_cmd_qp_modify2rst_s *)cqm_cmd_inbuf->buf;
+ qp_moidfy2rst_inbuf->com.index = cpu_to_be32(qpn);
+ qp_moidfy2rst_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_2RST_QP, cqm_cmd_inbuf,
+ NULL, ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send 2RST_QP command, qpn(0x%x), func_id(%d), ret(0x%x)",
+ qpn, rdev->glb_func_id, ret);
+
+ ret = (-EINVAL);
+
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Card not present, return OK, func_id(%d)",
+ rdev->glb_func_id);
+ ret = 0;
+ }
+ goto err_out;
+ }
+
+err_out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_check_rdmarc
+ Description : roce5_qp_check_rdmarc
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2017/04/26
+ Modification : Create function
+
+**************************************************************************** */
+static int roce5_qp_check_rdmarc(struct roce5_device *rdev,
+ struct roce5_qp *rqp, int *cost)
+{
+ int times = 0;
+ u32 rc_num = 0;
+ u32 rc_check_index = 0;
+ void *rdmarc_vaddr = NULL;
+ dma_addr_t rdmarc_paddr = 0;
+
+ rc_num =
+ (u32)(((u32)1 << rqp->rdmarc.order) / RDMARC_NUM_PER_CACHELINE);
+ rdmarc_vaddr = rqp->rdmarc.vaddr;
+ rdmarc_paddr = rqp->rdmarc.dma_addr;
+
+ times = rdev->try_times;
+ do {
+ if ((*((u32 *)rdmarc_vaddr) ==
+ ROCE_RDMARC_DESTROY_CHECK_VALUE) &&
+ (cpu_to_be32(*((u32 *)rdmarc_vaddr + 1)) == rqp->qpn) &&
+ (cpu_to_be64(*((u64 *)rdmarc_vaddr + 1)) ==
+ ((u64)rdmarc_paddr +
+ ((u64)ROCE_CACHE_LINE_SIZE * (u64)rc_check_index)))) {
+ rdmarc_vaddr = (void *)((u8 *)rdmarc_vaddr +
+ ROCE_CACHE_LINE_SIZE);
+ rc_check_index++;
+ if (rc_num == rc_check_index) {
+ break;
+ }
+ } else {
+ ROCE_DELAY();
+ times--;
+ }
+ } while (times != 0);
+
+ if (rc_num != rc_check_index) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to read rdmarc field back after try %d times, func_id(%d) rc_check_index:%u rc_num:%u",
+ ((rdev->try_times - times) + 1), rdev->glb_func_id,
+ rc_check_index, rc_num);
+ *cost = (rdev->try_times - times) + 1;
+ return -1;
+ }
+ *cost = (rdev->try_times - times) + 1;
+ return 0;
+}
+
+static int roce5_qp_check_state(struct roce5_device *rdev,
+ const struct roce5_qp *rqp, const u32 *wb_va,
+ int *cost)
+{
+ int times = 0;
+ int read_back_flag = 0;
+
+ times = rdev->try_times;
+ while ((times--) != 0) {
+ if (*(u32 *)wb_va == ROCE_QP_DESTROY_CHECK_VALUE_HIGH_4B &&
+ (*((u32 *)wb_va + 1) ==
+ ROCE_QP_DESTROY_CHECK_VALUE_LOW_4B)) {
+ read_back_flag = 1;
+ break;
+ }
+ ROCE_DELAY();
+ }
+
+ if (read_back_flag == 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to read QP field back after try %d times,qpn(0x%x), wb_data(0x%x), wb_data+1(0x%x) func_id(%d)",
+ ((rdev->try_times - times) + 1), rqp->qpn,
+ *(u32 *)wb_va, *((u32 *)wb_va + 1), rdev->glb_func_id);
+ *cost = (rdev->try_times - times) + 1;
+ return -1;
+ }
+ *cost = (rdev->try_times - times) + 1;
+ return 0;
+}
+
+static void roce5_qp_fill_cacheout_inbuf(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ dma_addr_t wb_dma,
+ cqm_cmd_buf_s *cqm_cmd_inbuf)
+{
+ roce_uni_cmd_qp_cache_invalid_s *qp_cacheout_inbuf = NULL;
+ struct rdma_service_cap *rdma_cap = NULL;
+ u32 page_size = roce5_get_page_size(rdev, true);
+
+ qp_cacheout_inbuf =
+ (roce_uni_cmd_qp_cache_invalid_s *)(cqm_cmd_inbuf)->buf;
+ rdma_cap = &rdev->rdma_cap;
+
+ qp_cacheout_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+ qp_cacheout_inbuf->com.index = cpu_to_be32(rqp->qpn);
+ qp_cacheout_inbuf->qp_cache.sq_buf_len = cpu_to_be32(
+ ALIGN(((u32)rqp->sq.wqebb_cnt) << ((u32)rqp->sq.wqe_shift),
+ page_size));
+ qp_cacheout_inbuf->qp_cache.rq_buf_len = cpu_to_be32(
+ ALIGN(((u32)rqp->rq.wqebb_cnt) << ((u32)rqp->sq.wqe_shift),
+ page_size));
+ qp_cacheout_inbuf->qp_cache.cmtt_cache.mtt_flags = 0;
+ qp_cacheout_inbuf->qp_cache.cmtt_cache.mtt_num = 0;
+ qp_cacheout_inbuf->qp_cache.cmtt_cache.mtt_cache_line_start =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_start);
+ qp_cacheout_inbuf->qp_cache.cmtt_cache.mtt_cache_line_end =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_end);
+ qp_cacheout_inbuf->qp_cache.cmtt_cache.mtt_cache_line_size =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_sz);
+ qp_cacheout_inbuf->qp_cache.wb_gpa = cpu_to_be64(wb_dma);
+ qp_cacheout_inbuf->qp_cache.wqe_cache.wqe_flags = 0;
+ qp_cacheout_inbuf->qp_cache.wqe_cache.wqe_num = 0;
+ qp_cacheout_inbuf->qp_cache.wqe_cache.wqe_cache_line_start =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_start);
+ qp_cacheout_inbuf->qp_cache.wqe_cache.wqe_cache_line_end =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_end);
+ qp_cacheout_inbuf->qp_cache.wqe_cache.wqe_cache_line_size =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_sz);
+}
+
+static int roce5_qp_send_cache_out_cmd(struct roce5_device *rdev,
+ struct roce5_qp *rqp, void *wb_va,
+ dma_addr_t wb_dma, int *cost)
+{
+ unsigned long end;
+ int times = 0;
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_qp_cache_invalid_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ roce5_qp_fill_cacheout_inbuf(rdev, rqp, wb_dma, cqm_cmd_inbuf);
+
+ end = jiffies +
+ (unsigned long)((unsigned int)rdev->destory_flow_timeout * HZ);
+ while (time_before(jiffies, end)) {
+ times++;
+ ret = roce5_send_qp_lb_cmd(rqp->qpn, rdev,
+ ROCE_CMD_MISC_CACHE_INVLD,
+ cqm_cmd_inbuf, NULL,
+ ROCE_CMD_TIME_CLASS_C);
+ if (ret <= 0) { /* return success or exception happened */
+ break;
+ }
+ cond_resched();
+ };
+
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed MISC_CACHE_INVLD command after try %d times, ret(%d), func_id(%d) qpn(%d)",
+ times, ret, rdev->glb_func_id, rqp->qpn);
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ *cost = times;
+
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Card not present, return ERROR, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -ENODEV;
+ }
+ return ret;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ *cost = (rdev->try_times - times) + 1;
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_qp_cache_out_cmd
+ Description : cache out qpc mtt
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ Output : None
+
+ 1.Date : 2016/9/24
+ Modification : Created function
+
+ 2.Date : 2017/04/26
+ Modification : Modify function
+
+**************************************************************************** */
+/* roce5_dealloc_latch_resource() collect use construct temporary change amount rqp to reuse this function. such as newly added for rqp intomember of use, need 排 query whether need adaptation */
+int roce5_qp_cache_out_cmd(struct roce5_device *rdev, struct roce5_qp *rqp)
+{
+ int ret = 0;
+ int cost = 0;
+ void *wb_va = NULL;
+ dma_addr_t wb_dma = 0;
+
+ wb_va = dma_alloc_coherent(rdev->dev, (size_t)8UL, &wb_dma, GFP_KERNEL);
+ if (wb_va == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc wb_va, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ ret = roce5_qp_send_cache_out_cmd(rdev, rqp, wb_va, wb_dma, &cost);
+ if (ret != 0) {
+ goto err;
+ }
+
+ if (rqp->rsp_depth > 0) {
+ ret = roce5_qp_check_rdmarc(rdev, rqp, &cost);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to check qp rdmarc, func_id(%d)",
+ rdev->glb_func_id);
+ goto err;
+ }
+ }
+
+ ret = roce5_qp_check_state(rdev, rqp, (u32 *)wb_va, &cost);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to check qp state, func_id(%d)",
+ rdev->glb_func_id);
+ goto err;
+ }
+
+err:
+ dma_free_coherent(rdev->dev, sizeof(u32), wb_va, wb_dma);
+
+ /* At the end of the check, if the failure is caused by a chip link down, release resources on the host side. */
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(rdev, "Card not present, return OK, func_id(%d)",
+ rdev->glb_func_id);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static u8 roce5_get_qp_cmdq_cmd(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask)
+{
+ static u16 op[ROCE_QP_STATE_NUM][ROCE_QP_STATE_NUM];
+ enum ib_qp_state cur_state, new_state;
+
+ cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ new_state = ((((u32)attr_mask) & IB_QP_STATE) != 0) ? attr->qp_state :
+ cur_state;
+ if ((cur_state > IB_QPS_ERR) || (new_state > IB_QPS_ERR)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "QP state modify invalid, cur_state(%d), new_state(%d), func_id(%d)",
+ cur_state, new_state, rdev->glb_func_id);
+ return 0;
+ }
+ op[IB_QPS_RESET][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_RESET][IB_QPS_INIT] = ROCE_CMD_RST2INIT_QP;
+
+ op[IB_QPS_INIT][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_INIT][IB_QPS_INIT] = ROCE_CMD_INIT2INIT_QP;
+ op[IB_QPS_INIT][IB_QPS_RTR] = ROCE_CMD_INIT2RTR_QP;
+
+ op[IB_QPS_RTR][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_RTR][IB_QPS_RTS] = ROCE_CMD_RTR2RTS_QP;
+
+ op[IB_QPS_RTS][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_RTS][IB_QPS_RTS] = ROCE_CMD_RTS2RTS_QP;
+ op[IB_QPS_RTS][IB_QPS_SQD] = ROCE_CMD_RTS2SQD_QP;
+
+ op[IB_QPS_SQD][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_SQD][IB_QPS_RTS] = ROCE_CMD_SQD2RTS_QP;
+ op[IB_QPS_SQD][IB_QPS_SQD] = ROCE_CMD_SQD2SQD_QP;
+
+ op[IB_QPS_SQE][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+ op[IB_QPS_SQE][IB_QPS_RTS] = ROCE_CMD_SQERR2RTS_QP;
+
+ op[IB_QPS_ERR][IB_QPS_ERR] = ROCE_CMD_2ERR_QP;
+
+ return (u8)op[cur_state][new_state];
+}
+
+static int roce5_qp_rts2sqd_cmd(struct roce5_device *rdev, struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr, int attr_mask)
+{
+ int ret = 0;
+ int sqd_event = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_qp_modify_rts2sqd_s *qp_rts2sqd_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_qp_modify_rts2sqd_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ sqd_event = ((((u32)attr_mask) & IB_QP_EN_SQD_ASYNC_NOTIFY) != 0) &&
+ (attr->en_sqd_async_notify != 0);
+ qp_rts2sqd_inbuf =
+ (roce_uni_cmd_qp_modify_rts2sqd_s *)cqm_cmd_inbuf->buf;
+ qp_rts2sqd_inbuf->com.index = cpu_to_be32(rqp->qpn);
+ qp_rts2sqd_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ qp_rts2sqd_inbuf->sqd_event_en = cpu_to_be32((u32)(sqd_event != 0));
+
+ ret = roce5_send_qp_lb_cmd(rqp->qpn, rdev, ROCE_CMD_RTS2SQD_QP,
+ cqm_cmd_inbuf, NULL, ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RTS2SQD_QP cmd, func_id(%d), ret(0x%x)",
+ rdev->glb_func_id, ret);
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return 0;
+}
+
+static int roce5_qp_handle_err(struct roce5_device *rdev,
+ const struct roce5_qp *rqp, u8 cmd, int ret)
+{
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send MODIFY_QP command, command(%u), func_id(%d), ret(%d)",
+ cmd, rdev->glb_func_id, ret);
+
+ if ((ret == (-ETIMEDOUT)) || (ret == (-EPERM))) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+
+ return -1;
+}
+
+static int roce5_qp_modify_cmd(struct roce5_device *rdev, struct roce5_qp *rqp,
+ u8 cmd, roce_modify_qp_param_s *modify_para)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_modify_qpc_s *qp_modify_inbuf = NULL;
+ roce_verbs_qp_attr_s *qp_attr = &modify_para->qp_attr;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_modify_qpc_s), &cqm_cmd_outbuf,
+ ROCE_QP_MODIFY_CMD_OUT_BUF_SIZE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return (-ENOMEM);
+ }
+
+ qp_modify_inbuf = (roce_uni_cmd_modify_qpc_s *)cqm_cmd_inbuf->buf;
+
+ roce5_transmit_ci_record_addr_ext(rqp, qp_attr);
+ roce5_qpc_to_be(qp_attr, rqp, (u32 *)&qp_modify_inbuf->qp_attr);
+ qp_modify_inbuf->com.index = cpu_to_be32(rqp->qpn);
+ qp_modify_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+ qp_modify_inbuf->com.opt = cpu_to_be32(modify_para->optpar);
+ ret = roce5_send_qp_lb_cmd(rqp->qpn, rdev, cmd, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ret = roce5_qp_handle_err(rdev, rqp, cmd, ret);
+ } else {
+ roce5_be32_2_le32(
+ cqm_cmd_outbuf->buf, (u32 *)&modify_para->modify_rsp,
+ sizeof(roce_verbs_cmd_qp_modify_rsp_s) / sizeof(u32));
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+void roce5_cq_clean(struct roce5_cq *cq, u32 qpn, struct roce5_srq *srq)
+{
+ spin_lock_irq(&cq->lock);
+ roce5_cq_clean_process(cq, qpn, srq);
+ spin_unlock_irq(&cq->lock);
+}
+
+static int roce5_qp_clean_kernel_res(struct roce5_qp *rqp)
+{
+ int ret = 0;
+ struct roce5_cq *send_cq = NULL;
+ struct roce5_cq *recv_cq = NULL;
+
+ roce5_get_cqs(rqp, &send_cq, &recv_cq);
+
+ roce5_cq_clean(recv_cq, rqp->qpn,
+ rqp->ibqp.srq ? to_roce5_srq(rqp->ibqp.srq) : NULL);
+ if (send_cq != recv_cq) {
+ roce5_cq_clean(send_cq, rqp->qpn, NULL);
+ }
+
+ rqp->rq.head = 0;
+ rqp->rq.tail = 0;
+
+ rqp->sq.head = 0;
+ rqp->sq.tail = 0;
+
+ rqp->sq_next_wqe = 0;
+ rqp->sq_wqe_ssn = 0;
+
+ *(rqp->db.db_record) = 0;
+
+ if (rqp->qp_type != IB_QPT_XRC_TGT) {
+ if (rqp->has_rq && rqp->qp_buf_info->q_header_vaddr) {
+ ret = memset_s(rqp->qp_buf_info->q_header_vaddr,
+ sizeof(u64), 0, sizeof(u64));
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to memset QP(0x%06x) q_header_vaddr(ret:%d)",
+ rqp->qpn, ret);
+ return (-ENOMEM);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int roce5_qp_modify_2rst(struct roce5_device *rdev, struct roce5_qp *rqp)
+{
+ int ret = 0;
+
+ ret = roce5_qp_modify_2rst_cmd(rdev, rqp->qpn);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify QP(0x%06x) to RESET, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_qp_cache_out_cmd(rdev, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "QP(0x%06x) cache invalid failed, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ rqp->qp_state = IB_QPS_RESET;
+
+ if (rqp->ibqp.uobject == NULL) {
+ ret = roce5_qp_clean_kernel_res(rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Clean kernel QP(0x%06x) failed, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void roce5_set_stub_field(struct roce5_device *rdev,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ qp_attr->com_info.dw6.bs.force_local = rdev->local_en;
+}
+
+static int roce5_modify_qp_cmd_process(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask,
+ roce_modify_qp_param_s *modify_para)
+{
+ u8 cmd;
+ int ret;
+ cmd = roce5_get_qp_cmdq_cmd(rdev, rqp, attr, attr_mask);
+ if (cmd == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid cmd, func_id(%u), qpn(%u), cmd(%u).",
+ rdev->glb_func_id, rqp->qpn, cmd);
+ return -EINVAL;
+ }
+ if (cmd == ROCE_CMD_RTS2SQD_QP) {
+ ret = roce5_qp_rts2sqd_cmd(rdev, rqp, attr, attr_mask);
+ } else {
+ ret = roce5_qp_modify_cmd(rdev, rqp, cmd, modify_para);
+ }
+ return ret;
+}
+
+static int roce5_qp_modify(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ roce_user_handle_t hdl;
+ roce_modify_qp_param_s modify_para;
+ roce_verbs_qp_attr_s *qp_attr = &modify_para.qp_attr;
+
+ (void)memset_s(&modify_para, sizeof(roce_modify_qp_param_s), 0,
+ sizeof(roce_modify_qp_param_s));
+ if ((((u32)attr_mask) & IB_QP_MAX_DEST_RD_ATOMIC) != 0) {
+ ret = roce5_alloc_opt_rdmarc(rqp, attr, attr_mask);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdmarc, func(%d).",
+ rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+ ret = roce5_set_opt_field(rqp, attr, attr_mask, &modify_para);
+ if (ret != 0) {
+ goto err_out;
+ }
+
+ roce5_set_abs_field(rqp, attr, attr_mask, qp_attr);
+ roce5_set_stub_field(rdev, qp_attr);
+
+ (void)memset_s(&hdl, sizeof(roce_user_handle_t), 0,
+ sizeof(roce_user_handle_t));
+ ROCE_CONSTUCT_ULD_HDL_RQP(&hdl, rdev, rqp, qp_attr, NULL, NULL, NULL);
+ ret = roce5_uld_qp_modify((roce_uld_handle)&hdl, attr, attr_mask,
+ udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify uld qp, func(%d), qpn(%d), ret(%d).",
+ rdev->glb_func_id, rqp->qpn, ret);
+ goto err_out;
+ }
+
+ ret = roce5_modify_qp_cmd_process(rdev, rqp, attr, attr_mask,
+ &modify_para);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to modify qp, func(%d), qpn(%d), ret(%d).",
+ rdev->glb_func_id, rqp->qpn, ret);
+ goto err_out;
+ }
+
+ ret = roce5_record_opt_field(rqp, attr, attr_mask, udata,
+ &modify_para.modify_rsp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to record_opt_field, func(%d), qpn(%d).",
+ rdev->glb_func_id, rqp->qpn);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ if ((((u32)attr_mask) & IB_QP_MAX_DEST_RD_ATOMIC) != 0) {
+ roce5_free_opt_rdmarc(rqp);
+ }
+
+ return ret;
+}
+
+static int roce5_qp_get_path(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct rdma_ah_attr *ah_attr)
+{
+ int ret = 0;
+ u16 vlan_id;
+
+ if ((ah_attr->ah_flags & IB_AH_GRH) == 0) {
+ ROCE_DEV_ERR(rdev, "Not supported, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ ret = roce5_resolve_grh(rdev, ah_attr, &vlan_id, NULL);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to find dmac by grh, func_id(%u)",
+ (u32)rdev->glb_func_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+roce5_qp_modify_check_rd_and_mtu(const struct roce5_qp *rqp,
+ const struct ib_qp_attr *attr, int attr_mask,
+ const struct rdma_service_cap *rdma_cap)
+{
+ struct roce5_device *rdev = to_roce5_dev(rqp->ibqp.device);
+ enum ib_qp_state cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ enum ib_qp_state new_state = (enum ib_qp_state)(
+ ((((u32)attr_mask) & IB_QP_STATE) != 0) ? attr->qp_state :
+ cur_state);
+ enum roce5_mtu rmtu = (enum roce5_mtu)attr->path_mtu;
+
+ if (((((u32)attr_mask) & IB_QP_MAX_QP_RD_ATOMIC) != 0) &&
+ (attr->max_rd_atomic >
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_qp_init_rdma)) {
+ ROCE_ERR(
+ "Qpn(0x%x), max_rd_atomic (%d) too large. Transition %d to %d. qp_type(%d)",
+ rqp->ibqp.qp_num, attr->max_rd_atomic, cur_state,
+ new_state, rqp->ibqp.qp_type);
+ return -EINVAL;
+ }
+
+ if (((((u32)attr_mask) & IB_QP_MAX_DEST_RD_ATOMIC) != 0) &&
+ (attr->max_dest_rd_atomic >
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_qp_dest_rdma)) {
+ ROCE_ERR(
+ "Qpn(0x%x), max_dest_rd_atomic (%d) too large. Transition %d to %d. qp_type(%d)",
+ rqp->ibqp.qp_num, attr->max_dest_rd_atomic, cur_state,
+ new_state, rqp->ibqp.qp_type);
+ return -EINVAL;
+ }
+
+ if (((((u32)attr_mask) & IB_QP_PATH_MTU) != 0) &&
+ ((rmtu < ROCE_MTU_256) ||
+ (rmtu > ((ROCE5_SUPPORT_8K_MTU(rdev) != 0) ? ROCE_MTU_8192 :
+ ROCE_MTU_4096)))) {
+ ROCE_ERR("Input path MTU(%u) is invalid", rmtu);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_qp_modify_check(struct roce5_qp *rqp, struct ib_qp_attr *attr,
+ int attr_mask,
+ struct rdma_service_cap *rdma_cap)
+{
+ int ret;
+ enum ib_qp_state cur_state, new_state;
+ cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ new_state = (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_STATE) != 0) ?
+ attr->qp_state :
+ cur_state);
+
+#ifndef ROCE_VBS_EN
+ if (!roce5_check_qp_modify_ok(
+ cur_state, new_state, (enum ib_qp_type)(rqp->ibqp.qp_type),
+ (enum ib_qp_attr_mask)attr_mask, IB_LINK_LAYER_ETHERNET)) {
+ ROCE_ERR(
+ "Qpn(0x%x), invalid attribute mask specified for transition %d to %d, qp_type(%d), "
+ "attr_mask(0x%x)",
+ rqp->ibqp.qp_num, cur_state, new_state,
+ rqp->ibqp.qp_type, attr_mask);
+ return (-EINVAL);
+ }
+#endif
+
+ if (((((u32)attr_mask) & IB_QP_PORT) != 0) &&
+ (attr->port_num != ROCE_DEFAULT_PORT_NUM)) {
+ ROCE_ERR(
+ "Qpn(0x%x), invalid port number(%d) specified for transition %d to %d. qp_type(%d)",
+ rqp->ibqp.qp_num, attr->port_num, cur_state, new_state,
+ rqp->ibqp.qp_type);
+ return (-EINVAL);
+ }
+
+ if ((((u32)attr_mask) & IB_QP_PKEY_INDEX) != 0) {
+ if (attr->pkey_index > 0) {
+ ROCE_ERR(
+ "Qpn(0x%x), invalid pkey index (%d) specified for transition %d to %d. "
+ "qp_type(%d)",
+ rqp->ibqp.qp_num, attr->pkey_index, cur_state,
+ new_state, rqp->ibqp.qp_type);
+ return (-EINVAL);
+ }
+ }
+
+ ret = roce5_qp_modify_check_rd_and_mtu(rqp, attr, attr_mask, rdma_cap);
+
+ return ret;
+}
+
+#define ROCE5_QP_HANDLE 0
+#define ROCE5_QP_CONTINUE 1
+static int roce5_modify_qp_pre(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_device *rdev = NULL;
+ enum ib_qp_state cur_state, new_state;
+
+ rqp = to_roce5_qp(ibqp);
+ rdev = to_roce5_dev(ibqp->device);
+ cur_state =
+ (enum ib_qp_state)(((((u32)attr_mask) & IB_QP_CUR_STATE) != 0) ?
+ attr->cur_qp_state :
+ rqp->qp_state);
+ new_state = ((((u32)attr_mask) & IB_QP_STATE) != 0) ? attr->qp_state :
+ cur_state;
+
+ ret = roce5_qp_modify_check(rqp, attr, attr_mask, &rdev->rdma_cap);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed qp modify check, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ if (new_state == IB_QPS_RESET) {
+ if (cur_state != new_state) {
+ ret = roce5_qp_modify_2rst(rdev, rqp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify 2rst, func_id(%d)",
+ rdev->glb_func_id);
+ }
+ }
+ return ROCE5_QP_HANDLE;
+ }
+
+ ret = roce5_modify_qp_pre_ext(rdev, rqp, attr, attr_mask, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to modify qp pre ext, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return ROCE5_QP_CONTINUE;
+}
+
+int roce5_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_device *rdev = NULL;
+
+ rqp = to_roce5_qp(ibqp);
+ rdev = to_roce5_dev(ibqp->device);
+
+ mutex_lock(&rqp->mutex);
+
+ ret = roce5_modify_qp_pre(ibqp, attr, attr_mask, udata);
+ if ((ret == ROCE5_QP_HANDLE) || (ret < 0)) {
+ goto out;
+ }
+
+ if ((((u32)attr_mask) & IB_QP_AV) != 0) {
+ ret = roce5_qp_get_path(rdev, rqp, &attr->ah_attr);
+ if (ret != 0) {
+ goto out;
+ }
+ }
+
+ ret = roce5_qp_modify(rdev, rqp, attr, attr_mask, udata);
+ if (ret != 0) {
+ goto out;
+ }
+
+out:
+ mutex_unlock(&rqp->mutex);
+ return ret;
+}
+
+static void roce5_verbs_shadow_set(struct roce5_device *rdev, u32 qpn,
+ cqm_cmd_buf_s *buf_in)
+{
+ roce_verbs_cmd_header_s *cmd_hdr =
+ (roce_verbs_cmd_header_s *)buf_in->buf;
+ struct roce5_qp *rqp = NULL;
+
+ if ((qpn == ROCE_QP_SMI_QP_NUM) || (qpn == ROCE_QP_GSI_QP_NUM)) {
+ return;
+ }
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ return;
+ }
+
+ if (rqp->shadow == 0 || cmd_hdr == NULL ||
+ cmd_hdr->dw0.bs.cmd_bitmask == VERBS_CMD_TYPE_VROCE_BITMASK) {
+ goto shadow_out;
+ }
+
+ cmd_hdr->dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_SHADOW_BITMASK);
+ cmd_hdr->dw3.bs.shadow_vfid = cpu_to_be16(rqp->shadow_vfid);
+
+shadow_out:
+ roce5_rqp_put(rqp);
+}
+
+int roce5_send_qp_lb_cmd(u32 qpn, struct roce5_device *rdev, u8 cmd,
+ cqm_cmd_buf_s *buf_in, cqm_cmd_buf_s *buf_out,
+ u32 timeout)
+{
+ int ret = 0;
+
+ roce5_verbs_shadow_set(rdev, qpn, buf_in);
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE, cmd, buf_in,
+ buf_out, NULL, timeout, HINIC5_CHANNEL_ROCE);
+
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_recv.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_recv.c
new file mode 100644
index 000000000..fa48a2671
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_recv.c
@@ -0,0 +1,238 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_compat.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_xrc.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+
+/* ****************************************************************************
+ Prototype : roce5_get_recv_wqe
+ Description : roce5_get_recv_wqe
+ Input : struct roce5_qp *rqp
+ int n
+ Output : None
+
+ 1.Date : 2015/5/26
+ Modification : Created function
+
+**************************************************************************** */
+static void *roce5_get_recv_wqe(struct roce5_qp *rqp, u32 n)
+{
+ return roce5_get_wqe(rqp, rqp->rq.offset +
+ (n << (unsigned)rqp->rq.wqe_shift));
+}
+
+static int roce5_post_recv_check_qp(const struct roce5_qp *qp,
+ const struct roce5_device *rdev,
+ const struct ib_recv_wr **bad_wr,
+ const struct ib_recv_wr *wr)
+{
+ if (ROCE_UNLIKELY((qp->qp_type == IB_QPT_XRC_INI) ||
+ (qp->qp_type == IB_QPT_XRC_TGT))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't post WQE when TGT XRC QP, func_id(%d), qp_type(%d)",
+ rdev->glb_func_id, qp->qp_type);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ if (ROCE_UNLIKELY(qp->qp_state == IB_QPS_RESET)) {
+ ROCE_DEV_ERR(rdev,
+ "Can't post WQE when QP is RST state, func_id(%d)",
+ rdev->glb_func_id);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_post_recv_check_wr(struct roce5_qp *qp,
+ const struct ib_recv_wr **bad_wr,
+ const struct ib_recv_wr *wr, u32 wr_num)
+{
+ if (roce5_wq_overflow(&qp->rq, wr_num, qp->ibqp.recv_cq) != 0) {
+ ROCE_ERR_ONCE("SQ is full head:%x, tali:%x, wr_num:%d",
+ (&qp->rq)->head, (&qp->rq)->tail, wr_num);
+ *bad_wr = wr;
+ return -ENOMEM;
+ }
+
+ if (ROCE_UNLIKELY(((u32)wr->num_sge) > qp->rq.max_sge)) {
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_post_recv_check_length(struct roce5_device *rdev,
+ const struct ib_recv_wr **bad_wr,
+ const struct ib_recv_wr *wr, int i)
+{
+ u32 data_len = 0;
+
+ /* single SGEָ signs data len should less than (2G-1)B */
+ if (ROCE_UNLIKELY(wr->sg_list[i].length >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz -
+ 1)) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Sge data len is over range, sg_list(%d), length(0x%x), max_msg_sz(0x%x), func_id(%d)",
+ i, wr->sg_list[i].length,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz,
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ data_len += wr->sg_list[i].length;
+ /* all SGEָ signs data len should less than 2GB */
+ if (ROCE_UNLIKELY(
+ data_len >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz)) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Data_len is over range, data_len(%d), max_msg_sz(%d), func_id(%d)",
+ data_len,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz,
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+static int roce5_post_recv_set_data_seg(const struct ib_recv_wr *wr,
+ struct roce5_device *rdev,
+ const struct ib_recv_wr **bad_wr,
+ struct roce5_qp *qp, u32 index)
+{
+ int i = 0;
+ int ret = 0;
+ struct roce_wqe_data_seg *dseg = NULL;
+
+ dseg = (struct roce_wqe_data_seg *)roce5_get_recv_wqe(qp, index);
+ for (i = 0; i < wr->num_sge; ++i) {
+ ret = roce5_post_recv_check_length(rdev, bad_wr, wr, i);
+ if (ret != 0) {
+ return ret;
+ }
+
+ roce5_set_data_seg(dseg, wr->sg_list + i);
+ dseg++;
+ }
+
+ if (wr->num_sge != 0) {
+ dseg--;
+ dseg->key =
+ cpu_to_be32((u32)(wr->sg_list[wr->num_sge - 1].lkey |
+ ROCE_WQE_NEXT_SGE_INVALID));
+ } else {
+ dseg->key = ROCE_WQE_NEXT_SGE_INVALID;
+ dseg->key = cpu_to_be32(dseg->key);
+ dseg->dw2.bs.len = 0;
+ }
+
+ return 0;
+}
+/* ****************************************************************************
+ Prototype : roce5_post_recv
+ Description : roce5_post_recv
+ Input : struct ib_qp *ibqp
+ struct ib_recv_wr *wr
+ struct ib_recv_wr **bad_wr
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
+ const struct ib_recv_wr **bad_wr)
+{
+ struct roce5_qp *qp = NULL;
+ struct roce5_device *rdev = NULL;
+ unsigned long flags = 0; /* type required by kernel API */
+ int ret = 0;
+ u32 wr_num = 0;
+ u32 index = 0;
+ const struct ib_recv_wr *wr_tmp = wr;
+
+ if (ROCE_UNLIKELY(ibqp == NULL || bad_wr == NULL)) {
+ ROCE_ERR("ibqp(%d) or bad_wr(%d) is NULL.", !!ibqp, !!bad_wr);
+ return -EINVAL;
+ }
+
+ qp = to_roce5_qp(ibqp);
+ rdev = to_roce5_dev(ibqp->device);
+
+ ret = roce5_post_recv_check_qp(qp, rdev, bad_wr, wr_tmp);
+ if (ret != 0) {
+ return ret;
+ }
+
+ spin_lock_irqsave(&qp->rq.lock, flags);
+
+ index = (unsigned int)qp->rq.head &
+ ((unsigned int)qp->rq.wqebb_cnt - 1);
+
+ for (wr_num = 0; wr_tmp != NULL; ++wr_num, wr_tmp = wr_tmp->next) {
+ ret = roce5_post_recv_check_wr(qp, bad_wr, wr_tmp, wr_num);
+ if (ret != 0) {
+ goto out;
+ }
+
+ ret = roce5_post_recv_set_data_seg(wr_tmp, rdev, bad_wr, qp,
+ index);
+ if (ret != 0) {
+ goto out;
+ }
+
+ qp->rq.wrid[index] = wr_tmp->wr_id;
+
+ index = (index + 1) & (qp->rq.wqebb_cnt - 1);
+ }
+
+out:
+ if (ROCE_LIKELY(wr_num != 0)) {
+ qp->rq.head += (u32)wr_num;
+
+ wmb();
+
+ /* SQ need head 4B,RQ need tail 4B */
+ *(qp->db.db_record + 1) = cpu_to_be32(qp->rq.head & 0xffff);
+ }
+
+ spin_unlock_irqrestore(&qp->rq.lock, flags);
+
+ return ret;
+}
+
+int roce5_post_recv_ofa(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ return roce5_post_recv(ibqp, (const struct ib_recv_wr *)wr,
+ (const struct ib_recv_wr **)bad_wr);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_send.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_send.c
new file mode 100644
index 000000000..ad1a8043a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_post_send.c
@@ -0,0 +1,1205 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <rdma/ib_verbs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include "roce_compat.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_user.h"
+#include "roce_xrc.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+#include "roce_post.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_kernel_compat_gen.h"
+
+#include "securec.h"
+
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+
+#define GOTO_LOCAL 1
+
+#define GOTO_OUT 2
+
+#define ROCE_NEED_JUMP 1
+
+#define BYTE_MASK 255
+
+#define ROCE_CTRL_SEG_SL 2
+/* ****************************************************************************
+ Prototype : roce5_get_send_wqe
+ Description : roce5_get_send_wqe
+ Input : struct roce5_qp *rqp
+ u32 n
+ Output : None
+
+ 1.Date : 2015/5/26
+ Modification : Created function
+
+**************************************************************************** */
+static void *roce5_get_send_wqe(struct roce5_qp *rqp, u32 n)
+{
+ u32 wqebb_index = (n & (((u32)rqp->sq.wqebb_cnt) - 1));
+ u32 wqebb_pos = wqebb_index << rqp->sq.wqe_shift;
+ return roce5_get_wqe(rqp, rqp->sq.offset + wqebb_pos);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_wq_overflow
+ Description : roce5_wq_overflow
+ Input : struct roce5_wq *wq
+ int wr_num
+ struct ib_cq *ibcq
+ Output : None
+
+ 1.Date : 2015/5/26
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_wq_overflow(struct roce5_wq *wq, u32 wr_num, struct ib_cq *ibcq)
+{
+ unsigned int cur = 0;
+ struct roce5_cq *cq = NULL;
+
+ cur = wq->head - wq->tail;
+ if (ROCE_LIKELY((cur + wr_num) < (unsigned int)wq->max_post)) {
+ return 0;
+ }
+
+ cq = to_roce5_cq(ibcq);
+ spin_lock(&cq->lock);
+ cur = wq->head - wq->tail;
+ spin_unlock(&cq->lock);
+
+ return ((cur + (unsigned int)wr_num) >= (unsigned int)wq->max_post);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_ib_opcode
+ Description :
+ Input :
+ Output : None
+ Return Value :
+ Calls :
+ Called By :
+
+ History :
+ 1.Date : 2015/7/30
+ Author :
+ Modification : Created function
+
+**************************************************************************** */
+static const u32 roce5_ib_opcode[] = {
+ [IB_WR_RDMA_WRITE] = ROCE_WQE_OPCODE_RDMA_WRITE,
+ [IB_WR_RDMA_WRITE_WITH_IMM] = ROCE_WQE_OPCODE_RDMA_WRITE_IMM,
+ [IB_WR_SEND] = ROCE_WQE_OPCODE_SEND,
+ [IB_WR_SEND_WITH_IMM] = ROCE_WQE_OPCODE_SEND_IMM,
+ [IB_WR_RDMA_READ] = ROCE_WQE_OPCODE_RDMA_READ,
+ [IB_WR_ATOMIC_CMP_AND_SWP] = ROCE_WQE_OPCODE_ATOMIC_CMP_SWP,
+ [IB_WR_ATOMIC_FETCH_AND_ADD] = ROCE_WQE_OPCODE_ATOMIC_FETCH_ADD,
+ [IB_WR_SEND_WITH_INV] = ROCE_WQE_OPCODE_SEND_INVAL,
+ [IB_WR_LOCAL_INV] = ROCE_WQE_OPCODE_LOCAL_INVAL,
+ [IB_WR_REG_MR] = ROCE_WQE_OPCODE_FRMR,
+ [IB_WR_MASKED_ATOMIC_CMP_AND_SWP] =
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_CMP_SWP,
+ [IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] =
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_FETCH_ADD,
+ [IB_WR_REG_MR_INTEGRITY] = ROCE_WQE_OPCODE_REG_SIG_MR,
+#if defined(IB_WR_OPCODE_HAVE_BIND_MW)
+ [IB_WR_BIND_MW] = ROCE_WQE_OPCODE_BIND_MW,
+#endif
+};
+
+static const roce_opcode_attr_s g_roce5_opcode_attr[ROCE_KERNEL_OPCODE_NUM] = {
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_SEND = 0x0,
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_SEND_WITH_INV,
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_SEND_WITH_IMM,
+ { 0 }, //ROCE_WQE_OPCODE_SEND_FT_TEST
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_RDMA_WRITE = 0x4,
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_RDMA_WRITE_WITH_IMM,
+ { 0 },
+ { 0 },
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_RDMA_READ = 0x8,
+ { 0 }, //ROCE_WQE_OPCODE_ATOMIC_WRITE,
+ { 0 }, //ROCE_WQE_OPCODE_CFLUSH,
+ { .remote_opcode =
+ 0x1 }, //ROCE_WQE_OPCODE_ATOMIC_EXT_CMP_AND_SWP, /* support max 64B */
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_ATOMIC_CMP_AND_SWP = 0xc,
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_ATOMIC_FETCH_AND_ADD,
+ { .remote_opcode = 0x1 }, //ROCE_WQE_OPCODE_MASKED_ATOMIC_CMP_AND_SWP,
+ { .remote_opcode =
+ 0x1 }, //ROCE_WQE_OPCODE_MASKED_ATOMIC_FETCH_AND_ADD,
+ { 0 }, //ROCE_WQE_OPCODE_FAST_REG_PMR, /* 8'h10-Fast Register PMR is not used by userspace */
+ { 0 }, //ROCE_WQE_OPCODE_LOCAL_INV = 0x11,
+ { 0 }, //ROCE_WQE_OPCODE_BIND_MW,
+ { 0 } //ROCE_WQE_OPCODE_REG_SIG_MR = 0x13, /* 8'h13-Local opreation(Extended for further local opreation) */
+};
+
+static void roce5_set_send_seg(struct roce_wqe_send_tsk_seg *snd_tsk_seg,
+ const struct ib_send_wr *wr)
+{
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ snd_tsk_seg->immdata_invkey = wr->ex.imm_data;
+ }
+
+ if (wr->opcode == IB_WR_SEND_WITH_INV) {
+ snd_tsk_seg->immdata_invkey =
+ cpu_to_be32(wr->ex.invalidate_rkey);
+ }
+}
+
+static void roce5_set_atomic_seg(struct roce_wqe_atomic_tsk_seg *atomic_tsk_seg,
+ const struct ib_send_wr *wr)
+{
+ const struct ib_atomic_wr *atomic = atomic_wr(wr);
+
+ atomic_tsk_seg->key = cpu_to_be32(atomic->rkey);
+ atomic_tsk_seg->dw2.va = cpu_to_be64(atomic->remote_addr);
+
+ if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
+ atomic_tsk_seg->dw4.swap_add_data = cpu_to_be64(atomic->swap);
+ atomic_tsk_seg->dw6.cmp_data = cpu_to_be64(atomic->compare_add);
+ } else if (wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
+ atomic_tsk_seg->dw4.swap_add_data =
+ cpu_to_be64(atomic->compare_add);
+ atomic_tsk_seg->dw6.cmp_data = 0;
+ } else {
+ /* IB_WR_MASKED_ATOMIC_FETCH_AND_ADD */
+ atomic_tsk_seg->dw4.swap_add_data =
+ cpu_to_be64(atomic->compare_add);
+ atomic_tsk_seg->dw6.cmp_data =
+ cpu_to_be64(atomic->compare_add_mask);
+ }
+}
+
+static __always_inline void
+roce5_set_rdma_seg(struct roce_wqe_rdma_tsk_seg *rdma_tsk_seg,
+ const struct ib_send_wr *wr)
+{
+ const struct ib_rdma_wr *rdma = rdma_wr(wr);
+
+ rdma_tsk_seg->va = cpu_to_be64(rdma->remote_addr);
+ rdma_tsk_seg->rkey = cpu_to_be32(rdma->rkey);
+
+ if (wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
+ rdma_tsk_seg->imm_data = cpu_to_be32(wr->ex.imm_data);
+ }
+}
+
+static void
+roce5_set_local_inv_seg(struct roce_wqe_local_inv_tsk_seg *inv_tsk_seg,
+ const struct ib_send_wr *wr)
+{
+ inv_tsk_seg->inv_key = cpu_to_be32(wr->ex.invalidate_rkey);
+}
+
+static void
+roce5_set_ud_seg_cycle1(struct roce_wqe_ud_tsk_seg_cycle1 *ud_tsk_seg_cycle1,
+ const struct ib_send_wr *wr)
+{
+ const struct ib_ud_wr *ud = ud_wr(wr);
+ struct roce5_ah *rah = to_roce5_ah(ud->ah);
+ int ret;
+
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ ud_tsk_seg_cycle1->immdata_invkey = wr->ex.imm_data;
+ }
+
+ ud_tsk_seg_cycle1->dw2.value = rah->priv_ah.dw0.value;
+ ud_tsk_seg_cycle1->dw3.value = rah->priv_ah.dw1.value;
+ ud_tsk_seg_cycle1->dw4.value = rah->priv_ah.dw2.value;
+ ret = memcpy_s((void *)ud_tsk_seg_cycle1->dgid, ROCE_GID_LEN,
+ (void *)rah->priv_ah.dgid, ROCE_GID_LEN);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return;
+ }
+ ud_tsk_seg_cycle1->dw9.value = cpu_to_be32(ud->remote_qpn);
+ ud_tsk_seg_cycle1->qkey = cpu_to_be32(ud->remote_qkey);
+}
+
+static void
+roce5_set_ud_seg_cycle2(struct roce_wqe_ud_tsk_seg_cycle2 *ud_tsk_seg_cycle2,
+ const struct ib_send_wr *wr)
+{
+ const struct ib_ud_wr *ud = ud_wr(wr);
+ struct roce5_ah *rah = to_roce5_ah(ud->ah);
+
+ ud_tsk_seg_cycle2->dw0.value = rah->priv_ah.dw7.value;
+ ud_tsk_seg_cycle2->dmac_l32 = rah->priv_ah.dmac_l32;
+}
+
+static void roce5_set_ud_seg(struct roce_wqe_ud_tsk_seg *ud_tsk_seg,
+ const struct ib_send_wr *wr)
+{
+ const struct ib_ud_wr *ud = ud_wr(wr);
+ struct roce5_ah *rah = to_roce5_ah(ud->ah);
+ int ret;
+
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ ud_tsk_seg->immdata_invkey = wr->ex.imm_data;
+ }
+
+ ud_tsk_seg->dw3.value = rah->priv_ah.dw0.value;
+ ud_tsk_seg->dw4.value = rah->priv_ah.dw1.value;
+ ud_tsk_seg->dw5.value = rah->priv_ah.dw2.value;
+ ret = memcpy_s((void *)ud_tsk_seg->dgid, sizeof(ud_tsk_seg->dgid),
+ (void *)rah->priv_ah.dgid, sizeof(ud_tsk_seg->dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return;
+ }
+ ud_tsk_seg->dw10.value = cpu_to_be32(ud->remote_qpn);
+ ud_tsk_seg->qkey = cpu_to_be32(ud->remote_qkey);
+ ud_tsk_seg->dw12.value = rah->priv_ah.dw7.value;
+ ud_tsk_seg->dmac_l32 = rah->priv_ah.dmac_l32;
+}
+
+void roce5_set_data_seg(struct roce_wqe_data_seg *dseg, struct ib_sge *sge)
+{
+ dseg->addr = cpu_to_be64(sge->addr);
+
+ dseg->dw2.bs.len = sge->length & 0x7fffffff;
+ dseg->dw2.bs.rsvd = 0;
+
+ dseg->dw2.value = cpu_to_be32(dseg->dw2.value);
+
+ dseg->key = cpu_to_be32(sge->lkey);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_set_gsi_seg
+ Input : struct roce5_qp *rqp
+ struct ib_send_wr *wr
+ void *wqe
+ Output : None
+
+ 1.Date : 2015/8/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_set_gsi_seg(struct roce5_qp *rqp, const struct ib_send_wr *wr,
+ void *wqe)
+{
+ struct roce_wqe_ud_tsk_seg *ud_tsk_seg =
+ (struct roce_wqe_ud_tsk_seg *)wqe;
+ struct ib_ud_wr *ud_wr = (struct ib_ud_wr *)(void *)wr;
+ struct roce5_ah *rah = to_roce5_ah(ud_wr->ah);
+ int ret;
+
+ if (rqp->sqp_attr == NULL) {
+ ROCE_ERR("Error! sqp attribute is NULL, qpn(%u).", rqp->qpn);
+ return -EINVAL;
+ }
+
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ ud_tsk_seg->immdata_invkey = wr->ex.imm_data;
+ ud_tsk_seg->dw2.bs.last_ext_len = ROCE_IMM_EXT_LEN;
+ ud_tsk_seg->dw2.value = cpu_to_be32(ud_tsk_seg->dw2.value);
+ }
+
+ ud_tsk_seg->common.bs.c = 1;
+ ud_tsk_seg->dw3.value = rah->priv_ah.dw0.value;
+ ud_tsk_seg->dw4.value = rah->priv_ah.dw1.value;
+ ud_tsk_seg->dw5.value = rah->priv_ah.dw2.value;
+ ret = memcpy_s((void *)ud_tsk_seg->dgid, sizeof(ud_tsk_seg->dgid),
+ (void *)rah->priv_ah.dgid, sizeof(ud_tsk_seg->dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return ret;
+ }
+ ud_tsk_seg->dw10.value = cpu_to_be32(ud_wr->remote_qpn);
+ ud_tsk_seg->qkey = cpu_to_be32(
+ ((ud_wr->remote_qkey & 0x80000000) != 0) ? rqp->sqp_attr->qkey :
+ ud_wr->remote_qkey);
+ ud_tsk_seg->dw12.value = rah->priv_ah.dw7.value;
+ ud_tsk_seg->dmac_l32 = rah->priv_ah.dmac_l32;
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : write_invalid_wqe
+ Description : set the next wqe invalidate
+ Input : struct roce5_qp *qp
+ u32 index
+ Output : None
+
+ 1.Date : 2015/9/8
+ Author : qianyuanpan
+ Modification : Created function
+
+**************************************************************************** */
+static void write_invalid_wqe(struct roce5_qp *qp, u32 index)
+{
+ u32 invalid_wqe_dw0 = 0;
+ struct roce5_wqe_ctrl_seg *ctrl_seg = NULL;
+
+ ctrl_seg = (struct roce5_wqe_ctrl_seg *)roce5_get_send_wqe(qp, index);
+ invalid_wqe_dw0 = ((index & (u32)qp->sq.wqebb_cnt) == 0) ? 0xff000000 :
+ 0x7f000000;
+ ctrl_seg->dw0.value = cpu_to_be32(invalid_wqe_dw0);
+}
+
+#define ROCE5_PCIE_ATOMIC_EN 0x1
+static inline bool roce5_is_pcie_atomic(struct roce5_qp *rqp)
+{
+ struct roce5_device *rdev = to_roce5_dev(rqp->ibqp.device);
+ return (rdev->cfg_info.pcie_atomic_en == ROCE5_PCIE_ATOMIC_EN);
+}
+
+static inline bool roce5_is_extend_atomic(enum ib_wr_opcode opcode)
+{
+ return ((roce5_ib_opcode[opcode] ==
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_CMP_SWP) ||
+ (roce5_ib_opcode[opcode] ==
+ ROCE_WQE_OPCODE_MASKED_ATOMIC_FETCH_ADD));
+}
+
+static inline int roce5_is_vaild_wr_opcode(struct roce5_qp *rqp,
+ enum ib_wr_opcode opcode)
+{
+ if (ROCE_UNLIKELY((opcode >= ARRAY_SIZE(roce5_ib_opcode)))) {
+ return -EINVAL;
+ }
+
+ if ((roce5_ib_opcode[opcode] == 0) && (opcode != IB_WR_SEND)) {
+ return -EINVAL;
+ }
+
+ if (roce5_is_pcie_atomic(rqp) && roce5_is_extend_atomic(opcode)) {
+ ROCE_ERR(
+ "The atomic mode is pcie atomic, but extended atomic is not supported.");
+ return -EINVAL;
+ }
+
+ return 0; /* Vaild IB opcode */
+}
+
+/* ****************************************************************************
+ Prototype : roce5_validate_wr
+ Description : roce5_validate_wr
+ Input : struct roce5_qp *rqp
+ struct ib_send_wr *wr
+ int wr_num
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_validate_wr(struct roce5_qp *rqp, const struct ib_send_wr *wr,
+ u32 wr_num)
+{
+ if (roce5_wq_overflow(&rqp->sq, wr_num, rqp->ibqp.send_cq) != 0) {
+ ROCE_ERR("SQ is full");
+ return -ENOMEM;
+ }
+
+ if (ROCE_UNLIKELY(((u32)wr->num_sge) > rqp->sq.max_sge)) {
+ ROCE_ERR(
+ "Sge num is invalide, wr->num_sge(%d), rqp->sq.max_sge(%d)",
+ wr->num_sge, rqp->sq.max_sge);
+ return -EINVAL;
+ }
+
+ if (ROCE_UNLIKELY(roce5_is_vaild_wr_opcode(rqp, wr->opcode) != 0)) {
+ ROCE_ERR("wr->opcode(%d)", wr->opcode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void
+roce5_set_rc_wqe_for_optype_send(const struct ib_send_wr *wr,
+ struct roce5_post_send_normal_param *param)
+{
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_SEND_LOCAL_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ roce5_set_send_seg((struct roce_wqe_send_tsk_seg *)param->wqe, wr);
+ param->data_len_addr =
+ &((struct roce_wqe_send_tsk_seg *)param->wqe)->data_len;
+ param->wqe = ((u8 *)param->wqe + sizeof(struct roce_wqe_send_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_send_tsk_seg);
+}
+
+static void
+roce5_set_rc_wqe_for_optype_atomic(const struct ib_send_wr *wr,
+ struct roce5_post_send_normal_param *param)
+{
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_RDMA_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ roce5_set_atomic_seg((struct roce_wqe_atomic_tsk_seg *)param->wqe, wr);
+ param->wqe =
+ ((u8 *)param->wqe + sizeof(struct roce_wqe_atomic_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_atomic_tsk_seg);
+}
+
+static void
+roce5_set_rc_wqe_for_optype_write(const struct ib_send_wr *wr,
+ struct roce5_post_send_normal_param *param)
+{
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_RDMA_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ roce5_set_rdma_seg((struct roce_wqe_rdma_tsk_seg *)param->wqe, wr);
+ param->data_len_addr =
+ &((struct roce_wqe_rdma_tsk_seg *)param->wqe)->data_len;
+ param->wqe = ((u8 *)param->wqe + sizeof(struct roce_wqe_rdma_tsk_seg));
+ param->wqe_size += (u32)(sizeof(struct roce_wqe_rdma_tsk_seg));
+}
+
+static void
+roce5_set_rc_wqe_for_optype_local(const struct ib_send_wr *wr,
+ struct roce5_post_send_normal_param *param)
+{
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_SEND_LOCAL_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ param->tsk_com_seg->bs.so = 1;
+ roce5_set_local_inv_seg((struct roce_wqe_local_inv_tsk_seg *)param->wqe,
+ wr);
+ param->wqe_size += (u32)sizeof(struct roce_wqe_local_inv_tsk_seg);
+ param->inline_flag = 0;
+ param->ctrl_seg_tmp.dw0.bs.df = 0;
+}
+
+static void roce5_set_wqe_last_len(u8 *wqe)
+{
+ struct roce_wqe_send_tsk_seg *snd_task =
+ (struct roce_wqe_send_tsk_seg *)(void *)wqe;
+ snd_task->dw3.value = 0;
+ snd_task->dw3.bs.last_ext_len = ROCE_IMM_EXT_LEN;
+ snd_task->dw3.value = cpu_to_be32(snd_task->dw3.value);
+}
+
+static inline u32 roce5_log2(u32 x)
+{
+ u32 shift;
+
+ for (shift = 0; (1U << shift) < x; ++shift) {
+ ;
+ }
+
+ return shift;
+}
+
+/* RoCE supports FRMR, for at privileged user, can via post send WR of way for at at free status of MR perform fast register.
+ frmr wqe contain a pbl(page buffer list) table start address, start va, length, page size etc. information.
+ 预 先 allocate of store space of start address (pa) need write pbl. only supports one level 寻 址, maximum supports 512(count word) PA. */
+static int set_frmr_wqe_section(const struct ib_send_wr *wr,
+ struct roce5_post_send_normal_param *param)
+{
+ u64 iova;
+ u32 fbo;
+ struct ib_reg_wr *frmr_reg_wr = NULL;
+ struct roce5_mr *roce5_kernel_frmr = NULL;
+ struct roce_wqe_frmr_tsk_seg *frmr_wqe_task = NULL;
+
+ frmr_reg_wr = (struct ib_reg_wr *)reg_wr((struct ib_send_wr *)wr);
+ roce5_kernel_frmr = to_roce5_mr(frmr_reg_wr->mr);
+
+ /* base section set */
+ param->wqe_size += sizeof(struct roce_wqe_frmr_tsk_seg);
+
+ frmr_wqe_task =
+ (struct roce_wqe_frmr_tsk_seg *)((void *)param->tsk_com_seg);
+ param->dseg =
+ (roce_wqe_data_seg_s *)(((u8 *)param->tsk_com_seg) +
+ sizeof(struct roce_wqe_frmr_tsk_seg));
+ param->ctrl_seg_tmp.dw0.bs.tsl =
+ sizeof(struct roce_wqe_frmr_tsk_seg) / ROCE_TASK_SEG_ALIGN;
+ /* fill wqe ctrl head section:cl bit */
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+
+ /* local invalidate associated section set */
+ param->tsk_com_seg->bs.so = 1;
+
+ iova = (u64)(void *)(uintptr_t)(frmr_reg_wr->mr->iova);
+ fbo = (u32)(iova & (FRMR_PAGE_SIZE - 1));
+ frmr_wqe_task->dw2.bs.fbo = fbo & 0x3FFFFF;
+ frmr_wqe_task->dw2.value = cpu_to_be32(frmr_wqe_task->dw2.value);
+
+ frmr_wqe_task->dw5.va =
+ (((u32)frmr_reg_wr->access & IB_ZERO_BASED) != 0) ?
+ 0 :
+ cpu_to_be64(iova);
+
+ /* fill in access permission */
+ frmr_wqe_task->dw3.bs.zbva =
+ (u32)(((u32)frmr_reg_wr->access & IB_ZERO_BASED) != 0);
+ frmr_wqe_task->dw3.bs.be =
+ (u32)(((u32)frmr_reg_wr->access & IB_ACCESS_MW_BIND) !=
+ 0); /* bind operation enable */
+ frmr_wqe_task->dw3.bs.lre = 1; /* this place read enable */
+ frmr_wqe_task->dw3.bs.lwe =
+ (u32)(((u32)frmr_reg_wr->access & IB_ACCESS_LOCAL_WRITE) !=
+ 0); /* this place write enable */
+ frmr_wqe_task->dw3.bs.rre =
+ (u32)(((u32)frmr_reg_wr->access & IB_ACCESS_REMOTE_READ) !=
+ 0); /* remote read enable */
+ frmr_wqe_task->dw3.bs.rwe =
+ (u32)(((u32)frmr_reg_wr->access & IB_ACCESS_REMOTE_WRITE) !=
+ 0); /* remote write enable */
+ frmr_wqe_task->dw3.bs.rae =
+ (u32)(((u32)frmr_reg_wr->access & IB_ACCESS_REMOTE_ATOMIC) !=
+ 0); /* remote Atomic enable */
+ frmr_wqe_task->dw3.bs.block = 1;
+ frmr_wqe_task->dw3.bs.rsvd = 0;
+ frmr_wqe_task->dw3.bs.pa_num = (roce5_kernel_frmr->npages == 0) ?
+ 1 :
+ roce5_kernel_frmr->npages;
+ /* MR memory page size. equals to (2^page_size)*4KB */
+ frmr_wqe_task->dw3.bs.page_size =
+ roce5_log2(frmr_reg_wr->mr->page_size) - 12; //12 is 4K page of shift
+ if (frmr_reg_wr->mr->page_size != PAGE_SIZE) {
+ ROCE_WARN(
+ "Frmr page size doesn't match page frame of OS! It may lead to unexpected memory translation.");
+ }
+ frmr_wqe_task->dw3.value = cpu_to_be32(frmr_wqe_task->dw3.value);
+
+ frmr_wqe_task->m_key = cpu_to_be32(frmr_reg_wr->key);
+ frmr_wqe_task->dw7.len = cpu_to_be64(frmr_reg_wr->mr->length);
+ frmr_wqe_task->dw9.pbl_addr = cpu_to_be64(roce5_kernel_frmr->page_map);
+ /* set inline and direct wqe handle section */
+ frmr_wqe_task->rsvd[0] = 0;
+ frmr_wqe_task->rsvd[1] = 0;
+
+ param->inline_flag = 0;
+ return 0;
+}
+
+static int roce5_post_send_rc(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev,
+ const struct ib_send_wr *wr)
+{
+ int ret = 0;
+
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_SEND_WITH_INV:
+ roce5_set_wqe_last_len(param->wqe);
+ roce5_set_rc_wqe_for_optype_send(wr, param);
+ break;
+ case IB_WR_SEND:
+ roce5_set_rc_wqe_for_optype_send(wr, param);
+ break;
+
+ case IB_WR_ATOMIC_CMP_AND_SWP:
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ roce5_set_rc_wqe_for_optype_atomic(wr, param);
+ break;
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ roce5_set_wqe_last_len(param->wqe);
+ roce5_set_rc_wqe_for_optype_write(wr, param);
+ break;
+
+ case IB_WR_RDMA_READ:
+ case IB_WR_RDMA_WRITE:
+ roce5_set_rc_wqe_for_optype_write(wr, param);
+ break;
+
+ case IB_WR_LOCAL_INV:
+ roce5_set_rc_wqe_for_optype_local(wr, param);
+ ret = ROCE_NEED_JUMP;
+ break;
+
+ case IB_WR_REG_MR:
+ set_frmr_wqe_section(wr, param);
+ ret = ROCE_NEED_JUMP;
+ break;
+
+ default:
+ ROCE_DEV_ERR(rdev, "Invalid opcode(%d), func_id(%d)",
+ wr->opcode, rdev->glb_func_id);
+ break;
+ }
+
+ return ret;
+}
+
+static int roce5_post_send_uc(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev,
+ const struct ib_send_wr *wr)
+{
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_SEND:
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ roce5_set_wqe_last_len(param->wqe);
+ }
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_SEND_LOCAL_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ roce5_set_send_seg((struct roce_wqe_send_tsk_seg *)param->wqe,
+ wr);
+ param->data_len_addr =
+ &((struct roce_wqe_send_tsk_seg *)param->wqe)->data_len;
+ param->wqe = ((u8 *)param->wqe +
+ sizeof(struct roce_wqe_send_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_send_tsk_seg);
+ break;
+
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ case IB_WR_RDMA_WRITE:
+ if (wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
+ roce5_set_wqe_last_len(param->wqe);
+ }
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_RDMA_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ roce5_set_rdma_seg((struct roce_wqe_rdma_tsk_seg *)param->wqe,
+ wr);
+ param->data_len_addr =
+ &((struct roce_wqe_rdma_tsk_seg *)param->wqe)->data_len;
+ param->wqe = ((u8 *)param->wqe +
+ sizeof(struct roce_wqe_rdma_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_rdma_tsk_seg);
+ break;
+
+ case IB_WR_LOCAL_INV:
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_SEND_LOCAL_WQE_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ param->tsk_com_seg->bs.so = 1;
+ roce5_set_local_inv_seg(
+ (struct roce_wqe_local_inv_tsk_seg *)param->wqe, wr);
+ param->wqe_size +=
+ (u32)sizeof(struct roce_wqe_local_inv_tsk_seg);
+ return ROCE_NEED_JUMP;
+
+ default:
+ ROCE_DEV_ERR(rdev, "Invalid opcode(%d), func_id(%d)",
+ wr->opcode, rdev->glb_func_id);
+ break;
+ }
+
+ return 0;
+}
+
+static int roce5_post_send_ud(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev, struct roce5_qp *rqp,
+ const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ struct roce_wqe_ud_tsk_seg *tsk_sg =
+ (struct roce_wqe_ud_tsk_seg *)param->wqe;
+
+ if (ROCE_UNLIKELY((wr->opcode != IB_WR_SEND) &&
+ (wr->opcode != IB_WR_SEND_WITH_IMM))) {
+ ROCE_DEV_ERR(rdev, "Wr->opcode(%d), func_id(%d)", wr->opcode,
+ rdev->glb_func_id);
+ *bad_wr = wr;
+ return ROCE_NEED_JUMP;
+ }
+
+ if (wr->opcode == IB_WR_SEND_WITH_IMM) {
+ tsk_sg->dw2.bs.last_ext_len = ROCE_IMM_EXT_LEN;
+ tsk_sg->dw2.value = cpu_to_be32(tsk_sg->dw2.value);
+ }
+
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_UD_WQE_COM_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+ param->data_len_addr =
+ &((struct roce_wqe_ud_tsk_seg *)param->wqe)->data_len;
+
+ if (param->sq_rmd_size > (1UL << (unsigned int)rqp->sq.wqe_shift)) {
+ roce5_set_ud_seg((struct roce_wqe_ud_tsk_seg *)(param->wqe),
+ wr);
+ param->wqe =
+ ((u8 *)param->wqe + sizeof(struct roce_wqe_ud_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_ud_tsk_seg);
+ } else {
+ roce5_set_ud_seg_cycle1(
+ (struct roce_wqe_ud_tsk_seg_cycle1 *)param->wqe, wr);
+ param->wqe = rqp->sq_head_addr;
+ param->wqe_size +=
+ (u32)sizeof(struct roce_wqe_ud_tsk_seg_cycle1);
+ roce5_set_ud_seg_cycle2(
+ (struct roce_wqe_ud_tsk_seg_cycle2 *)param->wqe, wr);
+ param->wqe = ((u8 *)param->wqe +
+ sizeof(struct roce_wqe_ud_tsk_seg_cycle2));
+ param->wqe_size +=
+ (u32)sizeof(struct roce_wqe_ud_tsk_seg_cycle2);
+ }
+
+ return 0;
+}
+
+static void roce5_post_send_set_normal_data_seg(const struct ib_send_wr *wr,
+ struct roce_wqe_data_seg **dseg,
+ struct roce5_qp *rqp)
+{
+ if (wr->num_sge != 0) {
+ if ((u8 *)(*dseg) == rqp->sq_head_addr) {
+ *dseg = (struct roce_wqe_data_seg *)((
+ void *)(rqp->sq_tail_addr -
+ sizeof(struct roce_wqe_data_seg)));
+ } else {
+ (*dseg)--;
+ }
+ (*dseg)->key = (u32)wr->sg_list[wr->num_sge - 1].lkey |
+ ROCE_WQE_NEXT_SGE_INVALID;
+ (*dseg)->key = cpu_to_be32((*dseg)->key);
+ }
+}
+
+static int
+roce5_post_send_set_normal_sge(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev, struct roce5_qp *rqp,
+ const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ int i;
+
+ param->data_len = 0;
+ param->dseg = (struct roce_wqe_data_seg *)param->wqe;
+ param->wqe_size +=
+ (u32)(wr->num_sge * (int)sizeof(struct roce_wqe_data_seg));
+ for (i = 0; i < wr->num_sge; ++i) {
+ if (param->sq_rmd_size < sizeof(struct roce_wqe_data_seg)) {
+ param->dseg = (struct roce_wqe_data_seg
+ *)((void *)rqp->sq_head_addr);
+ }
+
+ if (ROCE_UNLIKELY(wr->sg_list[i].length >
+ (rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz))) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Sge_data length is over range, sg_list(%d), length(0x%x), max_msg_sz(0x%x), func_id(%d)",
+ i, wr->sg_list[i].length,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz,
+ rdev->glb_func_id);
+ return ROCE_NEED_JUMP;
+ }
+
+ param->data_len += wr->sg_list[i].length;
+ if (ROCE_UNLIKELY(param->data_len >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz)) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Data len is over range, data_len(%d), max_msg_sz(%d), func_id(%d)",
+ param->data_len,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz,
+ rdev->glb_func_id);
+ return ROCE_NEED_JUMP;
+ }
+ roce5_set_data_seg(param->dseg, wr->sg_list + i);
+
+ (param->dseg)++;
+ param->sq_rmd_size =
+ (u32)(rqp->sq_tail_addr - (u8 *)param->dseg);
+ }
+
+ return 0;
+}
+
+static void roce5_copy_inline_data(struct roce5_post_send_normal_param *param,
+ const struct ib_send_wr *wr,
+ struct roce5_qp *rqp, int i)
+{
+ int ret = 0;
+ struct ib_sge *sge = wr->sg_list + i;
+
+ if (param->sq_rmd_size >= wr->sg_list[i].length) {
+ /* Set inline data */
+ ret = memcpy_s(param->wqe, sge->length,
+ (void *)(uintptr_t)sge->addr, sge->length);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy param->wqe.(ret:%d)", ret);
+ return;
+ }
+ param->wqe = ((u8 *)param->wqe + wr->sg_list[i].length);
+ if ((u8 *)param->wqe == rqp->sq_tail_addr) {
+ param->wqe = rqp->sq_head_addr;
+ }
+ } else {
+ /* Set inline data cycle1 */
+ u32 size = param->sq_rmd_size;
+ ret = memcpy_s(param->wqe, size, (void *)(uintptr_t)sge->addr,
+ size);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy param->wqe.(ret:%d)", ret);
+ return;
+ }
+ param->wqe = rqp->sq_head_addr;
+
+ /* Set inline data cycle2 */
+ size = wr->sg_list[i].length - param->sq_rmd_size;
+ ret = memcpy_s(
+ param->wqe, size,
+ (void *)((u8 *)(void *)(uintptr_t)sge->addr + size),
+ size);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy param->wqe.(ret:%d)", ret);
+ return;
+ }
+ param->wqe = ((u8 *)param->wqe + wr->sg_list[i].length -
+ param->sq_rmd_size);
+
+ param->cycle = 1;
+ }
+}
+
+static int
+roce5_post_send_set_data_seg(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev, struct roce5_qp *rqp,
+ const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ int i;
+ int ret;
+
+ if ((((unsigned int)wr->send_flags & (unsigned int)IB_SEND_INLINE) !=
+ 0) &&
+ (wr->num_sge != 0) && (param->inline_flag != 0)) {
+ param->data_len = 0;
+
+ for (i = 0; i < wr->num_sge; ++i) {
+ param->wqe_size += wr->sg_list[i].length;
+ param->data_len += wr->sg_list[i].length;
+ if (param->data_len > rqp->max_inline_data) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Data len is too big, data_len(%d), max_inline_data(%d), func_id(%d)",
+ param->data_len, rqp->max_inline_data,
+ rdev->glb_func_id);
+ return ROCE_NEED_JUMP;
+ }
+
+ if ((u8 *)param->wqe == rqp->sq_head_addr) {
+ param->cycle = 1;
+ }
+
+ roce5_copy_inline_data(param, wr, rqp, i);
+
+ param->sq_rmd_size =
+ (u32)(rqp->sq_tail_addr - (u8 *)param->wqe);
+ }
+ param->ctrl_seg_tmp.dw0.bs.bdsl =
+ (ALIGN((u32)(param->data_len), ROCE_TASK_SEG_ALIGN) /
+ ROCE_TASK_SEG_ALIGN) &
+ 0x7ff;
+ param->ctrl_seg_tmp.dw0.bs.df = 1;
+ param->inline_flag = 1;
+ } else {
+ ret = roce5_post_send_set_normal_sge(param, rdev, rqp, wr,
+ bad_wr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ roce5_post_send_set_normal_data_seg(wr, ¶m->dseg, rqp);
+
+ param->ctrl_seg_tmp.dw0.bs.bdsl =
+ (u32)((wr->num_sge *
+ (int)sizeof(struct roce_wqe_data_seg)) /
+ ROCE_TASK_SEG_ALIGN) &
+ 0x7ff;
+ param->ctrl_seg_tmp.dw0.bs.df = 0;
+ }
+
+ return 0;
+}
+
+static void roce5_fill_task_data_len(u32 *data_len_addr, u32 data_len)
+{
+ if (data_len_addr != NULL) {
+ *data_len_addr = cpu_to_be32(data_len);
+ }
+}
+
+static int roce5_construct_wqe(struct roce5_post_send_normal_param *param,
+ struct roce5_device *rdev, struct roce5_qp *rqp,
+ const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ int need_goto = 0;
+ int ret;
+
+ switch (rqp->qp_type) {
+ case IB_QPT_RC:
+ need_goto = roce5_post_send_rc(param, rdev, wr);
+ if (need_goto == ROCE_NEED_JUMP) {
+ return GOTO_LOCAL;
+ }
+ break;
+
+ case IB_QPT_UC:
+ need_goto = roce5_post_send_uc(param, rdev, wr);
+ if (need_goto == ROCE_NEED_JUMP) {
+ return GOTO_LOCAL;
+ }
+ break;
+
+ case IB_QPT_UD:
+ need_goto = roce5_post_send_ud(param, rdev, rqp, wr, bad_wr);
+ if (need_goto == ROCE_NEED_JUMP) {
+ return GOTO_OUT;
+ }
+ break;
+
+ case IB_QPT_GSI:
+ param->ctrl_seg_tmp.dw0.bs.tsl = ROCE_UD_WQE_COM_TSL;
+ param->ctrl_seg_tmp.dw1.bs.cl = 1;
+
+ ret = roce5_set_gsi_seg(rqp, wr, param->wqe);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to set gsi seg, ret(%d).",
+ ret);
+ return GOTO_OUT;
+ }
+
+ param->data_len_addr =
+ &((struct roce_wqe_ud_tsk_seg *)param->wqe)->data_len;
+ param->wqe =
+ ((u8 *)param->wqe + sizeof(struct roce_wqe_ud_tsk_seg));
+ param->wqe_size += (u32)sizeof(struct roce_wqe_ud_tsk_seg);
+ break;
+
+ default:
+ ROCE_DEV_ERR(rdev, "Unknown qp type, func_id(%d)",
+ rdev->glb_func_id);
+ break;
+ }
+
+ return 0;
+}
+
+static void roce5_init_ctrl_seg(struct roce5_post_send_normal_param *param,
+ const struct ib_send_wr *wr,
+ const struct roce5_qp *rqp)
+{
+ u32 wqe_opcode = roce5_ib_opcode[wr->opcode] & 0x1f;
+ param->ctrl_seg_tmp.dw0.bs.owner =
+ ((param->index & (u32)rqp->sq.wqebb_cnt) != 0) ? 1 : 0;
+ param->ctrl_seg_tmp.dw0.bs.drvsl = 0;
+ param->ctrl_seg_tmp.dw0.bs.wf = 0;
+ param->ctrl_seg_tmp.dw0.bs.cf = 0;
+ param->ctrl_seg_tmp.dw0.bs.va = 1;
+ param->ctrl_seg_tmp.dw0.bs.df = 0; /* va:1bits, 0-sge,1-inline */
+ param->ctrl_seg_tmp.dw0.bs.cr =
+ (u32)(!(((((u32)wr->send_flags) & IB_SEND_SIGNALED) |
+ rqp->sq_signal_bits) == 0));
+ param->ctrl_seg_tmp.dw0.bs.difsl = 0;
+ param->ctrl_seg_tmp.dw0.bs.csl = 0;
+ param->ctrl_seg_tmp.dw0.bs.ctrlsl = ROCE_CTRL_SEG_SL;
+ param->ctrl_seg_tmp.dw0.bs.bdsl = 0;
+
+ param->ctrl_seg_tmp.dw0.bs.wqe_ssn = (param->sq_wqe_ssn & 0x3);
+ param->sq_wqe_ssn += (u8)g_roce5_opcode_attr[wqe_opcode].remote_opcode;
+}
+
+static void roce5_init_task_com_seg(union roce5_wqe_tsk_com_seg **tsk_com_seg,
+ u8 *wqe, const struct ib_send_wr *wr,
+ const struct roce5_qp *rqp)
+{
+ struct roce_wqe_send_tsk_seg *send_task =
+ (struct roce_wqe_send_tsk_seg *)(void *)wqe;
+ *tsk_com_seg = (union roce5_wqe_tsk_com_seg *)(void *)wqe;
+
+ send_task->dw3.value = 0;
+ (*tsk_com_seg)->bs.c = (u32)(!(
+ (((unsigned)wr->send_flags & (unsigned)IB_SEND_SIGNALED) |
+ rqp->sq_signal_bits) == 0));
+ (*tsk_com_seg)->bs.se = (u32)(!(
+ ((unsigned)wr->send_flags & (unsigned)IB_SEND_SOLICITED) == 0));
+ (*tsk_com_seg)->bs.f = (u32)(!(
+ ((unsigned)wr->send_flags & (unsigned)IB_SEND_FENCE) == 0));
+ (*tsk_com_seg)->bs.op_type = roce5_ib_opcode[wr->opcode] & 0x1f;
+}
+
+static void
+roce5_post_send_local_operation(struct roce5_post_send_normal_param *param,
+ struct roce5_qp *rqp, struct roce5_device *rdev)
+{
+ param->opcode = param->tsk_com_seg->bs.op_type;
+ param->tsk_com_seg->value = cpu_to_be32(param->tsk_com_seg->value);
+ param->ctrl_seg->dw1.value = cpu_to_be32(param->ctrl_seg_tmp.dw1.value);
+ param->index += (u32)ROCE_DIV_ROUND_UP(param->wqe_size,
+ 1U << (u32)rqp->sq.wqe_shift);
+
+ write_invalid_wqe(rqp, param->index);
+
+ /*
+ * Make sure descriptor is fully written before
+ * setting ownership bit (because HW can start
+ * executing as soon as we do).
+ */
+ wmb();
+
+ param->ctrl_seg->dw0.value = cpu_to_be32(param->ctrl_seg_tmp.dw0.value);
+}
+/* ****************************************************************************
+ Prototype : roce5_post_send_normal
+ Description : roce5_post_send_normal
+ Input : struct roce5_device *rdev
+ struct roce5_qp *rqp
+ struct ib_send_wr *wr
+ struct ib_send_wr **bad_wr
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+ 2.Date : 2015/8/8
+ Modification : Modify function
+
+**************************************************************************** */
+static int roce5_post_send_normal(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ int need_goto = 0;
+ int ret = 0;
+ struct roce5_post_send_normal_param param = { 0 };
+ const struct ib_send_wr *wr_tmp = wr;
+
+ spin_lock_irqsave(&rqp->sq.lock, param.flags);
+
+ param.index = rqp->sq_next_wqe;
+ param.sq_wqe_ssn = rqp->sq_wqe_ssn;
+
+ for (param.wr_num = 0; wr_tmp != NULL;
+ ++(param.wr_num), wr_tmp = wr_tmp->next) {
+ ret = roce5_validate_wr(rqp, wr_tmp, param.wr_num);
+ if (ret != 0) {
+ *bad_wr = wr_tmp;
+ ROCE_DEV_ERR(rdev,
+ " Failed to validate wr, func(%d) qpn(%u)",
+ rdev->glb_func_id, rqp->qpn);
+ goto out;
+ }
+
+ param.wqe = (u8 *)roce5_get_send_wqe(rqp, param.index);
+ param.ctrl_seg = (struct roce5_wqe_ctrl_seg *)param.wqe;
+
+ param.sq_rmd_size = (u32)(rqp->sq_tail_addr - (u8 *)param.wqe);
+
+ rqp->sq.wrid[(rqp->sq.head + param.wr_num) &
+ (u32)(rqp->sq.wqebb_cnt - 1)] = wr_tmp->wr_id;
+
+ roce5_init_ctrl_seg(¶m, wr_tmp, rqp);
+
+ param.wqe = ((u8 *)param.wqe + sizeof(*(param.ctrl_seg)));
+ param.wqe_size = (u32)sizeof(*param.ctrl_seg);
+ roce5_init_task_com_seg(¶m.tsk_com_seg, param.wqe, wr_tmp,
+ rqp);
+
+ ret = roce5_construct_wqe(¶m, rdev, rqp, wr_tmp, bad_wr);
+ if (ret == GOTO_LOCAL) {
+ ret = 0;
+ goto local;
+ } else if (ret == GOTO_OUT) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ param.sq_rmd_size = (u32)(rqp->sq_tail_addr - (u8 *)param.wqe);
+
+ need_goto = roce5_post_send_set_data_seg(¶m, rdev, rqp,
+ wr_tmp, bad_wr);
+ if (need_goto == ROCE_NEED_JUMP) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ roce5_fill_task_data_len(param.data_len_addr, param.data_len);
+
+local:
+ roce5_post_send_local_operation(¶m, rqp, rdev);
+ }
+
+out:
+ if (ROCE_LIKELY(param.wr_num != 0)) {
+ rqp->sq.head += param.wr_num;
+
+ wmb();
+
+ ret = roce5_write_sq_db(rdev, rqp, param.index, NULL);
+ rqp->sq_next_wqe = param.index;
+ rqp->sq_wqe_ssn = param.sq_wqe_ssn;
+ }
+
+ spin_unlock_irqrestore(&rqp->sq.lock, param.flags);
+
+ return ret;
+}
+
+static int roce5_post_send_check_qp_type(const struct roce5_qp *rqp)
+{
+ if (ROCE_UNLIKELY(rqp->qp_type == IB_QPT_XRC_TGT)) {
+ ROCE_ERR("Can't post WQE when TGT XRC QP");
+ return -EINVAL;
+ }
+
+ if (ROCE_UNLIKELY(rqp->qp_type == IB_QPT_XRC_INI)) {
+ ROCE_ERR("not support xrc in kernel space");
+ return -EINVAL;
+ }
+
+ if (ROCE_UNLIKELY((rqp->qp_state == IB_QPS_RESET) ||
+ (rqp->qp_state == IB_QPS_INIT) ||
+ (rqp->qp_state == IB_QPS_RTR))) {
+ ROCE_ERR("Can't post WQE when QP is RST/INIT/RTR state");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_post_send
+ Description : roce5_post_send
+ Input : struct ib_qp *ibqp
+ struct ib_send_wr *wr
+ const struct ib_send_wr **bad_wr
+ Output : None
+**************************************************************************** */
+int roce5_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ const struct ib_send_wr **bad_wr)
+{
+ int ret = 0;
+ struct roce5_qp *rqp = to_roce5_qp(ibqp);
+ struct roce5_device *rdev = to_roce5_dev(ibqp->device);
+
+ ret = roce5_post_send_check_qp_type(rqp);
+ if (ret != 0) {
+ *bad_wr = wr;
+ ROCE_DEV_ERR(rdev, "Failed to check qp.ret(%d)", ret);
+ return ret;
+ }
+
+ ret = roce5_post_send_normal(rdev, rqp, wr, bad_wr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to post send normal wr, ret(%d)",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_post_send_ofa(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr)
+{
+ return roce5_post_send(ibqp, (const struct ib_send_wr *)wr,
+ (const struct ib_send_wr **)bad_wr);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_query.c b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_query.c
new file mode 100644
index 000000000..260eca49e
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/qp/roce_qp_query.c
@@ -0,0 +1,543 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_compat.h"
+
+#include "hinic5_crm.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_mr.h"
+#include "roce_xrc.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_cqm_cmd.h"
+#include "roce_qp.h"
+#include "roce_restore.h"
+#include "roce_npu_cmd.h"
+#include "roce_main_extension.h"
+#include "roce_com.h"
+#include "securec.h"
+#ifdef __ROCE_DFX__
+#include "roce_dfx.h"
+#endif
+
+/**
+ * @brief Get roce qp by qpn. When querying succeeded, you have to call roce5_rqp_put() to free
+ the cqm_obj_qp. But there is no need to call roce5_rqp_put() if querying failed.
+ * @return Success: return the roce qp. Failure: return NULL.
+ */
+struct roce5_qp *roce5_get_rqp_by_qpn(struct roce5_device *rdev, u32 qpn)
+{
+ cqm_object_s *cqm_obj_qp = NULL;
+ struct roce5_qp *rqp = NULL;
+
+ cqm_obj_qp = cqm5_object_get(rdev->hwdev, CQM_OBJECT_SERVICE_CTX, qpn,
+ false);
+ if (cqm_obj_qp == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't find rqp according to qpn(0x%x), func_id(%d)",
+ qpn, rdev->glb_func_id);
+ return NULL;
+ }
+
+ rqp = cqmobj_to_roce_qp(cqm_obj_qp);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to convert obj to rqp.");
+ cqm5_object_put(cqm_obj_qp);
+ }
+
+ return rqp;
+}
+
+static enum ib_mig_state to_ib_mig_state(int roce5_mig_state)
+{
+ switch (roce5_mig_state) {
+ case ROCE_QP_PM_ARMED:
+ return IB_MIG_ARMED;
+
+ case ROCE_QP_PM_REARM:
+ return IB_MIG_REARM;
+
+ case ROCE_QP_PM_MIGRATED:
+ return IB_MIG_MIGRATED;
+
+ default:
+ return (enum ib_mig_state)(-1);
+ }
+}
+
+static int to_ib_qp_access_flags(const roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ unsigned int ib_flags = 0;
+ u32 tmp = 0;
+
+ /* RRE */
+ if (verbs_qp_attr->com_info.dw0.bs.rre != 0) {
+ tmp = ib_flags | IB_ACCESS_REMOTE_READ;
+ ib_flags = tmp;
+ }
+
+ /* RWE */
+ if (verbs_qp_attr->com_info.dw0.bs.rwe != 0) {
+ tmp = ib_flags | IB_ACCESS_REMOTE_WRITE;
+ ib_flags = tmp;
+ }
+
+ /* RAE */
+ if (verbs_qp_attr->com_info.dw0.bs.rae != 0) {
+ tmp = ib_flags | IB_ACCESS_REMOTE_ATOMIC;
+ ib_flags = tmp;
+ }
+
+ return (int)ib_flags;
+}
+
+/* ****************************************************************************
+ Prototype : to_ib_ah_attr
+ Description : to_ib_ah_attr
+ Input : struct roce5_device *rdev
+ struct ib_ah_attr *ah_attr(struct rdma_ah_attr *ah_attr)
+ struct roce5_qp_context *context
+ Output : None
+
+ 1.Date : 2015/5/26
+ Modification : Created function
+
+**************************************************************************** */
+static void to_ib_ah_attr(struct roce5_device *rdev,
+ struct rdma_ah_attr *ah_attr,
+ roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ int ret;
+
+ ret = memset_s(ah_attr, sizeof(*ah_attr), 0, sizeof(*ah_attr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ah_attr.(ret:%d)", ret);
+ return;
+ }
+
+ ah_attr->port_num = verbs_qp_attr->com_info.dw5.bs.port;
+
+ ah_attr->sl = 0x7 - verbs_qp_attr->path_info.dw7.bs.sl;
+
+ ah_attr->static_rate = 0;
+
+ ah_attr->ah_flags = IB_AH_GRH;
+
+ ah_attr->grh.sgid_index = verbs_qp_attr->path_info.dw7.bs.sgid_index;
+ ah_attr->grh.hop_limit = verbs_qp_attr->path_info.dw7.bs.hoplmt;
+ ah_attr->grh.traffic_class = verbs_qp_attr->path_info.dw6.bs.tclass;
+ ah_attr->grh.flow_label = verbs_qp_attr->path_info.dw6.bs.flow_label;
+
+ ret = memcpy_s((void *)ah_attr->grh.dgid.raw,
+ sizeof(ah_attr->grh.dgid.raw),
+ (void *)verbs_qp_attr->path_info.dgid,
+ sizeof(ah_attr->grh.dgid.raw));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy dgid.(ret:%d)", ret);
+ }
+}
+
+int roce5_uni_cmd_qp_query(struct roce5_device *rdev, u32 qpn,
+ u32 *verbs_qp_attr, int qp_attr_size)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_qp_query_s *qp_query_inbuf = NULL;
+ roce_uni_cmd_qp_query_outbuf_s *qp_query_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_qp_query_s), &cqm_cmd_outbuf,
+ (u16)sizeof(roce_uni_cmd_qp_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc cqm_cmd_inoutbuf, ret=%d",
+ ret);
+ return ret;
+ }
+
+ qp_query_inbuf = (roce_uni_cmd_qp_query_s *)cqm_cmd_inbuf->buf;
+ qp_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+ qp_query_inbuf->com.index = cpu_to_be32(qpn);
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_QUERY_QP, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, ROCE_CMD_TIME_CLASS_B);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to send QUERY_QP command, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -1;
+ goto free_cqm_buf;
+ }
+
+ qp_query_outbuf = (roce_uni_cmd_qp_query_outbuf_s *)cqm_cmd_outbuf->buf;
+ ret = (int)memcpy_s((void *)verbs_qp_attr, (size_t)qp_attr_size,
+ (void *)&qp_query_outbuf->qp_info.qp_attr,
+ (size_t)qp_attr_size);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy verbs_qp_attr, ret(%d).",
+ ret);
+ ret = -EINVAL;
+ }
+free_cqm_buf:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+int roce5_qp_query(struct roce5_device *rdev, u32 qpn, u32 *context,
+ int qpc_size)
+{
+ if (ROCE5_SUPPORT_IB_CMD_QUERY_QP_MSG_V2(rdev) != 0) {
+ return roce5_uni_cmd_qp_query(rdev, qpn, context, qpc_size);
+ }
+ return -EINVAL;
+}
+
+void qpc_seg_to_le32(struct roce5_qp_context *be_ctx,
+ struct roce5_qp_context *le_ctx, u32 srq_vld)
+{
+ /* DRV Seg */
+ int ret;
+
+ ret = memcpy_s((void *)le_ctx->sw_seg.path_seg.dgid,
+ sizeof(be_ctx->sw_seg.path_seg.dgid),
+ (void *)be_ctx->sw_seg.path_seg.dgid,
+ sizeof(be_ctx->sw_seg.path_seg.dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return;
+ }
+
+ /* CHIP Seg */
+ le_ctx->chip_seg.qpcc.sq_rq_l0mtt_gpa =
+ be64_to_cpu(be_ctx->chip_seg.qpcc.sq_rq_l0mtt_gpa);
+ le_ctx->chip_seg.qpcc.sq_rq_pi_record_gpa_at_hop_num = cpu_to_be64(
+ be_ctx->chip_seg.qpcc.sq_rq_pi_record_gpa_at_hop_num);
+ le_ctx->chip_seg.rcc.rc_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.rcc.rc_curt_sge_va);
+ le_ctx->chip_seg.sqc.sq_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.sqc.sq_curt_sge_va);
+ le_ctx->chip_seg.sqac.sqa_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.sqac.sqa_curt_sge_va);
+
+ if (srq_vld != 0) {
+ le_ctx->chip_seg.srqc.srq_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.srqc.srq_curt_sge_va);
+ } else {
+ le_ctx->chip_seg.rqc.rq_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.rqc.rq_curt_sge_va);
+ }
+
+ le_ctx->chip_seg.rrwc.rrw_curt_sge_va =
+ be64_to_cpu(be_ctx->chip_seg.rrwc.rrw_curt_sge_va);
+}
+
+void roce5_be32_2_le32(void *context, u32 *le_ctx, u32 ctx_size)
+{
+ u32 *ctx = NULL, *ctx1 = NULL;
+ u32 i = 0;
+
+ ctx = le_ctx;
+ ctx1 = (u32 *)context;
+
+ for (i = 0; i < ctx_size; ++i, ++ctx1, ++ctx) {
+ *ctx = be32_to_cpu(*ctx1);
+ }
+
+ return;
+}
+
+static void roce5_get_ah_attr(const struct roce5_qp *rqp,
+ struct ib_qp_attr *qp_attr,
+ struct roce5_device *rdev,
+ roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ if ((rqp->qp_type == IB_QPT_RC) || (rqp->qp_type == IB_QPT_UC)) {
+ to_ib_ah_attr(rdev, &qp_attr->ah_attr, verbs_qp_attr);
+ }
+}
+
+static void roce5_query_set_common_attr(struct ib_qp_attr *qp_attr,
+ const struct ib_qp *ibqp,
+ struct roce5_qp *rqp,
+ struct ib_qp_init_attr *qp_init_attr)
+{
+ qp_attr->cur_qp_state = qp_attr->qp_state;
+ qp_attr->cap.max_recv_wr = (u32)rqp->rq.wqebb_cnt;
+ qp_attr->cap.max_recv_sge = (u32)rqp->rq.max_sge;
+
+ if (!ibqp->uobject) {
+ qp_attr->cap.max_send_wr = (u32)rqp->sq.max_post;
+ qp_attr->cap.max_send_sge = (u32)rqp->sq.max_sge;
+ } else {
+ qp_attr->cap.max_send_wr = 0;
+ qp_attr->cap.max_send_sge = 0;
+ }
+
+ qp_attr->cap.max_inline_data = rqp->max_inline_data;
+
+ qp_init_attr->cap = qp_attr->cap;
+
+ qp_init_attr->create_flags = (enum ib_qp_create_flags)0;
+
+ qp_init_attr->sq_sig_type = (rqp->sq_signal_bits == 1) ?
+ IB_SIGNAL_ALL_WR :
+ IB_SIGNAL_REQ_WR;
+}
+
+static void roce5_query_set_attr(struct ib_qp_attr *qp_attr, u8 tmp_qp_state,
+ struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *verbs_qp_attr,
+ struct roce5_device *rdev)
+{
+ qp_attr->qp_state = (enum ib_qp_state)rqp->qp_state;
+ qp_attr->path_mtu = (enum ib_mtu)verbs_qp_attr->com_info.dw3.bs.pmtu;
+ qp_attr->path_mig_state =
+ (enum ib_mig_state)to_ib_mig_state(ROCE_QP_PM_MIGRATED);
+ qp_attr->qkey = verbs_qp_attr->com_info.q_key;
+ qp_attr->rq_psn = verbs_qp_attr->com_info.dw9.bs.next_rcv_psn;
+ qp_attr->sq_psn = verbs_qp_attr->com_info.dw8.bs.next_send_psn;
+ qp_attr->dest_qp_num = verbs_qp_attr->com_info.dw0.bs.dest_qp;
+ qp_attr->qp_access_flags = to_ib_qp_access_flags(verbs_qp_attr);
+
+ roce5_get_ah_attr(rqp, qp_attr, rdev, verbs_qp_attr);
+
+ qp_attr->pkey_index = 0;
+
+ if (qp_attr->qp_state == IB_QPS_INIT) {
+ qp_attr->port_num = rqp->port;
+ } else {
+ qp_attr->port_num = verbs_qp_attr->com_info.dw5.bs.port;
+ }
+
+ /* qp_attr->en_sqd_async_notify is only applicable in modify qp */
+
+ /* SQ Draining FLAG */
+ qp_attr->sq_draining =
+ (tmp_qp_state ==
+ (u8)(enum roce_qp_state)ROCE_QP_STATE_SQ_DRAINING);
+
+ qp_attr->max_rd_atomic = (1 << verbs_qp_attr->com_info.dw1.bs.sra_max);
+ qp_attr->max_dest_rd_atomic =
+ (1 << verbs_qp_attr->com_info.dw1.bs.rra_max);
+
+ qp_attr->min_rnr_timer = verbs_qp_attr->com_info.dw2.bs.min_rnr_nak;
+ qp_attr->timeout = verbs_qp_attr->com_info.dw2.bs.ack_to;
+ qp_attr->retry_cnt = verbs_qp_attr->com_info.dw1.bs.to_retry_limit;
+ qp_attr->rnr_retry = verbs_qp_attr->com_info.dw1.bs.rnr_retry_limit;
+}
+
+static int roce5_query_qp_struct_clean(struct ib_qp_attr *qp_attr,
+ struct ib_qp_init_attr *qp_init_attr,
+ roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ int ret;
+
+ ret = memset_s(qp_attr, sizeof(struct ib_qp_attr), 0,
+ sizeof(struct ib_qp_attr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset qp_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = memset_s(qp_init_attr, sizeof(struct ib_qp_init_attr), 0,
+ sizeof(struct ib_qp_init_attr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset qp_init_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = memset_s(verbs_qp_attr, sizeof(roce_verbs_qp_attr_s), 0,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset verbs_qp_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void roce_qp_attr_com_info_to_le32(roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ verbs_qp_attr->com_info.dw0.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw0.value);
+ verbs_qp_attr->com_info.dw1.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw1.value);
+ verbs_qp_attr->com_info.dw2.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw2.value);
+ verbs_qp_attr->com_info.dw3.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw3.value);
+ verbs_qp_attr->com_info.q_key =
+ be32_to_cpu(verbs_qp_attr->com_info.q_key);
+ verbs_qp_attr->com_info.dw5.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw5.value);
+ verbs_qp_attr->com_info.dw6.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw6.value);
+ verbs_qp_attr->com_info.dw7.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw7.value);
+ verbs_qp_attr->com_info.dw8.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw8.value);
+ verbs_qp_attr->com_info.dw9.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw9.value);
+ verbs_qp_attr->com_info.lsn = be32_to_cpu(verbs_qp_attr->com_info.lsn);
+ verbs_qp_attr->com_info.dw11.value =
+ be32_to_cpu(verbs_qp_attr->com_info.dw11.value);
+ verbs_qp_attr->com_info.rsvd =
+ be32_to_cpu(verbs_qp_attr->com_info.rsvd);
+}
+
+static void roce_qp_attr_path_info_to_le32(roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ verbs_qp_attr->path_info.dw0.value =
+ be32_to_cpu(verbs_qp_attr->path_info.dw0.value);
+ verbs_qp_attr->path_info.dmac_l32 =
+ be32_to_cpu(verbs_qp_attr->path_info.dmac_l32);
+ verbs_qp_attr->path_info.dw6.value =
+ be32_to_cpu(verbs_qp_attr->path_info.dw6.value);
+ verbs_qp_attr->path_info.dw7.value =
+ be32_to_cpu(verbs_qp_attr->path_info.dw7.value);
+}
+
+static void roce_qp_attr_chip_seg_to_le32(roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ verbs_qp_attr->chip_seg.dw0.sq_rq_l0mtt_gpa =
+ be64_to_cpu(verbs_qp_attr->chip_seg.dw0.sq_rq_l0mtt_gpa);
+ verbs_qp_attr->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num = be64_to_cpu(
+ verbs_qp_attr->chip_seg.dw2.sq_rq_pi_record_gpa_at_hop_num);
+ verbs_qp_attr->chip_seg.dw4.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw4.value);
+ verbs_qp_attr->chip_seg.dw5.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw5.value);
+ verbs_qp_attr->chip_seg.dw6.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw6.value);
+ verbs_qp_attr->chip_seg.dw7.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw7.value);
+ verbs_qp_attr->chip_seg.dw8.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw8.value);
+ verbs_qp_attr->chip_seg.dw9.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw9.value);
+ verbs_qp_attr->chip_seg.dw10.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw10.value);
+ verbs_qp_attr->chip_seg.rc_page_gpa_l =
+ be32_to_cpu(verbs_qp_attr->chip_seg.rc_page_gpa_l);
+ verbs_qp_attr->chip_seg.dw12.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw12.value);
+ verbs_qp_attr->chip_seg.dw13.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw13.value);
+ verbs_qp_attr->chip_seg.dw14.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw14.value);
+ verbs_qp_attr->chip_seg.dw15.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw15.value);
+ verbs_qp_attr->chip_seg.dw16.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw16.value);
+ verbs_qp_attr->chip_seg.dw17.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw17.value);
+ verbs_qp_attr->chip_seg.dw18.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw18.value);
+ verbs_qp_attr->chip_seg.dw19.value =
+ be32_to_cpu(verbs_qp_attr->chip_seg.dw19.value);
+}
+
+static void roce5_qp_attr_to_le32(roce_verbs_qp_attr_s *verbs_qp_attr)
+{
+ roce_qp_attr_com_info_to_le32(verbs_qp_attr);
+ roce_qp_attr_path_info_to_le32(verbs_qp_attr);
+ roce_qp_attr_chip_seg_to_le32(verbs_qp_attr);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_query_qp
+ Description : roce5_query_qp
+ Input : struct ib_qp *ibqp
+ struct ib_qp_attr *qp_attr
+ int qp_attr_mask
+ struct ib_qp_init_attr *qp_init_attr
+ Output : None
+
+ 1.Date : 2015/4/29
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+{
+ int ret = 0;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_device *rdev = NULL;
+ roce_verbs_qp_attr_s verbs_qp_attr;
+ u32 srq_vld;
+ u8 tmp_qp_state = 0;
+
+ if ((ibqp == NULL) || (qp_attr == NULL) || (qp_init_attr == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ ret = roce5_query_qp_struct_clean(qp_attr, qp_init_attr,
+ &verbs_qp_attr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ rqp = to_roce5_qp(ibqp);
+ rdev = to_roce5_dev(ibqp->device);
+
+ mutex_lock(&rqp->mutex);
+
+ if (rqp->qp_state == (u8)(enum ib_qp_state)IB_QPS_RESET) {
+ qp_attr->qp_state = IB_QPS_RESET;
+ goto done;
+ }
+
+ if (ROCE5_SUPPORT_IB_CMD_QUERY_QP_MSG_V2(rdev) != 0) {
+ ret = roce5_qp_query(rdev, rqp->qpn,
+ (u32 *)(void *)(&verbs_qp_attr),
+ sizeof(verbs_qp_attr));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to query qp with 25V100 or 23V200, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ mutex_unlock(&rqp->mutex);
+ return ret;
+ }
+ }
+
+ srq_vld = (!(rqp->ibqp.srq)) ? ROCE_QP_NO_SRQ : ROCE_QP_HAS_SRQ;
+
+ if (ROCE5_SUPPORT_IB_CMD_QUERY_QP_MSG_V2(rdev) != 0) {
+ roce5_qp_attr_to_le32(&verbs_qp_attr);
+ rqp->qp_state = verbs_qp_attr.com_info.dw6.bs
+ .state; /* 25V100 or 23V200 qp state */
+ }
+
+ tmp_qp_state = rqp->qp_state;
+ if (rqp->qp_state ==
+ (u8)(enum roce_qp_state)ROCE_QP_STATE_SQ_DRAINING) {
+ rqp->qp_state = (u8)(enum ib_qp_state)IB_QPS_SQD;
+ }
+
+ if (ROCE5_SUPPORT_IB_CMD_QUERY_QP_MSG_V2(rdev) != 0) {
+ /* 25V100 or 23V200 set attr */
+ roce5_query_set_attr(qp_attr, tmp_qp_state, rqp, &verbs_qp_attr,
+ rdev);
+ }
+
+done:
+ roce5_query_set_common_attr(qp_attr, ibqp, rqp, qp_init_attr);
+
+ mutex_unlock(&rqp->mutex);
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.c
new file mode 100644
index 000000000..257e9a8aa
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.c
@@ -0,0 +1,22 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+
+struct rdma_comp_priv *get_rdma_comp_priv(void *hwdev)
+{
+ struct rdma_comp_priv *comp_private = NULL;
+ comp_private = (struct rdma_comp_priv *)hinic5_get_service_adapter(
+ hwdev, SERVICE_T_ROCE);
+ return comp_private;
+}
+
+void rdma_cleanup_pd_table(struct rdma_comp_priv *comp_priv)
+{
+ rdma_bitmap_cleanup(&comp_priv->pd_bitmap);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.h b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.h
new file mode 100644
index 000000000..8a1a8d665
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp.h
@@ -0,0 +1,166 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef RDMA_COMP_H
+#define RDMA_COMP_H
+
+/* x86 */
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 0x1234
+#endif
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#ifdef ROCE_KNL_DT
+#include <linux/compiler_types.h>
+#endif
+
+#include "hinic5_crm.h"
+#include "hinic5_cqm.h"
+#include "hinic5_rdma.h"
+
+#include "roce_gid.h"
+#include "roce_npu_cmd_defs.h"
+#include "roce.h"
+#include "roce_compat.h"
+
+#include "rdma_bitmap.h"
+#include "hmm_em_inner.h"
+#include "hmm_common.h"
+
+#ifndef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": [RDMA]" fmt
+#endif
+
+#define RDMA_DEFAULT_GID_SUBNET_PREFIX 0xFE80000000000000ULL
+
+#define RDMA_INVALID_GUID 0
+
+#define RDMA_SERVICE_TYPE_ROCE SERVICE_T_ROCE
+
+#define RDMA_BIT_SHIFT_1 1
+#define RDMA_BIT_SHIFT_2 2
+#define RDMA_BIT_SHIFT_4 4
+#define RDMA_BIT_SHIFT_8 8
+#define RDMA_BIT_SHIFT_16 16
+
+#define ROCE5_RDMARC_MIN_DEPTH 1
+#define ROCE5_RDMARC_MAX_DEPTH 512
+#define ROCE5_RDMARC_MIN_ENTRY 8 /* min entry aligned required by engine */
+#define ROCE5_RDMARC_MAX_ENTRY 128 /* max entry supported by engine */
+#define ROCE5_RDMARC_EXT_ENTRY 384 //384 /* ext tbl 12K. 12k/32 = 384 */
+
+#define ROCE5_RDMARC_GPA_H_SHIFT 40 /* high:24bit, 64-24= 40 */
+#define ROCE5_RDMARC_GPA_L_SHIFT 8 /* bit[39:8] */
+#define ROCE5_RDMARC_RRA_MAX_MASK 0x7 /* rra_max:3bit */
+#define ROCE5_RDMARC_EXT_ORDER_SHIFT 3
+
+extern u32 g_mtt_page_size;
+
+#define RDMA_EM_MIN_ORDER 2 /* rdma rc extend table at least 4 page */
+
+#define ROCE_MTT_PAGE_SIZE_4K 4096
+#define ROCE_MTT_PAGE_SIZE_64K (64 * 1024)
+#define ROCE_MTT_PAGE_SIZE_2M (2 * 1024 * 1024)
+#define ROCE_MTT_PAGE_SIZE_4K_SHIFT 12
+#define ROCE_MTT_PAGE_SIZE_64K_SHIFT 16
+#define ROCE_MTT_PAGE_SIZE_2M_SHIFT 21
+
+enum {
+ ROCE5_RDMA_MTT_PAGE_SIZE_4K = 0,
+ ROCE5_RDMA_MTT_PAGE_SIZE_64K = 1,
+ ROCE5_RDMA_MTT_PAGE_SIZE_2M = 2
+};
+
+enum {
+ ROCE5_RDMA_CMD_TIME_OUT_A = 30000,
+ ROCE5_RDMA_CMD_TIME_OUT_B = 40000,
+ ROCE5_RDMA_CMD_TIME_OUT_C = 50000
+};
+
+/**
+ * @brief struct rdma_comp_resource
+ * @details RDMA component resource structure, used to store RDMA component of related resources
+ */
+struct rdma_comp_resource {
+ struct mutex mutex; /**< gid_entry mutex used by */
+ __be64 node_guid; /**< and ibdev in of node_guid same as */
+ struct rdma_gid_entry *
+ *gid_table; /**< gid_entry in rdma component initialize when allocate memory */
+};
+
+/**
+ * @brief enum rdma_mw_type
+ * @details define an enum type, used to represent RDMA memory window of type
+ */
+enum rdma_mw_type { RDMA_MW_TYPE_1 = 1, RDMA_MW_TYPE_2 = 2 };
+
+/**
+ * @brief struct rdma_mw
+ * @details define a rdma_mw structure, used to represent a RDMA memory window
+ */
+struct rdma_mw {
+ struct mpt mpt;
+ u32 key; /**< mw corresponding to key */
+ u32 pdn; /**< mw bind of pdn */
+ enum rdma_mw_type type; /**< mw of type,type1,type2 */
+ int enabled; /**< mw of status */
+};
+
+struct rdma_comp_priv {
+ struct hmm_comp_priv hmm_priv;
+ struct rdma_comp_resource rdma_comp_res; /* gid & guid */
+ struct hmm_rdma rsvd_lkey;
+ struct hmm_rdma fixed_mr;
+ struct rdma_service_cap rdma_cap;
+
+ struct rdma_bitmap pd_bitmap;
+ struct rdma_bitmap xrcd_bitmap;
+
+ struct hmm_buddy rdmarc_buddy;
+ struct hmm_em_table rdmarc_em_table;
+};
+
+/* Only V100 use */
+struct rdma_gid_update_inbuf {
+ roce_verbs_cmd_com_s com;
+ __be32 port;
+ __be32 rsvd;
+ struct rdma_gid_entry gid_entry;
+};
+
+struct rdma_gid_clear_inbuf {
+ __be32 port;
+ __be32 gid_num;
+};
+
+typedef struct tag_roce_clear_gid {
+ roce_verbs_cmd_com_s com;
+
+ u32 port;
+ u32 gid_num;
+} roce_cmd_clear_gid_s;
+
+/* for llt to set stub */
+void rdma_cleanup_pd_table(struct rdma_comp_priv *comp_priv);
+struct rdma_comp_priv *get_rdma_comp_priv(void *hwdev);
+int rdma_gid_entry_cmp(struct rdma_gid_entry *gid_tbl_entry,
+ struct rdma_gid_entry *gid_entry);
+int roce5_update_gid_mac(struct roce5_device *rdev, u32 port, int *index,
+ struct rdma_gid_entry *gid_entry);
+int roce5_update_gid(struct roce5_device *rdev, u32 port, u32 update_index,
+ struct rdma_gid_entry *gid_entry);
+int roce5_reset_gid_table(struct roce5_device *rdev, u32 port);
+int roce5_get_gid(struct roce5_device *rdev, u32 port, u32 gid_index,
+ struct rdma_gid_entry *gid);
+
+#endif //RDMA_COMP_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_gid.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_gid.c
new file mode 100644
index 000000000..b7919b409
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_gid.c
@@ -0,0 +1,489 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+#include "roce.h"
+#include "roce_cqm_cmd.h"
+#include "roce_npu_cmd.h"
+#include "roce_mix.h"
+#include "roce_gid.h"
+#include "securec.h"
+#include "roce_npu_cmd_gid_defs.h"
+
+#define ROCE_GID_IFID_DW_INDEX \
+ 2 /* Interface ID starts at dword index 2 in u32 gid[4] (indices 0-1: subnet_prefix, 2-3: interface_id) */
+
+static int roce5_uni_cmd_update_gid(struct roce5_device *rdev,
+ struct rdma_comp_priv *comp_priv,
+ struct rdma_gid_entry *new_gid_entry,
+ int port, int gid_index)
+{
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_update_gid_s *gid_update_inbuf = NULL;
+ int ret;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ comp_priv->hmm_priv.hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_update_gid_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_ERR("Failed to alloc cqm_cmd_inoutbuf, ret(%d)", ret);
+ return -ENOMEM;
+ }
+
+ gid_update_inbuf = (roce_uni_cmd_update_gid_s *)cqm_cmd_inbuf->buf;
+ *(u64 *)(&gid_update_inbuf->gid_attr.gid[0]) =
+ new_gid_entry->global.subnet_prefix;
+ *(u64 *)(&gid_update_inbuf->gid_attr.gid[ROCE_GID_IFID_DW_INDEX]) =
+ new_gid_entry->global.interface_id;
+ gid_update_inbuf->gid_attr.dw4.value =
+ cpu_to_be32(new_gid_entry->dw4.value);
+ gid_update_inbuf->gid_attr.dw5.value =
+ cpu_to_be32(new_gid_entry->hdr_len_value);
+ gid_update_inbuf->gid_attr.dw6.bs1.ctrl_val =
+ new_gid_entry->dw6_h.value;
+ gid_update_inbuf->gid_attr.dw6.bs1.smac_hi16 =
+ be16_to_cpu(*((u16 *)(&new_gid_entry->smac[0])));
+ gid_update_inbuf->gid_attr.dw6.value =
+ cpu_to_be32(gid_update_inbuf->gid_attr.dw6.value);
+ gid_update_inbuf->gid_attr.smac_lo32 =
+ *((u32 *)(&new_gid_entry->smac[2])); //4=lo32
+
+ gid_update_inbuf->com.index = cpu_to_be32((u32)gid_index);
+ gid_update_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_GID_BITMASK);
+ gid_update_inbuf->com.opt = cpu_to_be32((u32)port);
+ if (rdev->shadow != 0) {
+ gid_update_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_SHADOW_BITMASK);
+ gid_update_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rdev->shadow_vfid);
+ gid_update_inbuf->gid_attr.dw10.shadow.shadow_vf_num =
+ rdev->shadow_vf_num;
+ gid_update_inbuf->gid_attr.dw10.value =
+ cpu_to_be32(gid_update_inbuf->gid_attr.dw10.value);
+ }
+
+ ROCE_PRINT_GID(rdev, new_gid_entry, "gid_index(0x%x)",
+ gid_update_inbuf->com.index);
+ ret = cqm5_send_cmd_box(comp_priv->hmm_priv.hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_UPDATE_GID, cqm_cmd_inbuf, NULL, NULL,
+ ROCE5_RDMA_CMD_TIME_OUT_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Send cmd update_gid failed, ret(%d)", ret);
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(comp_priv->hmm_priv.hwdev, cqm_cmd_inbuf,
+ NULL);
+
+ return ret;
+}
+
+static int roce5_cmd_update_gid(struct roce5_device *rdev,
+ struct rdma_comp_priv *comp_priv,
+ struct rdma_gid_entry *new_gid_entry, int port,
+ int gid_index)
+{
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ struct rdma_gid_update_inbuf *gid_update_inbuf = NULL;
+ int ret;
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ return roce5_uni_cmd_update_gid(rdev, comp_priv, new_gid_entry,
+ port, gid_index);
+ }
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ comp_priv->hmm_priv.hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct rdma_gid_update_inbuf), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc cqm_cmd_inoutbuf, ret(%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ gid_update_inbuf = (struct rdma_gid_update_inbuf *)cqm_cmd_inbuf->buf;
+ gid_update_inbuf->port = cpu_to_be32((u32)port);
+ gid_update_inbuf->com.index = cpu_to_be32((u32)gid_index);
+ gid_update_inbuf->gid_entry.global.subnet_prefix =
+ new_gid_entry->global.subnet_prefix;
+ gid_update_inbuf->gid_entry.global.interface_id =
+ new_gid_entry->global.interface_id;
+ gid_update_inbuf->gid_entry.dw4.value =
+ cpu_to_be32(new_gid_entry->dw4.value);
+ gid_update_inbuf->gid_entry.dw6_h.value =
+ cpu_to_be16(new_gid_entry->dw6_h.value);
+ gid_update_inbuf->gid_entry.hdr_len_value =
+ cpu_to_be32(new_gid_entry->hdr_len_value);
+ gid_update_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_GID_BITMASK);
+
+ ret = memcpy_s(&gid_update_inbuf->gid_entry.smac[0], ETH_ALEN,
+ &new_gid_entry->smac[0], ETH_ALEN);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy_s smac.(ret:%d)", ret);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ROCE_PRINT_GID(rdev, new_gid_entry, "gid_index(0x%x) ",
+ gid_update_inbuf->com.index);
+ ret = cqm5_send_cmd_box(comp_priv->hmm_priv.hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_UPDATE_GID, cqm_cmd_inbuf, NULL, NULL,
+ ROCE5_RDMA_CMD_TIME_OUT_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Send cmd update_gid failed, ret(%d)", ret);
+ ret = -1;
+ }
+
+err:
+ roce5_cqm5_cmd_free_inoutbuf(comp_priv->hmm_priv.hwdev, cqm_cmd_inbuf,
+ NULL);
+
+ return ret;
+}
+
+int rdma_gid_entry_cmp(struct rdma_gid_entry *gid_tbl_entry,
+ struct rdma_gid_entry *gid_entry)
+{
+ struct rdma_gid_entry entry1;
+ struct rdma_gid_entry entry2;
+ int ret;
+
+ ret = memcpy_s(&entry1, sizeof(struct rdma_gid_entry), gid_tbl_entry,
+ sizeof(struct rdma_gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy entry1.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = memcpy_s(&entry2, sizeof(struct rdma_gid_entry), gid_entry,
+ sizeof(struct rdma_gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy entry2.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ /* compare ip+vlan, compare after clear smac */
+ ret = memset_s((void *)entry1.smac, sizeof(entry1.smac), 0,
+ sizeof(entry1.smac));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset entry1 smac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = memset_s((void *)entry2.smac, sizeof(entry2.smac), 0,
+ sizeof(entry2.smac));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset entry2.smac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ return memcmp((void *)&entry1, (void *)&entry2,
+ sizeof(struct rdma_gid_entry));
+}
+
+static int roce5_uni_cmd_reset_gid(struct roce5_device *rdev,
+ struct rdma_comp_priv *comp_priv, u32 port,
+ u32 gid_num)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_clear_gid_s *gid_clear_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ comp_priv->hmm_priv.hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_clear_gid_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_ERR("Failed to alloc cqm_cmd_inoutbuf, ret(%d)", ret);
+ return -ENOMEM;
+ }
+
+ gid_clear_inbuf = (roce_uni_cmd_clear_gid_s *)cqm_cmd_inbuf->buf;
+ gid_clear_inbuf->gid_clear.gid_num = cpu_to_be32(gid_num);
+ gid_clear_inbuf->com.index = 0;
+ gid_clear_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_GID_BITMASK);
+ gid_clear_inbuf->com.opt = cpu_to_be32((u32)port);
+
+ if (rdev->shadow != 0) {
+ gid_clear_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_SHADOW_BITMASK);
+ gid_clear_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rdev->shadow_vfid);
+ gid_clear_inbuf->gid_clear.dw1.shadow.shadow_vf_num =
+ rdev->shadow_vf_num;
+ gid_clear_inbuf->gid_clear.dw1.value =
+ cpu_to_be32(gid_clear_inbuf->gid_clear.dw1.value);
+ }
+
+ ret = cqm5_send_cmd_box(comp_priv->hmm_priv.hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_CLEAR_GID, cqm_cmd_inbuf, NULL, NULL,
+ ROCE5_RDMA_CMD_TIME_OUT_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Send cmd clear_gid failed, ret(%d)", ret);
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(comp_priv->hmm_priv.hwdev, cqm_cmd_inbuf,
+ NULL);
+
+ return ret;
+}
+
+static int roce5_cmd_reset_gid(struct roce5_device *rdev,
+ struct rdma_comp_priv *comp_priv, u32 port,
+ u32 gid_num)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_cmd_clear_gid_s *gid_clear_inbuf = NULL;
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ return roce5_uni_cmd_reset_gid(rdev, comp_priv, port, gid_num);
+ }
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(comp_priv->hmm_priv.hwdev,
+ &cqm_cmd_inbuf,
+ (u16)sizeof(roce_cmd_clear_gid_s),
+ NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc cqm_cmd_inoutbuf, ret(%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ gid_clear_inbuf = (roce_cmd_clear_gid_s *)cqm_cmd_inbuf->buf;
+ gid_clear_inbuf->port = cpu_to_be32(port);
+ gid_clear_inbuf->gid_num = cpu_to_be32(gid_num);
+ gid_clear_inbuf->com.index = 0;
+ gid_clear_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_GID_BITMASK);
+
+ ret = cqm5_send_cmd_box(comp_priv->hmm_priv.hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_CLEAR_GID, cqm_cmd_inbuf, NULL, NULL,
+ ROCE5_RDMA_CMD_TIME_OUT_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Send cmd clear_gid failed, ret(%d)", ret);
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(comp_priv->hmm_priv.hwdev, cqm_cmd_inbuf,
+ NULL);
+
+ return ret;
+}
+
+int roce5_update_gid_mac(struct roce5_device *rdev, u32 port, int *index,
+ struct rdma_gid_entry *gid_entry)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+ struct rdma_gid_entry **gid_table = NULL;
+ u32 gid_index = 0;
+ int update_index =
+ -1; /* -1 is initvalue, indicating no need to update */
+ int ret = 0;
+ if ((rdev->hwdev == NULL) || (gid_entry == NULL)) {
+ ROCE_ERR("Hwdev or gid_tbl is null");
+ return -EINVAL;
+ }
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+ /* port num index from zero */
+ if (port >= comp_priv->rdma_cap.num_ports) {
+ ROCE_ERR("Input port(%d) is invalid", port);
+ return -EINVAL;
+ }
+ /* invalid gid cause of with the head fe80:: of IPV6 */
+ if (cpu_to_be64(gid_entry->global.subnet_prefix) ==
+ RDMA_DEFAULT_GID_SUBNET_PREFIX) {
+ return 0;
+ }
+ gid_table = comp_priv->rdma_comp_res.gid_table;
+ mutex_lock(&comp_priv->rdma_comp_res.mutex);
+ /* loop all gid, ensure all gid cleared not exist */
+ for (gid_index = 1; gid_index < comp_priv->rdma_cap.max_gid_per_port;
+ gid_index++) {
+ if (rdma_gid_entry_cmp(&gid_table[port][gid_index],
+ gid_entry) == 0) {
+ update_index = (int)gid_index;
+ break;
+ }
+ }
+
+ if (update_index > 0) {
+ ret = roce5_cmd_update_gid(rdev, comp_priv, gid_entry,
+ (int)port, update_index);
+ if (ret != 0) {
+ ROCE_ERR("Update gid tbl failed, ret(%d)", ret);
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return ret;
+ }
+ /* update gid table after CMDQ */
+ ret = memcpy_s((void *)&gid_table[port][update_index],
+ sizeof(*gid_entry), (void *)gid_entry,
+ sizeof(*gid_entry));
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to memcpy gid_entry to gid_table.(ret:%d)",
+ ret);
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return (-ENOMEM);
+ }
+
+ *index = update_index;
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return 0;
+ }
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return 0;
+}
+
+int roce5_update_gid(struct roce5_device *rdev, u32 port, u32 update_index,
+ struct rdma_gid_entry *gid_entry)
+{
+ int ret = 0;
+ u32 port_num = 0;
+ struct rdma_comp_priv *comp_priv = NULL;
+ struct rdma_gid_entry **gid_table = NULL;
+
+ if ((rdev->hwdev == NULL) || (gid_entry == NULL)) {
+ ROCE_ERR("Hwdev or gid_tbl is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ gid_table = comp_priv->rdma_comp_res.gid_table;
+
+ /* port start from zero */
+ port_num = comp_priv->rdma_cap.num_ports;
+ if (port >= port_num) {
+ ROCE_DEV_ERR(rdev, "Input port(%d) is invalid", port);
+ return -EINVAL;
+ }
+
+ mutex_lock(&comp_priv->rdma_comp_res.mutex);
+ ret = roce5_cmd_update_gid(rdev, comp_priv, gid_entry, (int)port,
+ (int)update_index);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Rdma_update_gid failed");
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return ret;
+ }
+
+ ret = memcpy_s((void *)&gid_table[port][update_index],
+ sizeof(*gid_entry), (void *)gid_entry,
+ sizeof(*gid_entry));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy gid_entry.(ret:%d)", ret);
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+ return -ENOMEM;
+ }
+ mutex_unlock(&comp_priv->rdma_comp_res.mutex);
+
+ return 0;
+}
+
+int roce5_reset_gid_table(struct roce5_device *rdev, u32 port)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+ struct rdma_gid_entry **gid_table = NULL;
+ int ret = 0;
+ u32 gids_per_port = 0;
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ gid_table = comp_priv->rdma_comp_res.gid_table;
+ if (gid_table == NULL) {
+ ROCE_ERR("Gid_table is null");
+ return -EINVAL;
+ }
+
+ gids_per_port = comp_priv->rdma_cap.max_gid_per_port;
+
+ if (gids_per_port == 0) {
+ ROCE_ERR("Gids_per_port(%d) is invalid", gids_per_port);
+ return -EINVAL;
+ }
+
+ ret = memset_s(&gid_table[port][0],
+ gids_per_port * sizeof(struct rdma_gid_entry), 0,
+ gids_per_port * sizeof(struct rdma_gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_table.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_cmd_reset_gid(rdev, comp_priv, port, gids_per_port);
+ if (ret != 0) {
+ ROCE_ERR("Reset gid table failed, gid_num(%d), ret(%d)",
+ gids_per_port, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_get_gid(struct roce5_device *rdev, u32 port, u32 gid_index,
+ struct rdma_gid_entry *gid)
+{
+ struct rdma_service_cap *rdma_cap = NULL;
+ struct rdma_comp_priv *comp_priv = NULL;
+ int ret;
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return -EINVAL;
+ }
+
+ if (gid == NULL) {
+ ROCE_ERR("Gid is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ rdma_cap = &comp_priv->rdma_cap;
+ if (port < 1 || port > rdma_cap->num_ports) {
+ ROCE_ERR("Port(%d) invalid", port);
+ return -EINVAL;
+ }
+
+ if (gid_index >= rdma_cap->max_gid_per_port) {
+ ROCE_ERR("gid_index(%d) invalid", gid_index);
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(
+ (void *)gid, sizeof(*gid),
+ (void *)&comp_priv->rdma_comp_res.gid_table[port - 1][gid_index],
+ sizeof(*gid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dmac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_init.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_init.c
new file mode 100644
index 000000000..ca5e88aff
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_init.c
@@ -0,0 +1,443 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+#include "roce_infra.h"
+#include "hinic5_hmm.h"
+#include "securec.h"
+
+#define ROCE_MAX_RDMA_RC_EXTEND 384 /* 12K */
+
+static int rdma_init_pd_table(struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+ u32 num = 0;
+ u32 reserved_bot = 0;
+
+ num = comp_priv->rdma_cap.num_pds;
+ reserved_bot = comp_priv->rdma_cap.reserved_pds;
+
+ ret = rdma_bitmap_init(&comp_priv->pd_bitmap, num, num - 1,
+ reserved_bot, 0);
+ if (ret != 0) {
+ ROCE_ERR("Can't initialize pd's bitmap, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void rdma_cleanup_gid_table(struct rdma_comp_priv *comp_priv)
+{
+ struct rdma_gid_entry **gid_table = NULL;
+ int i = 0;
+ int port_num = 0;
+
+ gid_table = comp_priv->rdma_comp_res.gid_table;
+ if (gid_table == NULL) {
+ ROCE_ERR("Gid_table is null");
+ return;
+ }
+
+ port_num = (int)comp_priv->rdma_cap.num_ports;
+ for (i = 0; i < port_num; i++) {
+ if (gid_table[i]) {
+ kfree(gid_table[i]);
+ gid_table[i] = NULL;
+ }
+ }
+
+ kfree(gid_table);
+ comp_priv->rdma_comp_res.gid_table = NULL;
+
+ return;
+}
+
+static int roce5_get_gid_nums(struct rdma_comp_priv *comp_priv)
+{
+ struct hinic5_hwdev *dev = comp_priv->hmm_priv.hwdev;
+ struct service_cap *cap = &(dev->cfg_mgmt->svc_cap);
+ struct dev_roce_svc_own_cap *roce_cap =
+ &(cap->rdma_cap.dev_rdma_cap.roce_own_cap);
+
+ /* 23v100 and earlier generations: The configuration file does not contain max gid. */
+ return (roce_cap->max_gid != 0 ? roce_cap->max_gid :
+ comp_priv->rdma_cap.max_gid_per_port);
+}
+
+static int rdma_init_gid_table(struct rdma_comp_priv *comp_priv)
+{
+ struct rdma_gid_entry **gid_table = NULL;
+ u32 i = 0;
+ u32 port_num = 0;
+ u32 gids_per_port = 0;
+
+ port_num = comp_priv->rdma_cap.num_ports;
+ gids_per_port = comp_priv->rdma_cap.max_gid_per_port;
+
+ if ((port_num == 0) || (gids_per_port == 0)) {
+ ROCE_ERR(
+ "Alloc memory for gid_tbl failed, port_num(%d), gids_per_ports(%d)",
+ port_num, gids_per_port);
+ return -EINVAL;
+ }
+
+ gid_table = (struct rdma_gid_entry **)kzalloc(
+ port_num * sizeof(struct rdma_gid_entry *), GFP_KERNEL);
+ if (gid_table == NULL) {
+ ROCE_ERR(
+ "Alloc memory for gid_tbl failed, ret(%d), port_num(%d)",
+ -ENOMEM, port_num);
+ return -ENOMEM;
+ }
+
+ comp_priv->rdma_comp_res.gid_table = gid_table;
+
+ for (i = 0; i < port_num; i++) {
+ gid_table[i] = (struct rdma_gid_entry *)kzalloc(
+ gids_per_port * sizeof(struct rdma_gid_entry),
+ GFP_KERNEL);
+ if (gid_table[i] == NULL) {
+ ROCE_ERR(
+ "Alloc memory for gid_tbl[%d] failed, ret(%d), gids_per_ports(%d)",
+ i, -ENOMEM, gids_per_port);
+ goto err_out;
+ }
+ }
+ return 0;
+err_out:
+ for (i = 0; i < port_num; i++) {
+ if (gid_table[i]) {
+ kfree(gid_table[i]);
+ gid_table[i] = NULL;
+ }
+ }
+ kfree(gid_table);
+ comp_priv->rdma_comp_res.gid_table = NULL;
+
+ return -ENOMEM;
+}
+
+static int rdma_init_xrcd_table(struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+ u32 num = 0;
+ u32 reserved_bot = 0;
+
+ num = comp_priv->rdma_cap.max_xrcds;
+ reserved_bot = comp_priv->rdma_cap.reserved_xrcds;
+
+ ret = rdma_bitmap_init(&comp_priv->xrcd_bitmap, num, num - 1,
+ reserved_bot, 0);
+ if (ret != 0) {
+ ROCE_ERR("Can't initialize xrcd's bitmap, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void rdma_cleanup_xrcd_table(struct rdma_comp_priv *comp_priv)
+{
+ rdma_bitmap_cleanup(&comp_priv->xrcd_bitmap);
+}
+
+static int rdma_init_rdmarc_table(struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+ u32 i = 0;
+ u32 max_order = 0; /* rdmarc buddy max priority num */
+ u32 qp_num = 0;
+ u32 rdmarc_per_qp = 0; /* rdmarc num per qp */
+ u32 rdmarc_size = 0;
+ u32 log_rdmarc_per_seg = 0; /* min num of entry, 2^log_rdmarc_per_seg */
+ u32 rdmarc_pow_of_two = 0;
+
+ qp_num = comp_priv->rdma_cap.dev_rdma_cap.roce_own_cap.max_qps;
+ rdmarc_per_qp =
+ comp_priv->rdma_cap.dev_rdma_cap.roce_own_cap.max_qp_dest_rdma +
+ ROCE_MAX_RDMA_RC_EXTEND;
+ rdmarc_size =
+ comp_priv->rdma_cap.dev_rdma_cap.roce_own_cap.rdmarc_entry_sz;
+ log_rdmarc_per_seg = comp_priv->rdma_cap.log_rdmarc_seg;
+ for (i = 1; i < qp_num * rdmarc_per_qp; i <<= 1) {
+ max_order++;
+ }
+
+ max_order = (max_order > log_rdmarc_per_seg) ?
+ (max_order - log_rdmarc_per_seg) :
+ 0;
+
+ ret = hmm_buddy_init(&comp_priv->rdmarc_buddy, max_order);
+ if (ret != 0) {
+ ROCE_ERR("Initialize rdmarc's buddy failed, ret(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+ rdmarc_pow_of_two =
+ roce_roundup_pow_of_two((u32)(qp_num * rdmarc_per_qp));
+ ret = hmm_em_init_table(comp_priv->hmm_priv.dev,
+ &comp_priv->rdmarc_em_table, rdmarc_size,
+ rdmarc_pow_of_two, 0, RDMA_EM_MIN_ORDER);
+ if (ret != 0) {
+ ROCE_ERR("Initialize rdmarc's em_table failed, ret(%d)", ret);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ hmm_buddy_cleanup(&comp_priv->rdmarc_buddy);
+
+ return -ENOMEM;
+}
+
+static int roce5_rdma_init_pd_table(struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+ ret = rdma_init_pd_table(comp_priv);
+ if (ret != 0) {
+ ROCE_ERR("Initialize pd's table failed, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int roce5_rdma_init_mtt_table(struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+ ret = hmm_mtt_init((struct hmm_comp_priv *)(void *)comp_priv);
+ if (ret != 0) {
+ ROCE_ERR("Initialize mtt's table failed, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int roce5_rdma_init_bitmap(struct rdma_comp_priv *comp_priv)
+{
+ int ret;
+ ret = roce5_rdma_init_pd_table(comp_priv);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = roce5_rdma_init_mtt_table(comp_priv);
+ if (ret != 0) {
+ rdma_cleanup_pd_table(comp_priv);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_rdma_unit_bitmap(struct rdma_comp_priv *comp_priv)
+{
+ hmm_mtt_cleanup((struct hmm_comp_priv *)(void *)comp_priv);
+ rdma_cleanup_pd_table(comp_priv);
+}
+
+static int roce5_rdma_init_table(void *hwdev, struct rdma_comp_priv *comp_priv)
+{
+ int ret = 0;
+
+ ret = roce5_rdma_init_bitmap(comp_priv);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = rdma_init_gid_table(comp_priv);
+ if (ret != 0) {
+ ROCE_ERR("Initialize gid table failed, ret(%d)", ret);
+ goto err_init_gid_table;
+ }
+
+ ret = rdma_init_xrcd_table(comp_priv);
+ if (ret != 0) {
+ ROCE_ERR("Initialize xrcd's table failed, ret(%d)", ret);
+ goto err_init_xrcd;
+ }
+
+ ret = rdma_init_rdmarc_table(comp_priv);
+ if (ret != 0) {
+ ROCE_ERR("Initialize rdmarc's table failed, ret(%d)", ret);
+ goto err_init_rdmarc_table;
+ }
+
+ ROCE_INFO("Rdma init resource successful.");
+ return 0;
+
+err_init_rdmarc_table:
+ rdma_cleanup_xrcd_table(comp_priv);
+err_init_xrcd:
+ rdma_cleanup_gid_table(comp_priv);
+err_init_gid_table:
+ roce5_rdma_unit_bitmap(comp_priv);
+ return ret;
+}
+
+static void rdma_cleanup_rdmarc_table(struct rdma_comp_priv *comp_priv)
+{
+ hmm_em_cleanup_table(comp_priv->hmm_priv.dev,
+ &comp_priv->rdmarc_em_table);
+
+ hmm_buddy_cleanup(&comp_priv->rdmarc_buddy);
+
+ return;
+}
+
+static void roce5_rdma_unit_table(void *hwdev, struct rdma_comp_priv *comp_priv)
+{
+ if (hinic5_support_roce(hwdev, NULL)) {
+ rdma_cleanup_rdmarc_table(comp_priv);
+ rdma_cleanup_xrcd_table(comp_priv);
+ rdma_cleanup_gid_table(comp_priv);
+ }
+
+ roce5_rdma_unit_bitmap(comp_priv);
+}
+
+void roce5_rdma_cleanup_resource(void *hwdev)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return;
+ }
+
+ if (!hinic5_support_rdma(hwdev, NULL)) {
+ ROCE_ERR("Not support rdma service");
+ return;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return;
+ }
+
+ roce5_rdma_unit_table(hwdev, comp_priv);
+
+ kfree(comp_priv);
+
+ hinic5_unregister_service_adapter((void *)hwdev, SERVICE_T_ROCE);
+
+ ROCE_INFO("Rdma cleanup resource successful.");
+
+ return;
+}
+
+static int roce5_rdma_init_comp_priv(struct rdma_comp_priv *comp_priv,
+ void *hwdev,
+ struct rdma_service_cap *rdma_cap)
+{
+ int ret;
+
+ mutex_init(&comp_priv->rdma_comp_res.mutex);
+ comp_priv->hmm_priv.hwdev = hwdev;
+
+ comp_priv->hmm_priv.dev =
+ (struct device *)(((struct hinic5_hwdev *)hwdev)->dev_hdl);
+ if (comp_priv->hmm_priv.dev == NULL) {
+ ROCE_ERR("Failed to init, device is NULL.");
+ return -EINVAL;
+ }
+
+ ret = memcpy_s((void *)&comp_priv->rdma_cap,
+ sizeof(struct rdma_service_cap), (void *)rdma_cap,
+ sizeof(struct rdma_service_cap));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy rdma_cap.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ //to adapt hmm struct
+ comp_priv->hmm_priv.dev_cap.log_mtt = rdma_cap->log_mtt;
+ comp_priv->hmm_priv.dev_cap.num_mtts = rdma_cap->num_mtts;
+ comp_priv->hmm_priv.dev_cap.log_mtt_seg = rdma_cap->log_mtt_seg;
+ comp_priv->hmm_priv.dev_cap.mtt_entry_sz = rdma_cap->mtt_entry_sz;
+ comp_priv->hmm_priv.dev_cap.mpt_entry_sz = rdma_cap->mpt_entry_sz;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_start = rdma_cap->dmtt_cl_start;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_end = rdma_cap->dmtt_cl_end;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_sz = rdma_cap->dmtt_cl_sz;
+
+ switch (g_mtt_page_size) {
+ case ROCE5_RDMA_MTT_PAGE_SIZE_4K:
+ comp_priv->hmm_priv.mtt_page_size = ROCE_MTT_PAGE_SIZE_4K;
+ comp_priv->hmm_priv.mtt_page_shift =
+ ROCE_MTT_PAGE_SIZE_4K_SHIFT;
+ break;
+ case ROCE5_RDMA_MTT_PAGE_SIZE_64K:
+ comp_priv->hmm_priv.mtt_page_size = ROCE_MTT_PAGE_SIZE_64K;
+ comp_priv->hmm_priv.mtt_page_shift =
+ ROCE_MTT_PAGE_SIZE_64K_SHIFT;
+ break;
+ case ROCE5_RDMA_MTT_PAGE_SIZE_2M:
+ comp_priv->hmm_priv.mtt_page_size = ROCE_MTT_PAGE_SIZE_2M;
+ comp_priv->hmm_priv.mtt_page_shift =
+ ROCE_MTT_PAGE_SIZE_2M_SHIFT;
+ break;
+ default:
+ comp_priv->hmm_priv.mtt_page_size = ROCE_MTT_PAGE_SIZE_4K;
+ comp_priv->hmm_priv.mtt_page_shift =
+ ROCE_MTT_PAGE_SIZE_4K_SHIFT;
+ break;
+ }
+
+ /* Recalculate the gid num. */
+ comp_priv->rdma_cap.max_gid_per_port =
+ (u32)roce5_get_gid_nums(comp_priv);
+
+ ret = roce5_rdma_init_table(hwdev, comp_priv);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = hinic5_register_service_adapter((void *)hwdev, (void *)comp_priv,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ roce5_rdma_unit_table(hwdev, comp_priv);
+ ROCE_ERR("put rdma_comp_res failed, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_rdma_init_resource(void *hwdev)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+ struct rdma_service_cap rdma_cap;
+ int ret = 0;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return -EINVAL;
+ }
+
+ if (hinic5_support_rdma(hwdev, &rdma_cap) == false) {
+ ROCE_INFO("Neither ROCE nor IWARP");
+ return 0;
+ }
+
+ comp_priv = (struct rdma_comp_priv *)kzalloc(
+ sizeof(struct rdma_comp_priv), GFP_KERNEL);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Alloc memory for comp_priv failed, ret(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ ret = roce5_rdma_init_comp_priv(comp_priv, hwdev, &rdma_cap);
+ if (ret != 0) {
+ kfree(comp_priv);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.c
new file mode 100644
index 000000000..aa252e2db
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+#include "roce_cqm_cmd.h"
+#include "hmm_common.h"
+#include "securec.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_main_extension.h"
+#include "roce_compat.h"
+#include "roce_mr.h"
+#include "rdma_comp_mw_mr.h"
+
+static int rdma_mpt_alloc_rsvd_lkey(struct rdma_comp_priv *comp_priv,
+ struct mpt *mpt)
+{
+ u32 mpt_entry_size = 0;
+
+ mpt_entry_size = comp_priv->hmm_priv.dev_cap.mpt_entry_sz;
+
+ /* call cqm interface allocate mpt, and mpt_index and vaddr save in rdma_mpt structure */
+ mpt->mpt_object = (void *)cqm5_object_qpc_mpt_create(
+ comp_priv->hmm_priv.hwdev, RDMA_SERVICE_TYPE_ROCE,
+ CQM_OBJECT_MPT, mpt_entry_size, mpt, mpt->mpt_index, 0, 0);
+ if (mpt->mpt_object == NULL) {
+ ROCE_ERR("Alloc mpt_object failed, err(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ mpt->vaddr = (void *)((cqm_qpc_mpt_s *)mpt->mpt_object)->vaddr;
+
+ return 0;
+}
+
+int roce5_rdma_init_rsvd_lkey(struct roce5_device *rdev)
+{
+ struct hmm_rdma *mr = NULL;
+ struct rdma_service_cap *rdma_cap = NULL;
+ struct rdma_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ rdma_cap = &comp_priv->rdma_cap;
+ mr = &comp_priv->rsvd_lkey;
+ mr->mpt.mpt_index = rdma_cap->reserved_lkey >> MR_KEY_LEFT_SHIFT_OFS;
+ if (mr->mpt.mpt_index >= rdma_cap->reserved_mrws) {
+ ROCE_ERR("Cfg err, reserved_lkey(0x%x), reserved_mrws(0x%x)",
+ rdma_cap->reserved_lkey, rdma_cap->reserved_mrws);
+ return -EINVAL;
+ }
+ /* Alloc MPT */
+ ret = rdma_mpt_alloc_rsvd_lkey(comp_priv, &mr->mpt);
+ if (ret != 0) {
+ ROCE_ERR("Rdma_mpt_alloc_rsvd_lkey failed, ret(%d)", ret);
+ return ret;
+ }
+ mr->mtt.mtt_layers = 0;
+ mr->iova = 0;
+ mr->size = ~0ULL;
+ mr->key = comp_priv->rdma_cap.reserved_lkey;
+ mr->type = roce5_mr_type2hmm(RDMA_RSVD_LKEY);
+ mr->access = RDMA_IB_ACCESS_LOCAL_WRITE;
+ /* Enable MPT */
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, mr,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Rdma_enable_mr_mpt failed, ret(%d)", ret);
+ goto err_out;
+ }
+ return 0;
+err_out:
+ hmm_mpt_free(rdev->hwdev, &mr->mpt);
+ return ret;
+}
+
+void roce5_rdma_free_rsvd_lkey(struct roce5_device *rdev)
+{
+ struct hmm_rdma *mr = NULL;
+ struct rdma_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is null");
+ return;
+ }
+
+ comp_priv = get_rdma_comp_priv(rdev->hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return;
+ }
+
+ mr = &comp_priv->rsvd_lkey;
+ ret = hmm_rdma_disable_mpt(rdev->lld_dev, rdev->hwdev, mr,
+ RDMA_SERVICE_TYPE_ROCE, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Disable mpt of mr failed, ret(%d)", ret);
+ return;
+ }
+
+ hmm_mpt_free(rdev->hwdev, &mr->mpt);
+
+ return;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.h b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.h
new file mode 100644
index 000000000..1e9c1132d
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_mw_mr.h
@@ -0,0 +1,12 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef RDMA_COMP_MW_MR_H
+#define RDMA_COMP_MW_MR_H
+
+#include "roce.h"
+
+int roce5_rdma_init_rsvd_lkey(struct roce5_device *rdev);
+void roce5_rdma_free_rsvd_lkey(struct roce5_device *rdev);
+
+#endif /* RDMA_COMP_MW_MR_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_pd.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_pd.c
new file mode 100644
index 000000000..ee3486e97
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_pd.c
@@ -0,0 +1,51 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+
+int roce5_rdma_pd_alloc(void *hwdev, u32 *pdn)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if ((hwdev == NULL) || (pdn == NULL)) {
+ ROCE_ERR("Hwdev or pdn is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ *pdn = rdma_bitmap_alloc(&comp_priv->pd_bitmap);
+ if (*pdn == RDMA_INVALID_INDEX) {
+ ROCE_ERR("Can't get valid pdn, err(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void roce5_rdma_pd_free(void *hwdev, u32 pdn)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return;
+ }
+
+ rdma_bitmap_free(&comp_priv->pd_bitmap, pdn);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_res.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_res.c
new file mode 100644
index 000000000..d1265e54e
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/rdma_comp_res.c
@@ -0,0 +1,140 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "rdma_comp.h"
+#include "hmm_em_inner.h"
+#include "hmm_buddy.h"
+
+static int roce5_rdma_rdmarc_alloc_check(struct rdma_comp_priv **comp_priv,
+ void *hwdev,
+ const struct rdma_rdmarc *rdmarc,
+ u32 *log_rdmarc_per_seg, u32 num)
+{
+ if ((hwdev == NULL) || (rdmarc == NULL)) {
+ ROCE_ERR("Hwdev or rdmarc is null");
+ return -EINVAL;
+ }
+
+ *comp_priv = get_rdma_comp_priv(hwdev);
+ if (*comp_priv == NULL || (*comp_priv)->hmm_priv.dev == NULL) {
+ ROCE_ERR("Comp_priv(%d) or PCI device is NULL.",
+ !!(*comp_priv));
+ return -EINVAL;
+ }
+
+ *log_rdmarc_per_seg = (*comp_priv)->rdma_cap.log_rdmarc_seg;
+
+ if ((num < ROCE5_RDMARC_MIN_DEPTH) || (num > ROCE5_RDMARC_MAX_DEPTH)) {
+ ROCE_ERR("Num is invalid, ret(%d)", -EINVAL);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void roce5_rdma_rdmarc_order_set(struct rdma_rdmarc *rdmarc, u32 order,
+ u32 ext_order, u32 log_rdmarc_per_seg)
+{
+ rdmarc->order = order;
+ rdmarc->ext_order = ext_order + log_rdmarc_per_seg;
+ return;
+}
+
+int roce5_rdma_rdmarc_alloc(void *hwdev, u32 num, struct rdma_rdmarc *rdmarc)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+ int ret = 0;
+ u32 i = 0;
+ u32 order = 0;
+ u32 ext_order = 0;
+ u32 ext_num = num + ROCE5_RDMARC_EXT_ENTRY;
+ u32 offset = 0;
+ void *vaddr = NULL;
+ u32 log_rdmarc_per_seg = 0;
+ u32 chip_num = (num < ROCE5_RDMARC_MIN_ENTRY) ? ROCE5_RDMARC_MIN_ENTRY :
+ num;
+ ret = roce5_rdma_rdmarc_alloc_check(&comp_priv, hwdev, rdmarc,
+ &log_rdmarc_per_seg, num);
+ if (ret != 0) {
+ return ret;
+ }
+ for (i = 1; i < chip_num; i <<= 1) {
+ order++;
+ }
+ for (i = 1; i < ext_num; i <<= 1) {
+ ext_order++;
+ }
+ ext_order = (ext_order > log_rdmarc_per_seg) ?
+ (ext_order - log_rdmarc_per_seg) :
+ 0;
+ roce5_rdma_rdmarc_order_set(rdmarc, order, ext_order,
+ log_rdmarc_per_seg);
+ offset = hmm_buddy_alloc(&comp_priv->rdmarc_buddy, ext_order);
+ if (offset == RDMA_INVALID_INDEX) {
+ ROCE_ERR("Alloc rdmarc index failed, ret(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+ rdmarc->offset = offset << log_rdmarc_per_seg;
+
+ ret = hmm_em_table_get_range(
+ comp_priv->hmm_priv.dev, &comp_priv->rdmarc_em_table,
+ rdmarc->offset, rdmarc->offset + (1U << rdmarc->ext_order) - 1);
+ if (ret != 0) {
+ ROCE_ERR("Alloc rdmarc entry failed, ret(%d)", -ENOMEM);
+ goto err_table_get;
+ }
+ vaddr = hmm_em_table_find(&comp_priv->rdmarc_em_table, rdmarc->offset,
+ &rdmarc->dma_addr);
+ if (vaddr == NULL) {
+ ret = -ENOMEM;
+ ROCE_ERR("Can't find va and pa of rdmarc entry, ret(%d)",
+ -ENOMEM);
+ goto err_rdmarc_find;
+ }
+ rdmarc->vaddr = vaddr;
+ return 0;
+
+err_rdmarc_find:
+ hmm_em_table_put_range(comp_priv->hmm_priv.dev,
+ &comp_priv->rdmarc_em_table, rdmarc->offset,
+ rdmarc->offset + (1U << rdmarc->ext_order) - 1);
+err_table_get:
+ hmm_buddy_free(&comp_priv->rdmarc_buddy, offset, ext_order);
+ return ret;
+}
+
+void roce5_rdma_rdmarc_free(void *hwdev, struct rdma_rdmarc *rdmarc)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+ u32 order = 0;
+ u32 offset = 0;
+ u32 log_rdmarc_per_seg = 0;
+
+ if ((hwdev == NULL) || (rdmarc == NULL)) {
+ ROCE_ERR("Hwdev or rdmarc is null");
+ return;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL || comp_priv->hmm_priv.dev == NULL) {
+ ROCE_ERR("Comp_priv(%d) or comp_priv->hmm_priv.dev is NULL",
+ !!comp_priv);
+ return;
+ }
+
+ hmm_em_table_put_range(comp_priv->hmm_priv.dev,
+ &comp_priv->rdmarc_em_table, rdmarc->offset,
+ rdmarc->offset + (1U << rdmarc->ext_order) - 1);
+
+ log_rdmarc_per_seg = comp_priv->rdma_cap.log_rdmarc_seg;
+
+ order = rdmarc->ext_order - log_rdmarc_per_seg;
+ offset = rdmarc->offset >> log_rdmarc_per_seg;
+
+ hmm_buddy_free(&comp_priv->rdmarc_buddy, offset, order);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_com.h b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_com.h
new file mode 100644
index 000000000..f268757a4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_com.h
@@ -0,0 +1,78 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_COM_H
+#define ROCE_COM_H
+
+#include "roce_cfg_format.h"
+
+/* kernel mode basic capability negotiation support macro */
+#define ROCE5_SUPPORT_IB_FEATURE(rdev, feature) \
+ ((rdev)->cfg_info.feature_cap.roce_kernel_ability & \
+ (ROCE_SUPPORT_IB_##feature))
+
+#define ROCE5_SUPPORT_IB_CMD_RESIZE_CQ_MSG_V2(rdev) \
+ ROCE5_SUPPORT_IB_FEATURE(rdev, CMD_RESIZE_CQ_MSG_V2)
+#define ROCE5_SUPPORT_IB_CMD_QUERY_QP_MSG_V2(rdev) \
+ ROCE5_SUPPORT_IB_FEATURE(rdev, CMD_QUERY_QP_MSG_V2)
+#define ROCE5_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2(rdev) \
+ ROCE5_SUPPORT_IB_FEATURE(rdev, CMD_MODIFY_SRQ_MSG_V2)
+#define ROCE5_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2(rdev) \
+ ROCE5_SUPPORT_IB_FEATURE(rdev, CMD_DESTROY_SRQ_MSG_V2)
+
+/* kernel mode extended capability negotiation support macro */
+#define ROCE5_SUPPORT_FEATURE(rdev, feature) \
+ ((rdev)->cfg_info.feature_cap.roce_kernel_ext_ability & \
+ (ROCE_SUPPORT_##feature))
+
+#define ROCE5_SUPPORT_CQ_MODIFY_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CQ_MODIFY_MSG_V2)
+#define ROCE5_SUPPORT_CQ_CHECK_DATA_STATE_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CQ_CHECK_DATA_STATE_MSG_V2)
+#define ROCE5_SUPPORT_CQ_CACHE_OUT_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CQ_CACHE_OUT_MSG_V2)
+#define ROCE5_SUPPORT_QP_SRQN_LB_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, QP_SRQN_LB_MSG_V2)
+#define ROCE5_SUPPORT_SET_PI_ON_CHIP_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, SET_PI_ON_CHIP_MSG_V2)
+#define ROCE5_SUPPORT_SQ_DB_TYPE_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, SQ_DB_TYPE_MSG_V2)
+#define ROCE5_SUPPORT_GET_QP_RX_PORT_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, GET_QP_RX_PORT_MSG_V2)
+#define ROCE5_SUPPORT_MODIFY_UDP_SRC_PORT_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, MODIFY_UDP_SRC_PORT_MSG_V2)
+#define ROCE5_SUPPORT_GET_QP_UDP_SRC_PORT_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, GET_QP_UDP_SRC_PORT_MSG_V2)
+#define ROCE5_SUPPORT_DFX_CMD_QUERY_MPT_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, DFX_CMD_QUERY_MPT_MSG_V2)
+#define ROCE5_SUPPORT_DFX_CMD_QUERY_GID_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, DFX_CMD_QUERY_GID_MSG_V2)
+#define ROCE5_SUPPORT_DFX_CMD_QUERY_PI_CI_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, DFX_CMD_QUERY_PI_CI_MSG_V2)
+#define ROCE5_SUPPORT_DFX_CMD_QUERY_CQ_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, DFX_CMD_QUERY_CQ_MSG_V2)
+#define ROCE5_SUPPORT_ALLOC_QPC_MSG_FEATURE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, ALLOC_QPC_MSG_FEATURE)
+#define ROCE5_SUPPORT_GET_OQID_MSG_FEATURE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, GET_OQID_MSG_FEATURE)
+#define ROCE5_SUPPORT_RETRY_LOAD_CQC_MSG_FEATURE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, RETRY_LOAD_CQC_MSG_FEATURE)
+#define ROCE5_SUPPORT_SET_HASH_VALUE_MSG_V2(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, SET_HASH_VALUE_MSG_V2)
+#define ROCE5_SUPPORT_CC_GET_DCQCN_ENABLE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CC_GET_DCQCN_ENABLE)
+#define ROCE5_SUPPORT_CC_GET_LDCP_ENABLE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CC_GET_LDCP_ENABLE)
+#define ROCE5_SUPPORT_CC_GET_IPQCN_ENABLE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CC_GET_IPQCN_ENABLE)
+#define ROCE5_SUPPORT_CC_GET_USER_ALGO_ENABLE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, CC_GET_USER_ALGO_ENABLE)
+#define ROCE5_SUPPORT_CC_PARAM_V1(rdev) ROCE5_SUPPORT_FEATURE(rdev, CC_PARAM_V1)
+#define ROCE5_SUPPORT_CC_PARAM_V2(rdev) ROCE5_SUPPORT_FEATURE(rdev, CC_PARAM_V2)
+#define ROCE5_SUPPORT_8K_MTU(rdev) ROCE5_SUPPORT_FEATURE(rdev, KERNEL_8K_MTU)
+#define ROCE5_SUPPORT_SML_MAC_TABLE(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, SML_MAC_TABLE)
+#define ROCE5_SUPPORT_SQ_DB_TYPE_21(rdev) \
+ ROCE5_SUPPORT_FEATURE(rdev, SQ_DB_TYPE_21)
+#endif /* ROCE_COM_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.c
new file mode 100644
index 000000000..a15e865ec
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.c
@@ -0,0 +1,1594 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <rdma/ib_mad.h>
+#include <rdma/ib_verbs.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include "securec.h" /* Huawei secure functions; */
+
+#include "hinic5_crm.h"
+#include "hinic5_srv_nic.h"
+#include "hinic5_lld.h"
+
+#include "roce.h"
+#include "roce_compat.h"
+#include "roce_user.h"
+#include "roce_pd.h"
+#include "roce_qp.h"
+#include "roce_cmd.h"
+#include "roce_gid.h"
+#include "roce_netdev.h"
+#include "roce_main_extension.h"
+#include "roce_qp_extension.h"
+#include "roce_restore.h"
+#include "roce_infra.h"
+#include "roce_ctx_format.h"
+#include "roce_kernel_compat_gen.h"
+#include "roce5_gid_type.h"
+
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+#include "roce_mix.h"
+
+uint8_t roce5_get_db_cos_from_vlan_pri(struct roce5_device *rdev,
+ uint8_t vlan_pri)
+{
+ uint8_t db_cos;
+ int ret;
+
+ ret = hinic5_get_cos_by_pri(rdev->hwdev, vlan_pri, &db_cos);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "ret:%d vlan_pri:%u", ret, vlan_pri);
+ db_cos = 0;
+ }
+
+ return db_cos;
+}
+
+struct net_device *roce5_ib_get_netdev(struct ib_device *ibdev, u32 port_num)
+{
+ struct roce5_device *rdev = NULL;
+ struct net_device *netdev = NULL;
+
+ if (ibdev == NULL) {
+ ROCE_ERR("Ibdev is null");
+ return NULL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+#ifdef ROCE_BONDING_EN
+ netdev = roce5_bond_get_netdev(rdev);
+ if (netdev != NULL) {
+ return netdev;
+ }
+#endif
+
+ netdev = rdev->ndev;
+
+ dev_hold(netdev);
+
+ return netdev;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+struct net_device *roce5_ib_get_netdev_compat(struct ib_device *ibdev,
+ u8 port_num)
+{
+ return roce5_ib_get_netdev(ibdev, (u32)port_num);
+}
+
+static void roce5_parse_fw_version(struct roce5_device *rdev, u64 *fw_ver)
+{
+ int ret;
+ int i = 0;
+ struct hinic5_fw_version fw_version;
+ char *fw_str = (char *)fw_version.microcode_ver;
+ char *fw_temp = NULL;
+ u64 fw_verion[ROCE_FW_VERSION_LEN] = { 0 };
+
+ ret = hinic5_get_fw_version(rdev->hwdev, &fw_version,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_WARN("get fw version failed");
+ *fw_ver = ROCE_FW_VER;
+ return;
+ }
+ ROCE_INFO("fw ver:%s - %s - %s", fw_version.boot_ver,
+ fw_version.mgmt_ver, fw_version.microcode_ver);
+
+ while (((fw_temp = strsep(&fw_str, ".")) != NULL) &&
+ (i < ROCE_FW_VERSION_LEN)) {
+ ret = sscanf_s(fw_temp, "%llu", &fw_verion[i]);
+ if (ret != 1) {
+ ROCE_WARN("parse fw version failed ret(%d)", ret);
+ *fw_ver = ROCE_FW_VER;
+ return;
+ }
+
+ i++;
+ }
+
+ *fw_ver = (((fw_verion[0] & 0xffffffff)
+ << 32) | // 0 is fw_version array idx, 32 is offset
+ ((fw_verion[1] & 0xffff)
+ << 16) | // 1 is fw_version array idx, 16 is offset
+ ((fw_verion[2] & 0xff)
+ << 8) | // 2 is fw_version array idx, 8 is offset
+ (fw_verion[3] & 0xff)); // 3 is fw_version array idx
+}
+
+static void roce5_set_local_cap_flag(const struct rdma_service_cap *rdma_cap,
+ struct ib_device_attr *props)
+{
+ if (((rdma_cap->flags & RDMA_BMME_FLAG_LOCAL_INV) != 0) &&
+ ((rdma_cap->flags & RDMA_BMME_FLAG_REMOTE_INV) != 0) &&
+ ((rdma_cap->flags & RDMA_BMME_FLAG_FAST_REG_WR) != 0)) {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_MEM_MGT_EXTENSIONS;
+ }
+}
+
+static void roce5_set_bmme_cap_flag(const struct rdma_service_cap *rdma_cap,
+ struct ib_device_attr *props)
+{
+ if ((rdma_cap->flags & RDMA_BMME_FLAG_TYPE_2_WIN) != 0) {
+ if ((rdma_cap->flags & RDMA_BMME_FLAG_WIN_TYPE_2B) != 0) {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_MEM_WINDOW_TYPE_2B;
+ } else {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_MEM_WINDOW_TYPE_2A;
+ }
+ }
+}
+
+static void roce5_query_device_props_set(struct roce5_device *rdev,
+ struct rdma_service_cap *rdma_cap,
+ struct ib_device_attr *props)
+{
+ if (rdev->lld_dev->dev_type == HINIC5_DEVICE_T_PCI) {
+ struct pci_dev *pdev =
+ container_of(rdev->dev, struct pci_dev, dev);
+ props->vendor_id = pdev->vendor;
+ props->vendor_part_id = pdev->device;
+ }
+ roce5_parse_fw_version(rdev, &props->fw_ver);
+ props->hw_ver = ROCE_HW_VER;
+
+ /* sys_image_guid equal GID */
+ props->sys_image_guid = rdev->ib_dev.node_guid;
+
+ props->max_mr_size = ~0ULL;
+ props->page_size_cap = rdma_cap->page_size_cap;
+ props->max_qp = (int)(rdma_cap->dev_rdma_cap.roce_own_cap.max_qps -
+ rdma_cap->reserved_qps);
+ props->max_qp_wr = (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_wqes;
+ /* We should ensure sq's max size(max_sq_sg) as the max_sge */
+ props->max_send_sge = (int)rdma_cap->max_sq_sg;
+ props->max_recv_sge =
+ (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_rq_sg;
+ props->max_cq = (int)(rdma_cap->dev_rdma_cap.roce_own_cap.max_cqs -
+ rdma_cap->reserved_cqs);
+ props->max_cqe = (int)rdma_cap->max_cqes;
+ props->max_mr = (int)(rdma_cap->dev_rdma_cap.roce_own_cap.max_mpts -
+ rdma_cap->reserved_mrws);
+ props->max_mw = props->max_mr;
+ props->max_pd = (int)(rdma_cap->num_pds - rdma_cap->reserved_pds);
+ props->max_qp_rd_atom =
+ (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_qp_dest_rdma;
+ props->max_qp_init_rd_atom =
+ (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_qp_init_rdma;
+ props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
+ props->max_srq =
+ (int)(rdma_cap->dev_rdma_cap.roce_own_cap.max_srqs -
+ rdma_cap->dev_rdma_cap.roce_own_cap.reserved_srqs);
+ props->max_srq_wr =
+ (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_srq_wqes;
+ props->max_srq_sge =
+ (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_srq_sge;
+ props->max_fast_reg_page_list_len = rdma_cap->max_frpl_len;
+ props->local_ca_ack_delay = (u8)rdma_cap->local_ca_ack_delay;
+ props->atomic_cap =
+ ((rdma_cap->flags & RDMA_DEV_CAP_FLAG_ATOMIC) != 0) ?
+ IB_ATOMIC_HCA :
+ IB_ATOMIC_NONE;
+ props->masked_atomic_cap = props->atomic_cap;
+ props->max_pkeys = (u16)rdma_cap->max_pkeys;
+ props->max_sge_rd = (int)rdma_cap->dev_rdma_cap.roce_own_cap.max_rq_sg;
+#if defined(IB_DEV_ATTR_HAVE_MAX_FMR)
+ props->max_fmr = props->max_map_per_fmr;
+#endif
+#if defined(IB_DEV_ATTR_HAVE_MAX_MAP_PER_FMR)
+ props->max_map_per_fmr = (int)rdma_cap->max_fmr_maps;
+#endif
+ props->max_ah = INT_MAX;
+ return;
+}
+/* ****************************************************************************
+ Prototype : roce5_query_device
+ Description : query device attribute
+ Input : struct ib_device *ibdev
+ struct ib_device_attr *props
+ struct ib_udata *uhw
+ Output : struct ib_device_attr *props
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
+ struct ib_udata *uhw)
+{
+ struct roce5_device *rdev = NULL;
+ struct rdma_service_cap *rdma_cap = NULL;
+ int ret;
+
+ if ((ibdev == NULL) || (props == NULL)) {
+ ROCE_ERR("Ibdev or props is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ ret = memset_s(props, sizeof(*props), 0, sizeof(*props));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset props.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ rdma_cap = &rdev->rdma_cap;
+
+ props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT |
+ IB_DEVICE_RC_RNR_NAK_GEN;
+
+ /* APM */
+ if ((rdma_cap->flags & RDMA_DEV_CAP_FLAG_APM) != 0) {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_AUTO_PATH_MIG;
+ }
+
+ /* rsvd_lKey */
+ if ((rdma_cap->flags & RDMA_BMME_FLAG_RESERVED_LKEY) != 0) {
+#if defined(HAVE_IB_DEVICE_LOCAL_DMA_LKEY)
+ props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY;
+#elif defined(HAVE_IB_KERNEL_CAP_FLAGS)
+ props->kernel_cap_flags |= IBK_LOCAL_DMA_LKEY;
+#endif
+ }
+
+ roce5_set_local_cap_flag(rdma_cap, props);
+
+ /* support XRC */
+ if ((rdma_cap->flags & RDMA_DEV_CAP_FLAG_XRC) != 0) {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_XRC;
+ }
+
+ /* support MW */
+ if ((rdma_cap->flags & RDMA_DEV_CAP_FLAG_MEM_WINDOW) != 0) {
+ props->device_cap_flags = props->device_cap_flags |
+ IB_DEVICE_MEM_WINDOW;
+ }
+
+ roce5_set_bmme_cap_flag(rdma_cap, props);
+
+ roce5_query_device_props_set(rdev, rdma_cap, props);
+ return 0;
+}
+
+static void roce5_eth_link_get_speed(struct ib_port_attr *props,
+ enum mag_cmd_port_speed speed)
+{
+ switch (speed) {
+ /* 10G <==> 1X x 10G */
+ case PORT_SPEED_10GB:
+ props->active_width = IB_WIDTH_1X;
+ props->active_speed = IB_SPEED_QDR;
+ break;
+
+ /* 25G <==> 1X x 25G */
+ case PORT_SPEED_25GB:
+ props->active_width = IB_WIDTH_1X;
+ props->active_speed = IB_SPEED_EDR;
+ break;
+
+ /* 40G <==> 4X x 10G */
+ case PORT_SPEED_40GB:
+ props->active_width = IB_WIDTH_4X;
+ props->active_speed = IB_SPEED_QDR;
+ break;
+
+ /* 100G <==> 4X x 25G */
+ case PORT_SPEED_100GB:
+ props->active_width = IB_WIDTH_4X;
+ props->active_speed = IB_SPEED_EDR;
+ break;
+
+ /* 200G <==> 8X x 25G */
+ case PORT_SPEED_200GB:
+ props->active_width = IB_WIDTH_8X;
+ props->active_speed = IB_SPEED_EDR;
+ break;
+
+ /* 400G <==> 8X x 50G */
+ case PORT_SPEED_400GB:
+ props->active_width = IB_WIDTH_8X;
+ props->active_speed = IB_SPEED_HDR;
+ break;
+
+ default:
+ props->active_width = 0;
+ props->active_speed = 0;
+ break;
+ }
+}
+
+static void roce5_set_ib_port_attr(struct ib_port_attr *props,
+ struct roce5_device *rdev)
+{
+ struct rdma_comp_priv *comp_priv = get_rdma_comp_priv(rdev->hwdev);
+
+ if (comp_priv == NULL) {
+ ROCE_ERR("comp_priv is NULL");
+ return;
+ }
+
+ props->port_cap_flags = IB_PORT_CM_SUP;
+ props->gid_tbl_len = (int)comp_priv->rdma_cap.max_gid_per_port;
+ props->max_msg_sz = rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz;
+ props->pkey_tbl_len = (u16)rdev->rdma_cap.max_pkeys;
+ props->max_mtu = (enum ib_mtu)((ROCE5_SUPPORT_8K_MTU(rdev) != 0) ?
+ ROCE_MTU_8192 :
+ ROCE_MTU_4096);
+ props->state = IB_PORT_DOWN;
+ props->phys_state = ROCE_PORT_PHYS_STATE_DISABLED;
+ props->active_mtu = IB_MTU_256;
+}
+
+static inline int roce5_get_port_speed_by_rdev(struct roce5_device *rdev,
+ enum mag_cmd_port_speed *speed)
+{
+ enum mag_cmd_port_speed speed_table[] = {
+ [ROCE5_4_25G_HCA] = PORT_SPEED_25GB,
+ [ROCE5_2_25G_HCA] = PORT_SPEED_25GB,
+ [ROCE5_1_100G_HCA] = PORT_SPEED_100GB,
+ [ROCE5_2_100G_HCA] = PORT_SPEED_100GB,
+ [ROCE5_2_200G_HCA] = PORT_SPEED_200GB,
+ [ROCE5_2_400G_HCA] = PORT_SPEED_400GB,
+ [ROCE5_4_200G_HCA] = PORT_SPEED_200GB,
+ };
+ int hca_type = rdev->hw_info.hca_type;
+
+ if (hca_type >= ARRAY_SIZE(speed_table) ||
+ speed_table[hca_type] == PORT_SPEED_NOT_SET) {
+ return -EINVAL;
+ }
+
+ *speed = speed_table[hca_type];
+ return 0;
+}
+
+static void roce5_eth_link_query_port(struct ib_device *ibdev,
+ struct ib_port_attr *props)
+{
+ struct roce5_device *rdev = NULL;
+ struct net_device *netdev = NULL;
+#ifdef ROCE_BONDING_EN
+ struct net_device *upper = NULL;
+#endif
+ enum roce5_mtu rmtu;
+ enum mag_cmd_port_speed speed = PORT_SPEED_10GB;
+ int ret = 0;
+
+ rdev = to_roce5_dev(ibdev);
+
+ roce5_set_ib_port_attr(props, rdev);
+
+ ret = roce5_get_port_speed_by_rdev(rdev, &speed);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to get speed, func_id(%d), hca_type(%d)",
+ rdev->glb_func_id, rdev->hw_info.hca_type);
+ props->active_width = 0;
+ props->active_speed = 0;
+ return;
+ }
+
+ roce5_eth_link_get_speed(props, speed);
+
+ netdev = roce5_ib_get_netdev(ibdev, ROCE_DEFAULT_PORT_NUM);
+ if (netdev == NULL) {
+ return;
+ }
+
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ rcu_read_lock();
+ upper = netdev_master_upper_dev_get_rcu(netdev);
+ if (upper != NULL) {
+ dev_put(netdev);
+ netdev = upper;
+ dev_hold(netdev);
+ }
+ rcu_read_unlock();
+ }
+#endif
+
+ if (netif_running(netdev) && netif_carrier_ok(netdev)) {
+ props->state = IB_PORT_ACTIVE;
+ props->phys_state = ROCE_PORT_PHYS_STATE_LINKUP;
+ }
+
+ rmtu = (ROCE5_SUPPORT_8K_MTU(rdev) != 0) ?
+ roce5_get_mtu((int)netdev->mtu) :
+ (enum roce5_mtu)iboe_get_mtu((int)netdev->mtu);
+
+ dev_put(netdev);
+
+ props->active_mtu =
+ (enum ib_mtu)ROCE_MIN((enum roce5_mtu)props->max_mtu, rmtu);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_query_port
+ Description : query port attribute
+ Input : struct ib_device *ibdev
+ u8 port
+ struct ib_port_attr *props
+ Output : struct ib_port_attr *props
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_query_port(struct ib_device *ibdev, u32 port,
+ struct ib_port_attr *props)
+{
+ int ret;
+ if ((ibdev == NULL) || (props == NULL)) {
+ ROCE_ERR("Ibdev or props is null");
+ return -EINVAL;
+ }
+
+ ret = memset_s(props, sizeof(*props), 0, sizeof(*props));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset props.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ roce5_eth_link_query_port(ibdev, props);
+
+ return 0;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+int roce5_query_port_compat(struct ib_device *ibdev, u8 port,
+ struct ib_port_attr *props)
+{
+ return roce5_query_port(ibdev, (u32)port, props);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_query_gid
+ Description : query gid
+ Input : struct ib_device *ibdev
+ u8 port
+ int index
+ union ib_gid *gid
+ Output : union ib_gid *gid
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+ 2.Date : 2015/6/8
+ Modification : Modify function
+
+**************************************************************************** */
+int roce5_query_gid(struct ib_device *ibdev, u32 port, int index,
+ union ib_gid *gid)
+{
+ int ret = 0;
+ struct roce5_device *rdev = NULL;
+ struct rdma_gid_entry gid_entry;
+
+ if ((ibdev == NULL) || (gid == NULL)) {
+ ROCE_ERR("Ibdev or gid is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ ret = roce5_get_gid(rdev, port, (u32)index, &gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get gid, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = memcpy_s((void *)gid->raw, sizeof(*gid), (void *)gid_entry.raw,
+ sizeof(*gid));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy gid.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ // per per OFED of gid generation method convert GID, only IPv4 scenario need convert
+ if (gid_entry.dw6_h.bs.gid_type == ROCE_IPv4_ROCEv2_GID) {
+ // not add of gid returns directly, no need to convert
+ if ((gid->global.subnet_prefix == 0) &&
+ (gid->global.interface_id == 0)) {
+ return 0;
+ }
+ ipv6_addr_set_v4mapped(*((u32 *)(void *)gid + ROCE_GID_IP_IDX),
+ (struct in6_addr *)gid);
+ }
+
+ return 0;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+int roce5_query_gid_compat(struct ib_device *ibdev, u8 port, int index,
+ union ib_gid *gid)
+{
+ return roce5_query_gid(ibdev, (u32)port, index, gid);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_query_pkey
+ Description : query pkey
+ Input : struct ib_device *ibdev
+ u8 port
+ u16 index
+ u16 *pkey
+ Output : u16 *pkey
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_query_pkey(struct ib_device *ibdev, u32 port, u16 index, u16 *pkey)
+{
+ struct roce5_device *rdev = NULL;
+ if ((ibdev == NULL) || (pkey == NULL)) {
+ ROCE_ERR("Ibdev or pkey is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ if (pkey == NULL) {
+ ROCE_ERR("Pkey is null");
+ return -EINVAL;
+ }
+
+ *pkey = 0xffff;
+
+ return 0;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+int roce5_query_pkey_compat(struct ib_device *ibdev, u8 port, u16 index,
+ u16 *pkey)
+{
+ return roce5_query_pkey(ibdev, (u32)port, index, pkey);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_modify_device
+ Description : modify device attribute
+ Input : struct ib_device *ibdev
+ int mask
+ struct ib_device_modify *props
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_modify_device(struct ib_device *ibdev, int mask,
+ struct ib_device_modify *props)
+{
+ unsigned long flags = 0; /* type required by kernel API */
+ struct roce5_device *rdev = NULL;
+ int ret;
+
+ if ((ibdev == NULL) || (props == NULL)) {
+ ROCE_ERR("Ibdev or props is null");
+ return -EINVAL;
+ }
+
+ if (((unsigned int)mask & ~IB_DEVICE_MODIFY_NODE_DESC) != 0) {
+ ROCE_ERR("Not supported to modify node description");
+ return -EOPNOTSUPP;
+ }
+
+ if ((((u32)mask) & IB_DEVICE_MODIFY_NODE_DESC) == 0) {
+ ROCE_INFO("No need to modify node description");
+ return 0;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ spin_lock_irqsave(&rdev->node_desc_lock, flags);
+ ret = memcpy_s((void *)ibdev->node_desc, IB_DEVICE_NODE_DESC_MAX,
+ (void *)props->node_desc, IB_DEVICE_NODE_DESC_MAX);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy node_desc.(ret:%d)", ret);
+ spin_unlock_irqrestore(&rdev->node_desc_lock, flags);
+ return -ENOMEM;
+ }
+ spin_unlock_irqrestore(&rdev->node_desc_lock, flags);
+
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_modify_port
+ Description : modify port attribute
+ Input : struct ib_device *ibdev
+ u8 port
+ int mask
+ struct ib_port_modify *props
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_modify_port(struct ib_device *ibdev, u32 port, int mask,
+ struct ib_port_modify *props)
+{
+ int ret = 0;
+ struct ib_port_attr attr;
+ struct roce5_device *rdev = NULL;
+
+ if (ibdev == NULL) {
+ ROCE_ERR("Ibdev is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ ret = memset_s(&attr, sizeof(struct ib_port_attr), 0,
+ sizeof(struct ib_port_attr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&rdev->cap_mask_mutex);
+
+ ret = roce5_query_port(ibdev, port, &attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query port, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ mutex_unlock(&rdev->cap_mask_mutex);
+
+ return ret;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+int roce5_modify_port_compat(struct ib_device *ibdev, u8 port, int mask,
+ struct ib_port_modify *props)
+{
+ return roce5_modify_port(ibdev, (u32)port, mask, props);
+}
+
+static int roce5_alloc_ucontext_set(struct roce5_device *rdev,
+ struct roce5_alloc_ucontext_resp *resp)
+{
+ struct rdma_service_cap *rdma_cap = NULL;
+
+ rdma_cap = &rdev->rdma_cap;
+
+ resp->num_qps = rdma_cap->dev_rdma_cap.roce_own_cap.max_qps;
+ resp->num_xsrqs = rdma_cap->dev_rdma_cap.roce_own_cap.max_srqs;
+ resp->cqe_size = rdma_cap->cqe_size;
+ resp->wqebb_size = rdma_cap->wqebb_size;
+ resp->dwqe_size = rdma_cap->direct_wqe_size;
+ resp->max_msg_size = rdma_cap->dev_rdma_cap.roce_own_cap.max_msg_sz;
+ resp->max_comp_vector = rdma_cap->num_comp_vectors;
+ resp->max_inline_size =
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_sq_inline_data_sz;
+
+ resp->storage_aa_en = 0;
+ resp->phy_port = rdev->hw_info.phy_port;
+ resp->srq_container_en = rdev->cfg_info.srq_container_en;
+ resp->srq_container_mode = rdev->cfg_info.srq_container_mode;
+ resp->xrc_srq_container_mode = rdev->cfg_info.xrc_srq_container_mode;
+ resp->warn_th = rdev->cfg_info.warn_th;
+ resp->func_id = rdev->glb_func_id;
+ resp->pcie_atomic_en = rdev->cfg_info.pcie_atomic_en;
+ resp->roce_user_ext_ability =
+ rdev->cfg_info.feature_cap.roce_user_ext_ability;
+ resp->roce_uld_ext_ability =
+ rdev->cfg_info.feature_cap.uld_feature.roce_uld_user_ext_ability;
+ resp->max_send_sge = (uint8_t)rdev->rdma_cap.max_sq_sg;
+ resp->max_recv_sge =
+ (uint8_t)rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_sg;
+ resp->max_sq_wqe_len = rdev->rdma_cap.max_sq_desc_sz;
+ resp->huge_page_en = rdev->huge_page_en;
+ return hinic5_get_chip_node_id(rdev->lld_dev, &(resp->card_id));
+}
+
+static int roce5_alloc_ucontext_pre_check(struct ib_device *ibdev,
+ const struct ib_udata *udata)
+{
+ struct roce5_device *rdev = NULL;
+
+ if ((ibdev == NULL) || (udata == NULL)) {
+ ROCE_ERR("Ibdev or udata is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+ if (!rdev->ib_active) {
+ ROCE_DEV_ERR(rdev, "Device is abnormal, func_id(%d)",
+ rdev->glb_func_id);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static int roce5_alloc_ucontext_return(struct roce5_device *rdev,
+ struct ib_udata *udata,
+ struct roce5_ucontext *context,
+ struct roce5_alloc_ucontext_resp *resp)
+{
+ int ret;
+
+ resp->db_offset = context->db_dma_addr & ((1 << PAGE_SHIFT) - 1);
+#ifdef ROCE_DWQE_EN
+ resp->dwqe_offset = context->dwqe_dma_addr & ((1 << PAGE_SHIFT) - 1);
+
+ if (context->dwqe_dma_addr == 0) {
+ ROCE_DEV_ERR(rdev, "dwqe_dma_addr = 0");
+ resp->dwqe_size = 0;
+ }
+#else
+ resp->dwqe_size = 0;
+#endif
+
+ INIT_LIST_HEAD(&context->db_page_list);
+ mutex_init(&context->db_page_mutex);
+
+ /* Copy data to user space */
+ ret = ib_copy_to_udata(udata, resp,
+ sizeof(struct roce5_alloc_ucontext_resp));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to copy data to user space, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata)
+{
+ int ret;
+
+ struct roce5_ucontext *context = to_roce5_ucontext(ibucontext);
+ struct roce5_device *rdev = to_roce5_dev(ibucontext->device);
+ struct roce5_alloc_ucontext_resp *resp = NULL;
+
+ ret = roce5_alloc_ucontext_pre_check(ibucontext->device, udata);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "pre check err, ret(%d), func_id(%d)", ret,
+ rdev->glb_func_id);
+ goto err;
+ }
+
+ resp = kzalloc(sizeof(struct roce5_alloc_ucontext_resp), GFP_KERNEL);
+ if (resp == NULL) {
+ ret = (-ENOMEM);
+ ROCE_DEV_ERR(rdev, "Failed alloc ucontext, func_id(%d)",
+ rdev->glb_func_id);
+ goto err;
+ }
+
+ ret = roce5_alloc_ucontext_set(rdev, resp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get chip node id, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_db;
+ }
+ /* Alloc user space context Doorbell and DWQE */
+ ret = hinic5_alloc_db_phy_addr(rdev->hwdev, &context->db_dma_addr,
+ &context->dwqe_dma_addr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc DB pa, ret(%d), func_id(%d)", ret,
+ rdev->glb_func_id);
+ goto err_db;
+ }
+
+ /* Copy data to user space */
+ ret = roce5_alloc_ucontext_return(rdev, udata, context, resp);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to return to user, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto err_return;
+ }
+
+ kfree(resp);
+#ifdef __ROCE_DFX__
+ rdev->ucontext = context;
+#endif
+ return 0;
+
+err_return:
+ hinic5_free_db_phy_addr(rdev->hwdev, context->db_dma_addr,
+ context->dwqe_dma_addr);
+err_db:
+ kfree(resp);
+err:
+ return ret;
+}
+
+void roce5_dealloc_ucontext(struct ib_ucontext *ibcontext)
+{
+ struct roce5_ucontext *context = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (ibcontext == NULL) {
+ ROCE_ERR("Ibcontext is null");
+ return;
+ }
+
+ context = to_roce5_ucontext(ibcontext);
+ rdev = to_roce5_dev(ibcontext->device);
+
+ hinic5_free_db_phy_addr(rdev->hwdev, context->db_dma_addr,
+ context->dwqe_dma_addr);
+
+ return;
+}
+
+struct ib_ucontext *roce5_alloc_ucontext_ofa(struct ib_device *ibdev,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_ucontext *context = NULL;
+
+ if (ibdev == NULL) {
+ ROCE_ERR("Ibdev is null");
+ return ERR_PTR(-EINVAL);
+ }
+
+ context = kzalloc(sizeof(struct roce5_ucontext), GFP_KERNEL);
+ if (context == NULL) {
+ ROCE_ERR("Failed to alloc ucontext");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ context->ibucontext.device = ibdev;
+ ret = roce5_alloc_ucontext(&context->ibucontext, udata);
+ if (ret != 0) {
+ kfree(context);
+ return ERR_PTR(ret);
+ }
+
+ return (struct ib_ucontext *)&context->ibucontext;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_dealloc_ucontext_ofa
+ Description : dealloc ucontext
+ Input : struct ib_ucontext *ibcontext
+ Output : None
+
+ 1.Date : 2023/11/9
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_dealloc_ucontext_ofa(struct ib_ucontext *ibcontext)
+{
+ struct roce5_ucontext *context = NULL;
+
+ if (ibcontext == NULL) {
+ ROCE_ERR("Ibcontext is null");
+ return -EINVAL;
+ }
+
+ roce5_dealloc_ucontext(ibcontext);
+ context = to_roce5_ucontext(ibcontext);
+
+ kfree(context);
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_mmap
+ Description : memory map
+ Input : struct ib_ucontext *ibcontext
+ struct vm_area_struct *vma
+ Output : None
+
+ 1.Date : 2015/5/8
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_ucontext *ucontext = NULL;
+ unsigned long db_pfn = 0;
+ unsigned long dwqe_pfn = 0;
+
+ if ((ibcontext == NULL) || (vma == NULL)) {
+ ROCE_ERR("Ibcontext or vma is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibcontext->device);
+ ucontext = to_roce5_ucontext(ibcontext);
+ db_pfn = ucontext->db_dma_addr >> PAGE_SHIFT;
+ dwqe_pfn = ucontext->dwqe_dma_addr >> PAGE_SHIFT;
+
+ if ((vma->vm_end - vma->vm_start) != PAGE_SIZE) {
+ ROCE_DEV_ERR(
+ rdev,
+ "(Vm_end(%lu) - vm_start(%lu)) is not equal to PAGE_SIZE, func_id(%d)",
+ vma->vm_end, vma->vm_start, rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ /* map hw DB to physical page from user */
+ if (vma->vm_pgoff == USR_MMAP_DB_OFFSET) {
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ /* construct vm_start~vm_start+PAGE_SIZE page table
+ * db_pfn is page number
+ * vm_page_prot means attr
+ */
+ if (io_remap_pfn_range(vma, vma->vm_start, db_pfn, PAGE_SIZE,
+ vma->vm_page_prot) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to do db io remap, func_id(%d)",
+ rdev->glb_func_id);
+ return -EAGAIN;
+ }
+ return 0;
+ }
+
+#ifdef ROCE_DWQE_EN
+ if ((vma->vm_pgoff == USR_MMAP_DWQE_OFFSET) &&
+ (rdev->rdma_cap.direct_wqe_size != 0)) { // DWQE mmap
+#ifdef __aarch64__
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#else
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#endif
+
+ if (io_remap_pfn_range(vma, vma->vm_start, dwqe_pfn, PAGE_SIZE,
+ vma->vm_page_prot) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to do dwqe io remap, func_id(%d)",
+ rdev->glb_func_id);
+ return -EAGAIN;
+ }
+ return 0;
+ }
+#endif
+
+ ROCE_DEV_ERR(rdev, "Not support, func_id(%d)", rdev->glb_func_id);
+ return -EINVAL;
+}
+
+enum rdma_link_layer roce5_port_link_layer(struct ib_device *ibdev,
+ u32 port_num)
+{
+ struct roce5_device *rdev = NULL;
+
+ if (ibdev == NULL) {
+ return IB_LINK_LAYER_UNSPECIFIED;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ if (port_num != ROCE_DEFAULT_PORT_NUM) {
+ return IB_LINK_LAYER_UNSPECIFIED;
+ }
+
+ return IB_LINK_LAYER_ETHERNET;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+enum rdma_link_layer roce5_port_link_layer_compat(struct ib_device *ibdev,
+ u8 port_num)
+{
+ return roce5_port_link_layer(ibdev, (u32)port_num);
+}
+
+static void roce5_resolve_cb(int status, struct sockaddr *src_addr,
+ struct rdma_dev_addr *addr, void *context)
+{
+ ((struct roce5_resolve_cb_context *)context)->status = status;
+ complete(&((struct roce5_resolve_cb_context *)context)->comp);
+}
+
+static int roce5_rdma_addr_find_l2_eth_by_grh(
+ const union ib_gid *sgid, const union ib_gid *dgid, u8 *dmac,
+ const struct net_device *ndev, int *hoplimit, struct roce5_device *rdev,
+ const struct ib_gid_attr *sgid_attr)
+{
+ struct rdma_dev_addr dev_addr;
+ struct roce5_resolve_cb_context ctx;
+ union {
+ struct sockaddr_in _sockaddr_in;
+ struct sockaddr_in6 _sockaddr_in6;
+ } sgid_addr, dgid_addr;
+ int ret;
+
+ rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid);
+ rdma_gid2ip((struct sockaddr *)&dgid_addr, dgid);
+
+ ret = memset_s(&dev_addr, sizeof(dev_addr), 0, sizeof(dev_addr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset dev_addr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ if (ndev) {
+ dev_addr.bound_dev_if = ndev->ifindex;
+ dev_addr.net = dev_net(ndev);
+ } else {
+ dev_addr.net = &init_net;
+ }
+
+ init_completion(&ctx.comp);
+#if defined(RDMA_RESOLVE_IP_HAVE_GID_ATTR)
+ dev_addr.sgid_attr = sgid_attr;
+ ret = rdma_resolve_ip((struct sockaddr *)&sgid_addr,
+ (struct sockaddr *)&dgid_addr, &dev_addr,
+ RESOLVE_IP_TIME_OUT, roce5_resolve_cb, true,
+ &ctx);
+#else
+ ret = rdma_resolve_ip((struct sockaddr *)&sgid_addr,
+ (struct sockaddr *)&dgid_addr, &dev_addr,
+ RESOLVE_IP_TIME_OUT, roce5_resolve_cb, &ctx);
+#endif
+ if (ret != 0) {
+ ROCE_ERR("rdma_resolve_ip failed. Igonore the err(%d).", ret);
+ roce5_resolve_cb(0, (struct sockaddr *)&sgid_addr, &dev_addr,
+ &ctx);
+ }
+
+ wait_for_completion(&ctx.comp);
+
+ ret = memcpy_s(dmac, ETH_ALEN, dev_addr.dst_dev_addr, ETH_ALEN);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dmac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ if (hoplimit) {
+ *hoplimit = dev_addr.hoplimit;
+ }
+
+ return 0;
+}
+
+static int roce5_ah_valid_check(struct ib_global_route *grh, u16 *vlan_id,
+ u8 *dmac)
+{
+ u8 unicast_gid0[ROCE_GID_LEN] = { 0 };
+ u8 unicast_gid1[ROCE_GID_LEN] = { 0 };
+
+ /* check gid(unicast gid can not be 0 or 1) */
+ unicast_gid0[ROCE_GID_HIGHEST_BYTE] = 0;
+ unicast_gid1[ROCE_GID_HIGHEST_BYTE] = 1;
+
+ if ((ROCE_MEMCMP(grh->dgid.raw, unicast_gid0, sizeof(union ib_gid)) ==
+ 0) ||
+ (ROCE_MEMCMP(grh->dgid.raw, unicast_gid1, sizeof(union ib_gid)) ==
+ 0)) {
+ ROCE_ERR(
+ "Invalid unicast dgid, The ROCE_GID_HIGHEST_BYTE of unicast_dgid is: 0x%02x",
+ *(grh->dgid.raw + ROCE_GID_HIGHEST_BYTE));
+ return (-EINVAL);
+ }
+
+ if (rdma_link_local_addr((struct in6_addr *)grh->dgid.raw) != 0) {
+ rdma_get_ll_mac((struct in6_addr *)grh->dgid.raw, dmac);
+ *vlan_id = ROCE_DEFAULT_VLAN_ID;
+ }
+
+ return 0;
+}
+
+static int roce5_fill_gid_attr(struct roce5_device *rdev,
+ struct rdma_ah_attr *ah_attr, union ib_gid *sgid,
+ const struct ib_gid_attr **sgid_attr)
+{
+ int ret = 0;
+
+ ret = rdma_query_gid(&rdev->ib_dev, ah_attr->port_num,
+ ah_attr->grh.sgid_index, sgid);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to query gid func_id(%hu),port_num(%d),gid_index(%d),ret(%d)",
+ rdev->glb_func_id, ah_attr->port_num,
+ ah_attr->grh.sgid_index, ret);
+ return ret;
+ }
+
+ *sgid_attr = rdma_get_gid_attr(&rdev->ib_dev, ah_attr->port_num,
+ ah_attr->grh.sgid_index);
+ if (IS_ERR_OR_NULL(*sgid_attr)) {
+ ret = (int)PTR_ERR(*sgid_attr);
+ ROCE_PRINT_GID(rdev, sgid->raw,
+ "Failed to get sgid_attr, func_id(%hu), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void roce5_release_gid_ref_cnt(const struct ib_gid_attr *sgid_attr)
+{
+ rdma_put_gid_attr(sgid_attr);
+}
+
+static struct net_device *roce5_fill_netdev(struct roce5_device *rdev,
+ union ib_gid *sgid)
+{
+ struct net_device *netdev = NULL;
+ union {
+ struct sockaddr_in _sockaddr_in;
+ struct sockaddr_in6 _sockaddr_in6;
+ } socket_addr;
+
+ rdma_gid2ip((struct sockaddr *)&socket_addr, sgid);
+
+ /* find netdev,rdev->ndevis not valid in vlan scenario */
+ netdev = ip_dev_find(&init_net,
+ socket_addr._sockaddr_in.sin_addr.s_addr);
+ if (netdev) {
+ dev_put(netdev);
+ }
+
+ return netdev;
+}
+
+int roce5_resolve_grh(struct roce5_device *rdev, struct rdma_ah_attr *ah_attr,
+ u16 *vlan_id, struct ib_udata *udata)
+{
+ int ret = 0;
+ u8 zero_mac[ETH_ALEN] = { 0 };
+ u8 *dmac = NULL;
+ union ib_gid sgid = { 0 };
+ const struct ib_gid_attr *sgid_attr = NULL;
+ struct net_device *netdev = NULL;
+
+ if ((rdev == NULL) || (ah_attr == NULL) || (vlan_id == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ dmac = ah_attr->roce.dmac;
+ ret = roce5_ah_valid_check(&ah_attr->grh, vlan_id, dmac);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to check grh input, func_id(%d), ret(%d),"
+ "The grh inputs are: vlan_id(%d), dmac:%02x-%02x-%02x-%02x-%02x-%02x",
+ rdev->glb_func_id, ret, *vlan_id,
+ *((u8 *)dmac + MAC_INDEX_0),
+ *((u8 *)dmac + MAC_INDEX_1),
+ *((u8 *)dmac + MAC_INDEX_2),
+ *((u8 *)dmac + MAC_INDEX_3),
+ *((u8 *)dmac + MAC_INDEX_4),
+ *((u8 *)dmac + MAC_INDEX_5));
+ return ret;
+ }
+ if (ROCE_MEMCMP(dmac, zero_mac, ETH_ALEN) != 0) {
+ return 0;
+ }
+
+ ret = roce5_fill_gid_attr(rdev, ah_attr, &sgid, &sgid_attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to fill gid attr, func_id(%hu), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ netdev = roce5_fill_netdev(rdev, &sgid);
+
+ /* reparse dmac avoiding invalid damc from OFED */
+ ret = roce5_rdma_addr_find_l2_eth_by_grh(
+ &sgid, &ah_attr->grh.dgid, dmac, netdev, NULL, rdev, sgid_attr);
+ if (ret != 0) {
+ ROCE_PRINT_GID(
+ rdev, sgid.raw,
+ "Failed to find dmac by grh, func_id(%hu), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto resolve_grh_end;
+ }
+
+ if (ROCE_MEMCMP(dmac, zero_mac, ETH_ALEN) == 0) {
+ ROCE_DEV_ERR(rdev, "Failed to find valid dmac, func_id(%hu)",
+ rdev->glb_func_id);
+ ret = (-EINVAL);
+ goto resolve_grh_end;
+ }
+
+ if (sgid_attr != NULL && sgid_attr->ndev != NULL) {
+ *vlan_id = rdma_vlan_dev_vlan_id(sgid_attr->ndev);
+ }
+
+resolve_grh_end:
+ roce5_release_gid_ref_cnt(sgid_attr);
+
+ return ret;
+}
+
+static int roce5_ah_get_vlan_id(struct roce5_device *rdev, struct ib_pd *pd,
+ struct rdma_ah_attr *ah_attr, u32 *vlan_id)
+{
+ u32 ret = 0;
+ struct net_device *ndev = NULL;
+ rcu_read_lock();
+ ndev = rcu_dereference(ah_attr->grh.sgid_attr->ndev);
+ if (ndev == NULL) {
+ rcu_read_unlock();
+ ROCE_DEV_ERR(rdev, "Net device is NULL, func_id(%hu)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+ ret = rdma_vlan_dev_vlan_id(ndev);
+ if (ret != 0xffff) {
+ *vlan_id = ret;
+ }
+ rcu_read_unlock();
+ return 0;
+}
+
+static int roce5_create_ib_ah_kernel(struct roce5_device *rdev,
+ struct ib_pd *pd, struct roce5_ah *rah,
+ struct rdma_ah_attr *ah_attr)
+{
+ int ret;
+ u8 *dmac = ah_attr->roce.dmac;
+ u32 vlan_id = 0;
+
+ ret = roce5_ah_get_vlan_id(rdev, pd, ah_attr, &vlan_id);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get vlan_id (ret:%d)", ret);
+ return -EFAULT;
+ }
+
+ if (((u32)rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) != 0) {
+ ret = memcpy_s((void *)rah->priv_ah.dgid,
+ sizeof(rah->priv_ah.dgid),
+ (void *)ah_attr->grh.dgid.raw,
+ sizeof(rah->priv_ah.dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ rah->priv_ah.dw2.bs.flow_label = ah_attr->grh.flow_label &
+ 0xfffff;
+ rah->priv_ah.dw1.bs.sgid_index = ah_attr->grh.sgid_index & 0x7f;
+ rah->priv_ah.dw1.bs.hoplimit = ah_attr->grh.hop_limit;
+ rah->priv_ah.dw1.bs.tclass =
+ (u8)(ah_attr->grh.traffic_class | IP_ECN_PERMIT);
+ }
+ rah->priv_ah.dw0.bs.pd = to_roce5_pd(pd)->pdn & 0x3ffff;
+ rah->priv_ah.dw0.bs.wqe_cos =
+ roce5_get_db_cos_from_vlan_pri(rdev, ah_attr->sl);
+ rah->priv_ah.dw0.value = cpu_to_be32(rah->priv_ah.dw0.value);
+
+ rah->priv_ah.dw1.bs.port = ah_attr->port_num & 0xf;
+ rah->priv_ah.dw2.bs.smac_index =
+ rdev->glb_func_id; /* set global Function ID */
+ rah->priv_ah.dw2.value = cpu_to_be32(rah->priv_ah.dw2.value);
+
+ rah->priv_ah.dw1.bs.resv = 0;
+ rah->priv_ah.dw7.bs.vlan_id = vlan_id & 0xfff;
+ rah->priv_ah.dw7.bs.vlan_pri = ah_attr->sl & 0x7;
+
+ rah->priv_ah.dw1.value = cpu_to_be32(rah->priv_ah.dw1.value);
+
+ rah->priv_ah.dw7.bs.dmac_h16 = (dmac[0] << ROCE_RAH_DMAC_H16_SHIFT) |
+ dmac[1];
+ rah->priv_ah.dw7.value = cpu_to_be32(rah->priv_ah.dw7.value);
+
+ ret = memcpy_s((void *)&rah->priv_ah.dmac_l32,
+ sizeof(rah->priv_ah.dmac_l32),
+ (void *)&dmac[ROCE_RAH_DMAC_L32_START],
+ sizeof(rah->priv_ah.dmac_l32));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dmac_l32.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int roce5_create_ib_ah_user(struct roce5_device *rdev,
+ struct rdma_ah_attr *ah_attr,
+ struct ib_udata *udata)
+{
+ struct roce5_create_ah_resp resp;
+ roce5_get_cos_inbuf_s dcb_inbuf;
+ int ret;
+
+ ret = memset_s(ah_attr->roce.dmac, sizeof(ah_attr->roce.dmac), 0,
+ sizeof(ah_attr->roce.dmac));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset dmac.");
+ return (-ENOMEM);
+ }
+
+ ret = roce5_resolve_grh(rdev, ah_attr, &resp.vlan_id, udata);
+ if (ret != 0) {
+ ROCE_ERR("Failed to resolve grh");
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(resp.dmac, ETH_ALEN, ah_attr->roce.dmac, ETH_ALEN);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy_s ah dmac.");
+ return (-ENOMEM);
+ }
+
+ dcb_inbuf.sl = ah_attr->sl;
+ dcb_inbuf.sgid_index = ah_attr->grh.sgid_index;
+ dcb_inbuf.port_num = ah_attr->port_num;
+ dcb_inbuf.traffic_class = ah_attr->grh.traffic_class;
+ ret = roce5_get_dcb_cfg_cos(rdev, &dcb_inbuf, &resp.cos, IB_QPT_UD);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get cos from dcb info, ret:%d", ret);
+ return ret;
+ }
+
+ ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
+ if (ret != 0) {
+ ROCE_ERR("Failed to copy data to user");
+ return ret;
+ }
+
+ return 0;
+}
+
+int roce5_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_ah *rah = NULL;
+ struct roce5_device *rdev = NULL;
+ struct rdma_ah_attr *ah_attr = NULL;
+ enum rdma_ah_attr_type ah_type = 0;
+
+ if ((ibah == NULL) || (init_attr == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ rah = to_roce5_ah(ibah);
+ rdev = to_roce5_dev(ibah->device);
+ ah_attr = init_attr->ah_attr;
+ ah_type = ah_attr->type;
+
+ if ((ah_type == RDMA_AH_ATTR_TYPE_ROCE) &&
+ (((u32)rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) == 0)) {
+ ROCE_DEV_ERR(rdev, "Invalid ah_type(%d)", ah_type);
+ return -EINVAL;
+ }
+
+ if (udata != NULL) {
+ ret = roce5_create_ib_ah_user(rdev, ah_attr, udata);
+ } else {
+ ret = roce5_create_ib_ah_kernel(rdev, ibah->pd, rah, ah_attr);
+ }
+ return ret;
+}
+
+struct ib_ah *roce5_create_ah_ofa(struct ib_pd *pd,
+ struct rdma_ah_attr *ah_attr,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_ah *rah = NULL;
+ struct roce5_device *rdev = NULL;
+ struct rdma_ah_init_attr init_attr;
+
+ if ((pd == NULL) || (ah_attr == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ rdev = to_roce5_dev(pd->device);
+ init_attr.ah_attr = ah_attr;
+
+ rah = kzalloc(sizeof(*rah), GFP_ATOMIC);
+ if (rah == NULL) {
+ ret = -ENOMEM;
+ ROCE_DEV_ERR(rdev, "Failed to alloc ah, func_id(%d)",
+ rdev->glb_func_id);
+ goto out;
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ rah->ibah.device = pd->device;
+ rah->ibah.pd = pd;
+ ret = roce5_create_ah(&rah->ibah, &init_attr, udata);
+ if (ret != 0) {
+ kfree(rah);
+ }
+
+out:
+ return (ret != 0) ? ERR_PTR(ret) : &rah->ibah;
+}
+
+int roce5_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
+{
+ struct roce5_ah *ah = NULL;
+ struct roce5_priv_ah priv_ah;
+ int ret;
+
+ if ((ibah == NULL) || (ah_attr == NULL)) {
+ ROCE_ERR("Ibah or ah_attr is null");
+ return -EINVAL;
+ }
+
+ ah = to_roce5_ah(ibah);
+ ret = memset_s(ah_attr, sizeof *ah_attr, 0, sizeof *ah_attr);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ah_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ priv_ah.dw1.value = be32_to_cpu(ah->priv_ah.dw1.value);
+ priv_ah.dw2.value = be32_to_cpu(ah->priv_ah.dw2.value);
+ priv_ah.dw7.value = be32_to_cpu(ah->priv_ah.dw7.value);
+
+ ah_attr->ah_flags = IB_AH_GRH;
+ ah_attr->sl = priv_ah.dw7.bs.vlan_pri;
+ ah_attr->port_num = priv_ah.dw1.bs.port;
+ ah_attr->grh.traffic_class = priv_ah.dw1.bs.tclass;
+ ah_attr->grh.hop_limit = priv_ah.dw1.bs.hoplimit;
+ ah_attr->grh.sgid_index = priv_ah.dw1.bs.sgid_index;
+ ah_attr->grh.flow_label = priv_ah.dw2.bs.flow_label;
+
+ ret = memcpy_s((void *)ah_attr->grh.dgid.raw, sizeof(ah->priv_ah.dgid),
+ (void *)ah->priv_ah.dgid, sizeof(ah->priv_ah.dgid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy dgid.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int roce5_destroy_ah(struct ib_ah *ibah, u32 flags)
+{
+ return 0;
+}
+
+int roce5_destroy_ah_ofa(struct ib_ah *ibah)
+{
+ struct roce5_ah *rah = NULL;
+
+ if (ibah == NULL) {
+ ROCE_ERR("Ibah is null");
+ return -EINVAL;
+ }
+
+ rah = to_roce5_ah(ibah);
+
+ kfree(rah);
+
+ return 0;
+}
+
+int roce5_port_immutable(struct ib_device *ibdev, u32 port_num,
+ struct ib_port_immutable *immutable)
+{
+ struct ib_port_attr attr;
+ int err;
+
+ if ((ibdev == NULL) || (immutable == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ immutable->core_cap_flags =
+ RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP; // only rocev2
+
+#if defined(IB_QUERY_PORT_HAVE_U8_PORT)
+ err = ib_query_port(ibdev, (u8)port_num, &attr);
+#elif defined(IB_QUERY_PORT_HAVE_U32_PORT)
+ err = ib_query_port(ibdev, port_num, &attr);
+#endif
+ if (err != 0) {
+ ROCE_ERR("dev(%s) query ib port(%d) failed, err(%d)",
+ ibdev->name, port_num, err);
+ return err;
+ }
+
+ immutable->pkey_tbl_len = attr.pkey_tbl_len;
+ immutable->gid_tbl_len = attr.gid_tbl_len;
+ immutable->max_mad_size = IB_MGMT_MAD_SIZE;
+
+ return 0;
+}
+
+/* compatible version for kernel 5.10 and kernel 4.19 */
+int roce5_port_immutable_compat(struct ib_device *ibdev, u8 port_num,
+ struct ib_port_immutable *immutable)
+{
+ return roce5_port_immutable(ibdev, (u32)port_num, immutable);
+}
+
+#define ROCE_DEFAULT_COS 3
+
+int roce5_get_dcb_cfg_cos(struct roce5_device *rdev,
+ roce5_get_cos_inbuf_s *inbuf, u8 *cos,
+ enum ib_qp_type qp_type)
+{
+ int ret;
+ u8 pri;
+ struct rdma_gid_entry gid;
+ struct hinic5_dcb_state dcb = { 0 };
+
+#if !defined(UVERBS_IOCTL_HAVE_DECLARE_UVERBS_WRITE_EX)
+ /* Note: low version of ofed in modify qp when unused udate->outbuf, cause cannot from kernel mode get db cos, therefore stub uses a fixed value. */
+ *cos = ROCE_DEFAULT_COS;
+ goto cos_success;
+#endif
+
+ ret = roce5_get_gid(rdev, inbuf->port_num, inbuf->sgid_index, &gid);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init gid info, ret(%d).", ret);
+ return -EINVAL;
+ }
+
+ ret = hinic5_get_dcb_state(rdev->hwdev, &dcb);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "hinic5_get_dcb_state failed, ret(%d).",
+ ret);
+ return -EINVAL;
+ }
+
+ *cos = dcb.default_cos;
+ gid.dw6_h.value = cpu_to_le16(gid.dw6_h.value);
+ if ((dcb.trust == ROCE5_DCB_PCP) &&
+ (gid.dw6_h.bs.tag == ROCE_GID_VLAN_INVALID)) {
+ // pcp cfg & no vlan should use default cos
+ goto cos_success;
+ }
+
+ pri = (dcb.trust == ROCE5_DCB_PCP) ?
+ inbuf->sl :
+ (inbuf->traffic_class >> ROCE5_DSCP_IDX);
+ ret = hinic5_get_cos_by_pri(rdev->hwdev, pri, cos);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "get cos failed, ret(%d), pri(%u), dcb_on(%u), trust(%u).",
+ ret, pri, dcb.dcb_on, dcb.trust);
+ return -EINVAL;
+ }
+
+cos_success:
+ roce5_cos_update_ext(rdev, cos, qp_type);
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.h b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.h
new file mode 100644
index 000000000..2fb0eb2b9
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_mix.h
@@ -0,0 +1,269 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_MIX_H
+#define ROCE_MIX_H
+
+#include <net/arp.h>
+#include <net/neighbour.h>
+#include <net/route.h>
+#include <net/addrconf.h>
+#include <net/ip6_route.h>
+#include <linux/mutex.h>
+#include <linux/inetdevice.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+
+#include <rdma/ib_addr.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_pack.h>
+
+#include "roce.h"
+
+#define ROCE_HW_VER 0ULL
+#define ROCE_FW_VER_0 1ULL
+#define ROCE_FW_VER_1 4ULL
+#define ROCE_FW_VER_2 0ULL
+#define ROCE_FW_VER_3 0ULL
+#define ROCE_FW_VER \
+ ((ROCE_FW_VER_0 << 32) | (ROCE_FW_VER_1 << 16) | \
+ (ROCE_FW_VER_2 << 8) | ROCE_FW_VER_3)
+
+#define RESOLVE_IP_TIME_OUT 1000
+#define ROCE_GID_HIGHEST_BYTE 15
+#define ROCE_FW_VERSION_LEN 4
+#define ROCE_DEFAULT_VLAN_ID 0xFFFF
+#define ROCE_RAH_TC_SHIFT 2
+#define ROCE_RAH_DMAC_H16_SHIFT 8
+#define ROCE_RAH_DMAC_L32_START 2
+#define ROCE_UDP_SRC_PORT_H8_SHIFT 8
+
+#define ROCE5_DCB_PCP 0
+#define ROCE5_DCB_DSCP 1
+
+#define ROCE5_DSCP_IDX 2 //dscp begin from bit 2 in traffic_class
+
+#define ROCE_GID_IP_IDX 3
+
+#define MAC_INDEX_0 0
+#define MAC_INDEX_1 1
+#define MAC_INDEX_2 2
+#define MAC_INDEX_3 3
+#define MAC_INDEX_4 4
+#define MAC_INDEX_5 5
+
+#define IP_INDEX_0 0
+#define IP_INDEX_1 1
+#define IP_INDEX_2 2
+#define IP_INDEX_3 3
+#define IP_INDEX_4 4
+#define IP_INDEX_5 5
+#define IP_INDEX_6 6
+#define IP_INDEX_7 7
+
+#define ROCE_MTU_256_INT 256
+#define ROCE_MTU_512_INT 512
+#define ROCE_MTU_1024_INT 1024
+#define ROCE_MTU_2048_INT 2048
+#define ROCE_MTU_4096_INT 4096
+#define ROCE_MTU_8192_INT 8192
+
+enum {
+ USR_MMAP_DB_OFFSET = 0,
+ USR_MMAP_DWQE_OFFSET,
+ USR_MMAP_DFX_OFFSET,
+ USR_MMAP_DBAR3_OFFSET
+};
+
+enum roce_port_state_e {
+ ROCE_PORT_PHYS_STATE_NO_CHANGE = 0,
+ ROCE_PORT_PHYS_STATE_SLEEP,
+ ROCE_PORT_PHYS_STATE_POLLING,
+ ROCE_PORT_PHYS_STATE_DISABLED = 3,
+ ROCE_PORT_PHYS_STATE_PORTCONFTRAIN,
+ ROCE_PORT_PHYS_STATE_LINKUP = 5,
+ ROCE_PORT_PHYS_STATE_LINKERRRECOVER,
+ ROCE_PORT_PHYS_STATE_PHYTEST
+};
+
+enum ROCE_MBOX_CMD { ROCE_MBOX_CMD_SEND_MAIL_BOX, ROCE_MBOX_CMD_MAX };
+
+enum roce5_mtu {
+ ROCE_MTU_256 = IB_MTU_256,
+ ROCE_MTU_512 = IB_MTU_512,
+ ROCE_MTU_1024 = IB_MTU_1024,
+ ROCE_MTU_2048 = IB_MTU_2048,
+ ROCE_MTU_4096 = IB_MTU_4096,
+ ROCE_MTU_8192,
+};
+
+static inline int roce5_mtu_enum_to_int(enum roce5_mtu mtu)
+{
+ switch (mtu) {
+ case ROCE_MTU_256:
+ return ROCE_MTU_256_INT;
+ case ROCE_MTU_512:
+ return ROCE_MTU_512_INT;
+ case ROCE_MTU_1024:
+ return ROCE_MTU_1024_INT;
+ case ROCE_MTU_2048:
+ return ROCE_MTU_2048_INT;
+ case ROCE_MTU_4096:
+ return ROCE_MTU_4096_INT;
+ case ROCE_MTU_8192:
+ return ROCE_MTU_8192_INT;
+ default:
+ return -1;
+ }
+}
+
+static inline enum roce5_mtu roce5_get_mtu(int mtu)
+{
+ int local_mtu = mtu - (IB_GRH_BYTES + IB_UDP_BYTES + IB_BTH_BYTES +
+ IB_EXT_XRC_BYTES + IB_EXT_ATOMICETH_BYTES +
+ IB_ICRC_BYTES);
+
+ if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_8192))
+ return ROCE_MTU_8192;
+ else if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_4096))
+ return ROCE_MTU_4096;
+ else if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_2048))
+ return ROCE_MTU_2048;
+ else if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_1024))
+ return ROCE_MTU_1024;
+ else if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_512))
+ return ROCE_MTU_512;
+ else if (local_mtu >= roce5_mtu_enum_to_int(ROCE_MTU_256))
+ return ROCE_MTU_256;
+ else
+ return 0;
+}
+
+struct roce5_priv_ah {
+ /* DW0 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 pd : 18;
+ u32 rsvd0 : 6;
+ u32 stat_rate : 4;
+ u32 wqe_cos : 3;
+ u32 fl : 1; /* forcelock flag, it is used in multicast communication */
+#else
+ u32 f1 : 1;
+ u32 wqe_cos : 3;
+ u32 stat_rate : 4;
+ u32 rsvd0 : 6;
+ u32 pd : 18;
+#endif
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 hoplimit : 8;
+ u32 sgid_index : 7;
+ u32 resv : 1;
+ u32 port : 4;
+ u32 rsvd1 : 4;
+ u32 tclass : 8;
+#else
+ u32 tclass : 8;
+ u32 rsvd1 : 4;
+ u32 port : 4;
+ u32 resv : 1;
+ u32 sgid_index : 7;
+ u32 hoplimit : 8;
+#endif
+ } bs;
+ u32 value;
+ } dw1;
+
+ /* DW2 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 flow_label : 20;
+ u32 smac_index : 10;
+ u32 rsvd : 2;
+#else
+ u32 rsvd : 2;
+ u32 smac_index : 10;
+ u32 flow_label : 20;
+#endif
+ } bs;
+ u32 value;
+ } dw2;
+
+ /* DW3~6 */
+ u8 dgid[16];
+
+ /* DW7 */
+ union {
+ struct {
+#if (BYTE_ORDER != BIG_ENDIAN)
+ u32 dmac_h16 : 16;
+ u32 vlan_id : 12;
+ u32 rsvd : 1;
+ u32 vlan_pri : 3;
+#else
+ u32 vlan_pri : 3;
+ u32 rsvd : 1;
+ u32 vlan_id : 12;
+ u32 dmac_h16 : 16;
+#endif
+ } bs;
+ u32 value;
+ } dw7;
+
+ /* DW8 */
+ u32 dmac_l32;
+};
+
+struct roce5_ah {
+ struct ib_ah ibah;
+ struct roce5_priv_ah priv_ah;
+};
+
+union gid_addr {
+ struct sockaddr _sockaddr;
+ struct sockaddr_in _sockaddr_in;
+ struct sockaddr_in6 _sockaddr_in6;
+};
+
+struct mailbox_header {
+ u32 dest_host_id;
+ u32 dest_global_function_id;
+};
+
+struct roce5_mail_box_buffer {
+ struct mailbox_header header;
+ u32 data[0];
+};
+
+struct roce5_resolve_cb_context {
+ struct completion comp;
+ int status;
+};
+
+typedef struct roce5_get_cos_inbuf {
+ u8 sl;
+ u8 sgid_index;
+ u8 port_num;
+ u8 traffic_class;
+} roce5_get_cos_inbuf_s;
+
+int roce5_resolve_grh(struct roce5_device *rdev, struct rdma_ah_attr *ah_attr,
+ u16 *vlan_id, struct ib_udata *udata);
+int roce5_get_dcb_cfg_cos(struct roce5_device *rdev,
+ roce5_get_cos_inbuf_s *inbuf, u8 *cos,
+ enum ib_qp_type qp_type);
+uint8_t roce5_get_db_cos_from_vlan_pri(struct roce5_device *rdev,
+ uint8_t vlan_pri);
+
+#endif /* ROCE_MIX_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.c b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.c
new file mode 100644
index 000000000..92a3ada97
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.c
@@ -0,0 +1,138 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "roce.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_pd.h"
+
+int roce5_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (CHECK_2LAYER_IS_NULL(ibpd, device)) {
+ ROCE_ERR(
+ "Invalid NULL parameter, ibpd or ibpd->device is NULL.");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ pd = to_roce5_pd(ibpd);
+ rdev = to_roce5_dev(ibpd->device);
+
+ ret = roce5_rdma_pd_alloc(rdev->hwdev, &pd->pdn);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc pdn, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto err_out;
+ }
+
+ if (udata != NULL) {
+ if (udata->outbuf == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid NULL parameter, udata->outbuf is NULL.");
+ ret = -EINVAL;
+ goto err_copy_to_user;
+ }
+
+ if (ib_copy_to_udata(udata, &pd->pdn, sizeof(u32)) != 0) {
+ ret = -EFAULT;
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to copy data to user space, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_copy_to_user;
+ }
+ }
+
+ return 0;
+
+err_copy_to_user:
+ roce5_rdma_pd_free(rdev->hwdev, pd->pdn);
+err_out:
+ return ret;
+}
+
+struct ib_pd *roce5_alloc_pd_ofa(struct ib_device *ibdev,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (ibdev == NULL) {
+ ret = -EINVAL;
+ ROCE_ERR("Ibdev is null");
+ goto err_out;
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ pd = (struct roce5_pd *)kmalloc(sizeof *pd, GFP_KERNEL);
+ if (pd == NULL) {
+ ret = -ENOMEM;
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc memory for roce pd, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_out;
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ pd->ibpd.device = ibdev;
+ ret = roce5_alloc_pd(&pd->ibpd, udata);
+ if (ret != 0) {
+ goto err_alloc_pdn;
+ }
+
+ return &pd->ibpd;
+
+err_alloc_pdn:
+ kfree(pd);
+
+err_out:
+ return (struct ib_pd *)ERR_PTR((long)ret);
+}
+
+int roce5_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+{
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+
+ if (ibpd == NULL) {
+ ROCE_ERR("Ibpd is null");
+ return -EINVAL;
+ }
+
+ pd = to_roce5_pd(ibpd);
+ rdev = to_roce5_dev(ibpd->device);
+
+ roce5_rdma_pd_free(rdev->hwdev, pd->pdn);
+
+ return 0;
+}
+
+int roce5_dealloc_pd_ofa(struct ib_pd *ibpd)
+{
+ int ret;
+ struct roce5_pd *pd = NULL;
+
+ if (ibpd == NULL) {
+ ROCE_ERR("Ibpd is null");
+ return -EINVAL;
+ }
+
+ pd = to_roce5_pd(ibpd);
+ ret = roce5_dealloc_pd(ibpd, NULL);
+ if (ret == 0) {
+ kfree(pd);
+ }
+
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.h b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.h
new file mode 100644
index 000000000..e40c5a476
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/rdma/roce_pd.h
@@ -0,0 +1,15 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_PD_H
+#define ROCE_PD_H
+
+#include <rdma/ib_verbs.h>
+
+struct roce5_pd {
+ struct ib_pd ibpd;
+ u32 pdn;
+};
+
+#endif //ROCE_PD_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq.h b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq.h
new file mode 100644
index 000000000..1886af73f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq.h
@@ -0,0 +1,191 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_SRQ_H
+#define ROCE_SRQ_H
+
+#include <linux/types.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "hinic5_rdma.h"
+#include "hinic5_cqm.h"
+
+#include "roce.h"
+#include "roce_pd.h"
+#include "roce_db.h"
+#include "roce_compat.h"
+#include "roce_wqe_format.h"
+
+/* definition SRQ SGE maximum max and minimum value */
+#define ROCE_SRQ_CONT_MAX_SGE 16
+#define ROCE_SRQ_MAX_SGE 15
+#define ROCE_SRQ_MID_SGE 7
+#define ROCE_SRQ_MIN_SGE 3
+
+#define ROCE_SRQN_INVLD CQM_INDEX_INVALID
+#define ROCE_SRQ_CONTAINER_LWM_MASK 0xFFFF
+#define ROCE_SRQ_CONTAINER_WARTH_MASK 0xF
+
+#define MAX_SUPPORT_CONTAINER_MODE 3
+#define DWORD_LEN 32
+#define XRC_CQN_FIRST_LEN 10
+#define XRC_CQN_SECOND_LEN 3
+#define SRQ_GPA_SIG_LEN 3
+#define SRQ_WQEBB_SIZE_CAL_SECTTOR \
+ 4 /* (2^rq_wqebb_size)*16B => divide 16 means shift need to minus 4 */
+#define RDMA_PREFETCH_WQE_MAX 7
+#define RDMA_PREFETCH_MTT_LEN_MAX 3
+#define ROCE_WQE_BB_SIZE_MIN 64
+
+#define LAST_SGE_NO_PRESENT \
+ 0x80000000UL /* Lbit:0 - The next SGE is present in the list \
+ * Lbit:1 - The last SGE, no SGE is present in the list */
+#define NORMAL_FMT_AND_NEXT_SGE_PRESENT \
+ 0x3FFFFFFFUL /* Ebit:b0 - Normal format, without extension. \
+ * Ebit:b1 - The pointer inside of SGE points to the next SGL. \
+ * "Length" and "Key" fields are */
+#define NORMAL_FMT_AND_LAST_SGE_NO_PRESENT 0xBFFFFFFFUL
+
+/**
+ * CHIP container_mode:
+ * chip mode: 0 -> Not container
+ * chip mode: 1 -> container_size: 2
+ * chip mode: 2 -> container_size: 4
+ * chip mode: 3 -> container_size: 8
+ * chip mode: 4 -> container_size: 16
+ */
+enum roce5_chip_srq_mode {
+ ROCE_CHIP_SRQ_MODE_N = 0,
+ ROCE_CHIP_SRQ_MODE_1,
+ ROCE_CHIP_SRQ_MODE_2,
+ ROCE_CHIP_SRQ_MODE_3,
+ ROCE_CHIP_SRQ_MODE_4
+};
+
+enum srq_state {
+ ROCE_SRQ_STATE_INVALID = 0x0,
+ ROCE_SRQ_STATE_ERR = 0x1,
+ ROCE_SRQ_STATE_VALID = 0xf,
+ ROCE_SRQ_STATE_MEM_INIT = 0xa
+};
+
+#define ROCE_SRQ_STATE_CHECK_VALUE 0x0
+
+struct roce5_wqe_srq_next_seg {
+ u16 reserved1;
+ __be16 pcnt; /* indicate the pi */
+ u8 signature;
+ u8 reserved2;
+ __be16 next_wqe_index;
+ u32 reserved3[2];
+};
+
+struct roce5_wqe_container_srq_next_seg {
+ u32 next_gpa_h;
+
+ struct {
+ u32 rsvd : 11;
+ u32 next_gpa_vd : 1;
+ u32 next_gpa_h : 20; /* indicate the pi */
+ } dw1;
+
+ struct {
+ u32 next_idx : 16;
+ u32 rsvd : 16;
+ } dw2;
+
+ struct {
+ u32 rsvd2 : 30;
+ u32 link_flag : 1;
+ u32 rsvd : 1;
+ } dw3;
+
+ struct {
+ u32 osd_next_idx : 16;
+ u32 osd_cur_idx : 16;
+ } dw4;
+};
+
+#define ROCE_SRQ_SGE_LAST 1
+#define ROCE_SRQ_SGE_NLAST 0
+
+#define ROCE_SRQ_SGE_LKEY_NOEXT 0
+#define ROCE_SRQ_SGE_LKEY_EXT 1
+
+struct roce5_srq {
+ struct ib_srq ibsrq; /* ibsrq */
+ cqm_queue_s *cqm_srq;
+
+ u32 srqn;
+ int max_depth;
+ int max_gs;
+ int wqe_shift;
+
+ cqm_buf_s *buf;
+ struct roce5_db db;
+ u64 *wrid;
+ spinlock_t lock;
+ int head;
+ int tail;
+ u16 wqe_ctr;
+ u8 xrc_en;
+ u8 rsvd;
+ struct ib_umem *umem;
+ struct mtt mtt;
+ struct mutex mutex;
+ u32 rqe_cnt_th;
+ u8 container_flag;
+ u8 container_size;
+ u8 container_mode;
+ u8 container_warn_th;
+
+ int buf_sz;
+};
+
+static inline u8 roce5_srq_get_max_sge(struct roce5_srq *rsrq)
+{
+ if (rsrq->container_flag != 0) {
+ return ROCE_SRQ_CONT_MAX_SGE;
+ }
+ return ROCE_SRQ_MAX_SGE;
+}
+
+static inline int roce5_srq_init_wqe_size(struct roce5_srq *rsrq)
+{
+ int desc_size = 0;
+
+ if (rsrq->container_flag != 0) {
+ desc_size = rsrq->max_gs * sizeof(struct roce_wqe_srq_data_seg);
+ } else {
+ desc_size = sizeof(struct roce5_wqe_srq_next_seg) +
+ rsrq->max_gs * sizeof(struct roce_wqe_srq_data_seg);
+ }
+ desc_size = (int)(ROCE_ROUNDUP_POW_OF_TWO((u32)desc_size));
+ desc_size = ROCE_MAX(ROCE_WQE_BB_SIZE_MIN, desc_size);
+
+ rsrq->wqe_shift = (int)ROCE_ILOG2((unsigned)desc_size);
+ return desc_size;
+}
+
+void roce5_free_srq_wqe(struct roce5_srq *srq, int wqe_index);
+void roce5_srq_async_event(struct roce5_device *rdev, struct roce5_srq *srq,
+ int type);
+void *roce5_srq_get_wqe(struct roce5_srq *srq, int n);
+u8 roce5_get_container_sz(u32 container_mode);
+u32 roce5_srq_max_avail_wr_set(struct roce5_srq *rsrq);
+int roce5_create_srq_common(struct roce5_device *rdev, struct roce5_srq *rsrq,
+ struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata, u32 index);
+struct roce5_srq *roce5_get_rsrq_by_srqn(struct roce5_device *rdev, u32 srqn);
+static inline void roce5_rsrq_put(struct roce5_srq *rsrq)
+{
+ if (rsrq == NULL) {
+ return;
+ }
+ cqm5_object_put(&rsrq->cqm_srq->object);
+}
+
+#endif //ROCE_SRQ_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_comm.c b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_comm.c
new file mode 100644
index 000000000..0a3beb338
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_comm.c
@@ -0,0 +1,116 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "roce.h"
+#include "roce_compat.h"
+#include "roce_xrc.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_aeq_format.h"
+#include "roce_srq_extension.h"
+#include "roce_restore.h"
+
+static void *roce5_srq_buf_offset(struct tag_cqm_buf *buf, int offset)
+{
+ return (void *)((char *)buf->direct.va + offset);
+}
+
+void *roce5_srq_get_wqe(struct roce5_srq *srq, int n)
+{
+ return roce5_srq_buf_offset(srq->buf,
+ (int)((u32)n << (unsigned)srq->wqe_shift));
+}
+
+void roce5_srq_async_event(struct roce5_device *rdev, struct roce5_srq *srq,
+ int type)
+{
+ struct ib_srq *ibsrq = &srq->ibsrq;
+ struct ib_event event;
+ int ret;
+
+ ret = memset_s(&event, sizeof(event), 0, sizeof(event));
+ if (ret != 0) {
+ ROCE_DEV_ERR_LIMIT(rdev, "Failed to memset event.(ret:%d)",
+ ret);
+ }
+ if (ibsrq->event_handler) {
+ event.device = ibsrq->device;
+ event.element.srq = ibsrq;
+ switch (type) {
+ case ROCE_EVENT_TYPE_SRQ_LIMIT:
+ event.event = IB_EVENT_SRQ_LIMIT_REACHED;
+ break;
+
+ case ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
+ event.event = IB_EVENT_SRQ_ERR;
+ break;
+
+ default:
+ ROCE_DEV_WARN_LIMIT(
+ rdev,
+ "unexpected event type(%d) on SRQ(%06x), func_id(%d)",
+ type, srq->srqn, rdev->glb_func_id);
+ return;
+ }
+
+ ibsrq->event_handler(&event, ibsrq->srq_context);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_free_srq_wqe
+ Description : roce5_free_srq_wqe
+ Input : struct roce5_srq *srq
+ int wqe_index
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+void roce5_free_srq_wqe(struct roce5_srq *srq, int wqe_index)
+{
+ struct roce5_wqe_srq_next_seg *next = NULL;
+
+ spin_lock(&srq->lock);
+
+ next = (struct roce5_wqe_srq_next_seg *)roce5_srq_get_wqe(srq,
+ srq->tail);
+ next->next_wqe_index = (u16)wqe_index;
+ srq->tail = wqe_index;
+
+ spin_unlock(&srq->lock);
+}
+
+/**
+ * @brief Get roce srq by srqn. When querying succeeded, you have to call roce5_rsrq_put() to free
+ the cqm_obj_srq. But there is no need to call roce5_rsrq_put() if querying failed.
+ * @return Success: return the roce srq. Failure: return NULL.
+ */
+struct roce5_srq *roce5_get_rsrq_by_srqn(struct roce5_device *rdev, u32 srqn)
+{
+ cqm_object_s *cqm_obj_srq = NULL;
+ struct roce5_srq *rsrq = NULL;
+
+ cqm_obj_srq =
+ cqm5_object_get(rdev->hwdev, CQM_OBJECT_RDMA_SRQ, srqn, false);
+ if (cqm_obj_srq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Can't find srq according to srqn(%u), func_id(%d).",
+ srqn, rdev->glb_func_id);
+ return NULL;
+ }
+
+ rsrq = cqmobj_to_roce5_srq(cqm_obj_srq);
+ if (rsrq == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to convert obj to rsrq.");
+ cqm5_object_put(cqm_obj_srq);
+ }
+
+ return rsrq;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_create.c b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_create.c
new file mode 100644
index 000000000..47c86b2fa
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_create.c
@@ -0,0 +1,712 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+
+#include "comm_defs.h"
+#include "roce.h"
+#include "roce_cq.h"
+#include "roce_cqm_cmd.h"
+#include "roce_user.h"
+#include "roce_xrc.h"
+#include "roce_pd.h"
+#include "roce_srq.h"
+#include "roce_restore.h"
+#include "roce_npu_cmd_srq_defs.h"
+#include "roce_npu_cmd_defs.h"
+
+#include "roce_srq_extension.h"
+#include "roce_main_extension.h"
+#include "hinic5_hmm.h"
+#include "roce_npu_cmd.h"
+#include "securec.h"
+#include "roce_os_compat.h"
+
+/* ****************************************************************************
+ Prototype : roce5_srq_sw2hw
+ Description : roce5_srq_sw2hw
+ Input : struct roce5_device *rdev
+ struct roce5_srq *rsrq
+ u32 pdn
+ u32 cqn
+ u16 xrcdn
+ int page_shift
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+ 1.Date : 2015/7/27
+ Modification : modify function
+**************************************************************************** */
+static void roce5_srq_sw2hw_set(roce_verbs_srq_attr_s *srq_attr,
+ struct roce5_srq *rsrq, u32 pdn, u32 cqn,
+ u16 xrcdn, int page_shift)
+{
+ srq_attr->dw0.bs.size = (u32)(ROCE_ILOG2((unsigned)rsrq->max_depth));
+ srq_attr->dw0.bs.page_size = (u32)page_shift;
+ srq_attr->dw0.bs.wqebb_size =
+ (u32)rsrq->wqe_shift - SRQ_WQEBB_SIZE_CAL_SECTTOR;
+ srq_attr->dw0.bs.mtt_page_size =
+ rsrq->mtt.mtt_page_shift - PAGE_SHIFT_4K;
+ srq_attr->dw0.bs.xrcd = xrcdn;
+
+ srq_attr->dw1.bs.dma_attr_idx = 0;
+ srq_attr->dw1.bs.so_ro = 1;
+ srq_attr->dw1.bs.state = ROCE_SRQ_STATE_VALID;
+
+ srq_attr->dw3.bs.container = rsrq->container_flag;
+ srq_attr->dw3.bs.lth_pre_en =
+ (rsrq->container_flag == 0); //rdma engine prefetch
+ srq_attr->dw3.bs.pcnt_on_chip = 0;
+ srq_attr->dw3.bs.rkey_en = 1;
+ srq_attr->dw3.bs.pd = pdn;
+
+ srq_attr->srqn = cpu_to_be32(rsrq->srqn);
+ srq_attr->xrc_cqn = cpu_to_be32(cqn);
+
+ if (rsrq->container_flag == 0) { //normal srq
+ srq_attr->dw1.bs.ep = 0;
+ srq_attr->dw1.bs.cos = 0;
+
+ srq_attr->dw2.value = 0;
+ srq_attr->dw2.bs.wqe_prefetch_max_num =
+ RDMA_PREFETCH_WQE_MAX; //rdma engine wqe prefetch max num
+ srq_attr->dw2.bs.wqecnt_lth = 0xe;
+ srq_attr->dw2.bs.mtt_prefetch_maxlen =
+ 0; //rdma engine mtt prefetch max len
+
+ srq_attr->dw3.bs.lth_pre_en = 1; //rdma engine prefetch
+ srq_attr->dw3.bs.lth_gap = 0;
+ } else {
+ srq_attr->cont.dw2.bs.head_idx = 0;
+ srq_attr->cont.dw2.bs.warn_th =
+ 0; //Do NOT init warn_th until user arm srq
+ srq_attr->cont.dw2.bs.cont_size =
+ (MAX_SUPPORT_CONTAINER_MODE - rsrq->container_mode) &
+ 0x3;
+ srq_attr->cont.dw2.value =
+ cpu_to_be32(srq_attr->cont.dw2.value);
+ srq_attr->record_gpa_at_hop_num =
+ cpu_to_be64((rsrq->mtt.mtt_layers & 0x3));
+ }
+
+ srq_attr->dw0.value = cpu_to_be32(srq_attr->dw0.value);
+ srq_attr->dw1.value = cpu_to_be32(srq_attr->dw1.value);
+ srq_attr->dw2.value = cpu_to_be32(srq_attr->dw2.value);
+ srq_attr->dw3.value = cpu_to_be32(srq_attr->dw3.value);
+
+ srq_attr->l0mtt_gpa = rsrq->mtt.mtt_paddr;
+
+ srq_attr->l0mtt_gpa = cpu_to_be64(srq_attr->l0mtt_gpa);
+
+ srq_attr->record_gpa_at_hop_num =
+ cpu_to_be64(rsrq->db.dma | (rsrq->mtt.mtt_layers & 0x3));
+
+ return;
+}
+
+static int roce5_srq_sw2hw(struct roce5_device *rdev, struct roce5_srq *rsrq,
+ u32 pdn, u32 cqn, u16 xrcdn, int page_shift)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_verbs_srq_attr_s *srq_attr = NULL;
+ roce_uni_cmd_create_srq_s *srq_sw2hw_inbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_create_srq_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ srq_sw2hw_inbuf = (roce_uni_cmd_create_srq_s *)cqm_cmd_inbuf->buf;
+ srq_sw2hw_inbuf->com.index = cpu_to_be32((u32)rsrq->srqn);
+ srq_sw2hw_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SRQ_BITMASK));
+ srq_attr = &srq_sw2hw_inbuf->srq_attr;
+
+ roce5_srq_sw2hw_set(srq_attr, rsrq, pdn, cqn, xrcdn, page_shift);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_SW2HW_SRQ, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send SW2HW_SRQ command, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+
+ /* update dev status after cmdq timeout or exception, notify PCIe reset */
+ if ((ret == -ETIMEDOUT) || (ret == -EPERM)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static int roce5_create_srq_check(const struct ib_pd *ibpd,
+ const struct ib_srq_init_attr *init_attr,
+ const struct roce5_srq *rsrq)
+{
+ struct roce5_device *rdev = NULL;
+
+ if ((ibpd == NULL) || (init_attr == NULL)) {
+ ROCE_ERR("Ibpd or init_attr is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibpd->device);
+ if ((init_attr->attr.max_wr >
+ (u32)rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_wqes) ||
+ (init_attr->attr.max_sge >
+ ((u32)rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_sge +
+ rsrq->container_flag))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid input parms, max_wr(%d), max_srq_wqes(%d), max_sge(%d), max_srq_sge(%d)",
+ init_attr->attr.max_wr,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_wqes,
+ init_attr->attr.max_sge,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_sge);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_create_srq_write_mtt_and_db(struct roce5_device *rdev,
+ struct roce5_srq *rsrq,
+ struct roce5_create_srq_cmd *ucmd,
+ struct roce5_pd *pd)
+{
+ int ret = 0;
+
+ ret = roce5_umem_write_mtt(rdev, &rsrq->mtt, rsrq->umem, 1);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_db_map_user(to_roce5_ucontext(pd->ibpd.uobject->context),
+ ucmd->db_addr, &rsrq->db, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to map db to user space, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int roce5_create_srq_get_umem(struct roce5_create_srq_cmd *ucmd,
+ struct ib_udata *udata,
+ struct roce5_srq *rsrq,
+ struct roce5_device *rdev,
+ struct roce5_pd *pd)
+{
+ int ret = 0;
+
+ if (ib_copy_from_udata(ucmd, udata, sizeof(*ucmd)) != 0) {
+ ret = -EFAULT;
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy from user space, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ rsrq->umem = roce5_umem_get(&rdev->ib_dev, pd->ibpd.uobject->context,
+ ucmd->buf_addr, (size_t)rsrq->buf_sz, 0, 0);
+ if (IS_ERR(rsrq->umem)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to get ib_umem, func_id(%d) rsrq->buf_sz:%u",
+ rdev->glb_func_id, rsrq->buf_sz);
+ ret = (int)PTR_ERR(rsrq->umem);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int roce5_create_user_srq_update(struct roce5_device *rdev,
+ struct roce5_srq *rsrq,
+ struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata, int page_shift)
+{
+ u32 cqn = 0;
+ u16 xrcdn = 0;
+ int ret = 0;
+
+ cqn = (u32)((init_attr->srq_type == IB_SRQT_XRC) ?
+ to_roce5_cq(init_attr->ext.cq)->cqn :
+ 0);
+ xrcdn = (init_attr->srq_type == IB_SRQT_XRC) ?
+ (u16)(to_roce5_xrcd(init_attr->ext.xrc.xrcd)->xrcdn) :
+ (u16)rdev->rdma_cap.reserved_xrcds;
+
+ /* set SRQC */
+ ret = roce5_srq_sw2hw(rdev, rsrq, pd->pdn, cqn, xrcdn,
+ (page_shift - PAGE_SHIFT_4K));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to handle srq_sw2hw, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_unmap;
+ }
+
+ rsrq->ibsrq.ext.xrc.srq_num = (u32)rsrq->srqn;
+
+ if (ib_copy_to_udata(udata, &rsrq->srqn, sizeof(u32)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy data to user space, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EFAULT;
+ goto err_unmap;
+ }
+
+ return 0;
+
+err_unmap:
+ roce5_db_unmap_user(to_roce5_ucontext(pd->ibpd.uobject->context),
+ &rsrq->db, 0);
+ return ret;
+}
+
+u32 roce5_srq_max_avail_wr_set(struct roce5_srq *rsrq)
+{
+ u32 link_wqe_count = 0;
+
+ if (rsrq->container_flag != 0) {
+ link_wqe_count = (u32)rsrq->max_depth / rsrq->container_size;
+ return ((u32)rsrq->max_depth - link_wqe_count) -
+ (rsrq->container_size - 1);
+ } else {
+ return (u32)rsrq->max_depth - 1;
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_user_srq
+ Description : roce5_create_user_srq
+ Input : struct roce5_device *rdev
+ struct roce5_srq *rsrq
+ struct roce5_pd *pd
+ struct ib_srq_init_attr *init_attr
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_user_srq(struct roce5_device *rdev,
+ struct roce5_srq *rsrq, struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata, u32 index)
+{
+ int ret = 0;
+ u32 npages = 0;
+ int page_shift = 0;
+ struct roce5_create_srq_cmd ucmd = { 0 };
+
+ /* dispatch SRQN and SRQC */
+ rsrq->cqm_srq = cqm5_object_rdma_queue_create(rdev->hwdev,
+ SERVICE_T_ROCE,
+ CQM_OBJECT_RDMA_SRQ, 0,
+ rsrq, false, index, 0, 0);
+ if (rsrq->cqm_srq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create rdma queue by cqm_object, func_id(%d) index(%d)",
+ rdev->glb_func_id, index);
+ return (-ENOMEM);
+ }
+
+ rsrq->srqn = rsrq->cqm_srq->index;
+
+ ret = roce5_create_srq_get_umem(&ucmd, udata, rsrq, rdev, pd);
+ if (ret != 0) {
+ goto err_free_cqm_srq;
+ }
+
+ page_shift =
+ roce5_umem_get_buf_page_shift(rdev, rsrq->umem, ucmd.buf_addr);
+ npages = roce5_umem_get_mtt_npages(rdev, rsrq->umem, (u32)page_shift);
+
+ rsrq->mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, npages, (u32)page_shift, &rsrq->mtt,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, " Failed to alloc rdma_mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_release_umem;
+ }
+
+ ret = roce5_create_srq_write_mtt_and_db(rdev, rsrq, &ucmd, pd);
+ if (ret != 0) {
+ goto err_free_mtt;
+ }
+
+ ret = roce5_create_user_srq_update(rdev, rsrq, pd, init_attr, udata,
+ page_shift);
+ if (ret != 0) {
+ goto err_free_mtt;
+ }
+
+ init_attr->attr.max_wr = roce5_srq_max_avail_wr_set(rsrq);
+
+ return 0;
+
+err_free_mtt:
+ hmm_mtt_free(rdev->hwdev, &rsrq->mtt, SERVICE_T_ROCE);
+
+err_release_umem:
+ ib_umem_release(rsrq->umem);
+
+err_free_cqm_srq:
+ cqm5_object_delete(&rsrq->cqm_srq->object);
+
+ return ret;
+}
+
+static void roce5_get_cqn_xrcdn(u32 *cqn, u16 *xrcdn,
+ struct ib_srq_init_attr *init_attr,
+ struct roce5_device *rdev)
+{
+ *cqn = (u32)((init_attr->srq_type == IB_SRQT_XRC) ?
+ to_roce5_cq(init_attr->ext.cq)->cqn :
+ 0);
+ *xrcdn = (init_attr->srq_type == IB_SRQT_XRC) ?
+ (u16)(to_roce5_xrcd(init_attr->ext.xrc.xrcd)->xrcdn) :
+ (u16)rdev->rdma_cap.reserved_xrcds;
+}
+
+static int roce5_create_kernel_srq_update(struct roce5_device *rdev,
+ struct roce5_srq *rsrq,
+ struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ int page_shift)
+{
+ u32 cqn = 0;
+ u16 xrcdn = 0;
+ int ret;
+ ret = roce5_buf_write_mtt(rdev, &rsrq->mtt, rsrq->buf);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_mtt;
+ }
+
+ rsrq->wrid = (u64 *)kmalloc(
+ (size_t)((u32)rsrq->max_depth * sizeof(u64)), GFP_KERNEL);
+ if (rsrq->wrid == NULL) {
+ rsrq->wrid = (u64 *)vzalloc(
+ (size_t)((u32)rsrq->max_depth * sizeof(u64)));
+ if (rsrq->wrid == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc srq wrid, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -ENOMEM;
+ goto err_free_mtt;
+ }
+ }
+
+ roce5_get_cqn_xrcdn(&cqn, &xrcdn, init_attr, rdev);
+
+ ret = roce5_srq_sw2hw(rdev, rsrq, pd->pdn, cqn, xrcdn,
+ (page_shift - PAGE_SHIFT_4K));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to handle srq sw2hw, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_wrid;
+ }
+
+ return 0;
+
+err_free_wrid:
+ kvfree(rsrq->wrid);
+ rsrq->wrid = NULL;
+
+err_free_mtt:
+ hmm_mtt_free(rdev->hwdev, &rsrq->mtt, SERVICE_T_ROCE);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_create_kernel_srq
+ Description : roce5_create_kernel_srq
+ Input : struct roce5_device *rdev
+ struct roce5_srq *rsrq
+ struct roce5_pd *pd
+ struct ib_srq_init_attr *init_attr
+ Output : None
+
+ 1.Date : 2017/5/4
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_create_kernel_srq(struct roce5_device *rdev,
+ struct roce5_srq *rsrq, struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ u32 index)
+{
+ int i = 0;
+ int ret = 0;
+ int page_shift = 0;
+ struct roce5_wqe_srq_next_seg *next = NULL;
+ struct roce_wqe_srq_data_seg *scatter = NULL;
+
+ /* alloc queue Buf/ Soft DB/SRQN/SRQC */
+ rsrq->cqm_srq = cqm5_object_rdma_queue_create(
+ rdev->hwdev, SERVICE_T_ROCE, CQM_OBJECT_RDMA_SRQ,
+ (u32)rsrq->buf_sz, rsrq, true, index, 0, 0);
+ if (rsrq->cqm_srq == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create rdma queue by cqm_object, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ rsrq->srqn = rsrq->cqm_srq->index;
+ rsrq->buf = &rsrq->cqm_srq->q_room_buf_1;
+
+ /* set Soft DB */
+ rsrq->db.db_record = (__be32 *)(void *)(&rsrq->cqm_srq->q_header_vaddr
+ ->doorbell_record);
+ rsrq->db.dma = rsrq->cqm_srq->q_header_paddr;
+ *rsrq->db.db_record = 0;
+
+ rsrq->head = 0;
+ rsrq->tail = rsrq->max_depth - 1;
+ rsrq->wqe_ctr = 0;
+
+ for (i = 0; i < rsrq->max_depth; ++i) {
+ next = (struct roce5_wqe_srq_next_seg *)roce5_srq_get_wqe(rsrq,
+ i);
+ next->next_wqe_index = cpu_to_be16(
+ (u16)((u32)(i + 1) & (u32)(rsrq->max_depth - 1)));
+
+ scatter = (struct roce_wqe_srq_data_seg *)(next + 1);
+ scatter->dw2.length = 0;
+
+ /* first SGE = last SGE */
+ scatter->dw3.lkey = LAST_SGE_NO_PRESENT;
+ scatter->dw3.lkey = cpu_to_be32(scatter->dw3.lkey);
+ }
+
+ page_shift = (int)ROCE_ILOG2(rsrq->buf->buf_size);
+ rsrq->mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(rdev->hwdev, rsrq->buf->buf_number, (u32)page_shift,
+ &rsrq->mtt, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma rdma_mtt, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free_cqm_srq;
+ }
+
+ ret = roce5_create_kernel_srq_update(rdev, rsrq, pd, init_attr,
+ page_shift);
+ if (ret != 0) {
+ goto err_free_cqm_srq;
+ }
+
+ rsrq->ibsrq.ext.xrc.srq_num = (u32)rsrq->srqn;
+ init_attr->attr.max_wr = (u32)rsrq->max_depth - 1;
+ return 0;
+
+err_free_cqm_srq:
+ cqm5_object_delete(&rsrq->cqm_srq->object);
+
+ return ret;
+}
+
+static void roce5_set_srq_depth(struct ib_srq_init_attr *init_attr,
+ struct roce5_srq *rsrq)
+{
+ u32 link_wqe_count = 0;
+ u32 remain_wqe_count = 0;
+
+ /*
+ * +---+---+---+---+---+---+---+---+
+ * |wqe|wqe|wqe|wqe|wqe|wqe|wqe|nil|
+ * +---+---+---+---+---+---+---+---+
+ * ^
+ * |
+ * full condition:head==tail==nil
+ */
+ if (rsrq->container_flag != 0) {
+ link_wqe_count =
+ init_attr->attr.max_wr / (rsrq->container_size - 1u);
+ remain_wqe_count =
+ init_attr->attr.max_wr % (rsrq->container_size - 1u);
+ link_wqe_count +=
+ ((remain_wqe_count == 0) ?
+ 0 :
+ (rsrq->container_size - remain_wqe_count));
+ rsrq->max_depth = (int)(init_attr->attr.max_wr +
+ link_wqe_count + rsrq->container_size);
+ } else {
+ rsrq->max_depth = (int)(init_attr->attr.max_wr + 1);
+ }
+ rsrq->max_depth =
+ (int)((ROCE_ROUNDUP_POW_OF_TWO((u32)rsrq->max_depth)) &
+ 0xffffffff);
+}
+
+static void roce5_rsrq_init(struct ib_srq_init_attr *init_attr,
+ struct roce5_srq *rsrq, struct roce5_device *rdev)
+{
+ int buf_size = 0;
+ int desc_size = 0;
+
+ roce5_srq_container_init(init_attr, rsrq, rdev);
+
+ mutex_init(&rsrq->mutex);
+ spin_lock_init(&rsrq->lock);
+
+ roce5_set_srq_depth(init_attr, rsrq);
+
+ rsrq->max_gs = (init_attr->attr.max_sge <= ROCE_SRQ_MIN_SGE) ?
+ ROCE_SRQ_MIN_SGE :
+ ((init_attr->attr.max_sge <= ROCE_SRQ_MID_SGE) ?
+ ROCE_SRQ_MID_SGE :
+ roce5_srq_get_max_sge(rsrq));
+ init_attr->attr.max_sge = (u32)rsrq->max_gs;
+
+ /* 0 <= max_gs <= 3, desc_size = 64
+ * 4 <= max_gs <= 7, desc_size = 128
+ */
+ desc_size = roce5_srq_init_wqe_size(rsrq);
+ buf_size = rsrq->max_depth * desc_size;
+
+ /* WQEBB align 1 PAGE */
+ if (buf_size < (int)PAGE_SIZE) {
+ rsrq->max_depth =
+ (int)((u64)PAGE_SIZE >> (unsigned int)rsrq->wqe_shift);
+ }
+
+ /* align with PAGE SIZE */
+ buf_size = (int)ROCE_ALIGN((u32)buf_size, PAGE_SIZE);
+ rsrq->buf_sz = buf_size;
+
+ ROCE_DEV_INFO(
+ rdev,
+ "RoCE srq mode: container_EN(%d), container_mode(%d), XRC_EN(%d), MAX_DEPTH(%d), MAX_SGE(%d), desc_size(%d)",
+ rsrq->container_flag, rsrq->container_mode, rsrq->xrc_en,
+ rsrq->max_depth, rsrq->max_gs, desc_size);
+}
+
+int roce5_create_srq_common(struct roce5_device *rdev, struct roce5_srq *rsrq,
+ struct roce5_pd *pd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata, u32 index)
+{
+ int ret;
+ roce5_rsrq_init(init_attr, rsrq, rdev);
+
+ ret = roce5_create_srq_check(&pd->ibpd, init_attr, rsrq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to check srq info");
+ return ret;
+ }
+
+ if (rsrq->ibsrq.uobject != NULL) {
+ ret = roce5_create_user_srq(rdev, rsrq, pd, init_attr, udata,
+ index);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to create user srq, func_id(%d), index(%d)",
+ rdev->glb_func_id, index);
+ }
+ } else {
+ ret = roce5_create_kernel_srq(rdev, rsrq, pd, init_attr, index);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to create kernel srq, func_id(%d)",
+ rdev->glb_func_id);
+ }
+ }
+
+ ROCE_DEV_INFO(
+ rdev,
+ "SRQ create:srqn:%d,container_en_mode:%d_%d,xrc_en:%d,max_depth:%d",
+ rsrq->srqn, rsrq->container_flag, rsrq->container_mode,
+ rsrq->xrc_en, rsrq->max_depth);
+
+ return ret;
+}
+
+int roce5_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct roce5_pd *pd = NULL;
+ struct roce5_device *rdev = NULL;
+ struct roce5_srq *rsrq = NULL;
+
+ if ((ibsrq == NULL) || (init_attr == NULL)) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ pd = to_roce5_pd(ibsrq->pd);
+ rdev = to_roce5_dev(ibsrq->device);
+ rsrq = to_roce5_srq(ibsrq);
+
+ return roce5_create_srq_common(rdev, rsrq, pd, init_attr, udata,
+ ROCE_SRQN_INVLD);
+}
+
+struct ib_srq *roce5_create_srq_ofa(struct ib_pd *ibpd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_srq *rsrq = NULL;
+
+ if (ibpd == NULL) {
+ ROCE_ERR("Ibpd is null");
+ return ERR_PTR(-EINVAL);
+ }
+
+ rsrq = (struct roce5_srq *)kzalloc(sizeof(struct roce5_srq),
+ GFP_KERNEL);
+ if (rsrq == NULL) {
+ ROCE_ERR("Failed to alloc srq");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ rsrq->ibsrq.pd = ibpd;
+ rsrq->ibsrq.device = ibpd->device;
+#if defined(IB_SRQ_HAVE_UOBJECT)
+ rsrq->ibsrq.uobject =
+ (udata ? ibpd->uobject :
+ NULL); /* udata not NULL means user srq create */
+#endif
+ ret = roce5_create_srq(&rsrq->ibsrq, init_attr, udata);
+ if (ret != 0) {
+ kfree(rsrq);
+ return ERR_PTR(ret);
+ }
+
+ return &rsrq->ibsrq;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_ctrl.c b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_ctrl.c
new file mode 100644
index 000000000..887a857ad
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_ctrl.c
@@ -0,0 +1,635 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "comm_defs.h"
+#include "roce.h"
+#include "roce_compat.h"
+#include "roce_user.h"
+#include "roce_xrc.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_mix.h"
+#include "roce_cqm_cmd.h"
+#include "roce_restore.h"
+#include "hinic5_hmm.h"
+#include "roce_main_extension.h"
+#include "roce_srq_extension.h"
+#include "roce_npu_cmd.h"
+#include "roce_com.h"
+#include "securec.h"
+#include "roce_os_compat.h"
+
+/* and above next is V100 compatible data structure */
+typedef struct tag_roce_cmd_srq_arm {
+ roce_verbs_cmd_com_s com;
+ union {
+ u32 limitwater;
+ struct {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
+ u32 lwm : 16;
+ u32 warth : 4;
+ u32 th_up_en : 1;
+ u32 cont_en : 1;
+ u32 rsvd : 10;
+#else
+ u32 rsvd : 10;
+ u32 cont_en : 1;
+ u32 th_up_en : 1;
+ u32 warth : 4;
+ u32 lwm : 16;
+#endif
+ } bs;
+ };
+} roce_cmd_srq_arm_s;
+
+typedef struct tag_roce_cmd_srq_hw2sw {
+ roce_verbs_cmd_com_s com;
+ roce_xq_mtt_info_s mtt_info;
+ u32 srq_buf_len;
+ u32 wqe_cache_line_start;
+ u32 wqe_cache_line_end;
+ u32 wqe_cache_line_size;
+} roce_cmd_srq_hw2sw_s;
+
+static u8 roce5_cal_srq_container_num(u32 avail_wr, struct roce5_srq *srq)
+{
+ u32 container_num = 0;
+ u32 srqe_num = 0;
+
+ /* cal container_num by avail_wr from user */
+ srqe_num = srq->container_size - 1;
+
+ /* explain the formula: round up by srqe_num */
+ container_num = (avail_wr + srqe_num - 1) / srqe_num;
+ return roce5_calculate_cont_th(container_num);
+}
+
+static void roce5_srq_arm_config_cqm_cmd(cqm_cmd_buf_s *cqm_cmd_inbuf,
+ struct roce5_srq *srq, u32 srq_limit,
+ u8 *warth)
+{
+ roce_uni_cmd_srq_arm_s *srq_arm_inbuf = NULL;
+
+ srq_arm_inbuf = (roce_uni_cmd_srq_arm_s *)cqm_cmd_inbuf->buf;
+ srq_arm_inbuf->com.index = cpu_to_be32((u32)(srq->srqn));
+ srq_arm_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_SRQ_BITMASK);
+ if (srq->container_flag != 0) {
+ srq_arm_inbuf->srq_arm.bs.cont_en = srq->container_flag;
+ srq_arm_inbuf->srq_arm.bs.th_up_en =
+ 1; //Valid for setting up container warn_threshold
+ *warth = roce5_cal_srq_container_num(srq_limit, srq);
+ srq_arm_inbuf->srq_arm.bs.warth = *warth &
+ ROCE_SRQ_CONTAINER_WARTH_MASK;
+ srq_arm_inbuf->srq_arm.limitwater =
+ cpu_to_be32(srq_arm_inbuf->srq_arm.limitwater);
+ } else {
+ srq_arm_inbuf->srq_arm.bs.lwm = srq_limit;
+ srq_arm_inbuf->srq_arm.limitwater =
+ cpu_to_be32(srq_arm_inbuf->srq_arm.limitwater);
+ }
+}
+
+/* ****************************************************************************
+ Prototype : roce5_srq_arm
+ Description : roce5_srq_arm
+ Input : struct roce5_device *rdev
+ struct roce5_srq *srq
+ u32 srq_limit
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_srq_arm(struct roce5_device *rdev, struct roce5_srq *srq,
+ u32 srq_limit)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ uint8_t warth = 0;
+ uint16_t inbuf_size = 0;
+
+ if (ROCE5_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2(rdev) != 0) {
+ inbuf_size = sizeof(roce_uni_cmd_srq_arm_s);
+ }
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(rdev->hwdev, &cqm_cmd_inbuf,
+ inbuf_size, NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ if (ROCE5_SUPPORT_IB_CMD_MODIFY_SRQ_MSG_V2(rdev) != 0) {
+ roce5_srq_arm_config_cqm_cmd(cqm_cmd_inbuf, srq, srq_limit,
+ &warth);
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE, ROCE_CMD_ARM_SRQ,
+ cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "send ARM_SRQ command Failed, ret(%d), func_id(%d), warth(%d)",
+ ret, rdev->glb_func_id, warth);
+
+ if ((ret == -ETIMEDOUT) || (ret == -EPERM)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_modify_srq
+ Description : roce5_modify_srq
+ Input : struct ib_srq *ibsrq
+ struct ib_srq_attr *attr
+ enum ib_srq_attr_mask attr_mask
+ struct ib_udata *udata
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
+{
+ int ret = 0;
+ struct roce5_device *rdev = NULL;
+ struct roce5_srq *srq = NULL;
+ struct roce5_modify_srq_cmd ucmd = { 0 };
+ u32 max_avail_wr = 0;
+
+ if ((ibsrq == NULL) || (attr == NULL)) {
+ ROCE_ERR("Ibsrq or attr is null");
+ return (-EINVAL);
+ }
+
+ if (((unsigned int)attr_mask & IB_SRQ_MAX_WR) != 0) {
+ ROCE_ERR("Not support resizing SRQs");
+ return (-EINVAL);
+ }
+
+ rdev = to_roce5_dev(ibsrq->device);
+ srq = to_roce5_srq(ibsrq);
+
+ if ((udata != NULL) &&
+ (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)) != 0)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "SRQN:(%d), Failed to copy from user space, func_id(%d)",
+ srq->srqn, rdev->glb_func_id);
+ return (-EFAULT);
+ }
+
+ if (((unsigned int)attr_mask & IB_SRQ_LIMIT) != 0) {
+ /* calculate max_wr */
+ max_avail_wr = roce5_srq_max_avail_wr_set(srq);
+ if (attr->srq_limit > max_avail_wr) {
+ ROCE_DEV_ERR(
+ rdev,
+ "srq_limit > max_wr, func_id(%d), max_avail_wr(%d)",
+ rdev->glb_func_id, max_avail_wr);
+ return (-EINVAL);
+ }
+
+ mutex_lock(&srq->mutex);
+ ret = roce5_srq_arm(rdev, srq, attr->srq_limit);
+ mutex_unlock(&srq->mutex);
+
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "[Failed to handle srq arm, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int roce5_cmd_srq_query(struct roce5_device *rdev, struct roce5_srq *srq,
+ u32 *srq_limit)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_srq_query_s *srq_query_inbuf = NULL;
+ roce_uni_cmd_srq_query_outbuf_s *srq_query_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_srq_query_s), &cqm_cmd_outbuf,
+ (u16)sizeof(roce_uni_cmd_srq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ srq_query_inbuf = (roce_uni_cmd_srq_query_s *)cqm_cmd_inbuf->buf;
+ srq_query_outbuf =
+ (roce_uni_cmd_srq_query_outbuf_s *)cqm_cmd_outbuf->buf;
+ srq_query_inbuf->com.index = cpu_to_be32((u32)srq->srqn);
+ srq_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SRQ_BITMASK));
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_QUERY_SRQ, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, ROCE_CMD_TIME_CLASS_A,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send QUERY_SRQ command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ if ((ret == -ETIMEDOUT) || (ret == -EPERM)) {
+ rdev->dev_status_to_ofed = ROCE_DEV_STATUS_CMDQ_TIMEOUT;
+ }
+
+ ret = -1;
+ goto err_cmd;
+ }
+
+ *srq_limit = be32_to_cpu(srq_query_outbuf->com.srq_limit);
+
+ if (srq->container_flag != 0) {
+ /* parse srqc to get warn_th */
+ u32 warn_th = be32_to_cpu(srq_query_outbuf->com.warn_th);
+ *srq_limit = (warn_th == 0) ? 0 :
+ ((u32)((srq->container_size - 1) *
+ (1U << warn_th)));
+ }
+
+err_cmd:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_query_srq
+ Description : roce5_query_srq
+ Input : struct ib_srq *ibsrq
+ struct ib_srq_attr *srq_attr
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+int roce5_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
+{
+ int ret = 0;
+ u32 limit_water = 0;
+ struct roce5_device *rdev = NULL;
+ struct roce5_srq *rsrq = NULL;
+
+ if ((ibsrq == NULL) || (srq_attr == NULL)) {
+ ROCE_ERR("Ibsrq or srq_attr is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibsrq->device);
+ rsrq = to_roce5_srq(ibsrq);
+
+ ret = roce5_cmd_srq_query(rdev, rsrq, &limit_water);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query srq, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ srq_attr->srq_limit = limit_water;
+ srq_attr->max_wr = roce5_srq_max_avail_wr_set(rsrq);
+ srq_attr->max_sge = (u32)rsrq->max_gs;
+
+ return 0;
+}
+
+static void roce5_srq_hw2sw_config_cqm_cmd(struct roce5_device *rdev,
+ cqm_cmd_buf_s *cqm_cmd_inbuf,
+ struct rdma_service_cap *rdma_cap,
+ struct roce5_srq *srq)
+{
+ roce_uni_cmd_srq_hw2sw_s *srq_hw2sw_inbuf = NULL;
+
+ srq_hw2sw_inbuf = (roce_uni_cmd_srq_hw2sw_s *)cqm_cmd_inbuf->buf;
+ srq_hw2sw_inbuf->com.index = cpu_to_be32((u32)srq->srqn);
+ srq_hw2sw_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SRQ_BITMASK));
+ srq_hw2sw_inbuf->srq_cache.srq_buf_len = cpu_to_be32((u32)srq->buf_sz);
+
+ srq_hw2sw_inbuf->srq_cache.cmtt_cache.mtt_flags = 0;
+ srq_hw2sw_inbuf->srq_cache.cmtt_cache.mtt_num = 0;
+ srq_hw2sw_inbuf->srq_cache.cmtt_cache.mtt_cache_line_start =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_start);
+ srq_hw2sw_inbuf->srq_cache.cmtt_cache.mtt_cache_line_end =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_end);
+ srq_hw2sw_inbuf->srq_cache.wqe_cache_line_size =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.cmtt_cl_sz);
+
+ srq_hw2sw_inbuf->srq_cache.wqe_cache_line_start =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_start);
+ srq_hw2sw_inbuf->srq_cache.wqe_cache_line_end =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_end);
+ srq_hw2sw_inbuf->srq_cache.wqe_cache_line_size =
+ cpu_to_be32(rdma_cap->dev_rdma_cap.roce_own_cap.wqe_cl_sz);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_srq_hw2sw
+ Description : roce5_srq_hw2sw
+ Input : struct roce5_device *rdev
+ struct roce5_srq *srq
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_srq_hw2sw(struct roce5_device *rdev, struct roce5_srq *srq)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ uint16_t inbuf_size = 0;
+
+ if (ROCE5_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2(rdev) != 0) {
+ inbuf_size = sizeof(roce_uni_cmd_srq_hw2sw_s);
+ }
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(rdev->hwdev, &cqm_cmd_inbuf,
+ inbuf_size, NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ if (ROCE5_SUPPORT_IB_CMD_DESTROY_SRQ_MSG_V2(rdev) != 0) {
+ roce5_srq_hw2sw_config_cqm_cmd(rdev, cqm_cmd_inbuf,
+ &rdev->rdma_cap, srq);
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_HW2SW_SRQ, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to send HW2SW_SRQ command, func_id(%d)",
+ rdev->glb_func_id);
+
+ ret = -1;
+
+ if (hinic5_get_chip_present_flag(rdev->hwdev) == 0) {
+ ROCE_DEV_ERR(rdev,
+ "Card not present, return OK, func_id(%d)",
+ rdev->glb_func_id);
+ ret = 0;
+ }
+
+ goto err_out;
+ }
+
+err_out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void roce5_free_srq(struct ib_srq *ibsrq, struct roce5_device *rdev,
+ struct roce5_srq *srq, struct ib_udata *udata)
+{
+ hmm_mtt_free(rdev->hwdev, &srq->mtt, SERVICE_T_ROCE);
+
+ if (ibsrq->uobject) {
+ struct roce5_ucontext *ucontext = roce5_queue_to_ucontext(
+ (void *)ibsrq, udata, ROCE_Q_TYPE_SRQ);
+ roce5_db_unmap_user(ucontext, &srq->db, 0);
+ ib_umem_release(srq->umem);
+ } else {
+ kfree(srq->wrid);
+ }
+
+ cqm5_object_delete(&srq->cqm_srq->object);
+}
+
+int roce5_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
+{
+ int ret = 0;
+ int times = 0;
+ struct roce5_device *rdev = NULL;
+ struct roce5_srq *rsrq = NULL;
+
+ if (ibsrq == NULL) {
+ ROCE_ERR("Ibsrq is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibsrq->device);
+ rsrq = to_roce5_srq(ibsrq);
+ times = rdev->try_times;
+
+ ret = roce5_srq_hw2sw(rdev, rsrq);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to handle srq hw2sw, func_id(%d), ret:%d",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ roce5_free_srq(ibsrq, rdev, rsrq, udata);
+ return 0;
+}
+
+int roce5_destroy_srq_ofa(struct ib_srq *ibsrq)
+{
+ int ret = roce5_destroy_srq(ibsrq, NULL);
+ if (ret == 0) {
+ kfree(ibsrq);
+ }
+
+ return ret;
+}
+
+static int roce5_check_sge_length(const struct ib_recv_wr *wr,
+ struct roce5_device *rdev,
+ const struct ib_recv_wr **bad_wr,
+ struct roce_wqe_srq_data_seg *scat)
+{
+ int i = 0;
+ int ret = 0;
+ u32 data_len = 0;
+
+ for (i = 0; i < wr->num_sge; ++i) {
+ if (ROCE_UNLIKELY(
+ wr->sg_list[i].length >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_msg_sz -
+ 1)) {
+ ret = -EINVAL;
+ *bad_wr = wr;
+ ROCE_DEV_ERR(
+ rdev,
+ "Sge data length is over range, sg_list(%d), length(0x%x), max_msg_sz(0x%x), func_id(%d)",
+ i, wr->sg_list[i].length,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz,
+ rdev->glb_func_id);
+
+ scat[0].dw2.length = 0;
+ scat[0].dw3.lkey = LAST_SGE_NO_PRESENT;
+ scat[0].dw3.lkey = cpu_to_be32(scat[0].dw3.lkey);
+ return ret;
+ }
+
+ data_len += wr->sg_list[i].length;
+ if (ROCE_UNLIKELY(data_len >
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz)) {
+ ret = -EINVAL;
+ *bad_wr = wr;
+ scat[0].dw2.length = 0;
+ scat[0].dw3.lkey = LAST_SGE_NO_PRESENT;
+ scat[0].dw3.lkey = cpu_to_be32(scat[0].dw3.lkey);
+
+ ROCE_DEV_ERR(
+ rdev,
+ "Data length is over range, data_len(0x%x), max_msg_sz(0x%x), func_id(%d)",
+ data_len,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap
+ .max_msg_sz,
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ scat[i].dw2.length = cpu_to_be32(wr->sg_list[i].length);
+ scat[i].dw3.lkey =
+ cpu_to_be32((u32)(wr->sg_list[i].lkey &
+ NORMAL_FMT_AND_NEXT_SGE_PRESENT));
+ scat[i].addr = cpu_to_be64(wr->sg_list[i].addr);
+ }
+
+ if (ROCE_UNLIKELY(i == 0)) {
+ scat[0].dw3.lkey = LAST_SGE_NO_PRESENT;
+ scat[0].dw3.lkey = cpu_to_be32(scat[0].dw3.lkey);
+ scat[0].dw2.length = 0;
+ } else {
+ scat[i - 1].dw3.lkey = cpu_to_be32(
+ (u32)((wr->sg_list[i - 1].lkey | LAST_SGE_NO_PRESENT) &
+ NORMAL_FMT_AND_LAST_SGE_NO_PRESENT));
+ }
+
+ return ret;
+}
+
+static int roce5_post_srq_recv_precheck(struct ib_srq *ibsrq,
+ const struct ib_recv_wr **bad_wr)
+{
+ if (ibsrq == NULL) {
+ ROCE_ERR("Ibsrq is null");
+ return -EINVAL;
+ }
+
+ if (bad_wr == NULL) {
+ ROCE_ERR("Bad_wr is null");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int roce5_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
+ const struct ib_recv_wr **bad_wr)
+{
+ int ret = 0;
+ int nreq = 0;
+ unsigned long flags = 0; /* type required by kernel API */
+ struct roce5_srq *srq = NULL;
+ struct roce5_device *rdev = NULL;
+ struct roce5_wqe_srq_next_seg *next = NULL;
+ struct roce_wqe_srq_data_seg *scat = NULL;
+ const struct ib_recv_wr *wr_tmp = wr;
+
+ ret = roce5_post_srq_recv_precheck(ibsrq, bad_wr);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+
+ srq = to_roce5_srq(ibsrq);
+ rdev = to_roce5_dev(ibsrq->device);
+
+ spin_lock_irqsave(&srq->lock, flags);
+
+ for (nreq = 0; wr_tmp; ++nreq, wr_tmp = wr_tmp->next) {
+ if (ROCE_UNLIKELY((wr_tmp->num_sge > srq->max_gs) ||
+ (srq->head == srq->tail))) {
+ ret = (wr_tmp->num_sge > srq->max_gs) ? (-EINVAL) :
+ (-ENOMEM);
+ *bad_wr = wr_tmp;
+ ROCE_DEV_ERR(
+ rdev,
+ "Num_sge(%d) > max_gs(%d) or srq is empty(head(%d) == tail(%d)), func_id(%d)",
+ wr_tmp->num_sge, srq->max_gs, rdev->glb_func_id,
+ srq->head, srq->tail);
+ break;
+ }
+
+ next = (struct roce5_wqe_srq_next_seg *)roce5_srq_get_wqe(
+ srq, srq->head);
+ scat = (struct roce_wqe_srq_data_seg *)(next + 1);
+
+ ret = roce5_check_sge_length(wr_tmp, rdev, bad_wr, scat);
+ if (ret != 0) {
+ goto sge_len_err;
+ }
+
+ next->pcnt = (u16)cpu_to_be16(srq->wqe_ctr + (u16)nreq);
+ srq->wrid[srq->head] = wr_tmp->wr_id;
+ srq->head = be16_to_cpu(next->next_wqe_index);
+ }
+
+sge_len_err:
+ if (ROCE_UNLIKELY(nreq != 0)) {
+ srq->wqe_ctr += (u16)nreq;
+
+ /*
+ * Make sure that descriptors are written before
+ * doorbell record.
+ */
+ wmb();
+
+ *srq->db.db_record = cpu_to_be32(srq->wqe_ctr);
+ }
+
+ spin_unlock_irqrestore(&srq->lock, flags);
+
+ return ret;
+}
+
+int roce5_post_srq_recv_ofa(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ return roce5_post_srq_recv(ibsrq, (const struct ib_recv_wr *)wr,
+ (const struct ib_recv_wr **)bad_wr);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_format.h b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_format.h
new file mode 100644
index 000000000..12d501b4c
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/srq/roce_srq_format.h
@@ -0,0 +1,36 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_SRQ_FORMAT_H
+#define ROCE_SRQ_FORMAT_H
+
+#include <linux/types.h>
+
+typedef struct roce5_srq_context {
+ /* DW0 */
+ union {
+ struct {
+ u32 size : 5;
+ u32 page_size : 4;
+ u32 wqebb_size : 3;
+ u32 rsvd : 2;
+ u32 pdn : 18;
+ } bs;
+ u32 value;
+ } dw0;
+
+ /* DW1 */
+ union {
+ struct {
+ u32 rsvd : 24;
+ u32 dma_attr_idx : 6;
+ u32 so_ro : 2;
+ } bs_c;
+ u32 value;
+ } dw1;
+
+ u32 rsvd[14];
+} roce5_srq_context_s;
+
+#endif /* ROCE_SRQ_FORMAT_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_api.c b/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_api.c
new file mode 100644
index 000000000..e66a99f39
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_api.c
@@ -0,0 +1,729 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "comm_defs.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_bond.h"
+#include "roce_uld_inner.h"
+#include "roce_mpu_cmd.h"
+#include "roce_cqm_cmd.h"
+
+#define PLUGIN __attribute__((__used__, __weak__, optimize("O0")))
+#define ROCE_ULD_PRINT_BUF_SIZE 256
+
+PLUGIN int roce5_uld_reg_user_mr(roce_uld_handle handle)
+{
+ return -1;
+}
+
+PLUGIN int roce5_uld_dereg_user_mr(roce_uld_handle handle)
+{
+ return 0;
+}
+
+PLUGIN int roce5_adm_dfx_uld_extend(roce_uld_handle handle, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ return 0;
+}
+
+PLUGIN int roce5_uld_qp_modify(roce_uld_handle handle, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+{
+ return 0;
+}
+
+PLUGIN void roce5_uld_rdev_remove(roce_uld_handle handle)
+{
+ return;
+}
+
+PLUGIN int roce5_uld_rdev_add(roce_uld_handle handle)
+{
+ return 0;
+}
+
+PLUGIN int roce5_uld_qp_destroy(roce_uld_handle handle)
+{
+ return 0;
+}
+
+PLUGIN int roce5_uld_qp_create(roce_uld_handle handle)
+{
+ return 0;
+}
+
+PLUGIN int roce5_uld_cq_create(roce_uld_handle handle)
+{
+ return 0;
+}
+
+PLUGIN void roce5_uld_cq_destroy(roce_uld_handle handle)
+{
+ return;
+}
+
+PLUGIN int32_t roce5_uld_user2kernel_msg_handle(roce_uld_handle handle,
+ void *buf_in, u16 buf_in_len,
+ void *buf_out, u16 buf_out_len,
+ u16 *buf_out_size)
+{
+ return 0;
+}
+
+PLUGIN int roce5_uld_service_init(void)
+{
+ return 0;
+}
+
+PLUGIN void roce5_uld_service_exit(void)
+{
+ return;
+}
+
+u64 roce5_mr_virt_addr_get(roce_uld_handle handle)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return 0;
+ }
+
+ return hdl->virt_addr;
+}
+
+int roce5_mr_virt_addr_set(roce_uld_handle handle, u64 virt_addr)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return -EINVAL;
+ }
+
+ hdl->virt_addr = virt_addr;
+
+ return 0;
+}
+
+int roce5_mr_user_data_get(roce_uld_handle handle, u8 *user_data,
+ u32 user_data_len)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ u32 cpy_len;
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ ROCE_ERR("handle is invalid");
+ return -EINVAL;
+ }
+
+ if (user_data == NULL) {
+ ROCE_ERR("user_data is NULL");
+ return -EINVAL;
+ }
+
+ cpy_len = (user_data_len > hdl->mr->user_data_len) ?
+ hdl->mr->user_data_len :
+ user_data_len;
+ (void)memcpy_s(user_data, user_data_len, hdl->mr->rdmamr.user_data,
+ cpy_len);
+
+ return cpy_len;
+}
+
+int roce5_mpt_alloc_and_init(roce_uld_handle handle, int mode, u8 *user_data,
+ u32 user_data_len, u32 mpt_xid_mode)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ struct roce5_mr *mr = NULL;
+ struct roce5_device *rdev = NULL;
+ int ret = 0;
+ u32 npages = 0;
+ u32 page_shift = PAGE_SHIFT;
+ u32 mpt_xid_create_mode;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return -EINVAL;
+ }
+
+ mr = hdl->mr;
+ rdev = hdl->rdev;
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is NULL");
+ return -EINVAL;
+ }
+
+ if (user_data_len > HMM_USER_DATA_MAX_BYTE) {
+ ROCE_ERR(
+ "user_data_len(%u) is invalid, max user_data_len is %u",
+ user_data_len, HMM_USER_DATA_MAX_BYTE);
+ return -EINVAL;
+ }
+
+ if (mode == ROCE_ULD_MPT_NORMAL) {
+ mr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+ npages = (u32)ib_umem_num_pages(mr->umem);
+#if defined(UMEM_HAVE_PAGE_SHIFT)
+ page_shift = (u32)(mr->umem->page_shift);
+#endif
+ }
+
+ mpt_xid_create_mode = CQM_DYNAMIC_XID_MOD(
+ CQM_XID_SEARCH_ALL, CQM_XID_LOW_BIT_0_0_1, mpt_xid_mode);
+ ret = roce5_alloc_tpt(rdev, &mr->rdmamr, npages, page_shift,
+ mpt_xid_create_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc mpt and mtt, func_id(%d), npages(%u), page_shift(%u)",
+ hinic5_global_func_id(rdev->hwdev), npages, page_shift);
+ goto err_alloc_tpt;
+ }
+
+ roce5_set_rdma_mr(&mr->rdmamr, RDMA_USER_MR, hdl->pdn, hdl->virt_addr,
+ hdl->length, hdl->access);
+
+ if (mode == ROCE_ULD_MPT_NORMAL) {
+ ret = roce5_umem_write_mtt(rdev, &mr->rdmamr.mtt, mr->umem, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to write mtt, func_id(%d)",
+ hinic5_global_func_id(rdev->hwdev));
+ goto err_write_mtt;
+ }
+ }
+
+ if (user_data != NULL) {
+ (void)memcpy_s(hdl->mr->rdmamr.user_data, user_data_len,
+ user_data, user_data_len);
+ hdl->mr->user_data_len = user_data_len;
+ } else {
+ hdl->mr->user_data_len = 0;
+ }
+
+ return 0;
+
+err_write_mtt:
+ roce5_free_tpt(rdev, &mr->rdmamr);
+
+err_alloc_tpt:
+ return ret;
+}
+
+void roce5_mpt_destroy(roce_uld_handle handle)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ struct roce5_device *rdev = NULL;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return;
+ }
+
+ if (hdl->mr == NULL) {
+ ROCE_ERR("mr is NULL");
+ return;
+ }
+
+ rdev = hdl->rdev;
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is NULL");
+ return;
+ }
+
+ if (hdl->mr->rdmamr.enabled != RDMA_MPT_DISABLED) {
+ roce5_free_tpt(rdev, &hdl->mr->rdmamr);
+ }
+
+ return;
+}
+
+int roce5_mpt_enable(roce_uld_handle handle)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ struct roce5_device *rdev = NULL;
+ int ret;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return -EINVAL;
+ }
+
+ rdev = hdl->rdev;
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is NULL");
+ return -EINVAL;
+ }
+
+ /* here hmm will userdata send to npu */
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, &hdl->mr->rdmamr,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to enable mpt of user mr, func_id(%d)",
+ hinic5_global_func_id(rdev->hwdev));
+ }
+
+ return ret;
+}
+
+int roce5_uld_get_func_id(roce_uld_handle handle)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) {
+ ROCE_ERR("handle is invalid");
+ return -1;
+ }
+
+ if (hdl->rdev == NULL) {
+ ROCE_ERR("rdev is NULL");
+ return -1;
+ }
+
+ return (int)hdl->rdev->glb_func_id;
+}
+
+int roce5_uld_send_msg_to_mgmt(roce_uld_handle handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((cmd < ROCE_MPU_CMD_ULP_START) || (cmd >= ROCE_MPU_CMD_MAX)) {
+ ROCE_ERR("cmd is invalid");
+ return -1;
+ }
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->rdev == NULL) || (buf_in == NULL) || (buf_out == NULL) ||
+ (out_size == NULL)) {
+ ROCE_ERR(
+ "handle is invalid, or buf_in(%d), buf_out(%d), out_size(%d) is invalid",
+ (buf_in == NULL), (buf_out == NULL),
+ (out_size == NULL));
+ return -1;
+ }
+
+ return hinic5_msg_to_mgmt_sync(hdl->rdev->hwdev, HINIC5_MOD_ROCE, cmd,
+ buf_in, in_size, buf_out, out_size, 0,
+ HINIC5_CHANNEL_ROCE);
+}
+
+int roce5_uld_get_qp_info(roce_uld_handle handle, roce_uld_qp_info *qp_info)
+{
+ struct roce5_qp *rqp = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->rqp == NULL) || (qp_info == NULL)) {
+ ROCE_ERR("param invalid");
+ return -1;
+ }
+
+ rqp = (struct roce5_qp *)hdl->rqp;
+ qp_info->qpn = rqp->qpn;
+ qp_info->qp_type = rqp->qp_type;
+ if (hdl->qp_attr != NULL) {
+ qp_info->dgid = (u8 *)&hdl->qp_attr->path_info.dgid[0];
+ }
+ return 0;
+}
+
+int roce5_uld_modify_qp_tx_bond_hash(roce_uld_handle handle, u32 tx_bond_hash)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->qp_attr == NULL)) {
+ ROCE_ERR("param invalid");
+ return -1;
+ }
+
+ hdl->qp_attr->path_info.dw0.bs.bond_tx_hash_value = tx_bond_hash & 0xf;
+ return 0;
+}
+
+u8 *roce5_get_rdev_uld_def(roce_uld_handle handle)
+{
+ struct roce5_device *rdev = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rdev = hdl->rdev;
+ if ((rdev == NULL) || (rdev->rdev_magic != ROCE_DEVICE_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rdev == NULL) ? ROCE_MAGIC_NULL : rdev->rdev_magic);
+ return NULL;
+ }
+ return (u8 *)&rdev->uld_def.self_def[0];
+}
+
+void *roce5_uld_get_rdev_hwdev(roce_uld_handle handle)
+{
+ struct roce5_device *rdev = NULL;
+ void *hwdev = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rdev = hdl->rdev;
+ if ((rdev == NULL) || (rdev->rdev_magic != ROCE_DEVICE_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rdev == NULL) ? ROCE_MAGIC_NULL : rdev->rdev_magic);
+ return NULL;
+ }
+ hwdev = hdl->rdev->hwdev;
+ if (hwdev == NULL) {
+ ROCE_ERR("handle is invalid, hwdev is NULL");
+ return NULL;
+ }
+ return hwdev;
+}
+
+struct ib_device *roce5_uld_get_rdev_ibdev(roce_uld_handle handle)
+{
+ struct roce5_device *rdev = NULL;
+ struct ib_device *ib_dev = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rdev = hdl->rdev;
+ if ((rdev == NULL) || (rdev->rdev_magic != ROCE_DEVICE_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rdev == NULL) ? ROCE_MAGIC_NULL : rdev->rdev_magic);
+ return NULL;
+ }
+ ib_dev = &(hdl->rdev->ib_dev);
+ return ib_dev;
+}
+
+struct hinic5_lld_dev *roce5_uld_get_rdev_lld_dev(roce_uld_handle handle)
+{
+ struct roce5_device *rdev = NULL;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rdev = hdl->rdev;
+ if ((rdev == NULL) || (rdev->rdev_magic != ROCE_DEVICE_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rdev == NULL) ? ROCE_MAGIC_NULL : rdev->rdev_magic);
+ return NULL;
+ }
+ lld_dev = hdl->rdev->lld_dev;
+ if (lld_dev == NULL) {
+ ROCE_ERR("handle is invalid, lld_dev is NULL");
+ return NULL;
+ }
+ return lld_dev;
+}
+
+#ifdef ROCE_BONDING_EN
+int roce5_uld_get_rdev_bond_dev_slave_cnt(roce_uld_handle handle,
+ u32 *slave_cnt, uint8_t *bond_en)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_bond_device *bond_dev = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (slave_cnt == NULL) || (bond_en == NULL)) {
+ return -EINVAL;
+ }
+ rdev = hdl->rdev;
+ if ((rdev == NULL) || (rdev->rdev_magic != ROCE_DEVICE_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rdev == NULL) ? ROCE_MAGIC_NULL : rdev->rdev_magic);
+ return -EINVAL;
+ }
+ bond_dev = rdev->bond_dev;
+ if (bond_dev == NULL) {
+ *slave_cnt = 0;
+ *bond_en = 0;
+ return 0;
+ }
+ *slave_cnt = hdl->rdev->bond_dev->slave_cnt;
+ *bond_en = 1;
+ return 0;
+}
+#endif
+
+u8 *roce5_get_rqp_uld_def(roce_uld_handle handle)
+{
+ struct roce5_qp *rqp = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rqp = (struct roce5_qp *)hdl->rqp;
+ if ((rqp == NULL) || (rqp->rqp_magic != ROCE_RQP_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rqp == NULL) ? ROCE_MAGIC_NULL : rqp->rqp_magic);
+ return NULL;
+ }
+ return (u8 *)&rqp->uld_def.uld_def[0];
+}
+
+u8 *roce5_get_rcq_uld_def(roce_uld_handle handle)
+{
+ struct roce5_cq *rcq = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ return NULL;
+ }
+
+ rcq = (struct roce5_cq *)hdl->rcq;
+ if ((rcq == NULL) || (rcq->rcq_magic != ROCE_RCQ_MAGIC)) {
+ ROCE_ERR("handle is invalid, magic:0x%x",
+ (rcq == NULL) ? ROCE_MAGIC_NULL : rcq->rcq_magic);
+ return NULL;
+ }
+ return (u8 *)&rcq->uld_def.uld_def[0];
+}
+
+int roce5_uld_cos_set(roce_uld_handle handle, struct ib_qp_attr *attr, u8 type,
+ u8 value)
+{
+ u8 cos;
+ roce5_get_cos_inbuf_s inbuf = { 0 };
+ struct roce5_qp *rqp = NULL;
+ roce_verbs_qp_attr_s *qp_attr = NULL;
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ int ret;
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->rqp == NULL) || (hdl->qp_attr == NULL) ||
+ (hdl->rdev == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ rqp = hdl->rqp;
+ qp_attr = hdl->qp_attr;
+
+ if (type == ROCE5_COS_SET_TYPE_CLASS) {
+ inbuf.sl = attr->ah_attr.sl;
+ inbuf.sgid_index = attr->ah_attr.grh.sgid_index;
+ inbuf.port_num = attr->ah_attr.port_num;
+ inbuf.traffic_class = value;
+
+ ret = roce5_get_dcb_cfg_cos(hdl->rdev, &inbuf, &cos,
+ rqp->qp_type);
+ if (ret != 0) {
+ ROCE_ERR("get dcb cfg cos failed");
+ return ret;
+ }
+
+ /* update tclass and cos */
+ qp_attr->path_info.dw6.bs.tclass = value;
+ qp_attr->com_info.dw5.bs.cos = cos;
+ rqp->db_cos = cos;
+ } else if (type == ROCE5_COS_SET_TYPE_COS) {
+ if (value > 7) { /* cos range is 0-7 */
+ ROCE_ERR("invalid cos(%u)", value);
+ return -EINVAL;
+ }
+ qp_attr->com_info.dw5.bs.cos = value;
+ rqp->db_cos = value;
+ } else {
+ ROCE_ERR("set type(%u) invalid", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int roce5_support_uld_kernel_feature(roce_uld_handle handle, u64 feature)
+{
+ roce_user_handle_t *user_handle = (roce_user_handle_t *)handle;
+ struct roce5_device *rdev = NULL;
+
+ if ((!user_handle) ||
+ (user_handle->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ ROCE_ERR("Invalid RoCE handle\n");
+ return -EINVAL;
+ }
+
+ rdev = user_handle->rdev;
+
+ if (rdev == NULL) {
+ ROCE_ERR("rdev is NULL in handle\n");
+ return -EINVAL;
+ }
+
+ //return capability bit AND result
+ return (rdev)->cfg_info.feature_cap.uld_feature
+ .roce_uld_kernel_ext_ability &
+ feature;
+}
+
+int roce5_uld_set_mpt_xid_mode(roce_uld_handle handle, u8 mode)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ struct roce5_device *rdev = NULL;
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->rdev == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ rdev = hdl->rdev;
+ rdev->mpt_xid_mode = mode;
+
+ return 0;
+}
+
+int roce5_uld_get_dgid(roce_uld_handle handle, u8 **dgid)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->qp_attr == NULL) || (dgid == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+ *dgid = hdl->qp_attr->path_info.dgid;
+ return 0;
+}
+
+int roce5_uld_set_bond_tx_hash_value(roce_uld_handle handle,
+ u32 bond_tx_hash_value)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->qp_attr == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ hdl->qp_attr->path_info.dw0.bs.bond_tx_hash_value = bond_tx_hash_value;
+ return 0;
+}
+
+int roce5_uld_get_mr_uld_self_def(roce_uld_handle handle, u8 **self_def,
+ u32 *self_def_len)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM) ||
+ (hdl->mr == NULL) || (self_def == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *self_def = &hdl->mr->uld_def.self_def[0];
+ if (self_def_len != NULL) {
+ *self_def_len = ROCE_MR_ULD_DEF_LEN;
+ }
+ return 0;
+}
+
+int roce5_uld_get_rdmamr(roce_uld_handle handle, struct hmm_rdma **rdmamr_ptr)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->mr == NULL) || (rdmamr_ptr == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *rdmamr_ptr = &(hdl->mr->rdmamr);
+ return 0;
+}
+
+int roce5_uld_set_qp_attr_ack_to(roce_uld_handle handle, u32 ack_to)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->qp_attr == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ hdl->qp_attr->com_info.dw2.bs.ack_to = ack_to;
+ return 0;
+}
+
+int roce5_uld_get_qp_state(roce_uld_handle handle, u8 *out_qp_state)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->rqp == NULL) || (out_qp_state == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *out_qp_state = hdl->rqp->qp_state;
+ return 0;
+}
+
+int roce5_uld_get_config_num_ports(roce_uld_handle handle,
+ int *out_cfg_num_ports)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (hdl->rdev == NULL) ||
+ (out_cfg_num_ports == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *out_cfg_num_ports = hdl->rdev->hw_info.config_num_ports;
+ return 0;
+}
+
+int roce5_uld_get_handle_length(roce_uld_handle handle, u64 *length)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+
+ if ((hdl == NULL) || (length == NULL)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *length = hdl->length;
+ return 0;
+}
+
+void roce5_uld_print_kernel_err_impl(roce_uld_handle handle, const char *func,
+ int line, const char *fmt, ...)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ va_list args;
+ char buf[ROCE_ULD_PRINT_BUF_SIZE];
+
+ va_start(args, fmt);
+ if (vsnprintf(buf, sizeof(buf), fmt, args) < 0) {
+ va_end(args);
+ return;
+ }
+ va_end(args);
+
+ if ((hdl != NULL) && (hdl->magic == ROCE_ULD_HANDLE_MAGIC_NUM) &&
+ (hdl->rdev != NULL)) {
+ ROCE_DEV_ERR(hdl->rdev, "[ULP][%s,%d]%s", func, line, buf);
+ } else {
+ ROCE_ERR("[ULP][%s,%d]%s", func, line, buf);
+ }
+}
+
+int roce5_uld_qp_get_port(roce_uld_handle handle, u8 *port)
+{
+ roce_user_handle_t *hdl = (roce_user_handle_t *)handle;
+ if ((hdl == NULL) || (hdl->rqp == NULL) || (port == NULL) ||
+ (hdl->magic != ROCE_ULD_HANDLE_MAGIC_NUM)) {
+ ROCE_ERR("param invalid");
+ return -EINVAL;
+ }
+
+ *port = hdl->rqp->port;
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_inner.h b/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_inner.h
new file mode 100644
index 000000000..e61160c2f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/uld/roce_uld_inner.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef ROCE_ULD_INNER_H
+#define ROCE_ULD_INNER_H
+
+#include "roce.h"
+#include "roce_mr.h"
+#include "roce_qp.h"
+#include "roce_cq.h"
+#include "hmm_common.h"
+#include "roce_npu_cmd_mr_defs.h"
+#include "roce_npu_cmd_qp_defs.h"
+
+#define ROCE_ULD_HANDLE_MAGIC_NUM 0x524F4345 /* "ROCE" string of ascii code */
+#define ROCE_MAGIC_NULL 0x12345678 /* used to distinguish null pointer and unassigned */
+
+typedef struct {
+ u32 magic; /* magic number, determine handle whether valid */
+ struct roce5_device *rdev;
+ struct roce5_mr *mr;
+ roce_verbs_mr_attr_s *mr_attr;
+ u64 virt_addr;
+ u64 length;
+ u32 pdn;
+ int access;
+
+ struct roce5_qp *rqp;
+ roce_verbs_qp_attr_s *qp_attr;
+
+ struct roce5_cq *rcq;
+ int cqe;
+
+ struct ib_udata *udata;
+ struct mtt *
+ mtt; /* hmm module of mtt management structure, shadow scenario page_shift and paddr mandatory, mtt_layers constraint is 0 */
+ dma_addr_t *db_dma_handle; /* software db of dma address */
+
+ u8 *shadow;
+ u32 *shadow_vfid;
+ u16 *shadow_vf_num;
+} roce_user_handle_t;
+
+#define ROCE_CONSTUCT_ULD_HDL_RQP(hdl, roce_dev, roce_qp, roce_qp_attr, \
+ roce_udata, roce_mtt, roce_db_dma_handle) \
+ do { \
+ (hdl)->magic = ROCE_ULD_HANDLE_MAGIC_NUM; \
+ (hdl)->rdev = (roce_dev); \
+ (hdl)->rqp = (roce_qp); \
+ (hdl)->qp_attr = (roce_qp_attr); \
+ (hdl)->udata = (roce_udata); \
+ (hdl)->mtt = (roce_mtt); \
+ (hdl)->db_dma_handle = (roce_db_dma_handle); \
+ } while (0)
+
+#define ROCE_CONSTUCT_ULD_HDL_RCQ(hdl, roce_dev, roce_cq, roce_udata, \
+ roce_mtt, roce_db_dma_handle, roce_cqe) \
+ do { \
+ (hdl)->magic = ROCE_ULD_HANDLE_MAGIC_NUM; \
+ (hdl)->rdev = (roce_dev); \
+ (hdl)->rcq = (roce_cq); \
+ (hdl)->udata = (roce_udata); \
+ (hdl)->mtt = (roce_mtt); \
+ (hdl)->db_dma_handle = (roce_db_dma_handle); \
+ (hdl)->cqe = (roce_cqe); \
+ } while (0)
+
+#define ROCE_CONSTUCT_ULD_HDL_SHADOW(hdl, roce_shadow, roce_shadow_vfid, \
+ roce_shadow_vf_num) \
+ do { \
+ (hdl)->shadow = (roce_shadow); \
+ (hdl)->shadow_vfid = (roce_shadow_vfid); \
+ (hdl)->shadow_vf_num = (roce_shadow_vf_num); \
+ } while (0)
+
+#endif
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.c b/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.c
new file mode 100644
index 000000000..7530a655b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.c
@@ -0,0 +1,169 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/slab.h>
+
+#include "roce.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "roce_xrc.h"
+
+static int roce5_rdma_xrcd_alloc(void *hwdev, u32 *xrcdn)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if ((hwdev == NULL) || (xrcdn == NULL)) {
+ ROCE_ERR("Hwdev or xrcdn is null");
+ return -EINVAL;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -EINVAL;
+ }
+
+ *xrcdn = rdma_bitmap_alloc(&comp_priv->xrcd_bitmap);
+ if (*xrcdn == RDMA_INVALID_INDEX) {
+ ROCE_ERR("Can't get valid xrcdn, err(%d)", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void roce5_rdma_xrcd_free(void *hwdev, u32 xrcdn)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return;
+ }
+
+ rdma_bitmap_free(&comp_priv->xrcd_bitmap, xrcdn);
+}
+
+static int roce5_init_xrcd(struct ib_device *ibdev, struct roce5_device *rdev,
+ struct roce5_xrcd *xrcd)
+{
+ int ret = 0;
+ struct ib_cq_init_attr cq_attr = { 0 };
+
+ ret = roce5_rdma_xrcd_alloc(rdev->hwdev, &xrcd->xrcdn);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma xrcd, ret(%d)", ret);
+ goto err_alloc_xrcdn;
+ }
+
+ xrcd->pd = ib_alloc_pd(ibdev, 0);
+
+ if (IS_ERR(xrcd->pd)) {
+ ret = (int)PTR_ERR(xrcd->pd);
+ ROCE_DEV_ERR(rdev, "Failed to alloc pd, ret(%d)", ret);
+ goto err_alloc_pd;
+ }
+
+ cq_attr.cqe = 1;
+ xrcd->cq = ib_create_cq(ibdev, NULL, NULL, xrcd, &cq_attr);
+ if (IS_ERR(xrcd->cq)) {
+ ret = (int)PTR_ERR(xrcd->cq);
+ ROCE_DEV_ERR(rdev, "Failed to create cq, ret(%d)", ret);
+ goto err_create_cq;
+ }
+ return 0;
+
+err_create_cq:
+ ib_dealloc_pd(xrcd->pd);
+
+err_alloc_pd:
+ roce5_rdma_xrcd_free(rdev->hwdev, xrcd->xrcdn);
+
+err_alloc_xrcdn:
+ return ret;
+}
+
+int roce5_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_xrcd *xrcd = NULL;
+
+ if (ibxrcd == NULL) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ rdev = to_roce5_dev(ibxrcd->device);
+ xrcd = to_roce5_xrcd(ibxrcd);
+
+ return roce5_init_xrcd(ibxrcd->device, rdev, xrcd);
+}
+
+struct ib_xrcd *roce5_alloc_xrcd_ofa(struct ib_device *ibdev,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_device *rdev = NULL;
+ struct roce5_xrcd *xrcd = NULL;
+
+ if (ibdev == NULL) {
+ ROCE_ERR("Ibdev is null");
+ return ERR_PTR(-EINVAL);
+ }
+
+ rdev = to_roce5_dev(ibdev);
+
+ xrcd = (struct roce5_xrcd *)kzalloc(sizeof(*xrcd), GFP_KERNEL);
+ if (xrcd == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc memory for xrcd");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Unreasonable, but for code reuse, driver associate the OFED resource in advance. */
+ xrcd->ibxrcd.device = ibdev;
+
+ ret = roce5_alloc_xrcd(&xrcd->ibxrcd, NULL);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init xrcd, ret(%d)", ret);
+ kfree(xrcd);
+ return ERR_PTR(ret);
+ }
+ return &xrcd->ibxrcd;
+}
+
+int roce5_dealloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
+{
+ struct roce5_device *rdev = NULL;
+ struct roce5_xrcd *xrcd = NULL;
+ if (ibxrcd == NULL) {
+ ROCE_ERR("Ibxrcd is null");
+ return -EINVAL;
+ }
+
+ rdev = to_roce5_dev(ibxrcd->device);
+ xrcd = to_roce5_xrcd(ibxrcd);
+ ib_destroy_cq(xrcd->cq);
+
+ ib_dealloc_pd(xrcd->pd);
+ roce5_rdma_xrcd_free(rdev->hwdev, xrcd->xrcdn);
+ return 0;
+}
+
+int roce5_dealloc_xrcd_ofa(struct ib_xrcd *ibxrcd)
+{
+ struct roce5_xrcd *xrcd = to_roce5_xrcd(ibxrcd);
+ int ret = roce5_dealloc_xrcd(ibxrcd, NULL);
+ if (ret == 0) {
+ kfree(xrcd);
+ }
+
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.h b/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.h
new file mode 100644
index 000000000..1a4e603ab
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/base/xrc/roce_xrc.h
@@ -0,0 +1,17 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_XRC_H
+#define ROCE_XRC_H
+
+#include <rdma/ib_verbs.h>
+
+struct roce5_xrcd {
+ struct ib_xrcd ibxrcd;
+ u32 xrcdn;
+ struct ib_pd *pd;
+ struct ib_cq *cq;
+};
+
+#endif //ROCE_XRC_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.c b/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.c
new file mode 100644
index 000000000..d67dd0844
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.c
@@ -0,0 +1,162 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+#include <rdma/ib_user_verbs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include "roce.h"
+#include "hinic5_lld.h"
+#include "roce_infra.h"
+#include "roce_card.h"
+
+static struct roce5_cards g_roce5_cards[MAX_DPU_CARD_NUM];
+
+void roce5_card_init(u16 idx, u64 card_id)
+{
+ g_roce5_cards[idx].card_status = RUNNING;
+ g_roce5_cards[idx].card_id = card_id;
+ INIT_LIST_HEAD(&g_roce5_cards[idx].rdev_list);
+ mutex_init(&g_roce5_cards[idx].card_mutex);
+}
+
+void roce5_card_deinit(u16 idx)
+{
+ g_roce5_cards[idx].card_status = INVALID;
+ g_roce5_cards[idx].card_id = 0;
+ mutex_destroy(&g_roce5_cards[idx].card_mutex);
+}
+
+int roce5_g_rdev_add(struct roce5_device *rdev)
+{
+ struct roce5_rdev_list_node *rdev_node = NULL;
+ u64 card_id;
+ u16 i;
+
+ if (hinic5_get_chip_node_id(rdev->lld_dev, &card_id) != 0) {
+ ROCE_ERR("Failed to get chip node id, func_id(%d)",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ rdev_node = kzalloc(sizeof(struct roce5_rdev_list_node), GFP_KERNEL);
+ if (rdev_node == NULL) {
+ ROCE_ERR("Failed to alloc memory.");
+ return -ENOMEM;
+ }
+ rdev_node->rdev = rdev;
+
+ for (i = 0; i < MAX_DPU_CARD_NUM; i++) {
+ if (g_roce5_cards[i].card_status == RUNNING &&
+ g_roce5_cards[i].card_id == card_id) {
+ break;
+ }
+ }
+
+ if (i >= MAX_DPU_CARD_NUM) {
+ for (i = 0; i < MAX_DPU_CARD_NUM; i++) {
+ if (g_roce5_cards[i].card_status == INVALID) {
+ roce5_card_init(i, card_id);
+ break;
+ }
+ }
+
+ if (i >= MAX_DPU_CARD_NUM) {
+ ROCE_ERR("Exceeded the MAX_DPU_CARD_NUM:0x%x",
+ MAX_DPU_CARD_NUM);
+ kfree(rdev_node);
+ return -ENOMEM;
+ }
+ }
+
+ mutex_lock(&g_roce5_cards[i].card_mutex);
+ list_add_tail(&rdev_node->node, &g_roce5_cards[i].rdev_list);
+ mutex_unlock(&g_roce5_cards[i].card_mutex);
+ return 0;
+}
+
+void roce5_g_rdev_remove(struct roce5_device *rdev)
+{
+ struct roce5_rdev_list_node *rdev_node = NULL, *rdev_next = NULL;
+ u64 card_id;
+ int i;
+
+ if (hinic5_get_chip_node_id(rdev->lld_dev, &card_id) != 0) {
+ ROCE_ERR("Failed to get chip node id, func_id(%d)",
+ rdev->glb_func_id);
+ return;
+ }
+
+ for (i = 0; i < MAX_DPU_CARD_NUM; i++) {
+ if (g_roce5_cards[i].card_status == RUNNING &&
+ g_roce5_cards[i].card_id == card_id) {
+ break;
+ }
+ }
+
+ if (i < MAX_DPU_CARD_NUM) {
+ mutex_lock(&g_roce5_cards[i].card_mutex);
+ list_for_each_entry_safe(rdev_node, rdev_next,
+ &g_roce5_cards[i].rdev_list, node) {
+ if (rdev_node->rdev == rdev) {
+ list_del(&rdev_node->node);
+ kfree(rdev_node);
+ break;
+ }
+ }
+ mutex_unlock(&g_roce5_cards[i].card_mutex);
+ /* deinit card if rdev list is empty */
+ if (list_empty(&g_roce5_cards[i].rdev_list)) {
+ roce5_card_deinit(i);
+ }
+ }
+}
+
+struct roce5_device *roce5_get_rdev_by_card_func_id(uint64_t card_id,
+ uint16_t func_id)
+{
+ struct roce5_rdev_list_node *rdev_node = NULL;
+ int i;
+
+ for (i = 0; i < MAX_DPU_CARD_NUM; i++) {
+ if (g_roce5_cards[i].card_status == RUNNING &&
+ g_roce5_cards[i].card_id == card_id) {
+ break;
+ }
+ }
+
+ if (i < MAX_DPU_CARD_NUM) {
+ list_for_each_entry(rdev_node, &g_roce5_cards[i].rdev_list,
+ node) {
+ if (rdev_node->rdev->glb_func_id == func_id) {
+ return rdev_node->rdev;
+ }
+ }
+ }
+ return NULL;
+}
+
+struct roce5_device *roce5_get_rdev_by_name(const char *dev_name)
+{
+ struct roce5_rdev_list_node *rdev_node = NULL;
+ int i;
+
+ if (dev_name == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < MAX_DPU_CARD_NUM; i++) {
+ if (g_roce5_cards[i].card_status == INVALID) {
+ continue;
+ }
+
+ list_for_each_entry(rdev_node, &g_roce5_cards[i].rdev_list,
+ node) {
+ if (strncmp(rdev_node->rdev->ib_dev.name, dev_name,
+ IB_DEVICE_NAME_MAX) == 0) {
+ return rdev_node->rdev;
+ }
+ }
+ }
+ return NULL;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.h b/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.h
new file mode 100644
index 000000000..5ceabdd1f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/card/roce_card.h
@@ -0,0 +1,27 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+#ifndef ROCE_CARD_H
+#define ROCE_CARD_H
+
+#include <linux/slab.h>
+#include <linux/list.h>
+
+#include "roce.h"
+
+#define MAX_DPU_CARD_NUM \
+ 1024 //current SDK PCIe on current cannot identifies VM on and bare metal on is same one 张 card, temporary add specification supports start multi VM
+struct roce5_rdev_list_node {
+ struct list_head node;
+ struct roce5_device *rdev;
+};
+
+typedef enum roce5_card_status { INVALID = 0, RUNNING } roce5_card_status_e;
+
+struct roce5_cards {
+ u64 card_id;
+ roce5_card_status_e card_status;
+ struct mutex card_mutex;
+ struct list_head rdev_list;
+};
+#endif /* ROCE_CARD_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.c b/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.c
new file mode 100644
index 000000000..2ad39f97f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.c
@@ -0,0 +1,1270 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/errno.h>
+#include <linux/if_ether.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+
+#include "rdma_comp.h"
+#include "roce5_gid_type.h"
+#include "roce_compat.h"
+#include "roce_com.h"
+#include "roce_cqm_cmd.h"
+#include "roce_mpu_cmd.h"
+#include "roce_ctx_format.h"
+#include "roce_infra.h"
+#include "roce_main_extension.h"
+#include "roce_mix.h"
+#include "roce_npu_cmd.h"
+#include "roce_npu_cmd_ext_defs.h"
+#include "roce_srq_extension.h"
+#include "roce_uld_inner.h"
+#include "roce_uld_kernel_api.h"
+#include "securec.h"
+#include "roce_cmd.h"
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+
+#define OVS_MPU_CMD_QOS_SET_VM_POLICING 30
+#define OVS_MPU_CMD_VPORT_SET 13
+#define OVS_MPU_VPORT_SET_CMD_ATTR 2
+
+uint8_t roce5_srq_mode_chip_adapt(uint8_t cfg_mode)
+{
+ switch (cfg_mode) {
+ case ROCE_CHIP_SRQ_MODE_1:
+ return ROCE_SRQ_MODE_3;
+ case ROCE_CHIP_SRQ_MODE_2:
+ return ROCE_SRQ_MODE_2;
+ case ROCE_CHIP_SRQ_MODE_3:
+ return ROCE_SRQ_MODE_1;
+ case ROCE_CHIP_SRQ_MODE_4:
+ return ROCE_SRQ_MODE_0;
+ default:
+ return ROCE_SRQ_MODE_3;
+ }
+}
+
+int roce5_add_mac_tbl_mac_entry(struct roce5_device *rdev, u8 *mac_addr,
+ size_t mac_addr_len, u32 vlan_id, u16 func_id)
+{
+ void *hwdev = rdev->hwdev;
+ u16 er_fwd_id = rdev->glb_func_id;
+ roce_cfg_mac_cmd_s add_mac_entry_info;
+ u16 out_size = (u16)sizeof(add_mac_entry_info);
+ int ret;
+
+ if (ROCE5_SUPPORT_SML_MAC_TABLE(rdev) == 0) {
+ return 0;
+ }
+
+ if (rdev->hca_vf_mode != 0) {
+ ROCE_INFO("No need to add mac table entry.");
+ return 0;
+ }
+
+ if ((hwdev == NULL) || (mac_addr == NULL)) {
+ ROCE_ERR("Hwdev or mac_addr is null");
+ return -EINVAL;
+ }
+
+ if ((vlan_id & ROCE_VLAN_ID_MASK) >= ROCE_VLAN_N_VID) {
+ ROCE_ERR("Invalid vlan_id(%u)", vlan_id);
+ return -EINVAL;
+ }
+
+ ret = memset_s(&add_mac_entry_info, sizeof(add_mac_entry_info), 0,
+ sizeof(add_mac_entry_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset add_mac_entry_info.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ add_mac_entry_info.func_id = func_id;
+ add_mac_entry_info.vlan_id = vlan_id;
+ add_mac_entry_info.er_fwd_id = er_fwd_id;
+ ret = memcpy_s(add_mac_entry_info.mac, ETH_ALEN, mac_addr, ETH_ALEN);
+ if (ret != 0) {
+ ROCE_ERR("memory copy failed. ret%d", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_ADD_MAC,
+ &add_mac_entry_info,
+ sizeof(add_mac_entry_info),
+ &add_mac_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (add_mac_entry_info.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to add mac entry, err(%d), status(0x%x), out size(0x%x)",
+ ret, add_mac_entry_info.head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int roce5_del_mac_tbl_mac_entry(struct roce5_device *rdev, u8 *mac_addr,
+ size_t mac_addr_len, u32 vlan_id, u16 func_id)
+{
+ void *hwdev = rdev->hwdev;
+ u16 er_fwd_id = rdev->glb_func_id;
+ roce_cfg_mac_cmd_s del_mac_tbl_info;
+ u16 out_size = (u16)sizeof(del_mac_tbl_info);
+ int ret;
+
+ if (ROCE5_SUPPORT_SML_MAC_TABLE(rdev) == 0) {
+ return 0;
+ }
+
+ if (rdev->hca_vf_mode != 0) {
+ ROCE_DEV_INFO(rdev, "No need to delete mac table entry.");
+ return 0;
+ }
+
+ if ((hwdev == NULL) || (mac_addr == NULL)) {
+ ROCE_ERR("Hwdev or mac_addr is null");
+ return -EINVAL;
+ }
+
+ if ((vlan_id & ROCE_VLAN_ID_MASK) >= ROCE_VLAN_N_VID) {
+ ROCE_ERR("Invalid vlan_id(%u)", vlan_id);
+ return -EINVAL;
+ }
+
+ ret = memset_s(&del_mac_tbl_info, sizeof(del_mac_tbl_info), 0,
+ sizeof(del_mac_tbl_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset del_mac_tbl_info.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ del_mac_tbl_info.func_id = func_id;
+ del_mac_tbl_info.vlan_id = vlan_id;
+ del_mac_tbl_info.er_fwd_id = er_fwd_id;
+ ret = memcpy_s(del_mac_tbl_info.mac, mac_addr_len, mac_addr,
+ mac_addr_len);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy_s dmac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_DEL_MAC,
+ &del_mac_tbl_info,
+ sizeof(del_mac_tbl_info),
+ &del_mac_tbl_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (del_mac_tbl_info.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to del mac entry, err(%d), status(0x%x), out size(0x%x)",
+ ret, del_mac_tbl_info.head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void roce5_add_ipsu_tbl_mac_entry(struct roce5_device *rdev,
+ u8 mac_addr[ETH_ALEN], u32 vlan_id,
+ u16 func_id, u8 er_id, u16 src_func_id)
+{
+ void *hwdev = rdev->hwdev;
+ roce_cfg_ipsu_mac_cmd_s ipsu_add_mac_entry_info;
+ u16 out_size = (u16)sizeof(ipsu_add_mac_entry_info);
+ int ret;
+
+ if (rdev->hca_vf_mode != 0) {
+ ROCE_INFO("No need to add ipsu tbl mac entry");
+ return;
+ }
+
+#ifdef ROCE_BONDING_EN
+ if (!roce5_get_bond_ipsurx_en()) {
+ ROCE_ERR("No need to add ipsu tbl mac entry");
+ return;
+ }
+#endif
+
+ if ((hwdev == NULL) || (mac_addr == NULL)) {
+ ROCE_ERR("Hwdev or mac_addr is null");
+ return;
+ }
+
+ if ((vlan_id & ROCE_VLAN_ID_MASK) >= ROCE_VLAN_N_VID) {
+ ROCE_ERR("Invalid vlan_id(%u)", vlan_id);
+ }
+
+ ret = memset_s(&ipsu_add_mac_entry_info,
+ sizeof(ipsu_add_mac_entry_info), 0,
+ sizeof(ipsu_add_mac_entry_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ipsu_add_mac_entry_info.(ret:%d)",
+ ret);
+ return;
+ }
+ ipsu_add_mac_entry_info.func_id = func_id;
+ ipsu_add_mac_entry_info.er_id = er_id;
+ ipsu_add_mac_entry_info.src_func_id = src_func_id;
+ ipsu_add_mac_entry_info.vlanid_vni = vlan_id & ROCE_VLAN_ID_MASK;
+ ipsu_add_mac_entry_info.vni_en = 0;
+ ret = memcpy_s(ipsu_add_mac_entry_info.mac, ETH_ALEN, mac_addr,
+ ETH_ALEN);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to memcpy ipsu_add_mac_entry_info.mac (ret:%d)",
+ ret);
+ return;
+ }
+
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_ADD_IPSU_MAC,
+ &ipsu_add_mac_entry_info,
+ sizeof(ipsu_add_mac_entry_info),
+ &ipsu_add_mac_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_add_mac_entry_info.head.status != 0) &&
+ (ipsu_add_mac_entry_info.head.status != ERR_EXIST))) {
+ ROCE_ERR(
+ "Failed to add mac entry to IPSU, err(%d), status(0x%x), out size(0x%x)",
+ ret, ipsu_add_mac_entry_info.head.status, out_size);
+ return;
+ }
+
+ if (ipsu_add_mac_entry_info.head.status == ERR_EXIST) {
+ ROCE_INFO("This mac entry has been added to IPSU");
+ }
+
+ return;
+}
+
+static int32_t roce5_del_mac_entry_precheck(struct roce5_device *rdev,
+ void *hwdev, uint8_t *mac_addr,
+ uint32_t vlan_id)
+{
+ if (rdev->hca_vf_mode != 0) {
+ ROCE_DEV_INFO(rdev, "No need to del ipsu tbl mac entry.");
+ return -EINVAL;
+ }
+
+ if ((hwdev == NULL) || (mac_addr == NULL)) {
+ ROCE_DEV_ERR(rdev, "hwdev or mac_addr is null.");
+ return -EINVAL;
+ }
+
+#ifdef ROCE_BONDING_EN
+ if (!roce5_get_bond_ipsurx_en()) {
+ ROCE_DEV_INFO(rdev, "No need to del ipsu tbl mac entry.");
+ return -EINVAL;
+ }
+#endif
+
+ if ((vlan_id & ROCE_VLAN_ID_MASK) >= ROCE_VLAN_N_VID) {
+ ROCE_DEV_ERR(rdev, "Invalid vlan_id(%d).", vlan_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void roce5_del_ipsu_tbl_mac_entry(struct roce5_device *rdev,
+ u8 mac_addr[ETH_ALEN], size_t eth_alen,
+ u32 vlan_id, u8 er_id, u16 src_func_id)
+{
+ void *hwdev = rdev->hwdev;
+ u16 func_id = rdev->glb_func_id;
+ roce_cfg_ipsu_mac_cmd_s ipsu_del_mac_entry_info;
+ u16 out_size = (u16)sizeof(ipsu_del_mac_entry_info);
+ int ret;
+
+ ret = roce5_del_mac_entry_precheck(rdev, hwdev, mac_addr, vlan_id);
+ if (ret != 0) {
+ return;
+ }
+
+ ret = memset_s(&ipsu_del_mac_entry_info,
+ sizeof(ipsu_del_mac_entry_info), 0,
+ sizeof(ipsu_del_mac_entry_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ipsu_del_mac_entry_info.(ret:%d)",
+ ret);
+ return;
+ }
+ ipsu_del_mac_entry_info.func_id = func_id;
+ ipsu_del_mac_entry_info.er_id = er_id;
+ ipsu_del_mac_entry_info.src_func_id = src_func_id;
+ ipsu_del_mac_entry_info.vlanid_vni = vlan_id & ROCE_VLAN_ID_MASK;
+ ipsu_del_mac_entry_info.vni_en = 0;
+ ret = memcpy_s(ipsu_del_mac_entry_info.mac, eth_alen, mac_addr,
+ eth_alen);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy_s dmac.(ret:%d)", ret);
+ return;
+ }
+
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_DEL_IPSU_MAC,
+ &ipsu_del_mac_entry_info,
+ sizeof(ipsu_del_mac_entry_info),
+ &ipsu_del_mac_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_del_mac_entry_info.head.status != 0) &&
+ (ipsu_del_mac_entry_info.head.status != ERR_NOT_FOUND))) {
+ ROCE_ERR(
+ "Failed to del mac entry, err(%d), status(0x%x), out size(0x%x)",
+ ret, ipsu_del_mac_entry_info.head.status, out_size);
+ return;
+ }
+
+ if (ipsu_del_mac_entry_info.head.status == ERR_NOT_FOUND) {
+ ROCE_INFO("This mac entry of ipsu has been deleted");
+ }
+
+ return;
+}
+
+int roce5_add_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct roce_cmd_mpu_addr_info *addr_info)
+{
+ roce_cfg_ipsu_ip_cmd_s ipsu_add_ip_entry_info;
+ u16 out_size = sizeof(ipsu_add_ip_entry_info);
+ union roce_addr_info *ip = NULL;
+ int ret;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL) || (addr_info == NULL)) {
+ ROCE_ERR("rdev, hwdev or addr_info is null");
+ return -EINVAL;
+ }
+
+ ip = &addr_info->ip_addr;
+
+ ret = memset_s(&ipsu_add_ip_entry_info, sizeof(ipsu_add_ip_entry_info),
+ 0, sizeof(ipsu_add_ip_entry_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ipsu_add_ip_entry_info.(ret:%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ ipsu_add_ip_entry_info.func_id = rdev->glb_func_id;
+ ipsu_add_ip_entry_info.ip_ver = addr_info->ip_ver;
+ ipsu_add_ip_entry_info.port_id = hinic5_physical_port_id(rdev->hwdev);
+ ret = memcpy_s(&ipsu_add_ip_entry_info.ip, sizeof(union roce_addr_info),
+ ip, sizeof(union roce_addr_info));
+ if (ret) {
+ ROCE_ERR("Failed to memcpy ip info.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ROCE_INFO("funcid=%u,ipver=%u,portid=%u,ip=0x%x-%x-%x-%x",
+ ipsu_add_ip_entry_info.func_id, ipsu_add_ip_entry_info.ip_ver,
+ ipsu_add_ip_entry_info.port_id, ip->dw[0x0], ip->dw[0x1],
+ ip->dw[0x2], ip->dw[0x3]);
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_ADD_IPSU_IP,
+ &ipsu_add_ip_entry_info,
+ sizeof(ipsu_add_ip_entry_info),
+ &ipsu_add_ip_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_add_ip_entry_info.head.status != 0) &&
+ (ipsu_add_ip_entry_info.head.status != ERR_EXIST))) {
+ ROCE_ERR(
+ "Failed to add ip tbl entry to IPSU, err(%d), status(0x%x), out size(0x%x)",
+ ret, ipsu_add_ip_entry_info.head.status, out_size);
+ return -EINVAL;
+ }
+
+ if (ipsu_add_ip_entry_info.head.status == ERR_EXIST) {
+ ROCE_INFO("This ip tbl entry has been added to IPSU");
+ }
+
+ return 0;
+}
+
+int roce5_del_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct roce_cmd_mpu_addr_info *addr_info)
+{
+ roce_cfg_ipsu_ip_cmd_s ipsu_del_ip_entry_info;
+ u16 out_size = sizeof(ipsu_del_ip_entry_info);
+ union roce_addr_info *ip = NULL;
+ int ret;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL) || (addr_info == NULL)) {
+ ROCE_ERR("rdev, hwdev or addr_info is null");
+ return -EINVAL;
+ }
+
+ ip = &addr_info->ip_addr;
+
+ ret = memset_s(&ipsu_del_ip_entry_info, sizeof(ipsu_del_ip_entry_info),
+ 0, sizeof(ipsu_del_ip_entry_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ipsu_add_ip_entry_info.(ret:%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ ipsu_del_ip_entry_info.func_id = rdev->glb_func_id;
+ ipsu_del_ip_entry_info.ip_ver = addr_info->ip_ver;
+ ipsu_del_ip_entry_info.port_id = hinic5_physical_port_id(rdev->hwdev);
+ ret = memcpy_s(&ipsu_del_ip_entry_info.ip, sizeof(union roce_addr_info),
+ ip, sizeof(union roce_addr_info));
+ if (ret) {
+ ROCE_ERR("Failed to memcpy ip info.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ROCE_INFO("funcid=%u,ipver=%u,portid=%u,ip=0x%x-%x-%x-%x",
+ ipsu_del_ip_entry_info.func_id, ipsu_del_ip_entry_info.ip_ver,
+ ipsu_del_ip_entry_info.port_id, ip->dw[0x0], ip->dw[0x1],
+ ip->dw[0x2], ip->dw[0x3]);
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_DEL_IPSU_IP,
+ &ipsu_del_ip_entry_info,
+ sizeof(ipsu_del_ip_entry_info),
+ &ipsu_del_ip_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_del_ip_entry_info.head.status != 0) &&
+ (ipsu_del_ip_entry_info.head.status != ERR_NOT_FOUND))) {
+ ROCE_ERR(
+ "Failed to add ip tbl entry to IPSU, err(%d), status(0x%x), out size(0x%x)",
+ ret, ipsu_del_ip_entry_info.head.status, out_size);
+ return -EINVAL;
+ }
+
+ if (ipsu_del_ip_entry_info.head.status == ERR_NOT_FOUND) {
+ ROCE_INFO("This ip tbl entry of ipsu has been deleted");
+ }
+
+ return 0;
+}
+
+int roce5_modify_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry, u8 type)
+{
+ struct roce_cmd_mpu_addr_info addr_info = { 0 };
+ union roce_addr_info *ip = NULL;
+ int ret;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL) || (gid_entry == NULL)) {
+ ROCE_ERR("rdev, hwdev or gid_entry is null");
+ return -EINVAL;
+ }
+
+ ip = (union roce_addr_info *)&gid_entry->raw;
+
+ if (rdev->hca_vf_mode == 0) {
+ ROCE_INFO("No need to modify ipsu tbl ip entry");
+ return 0;
+ }
+
+ if (gid_entry->dw6_h.bs.gid_type >= ROCE_ROCEv1_GID) {
+ ROCE_ERR("gid_type:%d is unsupported",
+ gid_entry->dw6_h.bs.gid_type);
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(&addr_info.ip_addr, sizeof(union roce_addr_info), ip,
+ sizeof(union roce_addr_info));
+ if (ret) {
+ ROCE_ERR("Failed to memcpy ip info.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ if (gid_entry->dw6_h.bs.gid_type == ROCE_IPv4_ROCEv2_GID) {
+ addr_info.ip_addr.dw[0x0] = 0x0;
+ addr_info.ip_addr.dw[0x1] = 0x0;
+ addr_info.ip_addr.dw[0x2] = 0x0;
+ addr_info.ip_ver = 0;
+ } else {
+ addr_info.ip_ver = 1;
+ }
+
+ if (type == ROCE_MPU_CMD_ADD_IPSU_IP) {
+ return roce5_add_ipsu_tbl_ip_entry(rdev, &addr_info);
+ }
+
+ return roce5_del_ipsu_tbl_ip_entry(rdev, &addr_info);
+}
+
+static int32_t
+roce5_add_ipsu_tcam_tbl_entry_precheck(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ if ((rdev->hwdev == NULL) || (gid_entry == NULL)) {
+ ROCE_DEV_ERR(rdev, "hwdev or gid_entry is null.");
+ return -EINVAL;
+ }
+
+ if (gid_entry->dw6_h.bs.gid_type >= ROCE_ROCEv1_GID) {
+ ROCE_DEV_ERR(rdev, "gid_type:%d is unsupported.",
+ gid_entry->dw6_h.bs.gid_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int32_t roce5_ipsu_tcam_tbl_set_entry(
+ struct roce5_device *rdev, struct rdma_gid_entry *gid_entry,
+ uint32_t gid_index, roce_cfg_ipsu_tcam_cmd_s *ipsu_add_tcam_entry_info)
+{
+ union roce_addr_info *ip = (union roce_addr_info *)&gid_entry->raw;
+ int32_t i;
+ int32_t ret;
+
+ ipsu_add_tcam_entry_info->func_id = rdev->glb_func_id;
+ ipsu_add_tcam_entry_info->ip_ver = gid_entry->dw6_h.bs.gid_type;
+ ipsu_add_tcam_entry_info->gid_idx = gid_index;
+ ret = memcpy_s(&ipsu_add_tcam_entry_info->ip,
+ sizeof(union roce_addr_info), ip,
+ sizeof(union roce_addr_info));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy ip info.(ret:%d).", ret);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 0x4; i++) {
+ ipsu_add_tcam_entry_info->ip.dw[i] =
+ htonl(ipsu_add_tcam_entry_info->ip.dw[i]);
+ }
+
+ if (gid_entry->dw6_h.bs.gid_type == ROCE_IPv4_ROCEv2_GID) {
+ ipsu_add_tcam_entry_info->ip.dw[0x0] = 0x0;
+ ipsu_add_tcam_entry_info->ip.dw[0x1] = 0x0;
+ ipsu_add_tcam_entry_info->ip.dw[0x2] = 0x0;
+ }
+
+ return 0;
+}
+
+void roce5_add_ipsu_tcam_tbl_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry,
+ u32 gid_index)
+{
+ roce_cfg_ipsu_tcam_cmd_s ipsu_add_tcam_entry_info;
+ u16 out_size = sizeof(roce_cfg_ipsu_tcam_cmd_s);
+ int ret;
+
+ ret = roce5_add_ipsu_tcam_tbl_entry_precheck(rdev, gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to precheck params(ret:%d).", ret);
+ return;
+ }
+
+ ret = memset_s(&ipsu_add_tcam_entry_info,
+ sizeof(ipsu_add_tcam_entry_info), 0,
+ sizeof(ipsu_add_tcam_entry_info));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to memset ipsu_tcam_entry_info(ret:%d).",
+ ret);
+ return;
+ }
+
+ ret = roce5_ipsu_tcam_tbl_set_entry(rdev, gid_entry, gid_index,
+ &ipsu_add_tcam_entry_info);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set ipsu_tcam_entry_info(ret:%d).",
+ ret);
+ return;
+ }
+
+ ROCE_DEV_INFO(rdev, "funcid=%u,ipver=%u,gid_idx=%u,ip=0x%x-%x-%x-%x.",
+ ipsu_add_tcam_entry_info.func_id,
+ ipsu_add_tcam_entry_info.ip_ver,
+ ipsu_add_tcam_entry_info.gid_idx,
+ ipsu_add_tcam_entry_info.ip.dw[0x0],
+ ipsu_add_tcam_entry_info.ip.dw[0x1],
+ ipsu_add_tcam_entry_info.ip.dw[0x2],
+ ipsu_add_tcam_entry_info.ip.dw[0x3]);
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_ADD_IPSU_TCAM,
+ &ipsu_add_tcam_entry_info,
+ sizeof(ipsu_add_tcam_entry_info),
+ &ipsu_add_tcam_entry_info, &out_size);
+ if (ipsu_add_tcam_entry_info.head.status == ERR_FULL) {
+ ROCE_DEV_INFO(rdev, "TCAM Table is full.");
+ } else if ((ret == 0) && (out_size != 0) &&
+ (ipsu_add_tcam_entry_info.head.status == ERR_EXIST)) {
+ ROCE_DEV_INFO(rdev, "This tcam entry has been added to IPSU.");
+ } else if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_add_tcam_entry_info.head.status != 0))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to add tcam tbl entry to IPSU, err(%d), status(0x%x), out size(0x%x).",
+ ret, ipsu_add_tcam_entry_info.head.status, out_size);
+ return;
+ }
+
+ return;
+}
+
+static int32_t
+roce5_del_ipsu_tcam_tbl_entry_precheck(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ if ((rdev->hwdev == NULL) || (gid_entry == NULL)) {
+ ROCE_DEV_ERR(rdev, "hwdev or gid_entry is null.");
+ return -EINVAL;
+ }
+
+ if (gid_entry->dw6_h.bs.gid_type >= ROCE_ROCEv1_GID) {
+ ROCE_DEV_ERR(rdev, "gid_type:%d is unsupported",
+ gid_entry->dw6_h.bs.gid_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void roce5_del_ipsu_tcam_tbl_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ roce_cfg_ipsu_tcam_cmd_s ipsu_del_tcam_entry_info;
+ u16 out_size = sizeof(roce_cfg_ipsu_tcam_cmd_s);
+ int ret;
+
+ ret = roce5_del_ipsu_tcam_tbl_entry_precheck(rdev, gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to precheck params(ret:%d).", ret);
+ return;
+ }
+
+ ret = memset_s(&ipsu_del_tcam_entry_info,
+ sizeof(ipsu_del_tcam_entry_info), 0,
+ sizeof(ipsu_del_tcam_entry_info));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to memset ipsu_tcam_entry_info(ret:%d).",
+ ret);
+ return;
+ }
+
+ ret = roce5_ipsu_tcam_tbl_set_entry(rdev, gid_entry, 0,
+ &ipsu_del_tcam_entry_info);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set ipsu_tcam_entry_info(ret:%d).",
+ ret);
+ return;
+ }
+
+ ROCE_DEV_INFO(rdev, "funcid=%u,ipver=%u,gid_idx=%u,ip=0x%x-%x-%x-%x",
+ ipsu_del_tcam_entry_info.func_id,
+ ipsu_del_tcam_entry_info.ip_ver,
+ ipsu_del_tcam_entry_info.gid_idx,
+ ipsu_del_tcam_entry_info.ip.dw[0x0],
+ ipsu_del_tcam_entry_info.ip.dw[0x1],
+ ipsu_del_tcam_entry_info.ip.dw[0x2],
+ ipsu_del_tcam_entry_info.ip.dw[0x3]);
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_DEL_IPSU_TCAM,
+ &ipsu_del_tcam_entry_info,
+ sizeof(ipsu_del_tcam_entry_info),
+ &ipsu_del_tcam_entry_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ ((ipsu_del_tcam_entry_info.head.status != 0) &&
+ (ipsu_del_tcam_entry_info.head.status != ERR_NOT_FOUND))) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to del tcam entry, err(%d), status(0x%x), out size(0x%x).",
+ ret, ipsu_del_tcam_entry_info.head.status, out_size);
+ return;
+ }
+
+ if (ipsu_del_tcam_entry_info.head.status == ERR_NOT_FOUND) {
+ ROCE_DEV_INFO(rdev,
+ "This tcam entry of ipsu has been deleted.");
+ }
+ return;
+}
+
+int roce5_set_sysfs_cfg_param(void *hwdev, u16 func_id, u32 *param,
+ u32 param_len, u16 type)
+{
+ roce_cc_cfg_param_cmd_s cfg_param;
+ u16 out_size = (u16)sizeof(cfg_param);
+ int ret;
+ int param_idx = 0;
+ int param_dw_num;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return -EINVAL;
+ }
+
+ param_dw_num = (int)(param_len / sizeof(u32));
+ if (param_dw_num > ROCE_CC_CFG_PARAM_MAX_DW_NUM) {
+ ROCE_ERR("cfg_param len :%d dw_num:%d exceed max, type:0x%x",
+ param_len, param_dw_num, type);
+ return -EINVAL;
+ }
+
+ ret = memset_s(&cfg_param, sizeof(cfg_param), 0, sizeof(cfg_param));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset cfg_param.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ cfg_param.func_id = func_id;
+ for (; param_idx < param_dw_num; param_idx++) {
+ cfg_param.param[param_idx] = param[param_idx];
+ }
+
+ ret = roce5_msg_to_mgmt_sync(hwdev, type, &cfg_param, sizeof(cfg_param),
+ &cfg_param, &out_size);
+ if ((ret != 0) || (out_size == 0) || (cfg_param.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to cfg param, err(%d), status(0x%x), out size(0x%x), type(0x%x)",
+ ret, cfg_param.head.status, out_size, type);
+
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int roce5_set_func_tbl_func_state(void *hwdev, u8 func_state, u16 func_id)
+{
+ roce_set_func_state_cmd_s set_func_state_info;
+ u16 out_size = (u16)sizeof(set_func_state_info);
+ int ret;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&set_func_state_info, sizeof(set_func_state_info), 0,
+ sizeof(set_func_state_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset set_func_state_info.(ret:%d)", ret);
+ return (-ENOMEM);
+ }
+ set_func_state_info.func_id = func_id;
+ set_func_state_info.func_en = func_state;
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_SET_FUNC_STATE,
+ &set_func_state_info,
+ sizeof(set_func_state_info),
+ &set_func_state_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (set_func_state_info.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set func state(%d), err(%d), status(0x%x), out size(0x%x), func_id(%d)",
+ func_state, ret, set_func_state_info.head.status,
+ out_size, func_id);
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+int roce5_get_func_table(void *hwdev, u16 func_id, u32 *func_tbl_value)
+{
+ roce_get_func_table_cmd_s get_func_table;
+ roce_get_func_table_rsp_s get_func_table_rsp;
+ u16 out_size = (u16)sizeof(get_func_table_rsp);
+ int ret;
+
+ if (hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&get_func_table, sizeof(get_func_table), 0,
+ sizeof(get_func_table));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset get_func_table.(ret:%d)", ret);
+ return (-ENOMEM);
+ }
+ ret = memset_s(&get_func_table_rsp, out_size, 0, out_size);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset get_func_table_rsp.(ret:%d)", ret);
+ return (-ENOMEM);
+ }
+ get_func_table.func_id = func_id;
+ ret = roce5_msg_to_mgmt_sync(hwdev, ROCE_MPU_CMD_GET_FUNC_TABLE,
+ &get_func_table, sizeof(get_func_table),
+ &get_func_table_rsp, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (get_func_table_rsp.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to get func table, err(%d), status(0x%x), out size(0x%x), func_id(%d)",
+ ret, get_func_table_rsp.head.status, out_size, func_id);
+ return (-EINVAL);
+ }
+
+ *func_tbl_value = get_func_table_rsp.func_tbl_value;
+
+ return 0;
+}
+
+int roce5_set_func_tbl_cpu_endian(struct roce5_device *rdev)
+{
+ roce_set_cpu_endian_cmd_s set_cpu_endian_info;
+ u16 out_size = (u16)sizeof(set_cpu_endian_info);
+ int ret;
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return -EINVAL;
+ }
+
+ ret = memset_s(&set_cpu_endian_info, sizeof(set_cpu_endian_info), 0,
+ sizeof(set_cpu_endian_info));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to memset set_cpu_endian_info.(ret:%d).",
+ ret);
+ return -ENOMEM;
+ }
+ set_cpu_endian_info.func_id = rdev->glb_func_id;
+ set_cpu_endian_info.cpu_endian = rdev->hw_info.cpu_endian;
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_SET_CPU_ENDIAN,
+ &set_cpu_endian_info,
+ sizeof(set_cpu_endian_info),
+ &set_cpu_endian_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (set_cpu_endian_info.head.status != 0)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set func state, err(%d), status(0x%x), out size(0x%x).",
+ ret, set_cpu_endian_info.head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void roce5_init_cfg_info_parse_resp(struct roce5_device *rdev,
+ roce_get_cfg_info_resp_s *resp)
+{
+ rdev->cfg_info.scence_id = resp->scence_id;
+ rdev->cfg_info.lb_en = resp->lb_en;
+ rdev->cfg_info.lb_mode = resp->lb_mode;
+ rdev->cfg_info.srq_container_en =
+ (resp->container_mode != ROCE_CHIP_SRQ_MODE_N);
+ rdev->cfg_info.srq_container_mode =
+ roce5_srq_mode_chip_adapt(resp->container_mode);
+ rdev->cfg_info.xrc_srq_container_mode = ROCE_SRQ_MODE_3;
+ rdev->cfg_info.warn_th = 0;
+
+ rdev->cfg_info.fake_en = resp->fake_en;
+ rdev->cfg_info.pf_start_bit = resp->pf_start_bit;
+ rdev->cfg_info.pf_end_bit = resp->pf_end_bit;
+ rdev->cfg_info.page_bit = resp->page_bit;
+
+ rdev->cfg_info.port_num = resp->port_num;
+ rdev->cfg_info.host_num = resp->host_num;
+ rdev->cfg_info.pcie_atomic_en = resp->pcie_atomic_en;
+
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes = resp->max_wqe;
+ rdev->rdma_cap.max_cqes = resp->max_cqe;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_wqes =
+ resp->max_srq_wqe;
+ rdev->rdma_cap.max_sq_sg = resp->max_sq_sge;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_sg = resp->max_rq_sge;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_sge =
+ resp->max_srq_sge;
+ rdev->rdma_cap.max_sq_desc_sz = resp->max_sq_wqe_len;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_desc_sz =
+ resp->max_rq_wqe_len;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_sq_inline_data_sz =
+ resp->max_sq_inline;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_pd = resp->max_pd;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_xrcd = resp->max_xrcd;
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_gid = resp->max_gid;
+
+ rdev->hca_vf_mode = resp->ip2func;
+
+ roce5_cfg_info_update_ext(rdev, resp);
+}
+
+int roce5_get_feature(struct roce5_device *rdev,
+ roce_get_chip_ability_s *roce_feature)
+{
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_verbs_cmd_header_s *cmd_hdr = NULL;
+ roce_get_chip_ability_s *resp_buf = NULL;
+ int ret = 0;
+
+ ret = memset_s(roce_feature, sizeof(*roce_feature), 0,
+ sizeof(*roce_feature));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset roce_feature, ret(%d).", ret);
+ return (-ENOMEM);
+ }
+
+ // allocate input and output buffer
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(rdev->hwdev, &cqm_cmd_inbuf,
+ sizeof(roce_verbs_cmd_header_s),
+ &cqm_cmd_outbuf,
+ sizeof(roce_get_chip_ability_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to allocate cqm buffers, ret = %d.",
+ ret);
+ return ret;
+ }
+
+ // fill input command
+ cmd_hdr = (roce_verbs_cmd_header_s *)cqm_cmd_inbuf->buf;
+ cmd_hdr->dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_COMM_BITMASK);
+
+ // send command and wait response
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_GET_CHIP_ABILITY, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, ROCE_CMD_TIME_CLASS_C,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send feature cmd, ret = %d.",
+ ret);
+ goto free_buf;
+ }
+
+ // get response data
+ resp_buf = (roce_get_chip_ability_s *)cqm_cmd_outbuf->buf;
+ roce_feature->roce_kernel_ability =
+ be64_to_cpu(resp_buf->roce_kernel_ability);
+ roce_feature->roce_kernel_ext_ability =
+ be64_to_cpu(resp_buf->roce_kernel_ext_ability);
+ roce_feature->roce_user_ext_ability =
+ be64_to_cpu(resp_buf->roce_user_ext_ability);
+
+ // get on layer service supported attribute
+ roce_feature->uld_feature.roce_uld_kernel_ext_ability =
+ be64_to_cpu(resp_buf->uld_feature.roce_uld_kernel_ext_ability);
+ roce_feature->uld_feature.roce_uld_user_ext_ability =
+ be64_to_cpu(resp_buf->uld_feature.roce_uld_user_ext_ability);
+free_buf:
+ // free buffer
+ if (cqm_cmd_inbuf || cqm_cmd_outbuf) {
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ }
+ return ret;
+}
+
+int roce5_uni_cmd_init_cfg_info(struct roce5_device *rdev)
+{
+ roce_get_cfg_info_cmd_s get_cfg_info;
+ roce_get_cfg_info_resp_s resp;
+ u16 out_size = (u16)sizeof(resp);
+ int ret = 0;
+
+ ret = memset_s(&get_cfg_info, sizeof(get_cfg_info), 0,
+ sizeof(get_cfg_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset get_cfg_info, ret(%d).", ret);
+ return (-ENOMEM);
+ }
+ ret = memset_s(&resp, sizeof(resp), 0, sizeof(resp));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset resp, ret(%d).", ret);
+ return (-ENOMEM);
+ }
+
+ get_cfg_info.func_id = rdev->glb_func_id;
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_GET_CFG_INFO,
+ &get_cfg_info, sizeof(get_cfg_info), &resp,
+ &out_size);
+ if ((ret != 0) || (out_size == 0) || (get_cfg_info.head.status != 0)) {
+ ROCE_DEV_ERR(rdev,
+ "Failed, err(%d), status(0x%x), out size(0x%x)",
+ ret, get_cfg_info.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ roce5_init_cfg_info_parse_resp(rdev, &resp);
+
+ ROCE_DEV_INFO(
+ rdev,
+ "init, func_id(%d), lb_en(%d), lb_mode(%d), srq_mode(%d), scence_id(%d), pcie_atomic_en(%d).",
+ rdev->glb_func_id, rdev->cfg_info.lb_en, rdev->cfg_info.lb_mode,
+ rdev->cfg_info.srq_container_mode, rdev->cfg_info.scence_id,
+ rdev->cfg_info.pcie_atomic_en);
+ ROCE_DEV_INFO(
+ rdev,
+ "max_wqes(0x%x), max_cqes(0x%x), max_srq_wqes(0x%x), max_sq_sg(0x%x), max_rq_sg(0x%x), "
+ "max_srq_sge(0x%x), max_sq_desc_sz(0x%x), max_rq_desc_sz(0x%x), max_sq_inline_data_sz(0x%x).",
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_wqes,
+ rdev->rdma_cap.max_cqes,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_wqes,
+ rdev->rdma_cap.max_sq_sg,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_sg,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_srq_sge,
+ rdev->rdma_cap.max_sq_desc_sz,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_rq_desc_sz,
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.max_sq_inline_data_sz);
+
+ return 0;
+}
+
+int roce5_init_cfg_info(struct roce5_device *rdev)
+{
+ roce_get_cfg_info_cmd_s get_cfg_info;
+ roce_get_cfg_info_comp_resp_s resp;
+ u16 out_size = (u16)sizeof(resp);
+ int ret = 0;
+
+ if (rdev == NULL || rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ return roce5_uni_cmd_init_cfg_info(rdev);
+ }
+
+ (void)memset_s(&get_cfg_info, sizeof(get_cfg_info), 0,
+ sizeof(get_cfg_info));
+ (void)memset_s(&resp, sizeof(resp), 0, sizeof(resp));
+
+ get_cfg_info.func_id = rdev->glb_func_id;
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_GET_CFG_INFO,
+ &get_cfg_info, sizeof(get_cfg_info), &resp,
+ &out_size);
+ if ((ret != 0) || (out_size == 0) || (get_cfg_info.head.status != 0)) {
+ ROCE_DEV_ERR(rdev,
+ "Failed, err(%d), status(0x%x), out size(0x%x)",
+ ret, get_cfg_info.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ rdev->cfg_info.scence_id = resp.scence_id;
+ rdev->cfg_info.lb_en = resp.lb_en;
+ rdev->cfg_info.lb_mode = resp.lb_mode;
+ rdev->cfg_info.srq_container_en =
+ (resp.container_mode != ROCE_CHIP_SRQ_MODE_N);
+ rdev->cfg_info.srq_container_mode =
+ roce5_srq_mode_chip_adapt(resp.container_mode);
+ rdev->cfg_info.xrc_srq_container_mode = ROCE_SRQ_MODE_3;
+ rdev->cfg_info.warn_th = 0;
+
+ rdev->cfg_info.fake_en = resp.fake_en;
+ rdev->cfg_info.pf_start_bit = resp.pf_start_bit;
+ rdev->cfg_info.pf_end_bit = resp.pf_end_bit;
+ rdev->cfg_info.page_bit = resp.page_bit;
+
+ rdev->cfg_info.port_num = resp.port_num;
+ rdev->cfg_info.host_num = resp.host_num;
+ rdev->cfg_info.pcie_atomic_en = resp.pcie_atomic_en;
+
+ rdev->hca_vf_mode = 0; // V100 fixed to mac mode
+
+ ROCE_DEV_INFO(
+ rdev,
+ "init, func_id(%d), lb_en(%d), lb_mode(%d), srq_mode(%d), scence_id(%d), pcie_atomic_en(%d).",
+ rdev->glb_func_id, rdev->cfg_info.lb_en, rdev->cfg_info.lb_mode,
+ rdev->cfg_info.srq_container_mode, rdev->cfg_info.scence_id,
+ rdev->cfg_info.pcie_atomic_en);
+ return 0;
+}
+
+int roce5_del_func_res(struct roce5_device *rdev)
+{
+ roce_set_func_state_cmd_s del_func_res_info;
+ u16 out_size = (u16)sizeof(del_func_res_info);
+ int ret;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL)) {
+ ROCE_ERR("rdev/Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&del_func_res_info, sizeof(del_func_res_info), 0,
+ sizeof(del_func_res_info));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset del_func_res_info.(ret:%d)", ret);
+ return (-ENOMEM);
+ }
+ del_func_res_info.func_id = rdev->glb_func_id;
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_DEL_FUNC_RES,
+ &del_func_res_info,
+ sizeof(del_func_res_info),
+ &del_func_res_info, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (del_func_res_info.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set func state, err(%d), status(0x%x), out size(0x%x)",
+ ret, del_func_res_info.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+int roce5_set_bw_ctrl_state(struct roce5_device *rdev, u8 cmd,
+ struct roce5_bw_ctrl_inbuf *inbuf)
+{
+ int ret = 0;
+ roce_cc_cfg_bw_ctrl_cmd_s set_bw_ctrl;
+ u16 out_size = (u16)sizeof(set_bw_ctrl);
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&set_bw_ctrl, sizeof(set_bw_ctrl), 0,
+ sizeof(set_bw_ctrl));
+ if (ret != 0) {
+ ROCE_ERR("Memset failed when set_bw_ctrl cmd");
+ return (-ENOMEM);
+ }
+
+ set_bw_ctrl.func_id = rdev->glb_func_id;
+ set_bw_ctrl.cmd = cmd;
+ set_bw_ctrl.cir = inbuf->ctrl_param.cir;
+ set_bw_ctrl.pir = inbuf->ctrl_param.pir;
+ set_bw_ctrl.cnp = inbuf->ctrl_param.cnp;
+ ROCE_INFO("func_id:%u, cmd:%u, cir:%u, pir:%u, cnp:%u",
+ rdev->glb_func_id, set_bw_ctrl.cmd, set_bw_ctrl.cir,
+ set_bw_ctrl.pir, set_bw_ctrl.cnp);
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_CC_SET_BW_CTRL,
+ &set_bw_ctrl, sizeof(set_bw_ctrl),
+ &set_bw_ctrl, &out_size);
+ if ((ret != 0) || (out_size == 0) || (set_bw_ctrl.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set set_bw_ctrl cmd, err(%d), status(0x%x), out size(0x%x)",
+ ret, set_bw_ctrl.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+int roce5_query_bw_ctrl_state(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_param *bw_ctrl_param)
+{
+ int ret = 0;
+ roce_cc_cfg_bw_ctrl_cmd_s query_bw_ctrl;
+ u16 out_size = (u16)sizeof(query_bw_ctrl);
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&query_bw_ctrl, sizeof(query_bw_ctrl), 0,
+ sizeof(query_bw_ctrl));
+ if (ret != 0) {
+ ROCE_ERR("Memset failed when set_bw_ctrl cmd");
+ return (-ENOMEM);
+ }
+
+ query_bw_ctrl.func_id = rdev->glb_func_id;
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_CC_QUERY_BW_CTRL,
+ &query_bw_ctrl, sizeof(query_bw_ctrl),
+ &query_bw_ctrl, &out_size);
+ if ((ret != 0) || (out_size == 0) || (query_bw_ctrl.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set query_bw_ctrl cmd, err(%d), status(0x%x), out size(0x%x)",
+ ret, query_bw_ctrl.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ ret = memcpy_s((void *)bw_ctrl_param,
+ sizeof(struct roce5_bw_ctrl_param),
+ (void *)((u8 *)(&query_bw_ctrl) + ROCE_CMD_DEFAULT_SIZE),
+ sizeof(struct roce5_bw_ctrl_param));
+ if (ret != 0) {
+ ROCE_ERR("memory copy failed. ret%d", ret);
+ return -ENOMEM;
+ }
+
+ ROCE_INFO("query_bw_ctrl_state:func_id:%u, cir:%u, pir:%u, cnp:%u",
+ rdev->glb_func_id, bw_ctrl_param->cir, bw_ctrl_param->pir,
+ bw_ctrl_param->cnp);
+
+ return 0;
+}
+
+#ifdef ROCE_CHIP_TEST
+int roce5_set_vnic_waterline_state(struct roce5_device *rdev,
+ struct roce5_vnic_waterline_ctrl_buf *inbuf,
+ struct roce5_vnic_waterline_ctrl_buf *outbuf)
+{
+ int ret = 0;
+ roce_cc_cfg_vnic_waterline_cmd_s set_vnic_waterline;
+ u16 out_size = (u16)sizeof(set_vnic_waterline);
+
+ (void)outbuf;
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&set_vnic_waterline, sizeof(set_vnic_waterline), 0,
+ sizeof(set_vnic_waterline));
+ if (ret != 0) {
+ ROCE_ERR("Memset failed when set_vnic_waterline cmd");
+ return (-ENOMEM);
+ }
+
+ set_vnic_waterline.func_id = rdev->glb_func_id;
+ set_vnic_waterline.ip_ver = 0;
+ set_vnic_waterline.param.red_waterline =
+ inbuf->waterline_param.red_waterline;
+ set_vnic_waterline.param.yellow_waterline =
+ inbuf->waterline_param.yellow_waterline;
+ set_vnic_waterline.param.ip_info.ipv4.val =
+ inbuf->waterline_param.ip_val;
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev,
+ ROCE_MPU_CMD_CC_SET_VNIC_WATERLINE,
+ &set_vnic_waterline,
+ sizeof(set_vnic_waterline),
+ &set_vnic_waterline, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (set_vnic_waterline.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set set_vnic_waterline cmd, err(%d), status(0x%x), out size(0x%x)",
+ ret, set_vnic_waterline.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+int roce5_get_vnic_waterline_state(struct roce5_device *rdev,
+ struct roce5_vnic_waterline_ctrl_buf *inbuf,
+ struct roce5_vnic_waterline_ctrl_buf *outbuf)
+{
+ int ret = 0;
+ roce_cc_cfg_vnic_waterline_cmd_s get_vnic_waterline;
+ u16 out_size = (u16)sizeof(get_vnic_waterline);
+
+ if (rdev->hwdev == NULL) {
+ ROCE_ERR("Hwdev is null");
+ return (-EINVAL);
+ }
+
+ ret = memset_s(&get_vnic_waterline, sizeof(get_vnic_waterline), 0,
+ sizeof(get_vnic_waterline));
+ if (ret != 0) {
+ ROCE_ERR("Memset failed when get_vnic_waterline cmd");
+ return (-ENOMEM);
+ }
+
+ get_vnic_waterline.func_id = rdev->glb_func_id;
+ get_vnic_waterline.ip_ver = 0;
+ get_vnic_waterline.param.ip_info.ipv4.val =
+ inbuf->waterline_param.ip_val;
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev,
+ ROCE_MPU_CMD_CC_GET_VNIC_WATERLINE,
+ &get_vnic_waterline,
+ sizeof(get_vnic_waterline),
+ &get_vnic_waterline, &out_size);
+ if ((ret != 0) || (out_size == 0) ||
+ (get_vnic_waterline.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set get_vnic_waterline cmd, err(%d), status(0x%x), out size(0x%x)",
+ ret, get_vnic_waterline.head.status, out_size);
+ return (-EINVAL);
+ }
+
+ outbuf->waterline_param.red_waterline =
+ get_vnic_waterline.param.red_waterline;
+ outbuf->waterline_param.yellow_waterline =
+ get_vnic_waterline.param.yellow_waterline;
+
+ return 0;
+}
+#endif /* ROCE_CHIP_TEST */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.h b/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.h
new file mode 100644
index 000000000..5fd787a67
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/cmd/roce_cmd.h
@@ -0,0 +1,82 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_CMD_H
+#define ROCE_CMD_H
+
+#include "comm_defs.h"
+#include "roce.h"
+#include "roce_dfx.h"
+#include "roce_srq.h"
+
+#include "roce_mpu_cmd_defs.h"
+#include "roce_cfg_format.h"
+
+#define ROCE_VLAN_ID_MASK 0x7FFF
+#define ROCE_VLAN_N_VID 4096
+
+#define ROCE_CMD_DEFAULT_SIZE 12
+
+#define ERR_EXIST 6
+#define ERR_FULL 12
+#define ERR_NOT_FOUND 13
+
+#define roce5_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out, out_size) \
+ hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_ROCE, cmd, buf_in, in_size, \
+ buf_out, out_size, 0, HINIC5_CHANNEL_ROCE)
+#define roce5_msg_to_ovs_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out, \
+ out_size) \
+ hinic5_msg_to_mgmt_sync(hwdev, HINIC5_MOD_OVS, cmd, buf_in, in_size, \
+ buf_out, out_size, 90000, HINIC5_CHANNEL_OVS)
+
+int roce5_add_mac_tbl_mac_entry(struct roce5_device *rdev, u8 *mac_addr,
+ size_t mac_addr_len, u32 vlan_id, u16 func_id);
+int roce5_del_mac_tbl_mac_entry(struct roce5_device *rdev, u8 *mac_addr,
+ size_t mac_addr_len, u32 vlan_id, u16 func_id);
+typedef int (*roce5_modify_mac_tbl)(struct roce5_device *rdev,
+ u8 mac_addr[ETH_ALEN], size_t eth_alen,
+ u32 vlan_id, u16 func_id);
+void roce5_add_ipsu_tbl_mac_entry(struct roce5_device *rdev,
+ u8 mac_addr[ETH_ALEN], u32 vlan_id,
+ u16 func_id, u8 er_id, u16 src_func_id);
+void roce5_del_ipsu_tbl_mac_entry(struct roce5_device *rdev,
+ u8 mac_addr[ETH_ALEN], size_t eth_alen,
+ u32 vlan_id, u8 er_id, u16 src_func_id);
+int roce5_add_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct roce_cmd_mpu_addr_info *addr_info);
+int roce5_del_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct roce_cmd_mpu_addr_info *addr_info);
+int roce5_modify_ipsu_tbl_ip_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry, u8 type);
+void roce5_add_ipsu_tcam_tbl_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry,
+ u32 gid_index);
+void roce5_del_ipsu_tcam_tbl_entry(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry);
+typedef void (*roce5_modify_ipsu_tbl_mac)(void *hwdev, u8 mac_addr[ETH_ALEN],
+ u32 vlan_id, u16 func_id, u8 er_id);
+
+int roce5_set_sysfs_cfg_param(void *hwdev, u16 func_id, u32 *param,
+ u32 param_len, u16 type);
+int roce5_set_bw_ctrl_state(struct roce5_device *rdev, u8 cmd,
+ struct roce5_bw_ctrl_inbuf *inbuf);
+int roce5_query_bw_ctrl_state(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_param *bw_ctrl_param);
+#ifdef ROCE_CHIP_TEST
+int roce5_set_vnic_waterline_state(struct roce5_device *rdev,
+ struct roce5_vnic_waterline_ctrl_buf *inbuf,
+ struct roce5_vnic_waterline_ctrl_buf *outbuf);
+int roce5_get_vnic_waterline_state(struct roce5_device *rdev,
+ struct roce5_vnic_waterline_ctrl_buf *inbuf,
+ struct roce5_vnic_waterline_ctrl_buf *outbuf);
+#endif /* ROCE_CHIP_TEST */
+int roce5_set_func_tbl_func_state(void *hwdev, u8 func_state, u16 func_id);
+int roce5_get_func_table(void *hwdev, u16 func_id, u32 *func_tbl_value);
+int roce5_set_func_tbl_cpu_endian(struct roce5_device *rdev);
+int roce5_get_feature(struct roce5_device *rdev,
+ roce_get_chip_ability_s *roce_feature);
+int roce5_init_cfg_info(struct roce5_device *rdev);
+int roce5_del_func_res(struct roce5_device *rdev);
+
+#endif /* ROCE_CMD_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.c b/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.c
new file mode 100644
index 000000000..11bd63d04
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.c
@@ -0,0 +1,86 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/kernel.h>
+
+#include "roce.h"
+#include "roce_os_compat.h"
+
+int roce5_db_map_user(struct roce5_ucontext *context, unsigned long virt,
+ struct roce5_db *db, u8 shadow_db)
+{
+ int ret = 0;
+ struct roce5_db_page *db_page = NULL;
+
+ if ((context == NULL) || (db == NULL)) {
+ return -EINVAL;
+ }
+ if (shadow_db != 0) {
+ return ret;
+ }
+ mutex_lock(&context->db_page_mutex);
+
+ list_for_each_entry(db_page, &context->db_page_list, list) {
+ if (db_page->user_virt == (virt & PAGE_MASK)) {
+ goto found;
+ }
+ }
+
+ db_page = (struct roce5_db_page *)kmalloc(sizeof(*db_page), GFP_KERNEL);
+ if (db_page == NULL) {
+ ret = -ENOMEM;
+ ROCE_ERR("Failed to alloc DB page");
+ goto out;
+ }
+
+ db_page->user_virt = (virt & PAGE_MASK);
+ db_page->refcnt = 0;
+ db_page->umem = roce5_umem_get(context->ibucontext.device,
+ &context->ibucontext, virt & PAGE_MASK,
+ PAGE_SIZE, 0, 0);
+ if (IS_ERR(db_page->umem)) {
+ ret = (int)PTR_ERR(db_page->umem);
+ ROCE_ERR("Failed to get ib_umem ret:%d", ret);
+ kfree(db_page);
+ goto out;
+ }
+
+ list_add(&db_page->list, &context->db_page_list);
+
+found:
+#if defined(IB_UMEM_HAVE_SG_APPEND_TABLE)
+ db->dma = sg_dma_address(db_page->umem->sgt_append.sgt.sgl) +
+ (virt & ~PAGE_MASK);
+#else
+ db->dma = sg_dma_address(db_page->umem->sg_head.sgl) +
+ (virt & ~PAGE_MASK);
+#endif
+ db->user_page = db_page;
+ ++db_page->refcnt;
+
+out:
+ mutex_unlock(&context->db_page_mutex);
+
+ return ret;
+}
+
+void roce5_db_unmap_user(struct roce5_ucontext *context, struct roce5_db *db,
+ u8 shadow_db)
+{
+ if ((context == NULL) || (db == NULL)) {
+ return;
+ }
+ if (shadow_db != 0) {
+ return;
+ }
+ mutex_lock(&context->db_page_mutex);
+
+ if ((--db->user_page->refcnt) == 0) {
+ list_del(&db->user_page->list);
+ ib_umem_release(db->user_page->umem);
+ kfree(db->user_page);
+ }
+
+ mutex_unlock(&context->db_page_mutex);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.h b/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.h
new file mode 100644
index 000000000..7232e9edc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/db/roce_db.h
@@ -0,0 +1,30 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_DB_H
+#define ROCE_DB_H
+
+#include <rdma/ib_umem.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+struct roce5_db_page {
+ struct list_head list;
+ struct ib_umem *umem;
+ unsigned long user_virt;
+ int refcnt;
+};
+
+struct roce5_db {
+ __be32 *db_record;
+ dma_addr_t dma;
+ struct roce5_db_page *user_page;
+};
+
+static inline void roce5_write64(u32 val[2], void __iomem *dest)
+{
+ __raw_writeq(*(u64 *)(void *)val, dest);
+}
+
+#endif //ROCE_DB_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/init/roce_main.c b/drivers/infiniband/hw/hiroce5/kernel/dev/init/roce_main.c
new file mode 100644
index 000000000..7d589afe1
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/init/roce_main.c
@@ -0,0 +1,1701 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <net/bonding.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_user_verbs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/inetdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/security.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/sizes.h>
+
+#include "hinic5_crm.h"
+#include "hinic5_hw.h"
+#include "hinic5_mt.h"
+#include "hinic5_srv_nic.h"
+#include "hinic5_rdma.h"
+#include "hinic5_id_tbl.h"
+
+#include "roce_dfx.h"
+#include "roce_mr.h"
+#include "roce_main_extension.h"
+#include "roce_uld_inner.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_netlink.h"
+#include "roce_cmd.h"
+#include "roce_qp.h"
+#include "roce_infra.h"
+#include "rdma_comp_mw_mr.h"
+#include "roce_xrc.h"
+#include "roce_com.h"
+#include "roce_kernel_compat_gen.h"
+#include "roce_netdev.h"
+
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+
+#ifdef ENABLE_HYPER_ROCE
+#include "hyper_roce_tool.h"
+#endif
+
+#include "securec.h"
+
+MODULE_AUTHOR(HIROCE5_DRV_AUTHOR);
+MODULE_DESCRIPTION(HIROCE5_DRV_DESC);
+MODULE_VERSION(HIROCE5_DRV_VERSION);
+MODULE_LICENSE("GPL");
+
+static int g_loop_times = 50000;
+module_param(g_loop_times, int, S_IRUGO);
+MODULE_PARM_DESC(g_loop_times,
+ "default: 50000. The number must be greater than 0.");
+
+static u8 g_destory_flow_timeout = 10;
+module_param(g_destory_flow_timeout, byte, S_IRUGO);
+MODULE_PARM_DESC(g_destory_flow_timeout, "default: 10");
+
+static bool g_local_en = false; // IP mode because IP in this place need switch control whether advancein this place switch
+module_param(g_local_en, bool, S_IRUGO);
+MODULE_PARM_DESC(g_local_en, "default false");
+
+static bool g_full_qp_spec = true; // calculate standard card scenario, supports single cq create full specification qp
+module_param(g_full_qp_spec, bool, S_IRUGO);
+MODULE_PARM_DESC(
+ g_full_qp_spec,
+ "Supports creating a maximum number of QPs through a single CQ. default true.");
+
+static bool g_huge_page_en = 0;
+module_param(g_huge_page_en, bool, S_IRUGO);
+MODULE_PARM_DESC(
+ g_huge_page_en,
+ "default: 0. value: 0 or 1, set huge page en, and users need to reserve huge pages in advance.");
+
+#define ROCE_BOND_SLAVE_BIT_MASK 0xf
+
+/* ****************************************************************************
+ Prototype : get_cpu_endian
+ Description : Acquire CPU's enianness
+ Return Value : 0: little endian; 1: big endian
+
+ 1.Date : 2016/6/23
+ Modification : Created function
+
+**************************************************************************** */
+static int get_cpu_endian(void)
+{
+ int cpu_mode = 0;
+ union {
+ unsigned int i;
+ unsigned char s[4];
+ } c;
+ c.i = 0x12345678;
+
+ if (c.s[0] == 0x12) {
+ ROCE_INFO("CPU is be");
+ cpu_mode = 1;
+ } else {
+ ROCE_INFO("CPU is le");
+ cpu_mode = 0;
+ }
+
+ return cpu_mode;
+}
+
+static int roce5_alloc_hw_resource(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = roce5_rdma_init_rsvd_lkey(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to init rsvd lkey, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ /* Clear gid table before register for a new IB device */
+ ret = roce5_reset_gid_table(rdev, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to reset gid_table, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_gid_reset;
+ }
+
+ return 0;
+
+err_gid_reset:
+ roce5_rdma_free_rsvd_lkey(rdev);
+
+ return ret;
+}
+
+static void roce5_dealloc_hw_resource(struct roce5_device *rdev)
+{
+ roce5_rdma_free_rsvd_lkey(rdev);
+}
+
+/* 1825 v100 esl sub did */
+#define HI_1825_V100_SUB_DEV_ID_2X100 0x1825
+#define HI_1825_V100_SUB_DEV_ID_COMPUTE_2X200 0x40B1
+#define HI_1825_V100_SUB_DEV_ID_COMPUTE_DY_YH 0x30C4
+#define HI_1825_V100_SUB_DEV_ID_COMPUTE_UBX 0x30C8
+
+static int roce5_init_ver_attr_pci(struct hinic5_lld_dev *lld_dev,
+ struct roce5_device *rdev)
+{
+ struct pci_dev *pdev = container_of(lld_dev->dev, struct pci_dev, dev);
+
+ if ((pdev->device == HINIC5_DEV_ID_25V1_PF) ||
+ (pdev->device == HINIC5_DEV_ID_25V1_VF)) {
+ rdev->device_type = ROCE_DEV_TYPE_HI1825_V100;
+ return 0;
+ }
+
+ switch (pdev->subsystem_device) {
+ case HI_1825_V100_SUB_DEV_ID_2X100:
+ case HI_1825_V100_SUB_DEV_ID_COMPUTE_2X200:
+ case HI_1825_V100_SUB_DEV_ID_COMPUTE_DY_YH:
+ case HI_1825_V100_SUB_DEV_ID_COMPUTE_UBX:
+ rdev->device_type = ROCE_DEV_TYPE_HI1825_V100;
+ break;
+ default:
+ ROCE_DEV_ERR(rdev, "Unknown subsystem id(%u).",
+ pdev->subsystem_device);
+ rdev->device_type = ROCE_DEV_TYPE_UNKNOWN;
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int roce5_init_ver_attr(struct hinic5_lld_dev *lld_dev,
+ struct roce5_device *rdev)
+{
+ int ret;
+
+ switch (lld_dev->dev_type) {
+ case HINIC5_DEVICE_T_PCI:
+ ret = roce5_init_ver_attr_pci(lld_dev, rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to init PCI version attributes, ret(%d).",
+ ret);
+ return ret;
+ }
+ break;
+
+ case HINIC5_DEVICE_T_UB:
+ /*
+ * The 'struct ub_dev' contains a 'module' member that can be used to distinguish the version of the card
+ * under the UBC. However, this member is only available in the most recent version of 'struct ub_dev', and
+ * the current development environment does not include the updated structure definition, making it
+ * inaccessible at present. Here, the fixed version(Hi1825V100) is returned.
+ */
+ rdev->device_type = ROCE_DEV_TYPE_HI1825_V100;
+ break;
+
+ default:
+ ROCE_DEV_ERR(rdev, "Unknown low level device type(%u).",
+ lld_dev->dev_type);
+ rdev->device_type = ROCE_DEV_TYPE_UNKNOWN;
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int roce5_get_perf_cq_step(struct roce5_device *rdev)
+{
+ int perf_step = 0;
+
+ if (ROCE_IS_DEV_1825V100(rdev)) {
+ perf_step = ROCE_1825V100_STEP;
+ } else {
+ ROCE_DEV_INFO(
+ rdev,
+ "not support high performance cq, device type(%u), func_id(%u).",
+ rdev->device_type, rdev->glb_func_id);
+ }
+ return perf_step;
+}
+
+static int roce5_get_perf_cq_cnt(struct roce5_device *rdev)
+{
+ if (rdev->cqn_ctrl.rsvd_cq_step == 0) {
+ return 0;
+ }
+ /* When you insmod the driver, CQ0 is consumed by default. */
+ return (int)((rdev->rdma_cap.dev_rdma_cap.roce_own_cap.reserved_cqs -
+ 1) /
+ rdev->cqn_ctrl.rsvd_cq_step) +
+ 1;
+}
+
+void roce5_init_perf_cq_attr(struct roce5_device *rdev)
+{
+ /* Calculate the step size and number of high-performance CQs */
+ rdev->cqn_ctrl.rsvd_cq_step = roce5_get_perf_cq_step(rdev);
+ rdev->cqn_ctrl.high_perf_cq_cnt = roce5_get_perf_cq_cnt(rdev);
+#ifdef ROCE_VBS_EN
+ // VBS RoCE scenario disable high performance cq
+ rdev->cqn_ctrl.high_perf_cq_cnt = 0;
+#endif
+ rdev->cqn_ctrl.alloc_cq_cnt = 0;
+}
+
+static struct roce5_device *
+roce5_rdev_alloc(struct hinic5_lld_dev *lld_dev, void **uld_dev,
+ const struct rdma_service_cap *rdma_cap)
+{
+ struct roce5_device *rdev = NULL;
+ int ret;
+
+ rdev = (struct roce5_device *)roce5_rdev_alloc_ext();
+ if (rdev == NULL) {
+ ROCE_ERR("Failed to alloc rdev");
+ return NULL;
+ }
+
+ *uld_dev = (void *)rdev;
+ rdev->lld_dev = lld_dev;
+ rdev->hwdev = lld_dev->hwdev;
+ rdev->dev = lld_dev->dev;
+ dma_set_max_seg_size(rdev->dev, SZ_2G);
+ ret = roce5_init_ver_attr(lld_dev, rdev);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to init version attribute of the device, ret(%d)",
+ ret);
+ goto alloc_failed;
+ }
+
+ mutex_init(&rdev->qp_cnt.cur_qps_mutex);
+ mutex_init(&rdev->cqn_ctrl.cq_ctrl_mutex);
+
+ rdev->hwdev_hdl = ((struct hinic5_hwdev *)(rdev->hwdev))->dev_hdl;
+ if (memcpy_s((void *)&rdev->rdma_cap, sizeof(*rdma_cap),
+ (void *)rdma_cap, sizeof(*rdma_cap)) != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy rdma_cap.");
+ goto alloc_failed;
+ }
+
+ rdev->ndev = hinic5_get_netdev_by_lld(rdev->lld_dev);
+ if (rdev->ndev == NULL) {
+ ROCE_DEV_ERR(rdev, "roce add failed, netdev is null.");
+ goto alloc_failed;
+ }
+
+ roce5_init_perf_cq_attr(rdev);
+ rdev->rdev_magic = ROCE_DEVICE_MAGIC;
+ return rdev;
+
+alloc_failed:
+ ib_dealloc_device(&rdev->ib_dev);
+ return NULL;
+}
+
+static int roce5_board_info_get(struct roce5_device *rdev)
+{
+ int ret = 0;
+
+ ret = hinic5_get_board_info(rdev->hwdev, &rdev->board_info,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get board info");
+ return ret;
+ }
+
+ ROCE_DEV_INFO(
+ rdev,
+ "Get board info success, board_type:0x%x, port_num:0x%x, pf_num:0x%x, vf_total_num:0x%x, "
+ "work_mode:0x%x, service_mode:0x%x, port_speed:0x%x.",
+ rdev->board_info.board_type, rdev->board_info.port_num,
+ rdev->board_info.pf_num, rdev->board_info.vf_total_num,
+ rdev->board_info.work_mode, rdev->board_info.service_mode,
+ rdev->board_info.port_speed);
+
+ ret = roce5_board_cfg_check(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to check board cfg info");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_fix_ibdev_name(struct roce5_device *rdev)
+{
+ int ret;
+
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ ret = strcpy_s(rdev->ib_dev.name, IB_DEVICE_NAME_MAX,
+ "hrn5_bond_%d");
+ if (ret != EOK) {
+ ROCE_DEV_ERR(rdev, "Strcpy_s error");
+ }
+ return;
+ }
+#endif
+ ret = strcpy_s(rdev->ib_dev.name, IB_DEVICE_NAME_MAX, "hrn5_%d");
+ if (ret != EOK) {
+ ROCE_DEV_ERR(rdev, "Strcpy_s error");
+ }
+}
+
+static int roce5_register_template(struct roce5_device *rdev)
+{
+ service_register_template_s svc_template;
+ int ret;
+
+ ret = memset_s(&svc_template, sizeof(svc_template), 0,
+ sizeof(svc_template));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memset svc_template.(ret:%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ svc_template.service_type = SERVICE_T_ROCE;
+ svc_template.scq_ctx_size = rdev->rdma_cap.cqc_entry_sz;
+ svc_template.srq_ctx_size =
+ rdev->rdma_cap.dev_rdma_cap.roce_own_cap.srqc_entry_sz;
+ svc_template.service_handle = rdev;
+ svc_template.embedded_cq_ceq_callback = NULL;
+ svc_template.no_cq_ceq_callback = NULL;
+
+ svc_template.shared_cq_ceq_callback = roce5_cq_completion;
+ svc_template.aeq_level_callback = roce5_async_event_level;
+ svc_template.aeq_callback = roce5_async_event;
+
+ ret = cqm5_service_register(rdev->hwdev, &svc_template);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to register cqm_service, func(%d).",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Alloc CEQs and alloc CEQN */
+static int roce5_alloc_ceq(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = hinic5_alloc_ceqs(rdev->hwdev, SERVICE_T_ROCE,
+ rdev->ib_dev.num_comp_vectors, rdev->ceqn,
+ &rdev->ceq_num);
+ if (ret < 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqes, num_comp_vectors(%d), func_id(%d), ret(%d)",
+ rdev->ib_dev.num_comp_vectors, rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_free_ceq(struct roce5_device *rdev)
+{
+ int i;
+
+ for (i = 0; i < rdev->ceq_num; ++i) {
+ hinic5_free_ceq(rdev->hwdev, SERVICE_T_ROCE, rdev->ceqn[i]);
+ }
+}
+
+static void roce5_init_hw_info(struct roce5_device *rdev)
+{
+ rdev->hw_info.config_num_ports = (int)rdev->rdma_cap.num_ports;
+ rdev->hw_info.ep_id = hinic5_ep_id(rdev->hwdev);
+ rdev->hw_info.phy_port = 1;
+ rdev->hw_info.is_vf = roce5_func_is_vf(rdev->hwdev);
+ rdev->hw_info.cpu_endian = (u8)get_cpu_endian();
+}
+
+static int roce5_init_dev_info(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = roce5_set_func_tbl_cpu_endian(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set func_tbl cpu_endian, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_init;
+ }
+
+ /* Set function table to ENABLE */
+ ret = roce5_set_func_tbl_func_state(rdev->hwdev, ROCE_FUNC_ENABLE,
+ rdev->glb_func_id);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set func_tbl, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_init;
+ }
+
+ return 0;
+
+err_init:
+ return ret;
+}
+#ifdef __ROCE_DFX__
+static void device_list_lock_init(struct roce5_device_res *device_res)
+{
+ mutex_init(&device_res->mr_list.node_lock);
+ INIT_LIST_HEAD(&device_res->mr_list.node);
+}
+
+static void device_list_lock_deinit(struct roce5_device_res *device_res)
+{
+ struct roce5_mr *mr = NULL;
+ struct roce5_mr *tmp_mr = NULL;
+
+ mutex_lock(&device_res->mr_list.node_lock);
+ list_for_each_entry_safe(mr, tmp_mr, &device_res->mr_list.node, node) {
+ list_del(&(mr->node));
+ }
+ mutex_unlock(&device_res->mr_list.node_lock);
+
+ mutex_destroy(&(device_res->mr_list.node_lock));
+}
+
+static int roce5_dfx_device_init(struct roce5_device *rdev)
+{
+ rdev->device_res = kzalloc(sizeof(struct roce5_device_res), GFP_KERNEL);
+ if (rdev->device_res == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc device resource.");
+ return -ENOMEM;
+ }
+
+ device_list_lock_init(rdev->device_res);
+
+ return 0;
+}
+
+static void roce5_dfx_device_deinit(struct roce5_device *rdev)
+{
+ if (rdev->device_res != NULL) {
+ device_list_lock_deinit(rdev->device_res);
+ kfree(rdev->device_res);
+ rdev->device_res = NULL;
+ }
+}
+#endif // __ROCE_DFX__
+
+static void roce5_deinit_dev_info(struct roce5_device *rdev)
+{
+ (void)roce5_set_func_tbl_func_state(rdev->hwdev, ROCE_FUNC_DISABLE,
+ rdev->glb_func_id);
+}
+
+static int roce5_ib_register_device(struct roce5_device *rdev)
+{
+#if defined(IB_REG_DEV_HAVE_PORT_CALLBACK)
+ roce5_fix_ibdev_name(rdev);
+ return ib_register_device(&rdev->ib_dev, NULL);
+#elif defined(IB_REG_DEV_HAVE_NAME) && defined(IB_REG_DEV_HAVE_DEVICE)
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ return ib_register_device(&rdev->ib_dev, "hrn5_bond_%d",
+ rdev->dev);
+ }
+#endif
+
+ return ib_register_device(&rdev->ib_dev, "hrn5_%d", rdev->dev);
+#endif
+}
+
+static int roce5_dev_register(struct roce5_device *rdev, char *uld_dev_name)
+{
+ int ret;
+
+ ret = roce5_ib_register_device(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to reg ibdev, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_reg_dev;
+ }
+
+ ret = memcpy_s(uld_dev_name, ROCE_ULD_DEV_NAME_LEN, rdev->ib_dev.name,
+ ROCE_ULD_DEV_NAME_LEN);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy uld_dev_name.(ret:%d)",
+ ret);
+ goto err_memcpy_uld;
+ }
+
+ return 0;
+
+err_memcpy_uld:
+ ib_unregister_device(&rdev->ib_dev);
+err_reg_dev:
+ return ret;
+}
+
+static void roce5_dev_unregister(struct roce5_device *rdev)
+{
+ ib_unregister_device(&rdev->ib_dev);
+}
+
+static int roce5_handle_register_event(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = roce5_add_real_device_mac(rdev, rdev->ndev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to add real device mac, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ if (netif_running(rdev->ndev) &&
+ test_and_set_bit(ROCE5_PORT_EVENT, &rdev->status) == 0) {
+ roce5_ifconfig_up_down_event_report(rdev, IB_EVENT_PORT_ACTIVE);
+ }
+
+ return 0;
+}
+
+static int roce5_init_dev(struct roce5_device *rdev, char *uld_dev_name)
+{
+ int ret;
+
+ ret = roce5_init_dev_info(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init dev info, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_init_dev_info;
+ }
+
+ ret = roce5_alloc_hw_resource(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc hw res, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_alloc_hw_res;
+ }
+
+ ret = roce5_dev_register(rdev, uld_dev_name);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init register, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_init_register;
+ }
+
+ ret = roce5_g_rdev_add(rdev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to add rdev to g_rdev");
+ goto err_add_rdev;
+ }
+
+ ret = roce5_get_feature(rdev, &rdev->cfg_info.feature_cap);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get feature, ret=%d", ret);
+ goto err_get_feature_or_init_sysfs;
+ }
+
+ ret = roce5_init_sysfs(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init sysfs, func_id(%d) ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_get_feature_or_init_sysfs;
+ }
+ rdev->ib_active = true;
+
+ ret = roce5_handle_register_event(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to handle register event, func_id(%d) ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_register_event;
+ }
+
+ ROCE_DEV_INFO(rdev, "Add init all ok, func_id(%d), dev_name(%s)",
+ rdev->glb_func_id, rdev->ib_dev.name);
+
+ return 0;
+
+err_register_event:
+ roce5_remove_sysfs(rdev);
+err_get_feature_or_init_sysfs:
+ roce5_g_rdev_remove(rdev);
+err_add_rdev:
+ roce5_dev_unregister(rdev);
+err_init_register:
+ roce5_dealloc_hw_resource(rdev);
+err_alloc_hw_res:
+ roce5_deinit_dev_info(rdev);
+err_init_dev_info:
+ return ret;
+}
+
+static void roce5_rdev_qp_lb_init(struct roce5_device *rdev)
+{
+ int i = 0;
+ mutex_init(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+ for (; i < ROCE_LB_QPN_MAX; i++) {
+ rdev->qp_lb_scqn_ctrl.qp[i] = 0;
+ }
+}
+
+static int roce5_add_rdev_init(struct roce5_device *rdev)
+{
+ int ret = 0;
+
+ ret = roce5_board_info_get(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get board info");
+ return ret;
+ }
+
+#ifdef ROCE_BONDING_EN
+ ret = roce5_bond_attach(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to attach bond device.");
+ return ret;
+ }
+
+ atomic_set(&rdev->next_port, 0);
+#endif
+
+ rdev->gid_dev = (struct net_device **)kzalloc(
+ rdev->rdma_cap.max_gid_per_port * sizeof(struct net_device *),
+ GFP_KERNEL);
+ if (rdev->gid_dev == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc gid dev memory");
+ return -ENOMEM;
+ }
+
+ ret = roce5_rdma_init_resource(rdev->hwdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init rdma resources.");
+ goto err_init_resource;
+ }
+
+ rdev->glb_func_id = hinic5_global_func_id(rdev->hwdev);
+ roce5_rdev_qp_lb_init(rdev);
+
+ roce5_init_hw_info(rdev);
+
+ ret = roce5_init_cfg_info(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get roce cfg, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_init_cfg;
+ }
+
+ ROCE_DEV_INFO(rdev, "Initializing.");
+ return 0;
+
+err_init_cfg:
+ roce5_rdma_cleanup_resource(rdev->hwdev);
+
+err_init_resource:
+ if (rdev->gid_dev != NULL) {
+ kfree(rdev->gid_dev);
+ }
+ return ret;
+}
+
+static void roce5_add_rdev_unit(struct roce5_device *rdev)
+{
+ roce5_rdma_cleanup_resource(rdev->hwdev);
+ if (rdev->gid_dev != NULL) {
+ kfree(rdev->gid_dev);
+ }
+}
+
+static __be64 rdma_gen_node_guid(u8 *dev_mac)
+{
+ u8 guid[8];
+ u8 mac_addr[6];
+ __be64 node_guid = 0;
+ int ret;
+
+ if (dev_mac == NULL) {
+ ROCE_ERR("Dev_mac is null");
+ return RDMA_INVALID_GUID;
+ }
+
+ ret = memcpy_s((void *)&mac_addr[0], sizeof(mac_addr), (void *)dev_mac,
+ sizeof(mac_addr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy mac_addr.(ret:%d)", ret);
+ return ENOMEM;
+ }
+
+ guid[0] = mac_addr[0] ^
+ DEV_ADDR_FIRST_BYTE_VAL_MASK; // 0 is mac & guid array idx
+ guid[1] = mac_addr[1]; // 1 is mac & guid array idx
+ guid[2] = mac_addr[2]; // 2 is mac & guid array idx
+ guid[3] = 0xff; // 3 is guid array idx
+ guid[4] = 0xfe; // 4 is guid array idx
+ guid[5] = mac_addr[3]; // 5 is guid array idx, 3 is mac array idx
+ guid[6] = mac_addr[4]; // 6 is guid array idx, 4 is mac array idx
+ guid[7] = mac_addr[5]; // 7 is guid array idx, 5 is mac array idx
+
+ /* node_guid is calculated by guid. */
+ node_guid =
+ ((u64)guid[0] << 56) | // 0 is guid array idx, 56 is guid offset
+ ((u64)guid[1] << 48) | // 1 is guid array idx, 48 is guid offset
+ ((u64)guid[2] << 40) | // 2 is guid array idx, 40 is guid offset
+ ((u64)guid[3] << 32) | // 3 is guid array idx, 32 is guid offset
+ ((u64)guid[4] << 24) | // 4 is guid array idx, 24 is guid offset
+ ((u64)guid[5] << 16) | // 5 is guid array idx, 16 is guid offset
+ ((u64)guid[6] << 8) | // 6 is guid array idx, 8 is guid offset
+ (u64)guid[7]; // 7 is guid array idx
+
+ return (__be64)cpu_to_be64(node_guid);
+}
+
+static __be64 roce5_rdma_init_guid(void *hwdev, struct net_device *netdev)
+{
+ struct rdma_comp_priv *comp_priv = NULL;
+
+ if ((hwdev == NULL) || (netdev == NULL)) {
+ ROCE_ERR("Hwdev or netdev is null");
+ return ~0ULL;
+ }
+
+ comp_priv = get_rdma_comp_priv(hwdev);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return ~0ULL;
+ }
+
+ comp_priv->rdma_comp_res.node_guid =
+ rdma_gen_node_guid((u8 *)netdev->dev_addr);
+
+ return comp_priv->rdma_comp_res.node_guid;
+}
+
+#if defined(HAVE_IB_DEVICE_OPS)
+static const struct ib_device_ops dev_ops = {
+ .owner = THIS_MODULE,
+ .driver_id = RDMA_DRIVER_HRN,
+ .uverbs_abi_ver = ROCE_IB_UVERBS_ABI_VERSION,
+
+ .modify_qp = roce5_modify_qp,
+ .query_qp = roce5_query_qp,
+ .destroy_qp = roce5_destroy_qp,
+ .post_send = roce5_post_send,
+ .post_recv = roce5_post_recv,
+ .create_cq = roce5_create_cq,
+ .modify_cq = roce5_modify_cq,
+ .resize_cq = roce5_resize_cq,
+ .destroy_cq = roce5_destroy_cq,
+ .poll_cq = roce5_poll_cq,
+ .req_notify_cq = roce5_arm_cq,
+ .create_srq = roce5_create_srq,
+ .modify_srq = roce5_modify_srq,
+ .query_srq = roce5_query_srq,
+ .destroy_srq = roce5_destroy_srq,
+ .post_srq_recv = roce5_post_srq_recv,
+ .map_mr_sg = roce5_map_kernel_frmr_sg,
+ .get_dma_mr = roce5_get_dma_mr,
+ .reg_user_mr = roce5_reg_user_mr,
+ .dereg_mr = roce5_dereg_mr,
+ .alloc_mr = roce5_alloc_mr,
+ .alloc_mw = roce5_alloc_mw,
+ .dealloc_mw = roce5_dealloc_mw,
+ .query_device = roce5_query_device,
+ .add_gid = roce5_ib_add_gid,
+ .del_gid = roce5_ib_del_gid,
+ .modify_device = roce5_modify_device,
+ .alloc_ucontext = roce5_alloc_ucontext,
+ .dealloc_ucontext = roce5_dealloc_ucontext,
+ .mmap = roce5_mmap,
+ .alloc_pd = roce5_alloc_pd,
+ .dealloc_pd = roce5_dealloc_pd,
+ .create_ah = roce5_create_ah,
+ .query_ah = roce5_query_ah,
+ .destroy_ah = roce5_destroy_ah,
+ .alloc_xrcd = roce5_alloc_xrcd,
+ .dealloc_xrcd = roce5_dealloc_xrcd,
+
+#if defined(ROCE_CREATE_QP_INT)
+ .create_qp = roce5_create_qp,
+#elif defined(ROCE_CREATE_QP_IB_QP)
+ .create_qp = roce5_create_qp_compat,
+#endif
+
+#if defined(HAVE_ALL_ROCE_FUNCS_U32_PORT)
+ .query_port = roce5_query_port,
+#elif defined(HAVE_ALL_ROCE_FUNCS_U8_PORT)
+ .query_port = roce5_query_port_compat,
+#endif
+
+#if defined(GET_LINK_LAYER_HAVE_U32_PORT)
+ .get_link_layer = roce5_port_link_layer,
+#elif defined(GET_LINK_LAYER_HAVE_U8_PORT)
+ .get_link_layer = roce5_port_link_layer_compat,
+#endif
+
+#if defined(QUERY_GID_HAVE_U32_PORT)
+ .query_gid = roce5_query_gid,
+#elif defined(QUERY_GID_HAVE_U8_PORT)
+ .query_gid = roce5_query_gid_compat,
+#endif
+
+#if defined(QUERY_PKEY_HAVE_U32_PORT)
+ .query_pkey = roce5_query_pkey,
+#elif defined(QUERY_PKEY_HAVE_U8_PORT)
+ .query_pkey = roce5_query_pkey_compat,
+#endif
+
+#if defined(MODIFY_PORT_HAVE_U32_PORT)
+ .modify_port = roce5_modify_port,
+#elif defined(MODIFY_PORT_HAVE_U8_PORT)
+ .modify_port = roce5_modify_port_compat,
+#endif
+
+#if defined(GET_PORT_IMMUTABLE_HAVE_U32_PORT)
+ .get_port_immutable = roce5_port_immutable,
+#elif defined(GET_PORT_IMMUTABLE_HAVE_U8_PORT)
+ .get_port_immutable = roce5_port_immutable_compat,
+#endif
+
+#if defined(GET_NETDEV_HAVE_U32_PORT)
+ .get_netdev = roce5_ib_get_netdev,
+#elif defined(GET_NETDEV_HAVE_U8_PORT)
+ .get_netdev = roce5_ib_get_netdev_compat,
+#endif
+
+#if defined(IB_DEVICE_OPS_HAVE_CREATE_USER_AH)
+ .create_user_ah = roce5_create_ah,
+#endif
+
+ INIT_RDMA_OBJ_SIZE(ib_ah, roce5_ah, ibah),
+ INIT_RDMA_OBJ_SIZE(ib_cq, roce5_cq, ibcq),
+ INIT_RDMA_OBJ_SIZE(ib_pd, roce5_pd, ibpd),
+ INIT_RDMA_OBJ_SIZE(ib_srq, roce5_srq, ibsrq),
+ INIT_RDMA_OBJ_SIZE(ib_ucontext, roce5_ucontext, ibucontext),
+ INIT_RDMA_OBJ_SIZE(ib_xrcd, roce5_xrcd, ibxrcd),
+ INIT_RDMA_OBJ_SIZE(ib_mw, roce5_mw, ibmw),
+#if defined(IB_DEVICE_OPS_HAVE_IB_QP_OBJ)
+ INIT_RDMA_OBJ_SIZE(ib_qp, roce5_qp, ibqp),
+#endif
+};
+
+static void roce5_add_init(struct roce5_device *rdev)
+{
+ struct ib_device *ib_dev = &rdev->ib_dev;
+
+ ib_dev->local_dma_lkey = rdev->rdma_cap.reserved_lkey;
+ ib_dev->phys_port_cnt = (u8)rdev->rdma_cap.num_ports;
+ ib_dev->num_comp_vectors =
+ (rdev->rdma_cap.num_comp_vectors <= MAX_CEQ_NEED) ?
+ (int)rdev->rdma_cap.num_comp_vectors :
+ MAX_CEQ_NEED;
+ ib_dev->node_type = RDMA_NODE_IB_CA;
+ ib_dev->node_guid = roce5_rdma_init_guid(rdev->hwdev, rdev->ndev);
+ ib_dev->dma_device = rdev->dev;
+ ib_dev->dev.parent = ib_dev->dma_device;
+ (void)strcpy_s(ib_dev->node_desc, IB_DEVICE_NODE_DESC_MAX, "hrn5");
+
+ rdev->ib_dev.uverbs_cmd_mask = ROCE_UVERBS_CMD_BASE_MASK;
+#if defined(IB_DEV_HAVE_UVERBS_EX_CMD_MASK)
+ rdev->ib_dev.uverbs_ex_cmd_mask = ROCE_UVERBS_EXT_CMD_MASK;
+#endif
+
+ ib_set_device_ops(ib_dev, &dev_ops);
+ roce5_init_dev_ext_handlers(rdev);
+}
+
+#else
+static void roce5_init_dev_qp_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.create_qp = roce5_create_qp_compat;
+ rdev->ib_dev.modify_qp = roce5_modify_qp;
+ rdev->ib_dev.query_qp = roce5_query_qp;
+ rdev->ib_dev.destroy_qp = roce5_destroy_qp_ofa;
+ rdev->ib_dev.post_send = roce5_post_send;
+ rdev->ib_dev.post_recv = roce5_post_recv;
+}
+
+static void roce5_init_dev_cq_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.create_cq = roce5_create_cq_ofa;
+ rdev->ib_dev.modify_cq = roce5_modify_cq;
+ rdev->ib_dev.resize_cq = roce5_resize_cq;
+ rdev->ib_dev.destroy_cq = roce5_destroy_cq_ofa;
+ rdev->ib_dev.poll_cq = roce5_poll_cq;
+ rdev->ib_dev.req_notify_cq = roce5_arm_cq;
+}
+
+static void roce5_init_dev_srq_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.create_srq = roce5_create_srq_ofa;
+ rdev->ib_dev.modify_srq = roce5_modify_srq;
+ rdev->ib_dev.query_srq = roce5_query_srq;
+ rdev->ib_dev.destroy_srq = roce5_destroy_srq_ofa;
+ rdev->ib_dev.post_srq_recv = roce5_post_srq_recv;
+}
+
+static void roce5_init_dev_mr_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.map_mr_sg = roce5_map_kernel_frmr_sg;
+
+ rdev->ib_dev.get_dma_mr = roce5_get_dma_mr;
+ rdev->ib_dev.reg_user_mr = roce5_reg_user_mr;
+ rdev->ib_dev.dereg_mr = roce5_dereg_mr_ofa;
+ rdev->ib_dev.alloc_mr = roce5_alloc_mr;
+
+ rdev->ib_dev.alloc_mw = roce5_alloc_mw_ofa;
+ rdev->ib_dev.dealloc_mw = roce5_dealloc_mw_ofa;
+}
+
+static void roce5_init_dev_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.query_device = roce5_query_device;
+ rdev->ib_dev.query_port = roce5_query_port_compat;
+ rdev->ib_dev.get_link_layer = roce5_port_link_layer_compat;
+ rdev->ib_dev.query_gid = roce5_query_gid_compat;
+ rdev->ib_dev.add_gid = roce5_ib_add_gid;
+ rdev->ib_dev.del_gid = roce5_ib_del_gid;
+ rdev->ib_dev.query_pkey = roce5_query_pkey_compat;
+ rdev->ib_dev.modify_device = roce5_modify_device;
+ rdev->ib_dev.modify_port = roce5_modify_port_compat;
+
+ rdev->ib_dev.alloc_ucontext = roce5_alloc_ucontext_ofa;
+ rdev->ib_dev.dealloc_ucontext = roce5_dealloc_ucontext_ofa;
+ rdev->ib_dev.mmap = roce5_mmap;
+
+ rdev->ib_dev.alloc_pd = roce5_alloc_pd_ofa;
+ rdev->ib_dev.dealloc_pd = roce5_dealloc_pd_ofa;
+
+ rdev->ib_dev.create_ah = roce5_create_ah_ofa;
+ rdev->ib_dev.query_ah = roce5_query_ah;
+ rdev->ib_dev.destroy_ah = roce5_destroy_ah_ofa;
+
+ roce5_init_dev_qp_handlers(rdev);
+ roce5_init_dev_cq_handlers(rdev);
+ roce5_init_dev_srq_handlers(rdev);
+ roce5_init_dev_mr_handlers(rdev);
+
+ rdev->ib_dev.alloc_xrcd = roce5_alloc_xrcd_ofa;
+ rdev->ib_dev.dealloc_xrcd = roce5_dealloc_xrcd_ofa;
+
+ rdev->ib_dev.get_port_immutable = roce5_port_immutable_compat;
+ rdev->ib_dev.get_netdev = roce5_ib_get_netdev_compat;
+}
+
+static void roce5_add_init(struct roce5_device *rdev)
+{
+ int ret;
+
+ rdev->ib_dev.owner = THIS_MODULE;
+ rdev->ib_dev.node_type = RDMA_NODE_IB_CA;
+ rdev->ib_dev.local_dma_lkey = rdev->rdma_cap.reserved_lkey;
+ rdev->ib_dev.phys_port_cnt = (u8)rdev->rdma_cap.num_ports;
+ rdev->ib_dev.num_comp_vectors =
+ (rdev->rdma_cap.num_comp_vectors <= MAX_CEQ_NEED) ?
+ (int)rdev->rdma_cap.num_comp_vectors :
+ MAX_CEQ_NEED;
+ rdev->ib_dev.dma_device = rdev->dev;
+ rdev->ib_dev.dev.parent = rdev->ib_dev.dma_device;
+ rdev->ib_dev.uverbs_abi_ver = ROCE_IB_UVERBS_ABI_VERSION;
+ rdev->ib_dev.node_guid = roce5_rdma_init_guid(rdev->hwdev, rdev->ndev);
+ ret = memcpy_s((void *)rdev->ib_dev.node_desc, ROCE_NODE_DESC_LEN,
+ "hrn5", ROCE_NODE_DESC_LEN);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy node_desc.(ret:%d)", ret);
+ return;
+ }
+
+ rdev->ib_dev.uverbs_cmd_mask = roce5_get_uverbs_cmd_mask();
+ rdev->ib_dev.uverbs_ex_cmd_mask = ROCE_UVERBS_EXT_CMD_MASK;
+
+ roce5_init_dev_handlers(rdev);
+ roce5_init_dev_ext_handlers(rdev);
+ return;
+}
+#endif
+
+static void roce5_mod_param_parse(struct roce5_device *rdev)
+{
+ if (g_loop_times <= 0) {
+ ROCE_DEV_WARN(
+ rdev,
+ "g_loop_times has been amended to 1, because original value(%d) is smaller than "
+ "or equal to 0.",
+ g_loop_times);
+ g_loop_times = 1;
+ }
+ rdev->try_times = g_loop_times;
+ rdev->destory_flow_timeout = g_destory_flow_timeout;
+ rdev->local_en = g_local_en;
+ rdev->full_qp_spec = g_full_qp_spec;
+ rdev->huge_page_en = g_huge_page_en;
+}
+
+static void roce5_init_mac_vlan(struct roce5_device *rdev)
+{
+ INIT_LIST_HEAD(&rdev->mac_vlan_list_head);
+ mutex_init(&rdev->mac_vlan_mutex);
+}
+
+static int roce5_rdev_init(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = hinic5_stateful_init(rdev->hwdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init stateful resource");
+ return ret;
+ }
+
+ roce5_init_mac_vlan(rdev);
+
+ ret = roce5_add_rdev_init(rdev);
+ if (ret != 0) {
+ goto err;
+ }
+
+ spin_lock_init(&rdev->node_desc_lock);
+ rwlock_init(&rdev->rwlock_func_tbl_bond);
+ mutex_init(&rdev->cap_mask_mutex);
+ spin_lock_init(&rdev->reset_flow_resource_lock);
+ INIT_LIST_HEAD(&rdev->qp_list);
+ roce5_mod_param_parse(rdev);
+
+ roce5_fix_ibdev_name(rdev);
+
+ return 0;
+err:
+ roce5_clean_vlan_device_mac(rdev);
+ hinic5_stateful_deinit(rdev->hwdev);
+ return ret;
+}
+
+static void roce5_rdev_unit(struct roce5_device *rdev)
+{
+ /* FLR by MPU when hotplug, don't need deinit anymore */
+ hinic5_stateful_deinit(rdev->hwdev);
+
+ roce5_add_rdev_unit(rdev);
+
+ mutex_destroy(&rdev->qp_lb_scqn_ctrl.qp_lb_scqn_ctrl_mutex);
+}
+
+static int roce5_add_do_init(struct roce5_device *rdev, char *uld_dev_name)
+{
+ int ret;
+
+ ret = roce5_rdev_init(rdev);
+ if (ret != 0) {
+ goto err_init_rdev;
+ }
+
+ ret = roce5_register_template(rdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to register cqm_service, func_id(%d) ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_cqm_register;
+ }
+
+ ret = hinic5_alloc_db_addr(rdev->hwdev, &rdev->kernel_db_map, NULL);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc db or dwqe, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_alloc_db;
+ }
+#ifdef __ROCE_DFX__
+ ret = roce5_dfx_device_init(rdev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to init dfx device");
+ goto err_init_dfx;
+ }
+#endif
+ roce5_add_init(rdev);
+
+ ret = roce5_alloc_ceq(rdev);
+ if (ret < 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc ceqs, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ goto err_alloc_ceq;
+ }
+
+ ret = roce5_init_dev(rdev, uld_dev_name);
+ if (ret != 0) {
+ goto err_init_dev;
+ }
+
+ return 0;
+
+err_init_dev:
+ roce5_free_ceq(rdev);
+
+err_alloc_ceq:
+#ifdef __ROCE_DFX__
+ roce5_dfx_device_deinit(rdev);
+
+err_init_dfx:
+#endif
+ hinic5_free_db_addr(rdev->hwdev, rdev->kernel_db_map, NULL);
+
+err_alloc_db:
+ cqm5_service_unregister(rdev->hwdev, SERVICE_T_ROCE);
+
+err_cqm_register:
+ roce5_rdev_unit(rdev);
+
+err_init_rdev:
+ return ret;
+}
+
+static int roce5_add_check(const struct hinic5_lld_dev *lld_dev)
+{
+ int ret = 0;
+
+ if (lld_dev == NULL || lld_dev->hwdev == NULL) {
+ ROCE_ERR("Lld_dev is null");
+ return (-EINVAL);
+ }
+
+ ret = roce5_add_check_ext(lld_dev);
+ return ret;
+}
+
+static int roce5_stateful_init(struct hinic5_lld_dev *lld_dev)
+{
+ int ret = 0;
+ struct hinic5_lld_dev *ppf_lld_dev = NULL;
+
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
+ return 0;
+ }
+
+ ppf_lld_dev = hinic5_get_ppf_lld_dev(lld_dev);
+ if (ppf_lld_dev == NULL) {
+ ROCE_ERR("Failed to get ppf lld dev, func id(%u).",
+ hinic5_global_func_id(lld_dev->hwdev));
+ return -EINVAL;
+ }
+
+ ret = hinic5_stateful_init(ppf_lld_dev->hwdev);
+ hinic5_lld_dev_put(ppf_lld_dev);
+
+ return ret;
+}
+
+static void roce5_stateful_deinit(struct hinic5_lld_dev *lld_dev)
+{
+ struct hinic5_lld_dev *ppf_lld_dev = NULL;
+
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
+ return;
+ }
+
+ ppf_lld_dev = hinic5_get_ppf_lld_dev(lld_dev);
+ if (ppf_lld_dev == NULL) {
+ ROCE_ERR("Failed to get ppf lld dev, func id(%u).",
+ hinic5_global_func_id(lld_dev->hwdev));
+ return;
+ }
+
+ hinic5_stateful_deinit(ppf_lld_dev->hwdev);
+
+ hinic5_lld_dev_put(ppf_lld_dev);
+}
+
+static void roce5_do_remove(struct roce5_device *rdev, u16 glb_func_id,
+ const char *dev_name)
+{
+#ifdef __ROCE_DFX__
+ roce5_dfx_device_deinit(rdev);
+#endif
+
+ roce5_g_rdev_remove(rdev);
+
+ roce5_remove_sysfs(rdev);
+
+ ib_unregister_device(&rdev->ib_dev);
+
+ roce5_dealloc_hw_resource(rdev);
+
+ roce5_deinit_dev_info(rdev);
+
+#ifdef ROCE_BONDING_EN
+ roce5_set_bond_ipsurx_en(true);
+#endif
+
+ roce5_clean_vlan_device_mac(rdev);
+ roce5_clean_real_device_mac(rdev);
+
+ roce5_free_ceq(rdev);
+
+ hinic5_free_db_addr(rdev->hwdev, rdev->kernel_db_map, NULL);
+
+ cqm5_service_unregister(rdev->hwdev, SERVICE_T_ROCE);
+
+ roce5_del_func_res(rdev);
+ ROCE_INFO("Function level resource clear ok, func_id(%d), name(%s)",
+ glb_func_id, dev_name);
+
+ roce5_rdev_unit(rdev);
+}
+
+static void roce5_remove(struct hinic5_lld_dev *lld_dev, void *uld_dev)
+{
+ struct roce5_device *rdev = NULL;
+ char *device_name = NULL;
+ u16 glb_func_id;
+ roce_user_handle_t hdl = { 0 };
+
+ if ((uld_dev == NULL) || (lld_dev == NULL)) {
+ ROCE_ERR("input param is null");
+ return;
+ }
+
+ if (hinic5_support_roce(lld_dev->hwdev, NULL) == false) {
+ ROCE_WARN("Not support RoCE.");
+ return;
+ }
+
+ rdev = (struct roce5_device *)uld_dev;
+ rdev->ib_active = false;
+ device_name = rdev->ib_dev.name;
+ glb_func_id = rdev->glb_func_id;
+
+ ROCE_DEV_INFO(rdev, "Remove start, func_id(%d), name(%s)",
+ rdev->glb_func_id, device_name);
+
+ hdl.magic = ROCE_ULD_HANDLE_MAGIC_NUM;
+ hdl.rdev = rdev;
+ roce5_uld_rdev_remove((roce_uld_handle)&hdl);
+
+ roce5_do_remove(rdev, glb_func_id, device_name);
+
+#ifdef ROCE_BONDING_EN
+ roce5_bond_detach(rdev);
+#endif
+
+ ib_dealloc_device(&rdev->ib_dev);
+
+ roce5_stateful_deinit(lld_dev);
+
+ ROCE_INFO("Remove end, func_id(%d), name(%s)", glb_func_id,
+ device_name);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_add
+ Description : roce5_add
+ Input : struct hinic_lld_dev *lld_dev
+ void **uld_dev
+ char *uld_dev_name
+ Output : None
+
+ 1.Date : 2015/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static int roce5_add(struct hinic5_lld_dev *lld_dev, void **uld_dev,
+ char *uld_dev_name)
+{
+ struct roce5_device *rdev = NULL;
+ struct rdma_service_cap rdma_cap;
+ int ret = 0;
+ roce_user_handle_t hdl = { 0 };
+
+ ret = roce5_add_check(lld_dev);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* return 0(false) if the hwdev don't support ROCE, make sure it probe success */
+ if (hinic5_support_roce(lld_dev->hwdev, &rdma_cap) == false) {
+ ROCE_WARN("Not support RoCE, func: %d",
+ hinic5_global_func_id(lld_dev->hwdev));
+ // this pf no has enable RoCE, but is not affect RoCE driver load, no need return exception value
+ ret = 0;
+ goto err_check;
+ }
+
+ ret = roce5_stateful_init(lld_dev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to add ref to ppf.");
+ goto err_check;
+ }
+
+ rdev = roce5_rdev_alloc(lld_dev, uld_dev, &rdma_cap);
+ if (rdev == NULL) {
+ ROCE_ERR("Failed to alloc rdev, func: %d",
+ hinic5_global_func_id(lld_dev->hwdev));
+ ret = -EINVAL;
+ goto err_alloc;
+ }
+
+ ret = roce5_add_do_init(rdev, uld_dev_name);
+ if (ret != 0) {
+ ROCE_ERR("Failed to init rdev.");
+ goto err_do_init;
+ }
+
+ hdl.magic = ROCE_ULD_HANDLE_MAGIC_NUM;
+ hdl.rdev = rdev;
+ ROCE_CONSTUCT_ULD_HDL_SHADOW(&hdl, &rdev->shadow, &rdev->shadow_vfid,
+ &rdev->shadow_vf_num);
+ ret = roce5_uld_rdev_add((roce_uld_handle)&hdl);
+ if (ret != 0) {
+ ROCE_ERR("Failed to add uld rdev.");
+ roce5_do_remove(rdev, rdev->glb_func_id, uld_dev_name);
+ goto err_do_init;
+ }
+
+ ROCE_DEV_INFO(rdev, "Device(0x%p) init success.", rdev);
+ return 0;
+
+err_do_init:
+ ib_dealloc_device(&rdev->ib_dev);
+err_alloc:
+ roce5_stateful_deinit(lld_dev);
+err_check:
+ *uld_dev = NULL;
+ return ret;
+}
+
+static int roce5_set_nic_event(struct roce5_device *rdev,
+ const struct hinic5_event_info *event)
+{
+ switch (event->type) {
+ case EVENT_NIC_LINK_UP:
+ if (test_and_set_bit(ROCE5_PORT_EVENT, &rdev->status) != 0) {
+ return -1;
+ }
+ ROCE_DEV_INFO(rdev, "Report NIC LINK_UP, func_id(%d)",
+ rdev->glb_func_id);
+ return IB_EVENT_PORT_ACTIVE;
+
+ case EVENT_NIC_LINK_DOWN:
+ if (test_and_clear_bit(ROCE5_PORT_EVENT, &rdev->status) == 0) {
+ return -1;
+ }
+ ROCE_DEV_INFO(rdev, "RoCE report NIC LINK_DOWN, func_id(%d)",
+ rdev->glb_func_id);
+ return IB_EVENT_PORT_ERR;
+
+ case EVENT_NIC_DCB_STATE_CHANGE:
+ ROCE_DEV_INFO(
+ rdev,
+ "DCB state change no longer requires RoCE involvement, func_id(%d)",
+ rdev->glb_func_id);
+ return -1;
+
+ default:
+ ROCE_DEV_ERR(rdev,
+ "Nic event unsupported, func_id(%d), event(%d)",
+ rdev->glb_func_id, event->type);
+ return -1;
+ }
+}
+
+static int roce5_set_ib_event(struct roce5_device *rdev,
+ const struct hinic5_event_info *event)
+{
+ switch (event->service) {
+ case EVENT_SRV_NIC:
+ return roce5_set_nic_event(rdev, event);
+
+ case EVENT_SRV_COMM:
+ return roce5_set_comm_event(rdev, event);
+
+ default:
+ ROCE_DEV_ERR(
+ rdev,
+ "func_id(%d) event from svc(%d) is not supported, event(%d)",
+ rdev->glb_func_id, event->service, event->type);
+ return -1;
+ }
+}
+
+void roce5_event(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ struct hinic5_event_info *event)
+{
+ struct ib_event ibevent;
+ struct roce5_device *rdev = NULL;
+ int type, ret = 0;
+
+ if ((lld_dev == NULL) || (uld_dev == NULL)) {
+ ROCE_ERR("Input params is null");
+ goto out;
+ }
+ roce5_lock_rdev();
+
+ ret = roce5_get_rdev_by_uld(lld_dev, uld_dev, &rdev, event);
+ if ((ret != 0) || (rdev == NULL)) {
+ ROCE_ERR("find rdev failed");
+ goto err_unlock;
+ }
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ roce5_handle_bonded_port_state_event(rdev);
+ goto err_unlock;
+ }
+#endif
+ type = roce5_set_ib_event(rdev, event);
+ if (type == -1) {
+ goto err_unlock;
+ }
+
+ ibevent.event = (enum ib_event_type)type;
+ ibevent.device = &rdev->ib_dev;
+ ibevent.element.port_num = ROCE_DEFAULT_PORT_NUM;
+
+ if (rdev->ib_active) {
+ ROCE_DEV_INFO(rdev, "report event: %d.", type);
+ ib_dispatch_event(&ibevent);
+ }
+
+err_unlock:
+ roce5_unlock_rdev();
+
+out:
+ return;
+}
+
+int roce5_adm_dfx_get_dev_type(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct roce5_dfx_common_inbuf *inbuf =
+ (struct roce5_dfx_common_inbuf *)buf_in;
+ union roce5_dfx_common_outbuf *outbuf =
+ (union roce5_dfx_common_outbuf *)buf_out;
+
+ struct roce5_device *find_rdev =
+ roce5_get_rdev_by_name(inbuf->dev_name);
+
+ if (in_size < sizeof(struct roce5_dfx_common_inbuf)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size,
+ (int)sizeof(struct roce5_dfx_common_inbuf));
+ return -ENOMEM;
+ }
+ if (find_rdev == NULL) {
+ ROCE_ERR("Failed to find rdev by device name(%s).",
+ inbuf->dev_name);
+ return -EINVAL;
+ }
+
+ outbuf->dev_type = find_rdev->device_type;
+ *out_size = (u32)sizeof(union roce5_dfx_common_outbuf);
+ return 0;
+}
+
+static roce5_adm_cmd_proc_t g_roce5_adm_cmd_proc[] = {
+#ifdef __ROCE_DFX__
+ { ROCE_CMD_GET_QPC_FROM_CACHE, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_QPC_FROM_HOST, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_CQC_FROM_CACHE, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_CQC_FROM_HOST, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_SRQC_FROM_CACHE, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_SRQC_FROM_HOST, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_MPT_FROM_CACHE, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_MPT_FROM_HOST, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_GID_FROM_CACHE, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_QPC_CQC_PI_CI, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_QP_COUNT, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_DEV_ALGO, roce5_adm_dfx_query },
+ { ROCE_CMD_GET_DEV_TYPE, roce5_adm_dfx_get_dev_type },
+#ifdef ENABLE_DEBUG
+ { ROCE_CMD_DFX_ATTACK, roce5_dfx_attack_func },
+#endif
+#ifdef ROCE_CHIP_TEST
+ { ROCE_CMD_SET_VNIC_WATERLINE, roce5_adm_dfx_vnic_wl_ctrl },
+ { ROCE_CMD_GET_VNIC_WATERLINE, roce5_adm_dfx_vnic_wl_ctrl },
+#endif /* ROCE_CHIP_TEST */
+ { ROCE_CMD_ROCE_SET, roce5_adm_dfx_roce_set },
+ { ROCE_CMD_ROCE_SET_DEBUG, roce5_adm_dfx_roce_set_debug },
+#endif /* __ROCE_DFX__ */
+ { ROCE_CMD_ENABLE_BW_CTRL, roce5_adm_dfx_bw_ctrl },
+ { ROCE_CMD_DISABLE_BW_CTRL, roce5_adm_dfx_bw_ctrl },
+ { ROCE_CMD_CHANGE_BW_CTRL_PARAM, roce5_adm_dfx_bw_ctrl },
+ { ROCE_CMD_QUERY_BW_CTRL_PARAM, roce5_adm_dfx_bw_ctrl },
+ { ROCE_CMD_SET_LDCP_PARAM, roce5_adm_dfx_set_ldcp_param },
+ { ROCE_CMD_PORT_TRAFFIC, roce5_adm_dfx_port_traffic },
+ { ROCE_CMD_ULD_IOCTL_EXTEND,
+ (roce5_adm_func_t)roce5_adm_dfx_uld_extend },
+#ifdef ENABLE_HYPER_ROCE
+ { ROCE_CMD_HYPER, roce5_hyper_tool_dispatch },
+#endif
+};
+
+static int roce5_ioctl(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ struct roce5_device *rdev = (struct roce5_device *)uld_dev;
+ const roce5_adm_generic_cmd_proc_t *generic_array =
+ (const roce5_adm_generic_cmd_proc_t *)g_roce5_adm_cmd_proc;
+ int elem_count =
+ sizeof(g_roce5_adm_cmd_proc) / sizeof(g_roce5_adm_cmd_proc[0]);
+ roce5_adm_func_t roce5_adm_func = NULL;
+
+ /* check whether is root user */
+ if (!capable(CAP_SYS_ADMIN)) {
+ ROCE_ERR("Invalid permission");
+ return -EPERM; /* if not is root, return error */
+ }
+
+ if (cmd == GET_DRV_VERSION) {
+ return roce5_get_drv_version(buf_out, out_size);
+ }
+
+ if (uld_dev == NULL || buf_in == NULL || buf_out == NULL ||
+ out_size == NULL) {
+ ROCE_ERR("Input params is null");
+ return -EINVAL;
+ }
+
+ if (hinic5_support_roce(rdev->hwdev, NULL) == false) {
+ ROCE_ERR("Not support RoCE.");
+ return -EINVAL;
+ }
+
+ if (cmd == GET_DRV_VERSION) {
+ return roce5_get_drv_version(buf_out, out_size);
+ }
+
+ roce5_adm_func = (roce5_adm_func_t)roce5_adm_generic_find_cmd_func(
+ generic_array, elem_count, cmd);
+ if (roce5_adm_func == NULL) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)", cmd);
+ return -EINVAL;
+ }
+ if (cmd == ROCE_CMD_ULD_IOCTL_EXTEND) {
+ roce_user_handle_t hdl = { 0 };
+ hdl.magic = ROCE_ULD_HANDLE_MAGIC_NUM;
+ hdl.rdev = rdev;
+ return roce5_adm_dfx_uld_extend(&hdl, buf_in, in_size, buf_out,
+ out_size);
+ } else {
+ return roce5_adm_func(rdev, buf_in, in_size, buf_out, out_size);
+ }
+}
+
+struct hinic5_uld_info roce5_info = {
+ .probe = roce5_add,
+ .remove = roce5_remove,
+ .suspend = NULL,
+ .resume = NULL,
+ .event = roce5_event,
+ .ioctl = roce5_ioctl,
+};
+
+struct hinic5_uld_info *roce5_info_get(void)
+{
+ return &roce5_info;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_service_init
+ Description :
+ Input : void
+ Output : None
+ Return Value :
+ Calls :
+ Called By :
+
+ History :
+ 1.Date : 2015/5/27
+ Author :
+ Modification : Created function
+
+**************************************************************************** */
+static int __init roce5_service_init(void)
+{
+ int ret;
+
+ roce5_service_init_pre();
+
+ ret = hinic5_register_uld(SERVICE_T_ROCE, roce5_info_get());
+ if (ret != 0) {
+ ROCE_ERR("Failed to register uld. ret(%d)", ret);
+ return ret;
+ }
+
+ ret = roce5_netlink_init();
+ if (ret != 0) {
+ ROCE_ERR("Failed to init netlink, ret(%d)", ret);
+ hinic5_unregister_uld(SERVICE_T_ROCE);
+ return ret;
+ }
+
+#ifdef ROCE_BONDING_EN
+ ret = roce5_bond_init();
+ if (ret != 0) {
+ ROCE_ERR("Failed to init RoCE Bond. ret(%d).", ret);
+ return ret;
+ }
+#endif
+
+ roce5_uld_service_init();
+
+ ret = roce5_register_netdev_notifier();
+ if (ret != 0) {
+ ROCE_ERR("Failed to register netdev notifier. ret(%d)", ret);
+ return ret;
+ }
+
+ ROCE_INFO("Register roce service successful");
+ return 0;
+}
+
+/* ****************************************************************************
+ Prototype : roce5_service_exit
+ Description : roce service disable
+ Input : void
+ Output : None
+ Return Value :
+ Calls :
+ Called By :
+
+ History :
+ 1.Date : 2015/5/27
+ Author :
+ Modification : Created function
+
+**************************************************************************** */
+static void __exit roce5_service_exit(void)
+{
+ roce5_unregister_netdev_notifier();
+
+ roce5_uld_service_exit();
+
+#ifdef ROCE_BONDING_EN
+ roce5_bond_exit();
+#endif
+
+ roce5_netlink_deinit();
+
+ hinic5_unregister_uld(SERVICE_T_ROCE);
+
+ ROCE_INFO("Unregister roce service successful");
+}
+
+module_init(roce5_service_init);
+module_exit(roce5_service_exit);
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.c b/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.c
new file mode 100644
index 000000000..99d3b3afa
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.c
@@ -0,0 +1,1082 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_netdev.h"
+#include "roce_main_extension.h"
+#include "roce_ctx_format.h"
+#include "roce_gid.h"
+#include "roce_cmd.h"
+#include "roce_mpu_cmd.h"
+#include "roce_restore.h"
+#include "rdma_comp.h"
+#include "roce_os_compat.h"
+#include "roce5_gid_type.h"
+
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+#include "hinic5_srv_nic.h"
+
+static struct notifier_block g_roce5_netdev_notifier;
+
+/* ****************************************************************************
+ Prototype : roce5_fill_gid_type
+ Description : fill gid type
+ Input : struct rdma_gid_entry *gid_entry
+ Output : None
+
+ 1.Date : 2016/5/27
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_fill_gid_type(struct rdma_gid_entry *gid_entry,
+ enum roce5_gid_type new_gid_type)
+{
+ static u32 index_roce5_gid_mapping[32][4] = {
+ { 0x120E1436, 3452, 224529784, 0x180E252A },
+ { 0x120E004A, 3472, 224660876, 0x6C0E403E },
+ { 0x120E0042, 3464, 224660836, 0x840E4036 },
+ { 0x120E0042, 3464, 224398688, 0xC00E0036 },
+ { 0x1212143A, 3456, 224791932, 0x1812252E },
+ { 0x1212004E, 3476, 224923024, 0x6C124042 },
+ { 0x12120046, 3468, 224922984, 0x8412403A },
+ { 0x12120046, 3468, 224660836, 0xC012003A },
+ { 0x1216143E, 3460, 225054080, 0x18162532 },
+ { 0x12160052, 3480, 225185172, 0x6C164046 },
+ { 0x1216004A, 3472, 225185132, 0x8416403E },
+ { 0x1216004A, 3472, 224922984, 0xC016003E },
+ { 0x10301458, 3484, 226626968, 0x1830254C },
+ { 0x1030006C, 3504, 226758060, 0x6C304060 },
+ { 0x10300064, 3496, 226758020, 0x84304058 },
+ { 0x10300064, 3496, 226495872, 0xC0300058 },
+ { 0x10401468, 838864300, 227675560, 0x1840255C },
+ { 0x1040007C, 1174408640, 227806652, 0x6C404070 },
+ { 0x10400074, 1040190904, 227806612, 0x84404068 },
+ { 0x10400074, 1040190904, 227544464, 0xC0400068 },
+ { 0x1044146C, 905973168, 227937708, 0x18442560 },
+ { 0x10440080, 1241517508, 228068800, 0x6C444074 },
+ { 0x10440078, 1107299772, 228068760, 0x8444406C },
+ { 0x10440078, 1107299772, 227806612, 0xC044006C },
+ { 0x10481470, 973082036, 228199856, 0x18482564 },
+ { 0x10480084, 1308626376, 228330948, 0x6C484078 },
+ { 0x1048007C, 1174408640, 228330908, 0x84484070 },
+ { 0x1048007C, 1174408640, 228068760, 0xC0480070 },
+ { 0x1262148A, 1040190928, 230034892, 0x1862257E },
+ { 0x1262009E, 1375735268, 230165984, 0x6C624092 },
+ { 0x12620096, 1241517532, 230165944, 0x8462408A },
+ { 0x12620096, 1241517532, 229903796, 0xC062008A },
+ };
+
+ u8 i = 0;
+ gid_entry->dw6_h.bs.gid_type = new_gid_type;
+ gid_entry->dw6_h.bs.gid_update = (new_gid_type == ROCE_IPv4_ROCEv2_GID);
+
+ i = ROCE_GID_MAP_TBL_IDX_GET(gid_entry->dw6_h.bs.tag, (u8)new_gid_type);
+ gid_entry->hdr_len_value = index_roce5_gid_mapping[i][0];
+ if (new_gid_type == ROCE_IPv4_ROCEv2_GID) {
+ *((u32 *)(void *)gid_entry + 1) =
+ cpu_to_be32(index_roce5_gid_mapping[i][1]);
+ *((u32 *)(void *)gid_entry + ROCE_GID_MAP_TBL_IDX2) =
+ cpu_to_be32(
+ index_roce5_gid_mapping[i]
+ [ROCE_GID_MAP_TBL_IDX2]);
+ }
+}
+
+static void roce5_fill_gid_smac(struct net_device *net_dev,
+ struct rdma_gid_entry *gid_entry)
+{
+ int ret;
+ ret = memcpy_s((void *)gid_entry->smac, sizeof(gid_entry->smac),
+ (void *)net_dev->dev_addr, sizeof(gid_entry->smac));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy smac.(ret:%d)", ret);
+ }
+}
+
+/*
+ 2024-04-05 add rdev parameters, because is in roce driver load, via roce5_ib_add_gid to next call, roce5_fill_gid_entry_ext
+ via net_dev get to rdev is empty, function in advance return, cannot execute expected of tunnel assignment logical
+*/
+static void roce5_fill_gid_vlan(const struct roce5_device *rdev,
+ struct net_device *net_dev,
+ struct rdma_gid_entry *gid_entry)
+{
+ if (rdma_vlan_dev_vlan_id(net_dev) != 0xffff) {
+ gid_entry->dw4.bs.cvlan = rdma_vlan_dev_vlan_id(net_dev) &
+ 0xfff;
+ gid_entry->dw6_h.bs.tag = ROCE_GID_VLAN_VALID;
+ }
+
+ roce5_fill_gid_entry_ext(rdev, gid_entry);
+}
+
+/* ****************************************************************************
+ Prototype : roce5_dispatch_event
+ Description : roce5_dispatch_event
+ Input : struct roce5_device *rdev
+ int port_num
+ enum ib_event_type type
+ Output : None
+
+ 1.Date : 2016/3/29
+ Modification : Created function
+
+**************************************************************************** */
+static void roce5_dispatch_event(struct roce5_device *rdev, int port_num,
+ enum ib_event_type type)
+{
+ struct ib_event event;
+ int ret;
+
+ if (rdev == NULL) {
+ ROCE_ERR("Rdev is null");
+ return;
+ }
+
+ ret = memset_s(&event, sizeof(event), 0, sizeof(event));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memset event.(ret:%d)", ret);
+ }
+
+ event.device = &rdev->ib_dev;
+ event.element.port_num = (u8)port_num;
+ event.event = type;
+
+ ROCE_DEV_INFO(rdev, "driver dispatch event: %d.", type);
+ ib_dispatch_event(&event);
+}
+
+static int roce5_del_old_gid_entry(struct roce5_device *rdev)
+{
+ struct rdma_gid_entry old_gid_entry;
+ int ret = 0;
+ int index = 0;
+
+ ret = memset_s(&old_gid_entry, sizeof(old_gid_entry), 0,
+ sizeof(old_gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ret = roce5_get_gid(rdev, 1, index, &old_gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get gid, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ret = roce5_modify_ipsu_tbl_ip_entry(rdev, &old_gid_entry,
+ ROCE_MPU_CMD_DEL_IPSU_IP);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to del ipsu ip entry, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_del_ipsu_tcam_tbl_entry(rdev, &old_gid_entry);
+ }
+ return ret;
+}
+
+static int roce5_netdev_event_ipv4_dev_scan(struct roce5_device *rdev,
+ struct net_device *event_netdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ struct in_device *in_dev = NULL;
+ int ret = 0;
+ int index = 0;
+
+ ret = roce5_del_old_gid_entry(rdev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to del gid_entry.(ret:%d)", ret);
+ return ret;
+ }
+
+ in_dev = in_dev_get(event_netdev);
+ if (in_dev) {
+ for_ifa(in_dev)
+ {
+ ipv6_addr_set_v4mapped(
+ ifa->ifa_address,
+ (struct in6_addr *)gid_entry->raw);
+
+ roce5_fill_gid_vlan(rdev, event_netdev, gid_entry);
+ roce5_fill_gid_smac(event_netdev, gid_entry);
+
+ /* RoCE V2 */
+ if (rdma_protocol_roce_udp_encap(
+ &rdev->ib_dev, ROCE_DEFAULT_PORT_NUM)) {
+ roce5_fill_gid_type(gid_entry,
+ ROCE_IPv4_ROCEv2_GID);
+ ret = roce5_update_gid_mac(rdev, 0, &index,
+ gid_entry);
+ }
+
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to update type(%u) gid(IPv4) when process netdev's event, func_id(%d)",
+ gid_entry->dw6_h.bs.gid_type,
+ rdev->glb_func_id);
+ in_dev_put(in_dev);
+ return ret;
+ }
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ret = roce5_modify_ipsu_tbl_ip_entry(
+ rdev, gid_entry,
+ ROCE_MPU_CMD_ADD_IPSU_IP);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to add ipsu ip entry, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_add_ipsu_tcam_tbl_entry(rdev, gid_entry,
+ index);
+ }
+ roce5_dispatch_event(rdev, ROCE_DEFAULT_PORT_NUM,
+ IB_EVENT_GID_CHANGE);
+ }
+ endfor_ifa(in_dev);
+ in_dev_put(in_dev);
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+struct sin6_list {
+ struct list_head list;
+ struct sockaddr_in6 sin6;
+};
+
+static int roce5_gid_fill(struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry,
+ struct net_device *event_netdev,
+ struct sin6_list *sin6_iter)
+{
+ int ret = 0;
+ int index;
+
+ ret = roce5_del_old_gid_entry(rdev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to del gid_entry.(ret:%d)", ret);
+ return ret;
+ }
+
+ if (cpu_to_be64(gid_entry->global.subnet_prefix) ==
+ ROCE_DEFAULT_GID_SUBNET_PREFIX) {
+ return ret;
+ }
+
+ roce5_fill_gid_vlan(rdev, event_netdev, gid_entry);
+ roce5_fill_gid_smac(event_netdev, gid_entry);
+
+ /* RoCE V2 */
+ if (rdma_protocol_roce_udp_encap(&rdev->ib_dev,
+ ROCE_DEFAULT_PORT_NUM)) {
+ roce5_fill_gid_type(gid_entry, ROCE_IPv6_ROCEv2_GID);
+ ret = roce5_update_gid_mac(rdev, 0, &index, gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to update V2 gid(IPv6), func_id(%d)",
+ rdev->glb_func_id);
+ list_del(&sin6_iter->list);
+ kfree(sin6_iter);
+ return ret;
+ }
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ret = roce5_modify_ipsu_tbl_ip_entry(
+ rdev, gid_entry, ROCE_MPU_CMD_ADD_IPSU_IP);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to add ipsu ip entry, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_add_ipsu_tcam_tbl_entry(rdev, gid_entry, index);
+ }
+ }
+
+ roce5_dispatch_event(rdev, ROCE_DEFAULT_PORT_NUM, IB_EVENT_GID_CHANGE);
+
+ return ret;
+}
+
+static int roce5_netdev_event_ipv6_dev_scan(struct roce5_device *rdev,
+ struct net_device *event_netdev,
+ struct rdma_gid_entry *gid_entry)
+{
+ struct sin6_list *sin6_temp = NULL;
+ struct sin6_list *sin6_iter = NULL;
+ struct inet6_dev *in6_dev = NULL;
+ struct inet6_ifaddr *ifp = NULL;
+ struct sin6_list *entry = NULL;
+ int ret;
+
+ LIST_HEAD(sin6_init_list);
+
+ in6_dev = in6_dev_get(event_netdev);
+ if (in6_dev == NULL) {
+ return 0;
+ }
+
+ read_lock_bh(&in6_dev->lock);
+ list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
+ entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+ if (entry == NULL) {
+ continue;
+ }
+
+ entry->sin6.sin6_family = AF_INET6;
+ entry->sin6.sin6_addr = ifp->addr;
+ list_add_tail(&entry->list, &sin6_init_list);
+ }
+
+ read_unlock_bh(&in6_dev->lock);
+ in6_dev_put(in6_dev);
+
+ list_for_each_entry_safe(sin6_iter, sin6_temp, &sin6_init_list, list) {
+ if (memcpy_s((void *)gid_entry->raw, sizeof(union ib_gid),
+ (void *)&sin6_iter->sin6.sin6_addr,
+ sizeof(union ib_gid)) != 0) {
+ ROCE_WARN("Failed to do memcpy_s");
+ }
+
+ ret = roce5_gid_fill(rdev, gid_entry, event_netdev, sin6_iter);
+ if (ret != 0) {
+ goto err_free;
+ }
+
+ list_del(&sin6_iter->list);
+ kfree(sin6_iter);
+ }
+
+ return 0;
+
+err_free:
+ list_for_each_entry_safe(sin6_iter, sin6_temp, &sin6_init_list, list) {
+ list_del(&sin6_iter->list);
+ kfree(sin6_iter);
+ }
+ return ret;
+}
+#endif
+
+static int roce5_netdev_event_ip_dev_scan(struct roce5_device *rdev,
+ struct net_device *event_netdev)
+{
+ struct rdma_gid_entry gid_entry;
+ int ret;
+
+ ret = memset_s(&gid_entry, sizeof(gid_entry), 0, sizeof(gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ret = roce5_netdev_event_ipv4_dev_scan(rdev, event_netdev, &gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to scan IPv4, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ ret = roce5_netdev_event_ipv6_dev_scan(rdev, event_netdev, &gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to scan IPv6, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static struct roce5_vlan_dev_list *
+roce5_find_vlan_device_list(const struct list_head *mac_list,
+ const struct net_device *netdev)
+{
+ struct roce5_vlan_dev_list *vlan_dev_list = NULL;
+
+ list_for_each_entry(vlan_dev_list, mac_list, list) {
+ if (vlan_dev_list->net_dev == netdev) {
+ return vlan_dev_list;
+ }
+ }
+
+ return NULL;
+}
+
+static int roce5_add_vlan_device(struct roce5_device *rdev,
+ struct net_device *netdev)
+{
+ struct roce5_vlan_dev_list *new_list = NULL;
+ int ret;
+
+ new_list = (struct roce5_vlan_dev_list *)kzalloc(sizeof(*new_list),
+ GFP_KERNEL);
+ if (new_list == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Malloc mac_vlan list_head is NULL, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+
+ new_list->ref_cnt = 1;
+ new_list->net_dev = netdev;
+ new_list->vlan_id = ROCE_GID_SET_VLAN_32BIT_VLAID(
+ ((u32)rdma_vlan_dev_vlan_id(netdev)));
+ ret = memcpy_s(new_list->mac, ROCE_MAC_ADDR_LEN, netdev->dev_addr,
+ ROCE_MAC_ADDR_LEN);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy mac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ INIT_LIST_HEAD(&new_list->list);
+ list_add_tail(&new_list->list, &rdev->mac_vlan_list_head);
+
+ return 0;
+}
+
+static void roce5_del_vlan_device(struct roce5_device *rdev,
+ struct roce5_vlan_dev_list *old_list)
+{
+ list_del(&old_list->list);
+ kfree(old_list);
+}
+
+int roce5_add_vlan_device_mac(struct roce5_device *rdev,
+ struct net_device *netdev)
+{
+ int ret = 0;
+ u32 vlan_id = 0;
+
+ vlan_id = ROCE_GID_SET_VLAN_32BIT_VLAID(
+ ((u32)rdma_vlan_dev_vlan_id(netdev)));
+ ROCE_DEV_INFO(
+ rdev,
+ "enter roce5_add_vlan_device_mac, vlan_id(0x%x), func_id(%d).",
+ vlan_id, rdev->glb_func_id);
+
+ ret = roce5_add_mac_tbl_mac_entry(rdev, (u8 *)netdev->dev_addr,
+ ETH_ALEN, vlan_id, rdev->glb_func_id);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set vlan device mac, vlan_id(0x%x), func_id(%d)",
+ vlan_id, rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_add_ipsu_tbl_mac_entry(rdev, (u8 *)netdev->dev_addr, vlan_id,
+ rdev->glb_func_id,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ ret = roce5_add_bond_vlan_slave_mac(
+ rdev, (u8 *)netdev->dev_addr, (u16)vlan_id);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set bond vlan slave mac, vlan_id(0x%x), func_id(%d)",
+ vlan_id, rdev->glb_func_id);
+ goto err_add_bond_vlan_slave_mac;
+ }
+ }
+#endif
+
+ return ret;
+
+#ifdef ROCE_BONDING_EN
+err_add_bond_vlan_slave_mac:
+ roce5_del_ipsu_tbl_mac_entry(rdev, (u8 *)netdev->dev_addr, ETH_ALEN,
+ vlan_id, hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+
+ (void)hinic5_del_mac(rdev->hwdev, (u8 *)netdev->dev_addr, (u16)vlan_id,
+ rdev->glb_func_id, HINIC5_CHANNEL_ROCE);
+
+ return ret;
+#endif
+}
+
+void roce5_del_vlan_device_mac(struct roce5_device *rdev,
+ struct roce5_vlan_dev_list *old_list)
+{
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ roce5_del_bond_vlan_slave_mac(rdev, old_list->mac,
+ (u16)old_list->vlan_id);
+ }
+#endif
+
+ roce5_del_ipsu_tbl_mac_entry(rdev, old_list->mac, ETH_ALEN,
+ old_list->vlan_id,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+
+ (void)roce5_del_mac_tbl_mac_entry(rdev, old_list->mac, ETH_ALEN,
+ old_list->vlan_id, rdev->glb_func_id);
+}
+
+static int roce5_update_vlan_device_mac(struct roce5_device *rdev,
+ struct net_device *netdev)
+{
+ struct roce5_vlan_dev_list *old_list = NULL;
+ int ret;
+
+ mutex_lock(&rdev->mac_vlan_mutex);
+ old_list =
+ roce5_find_vlan_device_list(&rdev->mac_vlan_list_head, netdev);
+ if (old_list == NULL) {
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ return 0;
+ }
+
+ if (ROCE_MEMCMP(old_list->mac, netdev->dev_addr, ROCE_MAC_ADDR_LEN) !=
+ 0) {
+ roce5_del_vlan_device_mac(rdev, old_list);
+
+ ret = roce5_add_vlan_device_mac(rdev, netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to add mac_vlan, func_id(%d)",
+ rdev->glb_func_id);
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ return ret;
+ }
+
+ ret = memcpy_s(old_list->mac, ROCE_MAC_ADDR_LEN,
+ netdev->dev_addr, ROCE_MAC_ADDR_LEN);
+ if (ret != 0) {
+ roce5_del_vlan_device_mac(rdev, old_list);
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ return ret;
+ }
+ }
+
+ mutex_unlock(&rdev->mac_vlan_mutex);
+
+ return 0;
+}
+
+int roce5_add_real_device_mac(struct roce5_device *rdev,
+ struct net_device *netdev)
+{
+ int ret;
+
+ roce5_add_ipsu_tbl_mac_entry(rdev, (u8 *)netdev->dev_addr, 0,
+ rdev->glb_func_id,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ ret = roce5_add_bond_real_slave_mac(rdev,
+ (u8 *)netdev->dev_addr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to add bond read device ipsu mac, func_id(%d)",
+ rdev->glb_func_id);
+ roce5_del_ipsu_tbl_mac_entry(
+ rdev, (u8 *)netdev->dev_addr, ETH_ALEN, 0,
+ hinic5_er_id(rdev->hwdev), rdev->glb_func_id);
+ return ret;
+ }
+ }
+#endif
+
+ ret = memcpy_s(rdev->mac, sizeof(rdev->mac), netdev->dev_addr,
+ sizeof(rdev->mac));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy mac.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void roce5_del_real_device_mac(struct roce5_device *rdev)
+{
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ roce5_del_bond_real_slave_mac(rdev);
+ }
+#endif
+
+ roce5_del_ipsu_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN, 0,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+}
+
+static int roce5_update_real_device_mac(struct roce5_device *rdev,
+ struct net_device *netdev)
+{
+ int ret;
+
+ roce5_del_real_device_mac(rdev);
+
+ ret = roce5_add_real_device_mac(rdev, netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to add real device ipsu mac, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+void roce5_clean_vlan_device_mac(struct roce5_device *rdev)
+{
+ struct roce5_vlan_dev_list *pos = NULL;
+ struct roce5_vlan_dev_list *tmp = NULL;
+
+ mutex_lock(&rdev->mac_vlan_mutex);
+ list_for_each_entry_safe(pos, tmp, &rdev->mac_vlan_list_head, list) {
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ (void)roce5_del_bond_vlan_slave_mac(rdev, pos->mac,
+ (u16)pos->vlan_id);
+ }
+#endif
+ roce5_del_ipsu_tbl_mac_entry(rdev, pos->mac, ETH_ALEN,
+ pos->vlan_id,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+
+ (void)roce5_del_mac_tbl_mac_entry(rdev, pos->mac, ETH_ALEN,
+ pos->vlan_id,
+ rdev->glb_func_id);
+
+ list_del(&pos->list);
+ kfree(pos);
+ }
+ mutex_unlock(&rdev->mac_vlan_mutex);
+}
+
+void roce5_clean_real_device_mac(struct roce5_device *rdev)
+{
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ (void)roce5_del_bond_real_slave_mac(rdev);
+ }
+#endif
+
+ roce5_del_ipsu_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN, 0,
+ hinic5_er_id(rdev->hwdev),
+ rdev->glb_func_id);
+}
+
+void roce5_ifconfig_up_down_event_report(struct roce5_device *rdev,
+ u8 net_event)
+{
+ struct ib_event event = {};
+
+ event.device = &rdev->ib_dev;
+ event.event = net_event;
+ event.element.port_num = ROCE_DEFAULT_PORT_NUM;
+
+ ib_dispatch_event(&event);
+}
+
+static int roce5_netdev_event_raw_dev(unsigned long event,
+ struct roce5_device *rdev,
+ struct net_device *event_netdev)
+{
+ int ret;
+
+ if (event == NETDEV_CHANGEADDR) {
+ ret = roce5_update_real_device_mac(rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to update real device mac, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_netdev_event_ip_dev_scan(rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to scan ip_dev, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+#ifdef ROCE_BONDING_EN
+ if (roce5_bond_is_active(rdev)) {
+ if ((event == NETDEV_DOWN) || (event == NETDEV_UP)) {
+ roce5_handle_bonded_port_state_event(rdev);
+ }
+ return 0;
+ }
+#endif
+ if (event == NETDEV_DOWN) {
+ if (test_and_clear_bit(ROCE5_PORT_EVENT, &rdev->status) != 0) {
+ roce5_ifconfig_up_down_event_report(rdev,
+ IB_EVENT_PORT_ERR);
+ }
+ }
+
+ if (event == NETDEV_UP) {
+ if (test_and_set_bit(ROCE5_PORT_EVENT, &rdev->status) == 0) {
+ roce5_ifconfig_up_down_event_report(
+ rdev, IB_EVENT_PORT_ACTIVE);
+ }
+ }
+
+ return 0;
+}
+
+static int roce5_netdev_event_vlan_dev(unsigned long event,
+ struct roce5_device *rdev,
+ struct net_device *event_netdev)
+{
+ int ret;
+
+ if (event == NETDEV_CHANGEADDR) {
+ ret = roce5_update_vlan_device_mac(rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to update vlan device mac, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_netdev_event_ip_dev_scan(rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to scan vlan device ip list, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int roce5_netdev_event(struct notifier_block *nb, unsigned long event,
+ void *ptr)
+{
+ struct net_device *event_netdev = NULL;
+ struct roce5_device *rdev = NULL;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ struct net_device *real_dev = NULL;
+ int ret;
+
+ if (nb == NULL || ptr == NULL) {
+ goto err_out;
+ }
+
+ event_netdev = netdev_notifier_info_to_dev(ptr);
+ if (event_netdev->type != ARPHRD_ETHER) {
+ goto err_out;
+ }
+
+ real_dev = (rdma_vlan_dev_real_dev(event_netdev) != 0) ?
+ rdma_vlan_dev_real_dev(event_netdev) :
+ event_netdev;
+
+ lld_dev = hinic5_get_lld_dev_by_netdev(real_dev);
+ if (lld_dev == NULL) {
+ goto err_out;
+ }
+
+ /*
+ * hinic5_get_uld_dev internal will call uld5_dev_hold add device reference count
+ * via uld5_dev_put free reference count
+ */
+ rdev = (struct roce5_device *)hinic5_get_uld_dev(lld_dev,
+ SERVICE_T_ROCE);
+
+ /*
+ * passed in of rdev is empty value when,roce5_bond_event_cfg_rdev will found lld corresponding to bond device rdev, call uld5_dev_hold add device reference count
+ * passed in of rdev non-null value when, reserved rdev original value, not will call uld5_dev_hold add device reference count
+ * via uld5_dev_put free reference count
+ */
+ ret = roce5_bond_event_cfg_rdev(lld_dev, (void *)rdev, &rdev, true);
+ if (ret != 0 || rdev == NULL) {
+ goto err_out;
+ }
+
+ /* not need extra of roce5_is_port_of_net_dev check */
+ if (real_dev == event_netdev) {
+ ret = roce5_netdev_event_raw_dev(event, rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to deal with raw device, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_put;
+ }
+ } else {
+ ret = roce5_netdev_event_vlan_dev(event, rdev, event_netdev);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to deal with vlan device, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_put;
+ }
+ }
+
+err_put:
+ uld5_dev_put(rdev->lld_dev, SERVICE_T_ROCE);
+err_out:
+ return NOTIFY_DONE;
+}
+
+int roce5_register_netdev_notifier(void)
+{
+ int ret;
+
+ g_roce5_netdev_notifier.notifier_call = roce5_netdev_event;
+ ret = register_netdevice_notifier(&g_roce5_netdev_notifier);
+ if (ret != 0) {
+ ROCE_ERR("Failed to register netdev notifier, ret(%d)", ret);
+ g_roce5_netdev_notifier.notifier_call = NULL;
+ }
+
+ return ret;
+}
+
+void roce5_unregister_netdev_notifier(void)
+{
+ if (g_roce5_netdev_notifier.notifier_call != NULL) {
+ unregister_netdevice_notifier(&g_roce5_netdev_notifier);
+ g_roce5_netdev_notifier.notifier_call = NULL;
+ }
+}
+
+static int roce5_set_gid_entry(const struct ib_gid_attr *attr,
+ struct rdma_gid_entry *gid_entry)
+{
+ int ret = 0;
+ enum rdma_network_type network_type;
+ static enum roce5_gid_type gid_type_map[] = {
+ // map rdma_network_type to roce5_gid_type
+ [RDMA_NETWORK_IB] = ROCE_ROCEv1_GID,
+ [RDMA_NETWORK_ROCE_V1] = ROCE_ROCEv1_GID,
+ [RDMA_NETWORK_IPV4] = ROCE_IPv4_ROCEv2_GID,
+ [RDMA_NETWORK_IPV6] = ROCE_IPv6_ROCEv2_GID,
+ };
+
+ ret = memset_s(gid_entry, sizeof(*gid_entry), 0, sizeof(*gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ network_type = rdma_gid_attr_network_type(attr);
+ ret = memcpy_s((void *)gid_entry->raw, sizeof(union ib_gid),
+ (void *)(&attr->gid), sizeof(union ib_gid));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ if (network_type == RDMA_NETWORK_ROCE_V1 ||
+ network_type == RDMA_NETWORK_IB) {
+ ROCE_ERR("network type(%d) is unsupported.", network_type);
+ return -EINVAL;
+ }
+
+ roce5_fill_gid_vlan(to_roce5_dev(attr->device), attr->ndev, gid_entry);
+ roce5_fill_gid_type(gid_entry, gid_type_map[network_type]);
+ roce5_fill_gid_smac(attr->ndev, gid_entry);
+
+ return 0;
+}
+
+/* add vlan_mac list or ref_cnt + 1
+ * add mac_vlan when new list add
+ */
+static int roce5_notify_vlan(struct roce5_device *rdev,
+ const struct ib_gid_attr *attr)
+{
+ int ret;
+ struct roce5_vlan_dev_list *old_list = NULL;
+
+ mutex_lock(&rdev->mac_vlan_mutex);
+ ROCE_DEV_INFO(rdev, "Add vlan: func_id(%d), netdev(%s).",
+ rdev->glb_func_id, attr->ndev->name);
+ old_list = roce5_find_vlan_device_list(&rdev->mac_vlan_list_head,
+ attr->ndev);
+ if (old_list != NULL) {
+ old_list->ref_cnt++;
+ ret = 0;
+ goto out;
+ }
+
+ ret = roce5_add_vlan_device(rdev, attr->ndev);
+ if (ret != 0) {
+ goto out;
+ }
+
+ ret = roce5_add_vlan_device_mac(rdev, attr->ndev);
+ if (ret != 0) {
+ old_list = roce5_find_vlan_device_list(
+ &rdev->mac_vlan_list_head, attr->ndev);
+ if (old_list) {
+ roce5_del_vlan_device(rdev, old_list);
+ }
+ }
+
+out:
+ mutex_unlock(&rdev->mac_vlan_mutex);
+
+ return ret;
+}
+
+int roce5_ib_add_gid_common(const struct ib_gid_attr *attr)
+{
+ int ret;
+ struct rdma_gid_entry gid_entry;
+ struct roce5_device *rdev = NULL;
+ unsigned int index;
+
+ // the input gid pointer is not needed to check on Euler OS
+ if (attr == NULL) {
+ ROCE_ERR("Input pointer is NULL");
+ return (-EINVAL);
+ }
+
+ rdev = to_roce5_dev(attr->device);
+ index = attr->index;
+
+ ret = roce5_set_gid_entry(attr, &gid_entry);
+ if (ret != 0) {
+ ROCE_ERR("Failed to set gid entry.");
+ return ret;
+ }
+
+ ret = roce5_update_gid(rdev, 0, index, &gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to update gid. ret(%d),func_id(%d)",
+ ret, rdev->glb_func_id);
+ return ret;
+ }
+
+ rdev->gid_dev[index] = attr->ndev;
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ret = roce5_modify_ipsu_tbl_ip_entry(rdev, &gid_entry,
+ ROCE_MPU_CMD_ADD_IPSU_IP);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to add ipsu ip entry, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_add_ipsu_tcam_tbl_entry(rdev, &gid_entry, index);
+ }
+
+ if (rdma_vlan_dev_real_dev(attr->ndev)) {
+ ret = roce5_notify_vlan(rdev, attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to nofify vlan, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int roce5_ib_add_gid(const struct ib_gid_attr *attr,
+ __always_unused void **context)
+{
+ return roce5_ib_add_gid_common(attr);
+}
+
+int roce5_ib_del_gid(const struct ib_gid_attr *attr,
+ __always_unused void **context)
+{
+ struct roce5_vlan_dev_list *old_list = NULL;
+ struct roce5_device *rdev = NULL;
+ struct rdma_gid_entry gid_entry;
+ u32 index = 0;
+ int ret;
+
+ if ((attr == NULL) || (attr->device == NULL)) {
+ ROCE_ERR("Attr or attr->device is null");
+ return (-EINVAL);
+ }
+
+ rdev = to_roce5_dev(attr->device);
+ index = attr->index;
+ if (index >= rdev->rdma_cap.max_gid_per_port) {
+ ROCE_DEV_ERR(rdev, "Invalid gid index(%u), func_id(%d)", index,
+ rdev->glb_func_id);
+ return (-EINVAL);
+ }
+
+ /* del vlan_mac list or ref_cnt - 1 */
+ /* del mac_vlan when ref_cnt = 0 */
+ if (rdev->ndev != rdev->gid_dev[index]) {
+ mutex_lock(&rdev->mac_vlan_mutex);
+ old_list = roce5_find_vlan_device_list(
+ &rdev->mac_vlan_list_head, rdev->gid_dev[index]);
+ if (old_list) {
+ old_list->ref_cnt--;
+ if (old_list->ref_cnt == 0) {
+ roce5_del_vlan_device_mac(rdev, old_list);
+
+ roce5_del_vlan_device(rdev, old_list);
+ }
+ }
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ }
+
+ ret = memset_s(&gid_entry, sizeof(gid_entry), 0, sizeof(gid_entry));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ret = roce5_get_gid(rdev, 1, index, &gid_entry);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get gid, func_id(%d), index(%u)",
+ rdev->glb_func_id, index);
+ return ret;
+ }
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ret = roce5_modify_ipsu_tbl_ip_entry(rdev, &gid_entry,
+ ROCE_MPU_CMD_DEL_IPSU_IP);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to del ipsu ip entry, func_id(%d)",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ roce5_del_ipsu_tcam_tbl_entry(rdev, &gid_entry);
+ }
+
+ /*
+ * delete gid no longer send cmd to ucode which write 0s to target entry,
+ * preventing PPE from building malformed packets. */
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.h b/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.h
new file mode 100644
index 000000000..f77f75dbc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netdev/roce_netdev.h
@@ -0,0 +1,70 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_NETDEV_H
+#define ROCE_NETDEV_H
+
+#include <net/ipv6.h>
+#include <net/bonding.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/inetdevice.h>
+#include <linux/if_vlan.h>
+
+#include <rdma/ib_addr.h>
+
+#include "roce.h"
+#include "roce_compat.h"
+#include "roce_mix.h"
+#include "roce_cmd.h"
+
+#ifdef ROCE_BONDING_EN
+#include "hinic5_srv_nic.h"
+#endif
+
+#include "securec.h"
+
+#define ROCE_GID_SET_VLAN_32BIT_VLAID(vlan_id) \
+ ((vlan_id) | (((u32)1) << 31)) /* the 31 bit is vlan eable bit */
+#define ROCE_MAC_ADDR_LEN 6
+
+/* ipv4 header len. unit:4B */
+#define IPV4_HDR_LEN 5
+
+#define IP_ECN_PERMIT 0x2 //ip header tclass bit[0:2]
+
+#define ROCE_DEFAULT_GID_SUBNET_PREFIX 0xFE80000000000000ULL
+
+#define ROCE_GID_MAP_TBL_IDX_GET(tag, new_gid_type) \
+ ((u8)(((tag) << 2) | (new_gid_type)))
+
+#define ROCE_GID_MAP_TBL_IDX2 2
+
+enum roce5_gid_vlan_type { ROCE_GID_VLAN_INVALID = 0, ROCE_GID_VLAN_VALID };
+
+enum roce5_gid_tunnel_type {
+ ROCE_GID_TUNNEL_INVALID = 0,
+ ROCE_GID_TUNNEL_VALID
+};
+
+struct roce5_vlan_dev_list {
+ u8 mac[ETH_ALEN];
+ u32 vlan_id;
+ u32 ref_cnt;
+ struct net_device *net_dev;
+ struct list_head list;
+};
+
+#if !defined(INETDEV_HAVE_FOR_IFA)
+#define for_ifa(in_dev) \
+ { \
+ struct in_ifaddr *ifa; \
+ for (ifa = (in_dev)->ifa_list; ifa; ifa = ifa->ifa_next)
+#define endfor_ifa(in_dev) }
+#endif
+
+int roce5_add_real_device_mac(struct roce5_device *rdev,
+ struct net_device *netdev);
+
+#endif /* ROCE_NETDEV_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.c b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.c
new file mode 100644
index 000000000..6a16c7f29
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.c
@@ -0,0 +1,413 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+
+
+#include <linux/genetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <net/genetlink.h>
+#include <net/net_namespace.h>
+#include <net/netlink.h>
+
+#include "roce.h"
+#include "hinic5_crm.h"
+#include "hinic5_lld.h"
+#include "roce_drv_msg_intf.h"
+#include "roce_infra.h"
+#include "roce_kernel_compat_gen.h"
+#include "roce_netlink_process.h"
+#include "securec.h"
+#include "udk_usrnl.h"
+#ifdef ENABLE_HYPER_ROCE
+#include "hyper_roce_netlink.h"
+#endif
+#include "roce_netlink.h"
+
+static int roce5_netlink_cmd_dispatch(struct sk_buff *skb,
+ struct genl_info *nl_info);
+
+static DEFINE_RWLOCK(g_cmd_process_rwlock); /* lock for cmd_cbs */
+static roce5_netlink_cmd_excute_callback cmd_cbs[USRNL_ROCE_CMD_NUM];
+
+static int roce5_netlink_register_cb(enum roce_usrnl_cmd cmd,
+ roce5_netlink_cmd_excute_callback cb)
+{
+ int ret = 0;
+
+ if (cmd >= USRNL_ROCE_CMD_NUM) {
+ ROCE_ERR("Invalid command(%u)", cmd);
+ return -EINVAL;
+ }
+
+ write_lock(&g_cmd_process_rwlock);
+
+ if (cmd_cbs[cmd] != NULL) {
+ ROCE_ERR(
+ "Repeated command setting, the callback of the command(%u) already exists.",
+ cmd);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ cmd_cbs[cmd] = cb;
+
+out:
+ write_unlock(&g_cmd_process_rwlock);
+ return ret;
+}
+
+static void roce5_netlink_unregister_cb(enum roce_usrnl_cmd cmd)
+{
+ if (cmd >= USRNL_ROCE_CMD_NUM) {
+ ROCE_ERR("Invalid command(%u)", cmd);
+ return;
+ }
+
+ write_lock(&g_cmd_process_rwlock);
+ cmd_cbs[cmd] = NULL;
+ write_unlock(&g_cmd_process_rwlock);
+}
+
+int roce5_netlink_register_cbs(roce5_netlink_cmd_process cmd_procs[],
+ u8 cmd_num)
+{
+ int ret, i;
+
+ for (i = 0; i < cmd_num; ++i) {
+ ret = roce5_netlink_register_cb(cmd_procs[i].cmd,
+ cmd_procs[i].callback);
+ if (ret != 0) {
+ ROCE_ERR("Failed to set callback in netlink, ret(%d)",
+ ret);
+ goto err_out;
+ }
+ }
+
+ return 0;
+
+err_out:
+ for (--i; i >= 0; --i) {
+ roce5_netlink_unregister_cb(cmd_procs[i].cmd);
+ }
+ return ret;
+}
+
+static roce5_netlink_cmd_process g_cmd_process[] = {
+#ifdef ROCE_BONDING_EN
+ { USRNL_ROCE_CMD_QUERY_QP_TX_PORT, roce5_genl_query_qp_tx_port },
+ { USRNL_ROCE_CMD_SET_QP_TX_PORT, roce5_genl_set_qp_tx_port },
+ { USRNL_ROCE_CMD_QUERY_QP_RX_PORT, roce5_genl_query_qp_rx_port },
+ { USRNL_ROCE_CMD_QUERY_BOND_PORT_INFO,
+ roce5_genl_query_bond_port_info },
+ { USRNL_ROCE_CMD_SET_QP_UDP_SRC_PORT, roce5_genl_set_qp_udp_src_port },
+ { USRNL_ROCE_CMD_QUERY_QP_UDP_SRC_PORT,
+ roce5_genl_query_qp_udp_src_port },
+#endif
+ { USRNL_ROCE_CMD_QUERY_NEXT_WQE_IDX, roce5_genl_query_next_wqe_idx },
+ { USRNL_ROCE_CMD_QUERY_QPC, roce5_genl_query_qpc },
+ { USRNL_ROCE_CMD_QUERY_CQC, roce5_genl_query_cqc },
+ { USRNL_ROCE_CMD_QP_HASH_VALUE_PROCESS,
+ roce5_genl_qp_hash_value_process },
+ { USRNL_ROCE_CMD_ULD,
+ roce5_netlink_uld_process }, /* usr kernel of uld interface */
+};
+
+static int roce5_netlink_init_cbs(void)
+{
+ int ret;
+
+ ret = roce5_netlink_register_cbs(
+ g_cmd_process,
+ sizeof(g_cmd_process) / sizeof(roce5_netlink_cmd_process));
+ if (ret != 0) {
+ ROCE_ERR("Failed to register netlink callbacks, ret(%d).", ret);
+ return ret;
+ }
+
+#ifdef ENABLE_HYPER_ROCE
+ ret = roce5_hyper_netlink_init();
+ if (ret != 0) {
+ ROCE_ERR("Failed to init hyper roce in netlink, ret(%d).", ret);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+#if defined(NLA_POLICY_HAVE_MIN_MAX)
+static const struct nla_policy roce5_policy[USRNL_GENL_ATTR_MAX + 1] = {
+ [USRNL_GENL_ATTR] = { .type = NLA_BINARY,
+ .len = CMD_BUF_LEN_MAX,
+ .min = 0,
+ .max = CMD_BUF_LEN_MAX },
+};
+#else
+static const struct nla_policy roce5_policy[USRNL_GENL_ATTR_MAX + 1] = {
+ [USRNL_GENL_ATTR] = { .type = NLA_BINARY, .len = CMD_BUF_LEN_MAX },
+};
+#endif
+
+static const struct genl_ops roce5_genl_ops[] = { {
+ .cmd = USRNL_DEV_DRV_CMD_EXECUTE,
+#ifdef HAVE_GENL_OPS_FIELD_VALIDATE
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
+ .flags = GENL_ADMIN_PERM,
+ .policy = roce5_policy,
+ .doit = roce5_netlink_cmd_dispatch,
+} };
+
+static struct genl_family roce5_genl_family = {
+ .hdrsize = 0,
+ .name = ROCE_GENL_FAMILY_NAME,
+ .version = 1,
+ .maxattr = USRNL_GENL_ATTR_MAX,
+ .netnsok = true,
+ .parallel_ops = true,
+ .ops = roce5_genl_ops,
+ .n_ops = ARRAY_SIZE(roce5_genl_ops),
+};
+
+static void roce5_drv_msg_hdr_push(struct sk_buff *skb,
+ usrnl_drv_msg_hdr_s *in_msg_hdr,
+ uint16_t out_msg_data_len)
+{
+ usrnl_drv_msg_hdr_s *out_msg_hdr = NULL;
+
+ out_msg_hdr = skb_push(skb, ROCE_DRV_MSG_HDRLEN);
+ out_msg_hdr->cmd = in_msg_hdr->cmd;
+ out_msg_hdr->msg_len = ROCE_DRV_MSG_HDRLEN + out_msg_data_len;
+ out_msg_hdr->module = in_msg_hdr->module;
+ out_msg_hdr->src_func_idx = in_msg_hdr->src_func_idx;
+ out_msg_hdr->err_code = 0;
+}
+
+static void roce5_nlahdr_push(struct sk_buff *skb, uint16_t type)
+{
+ struct nlattr *nlahdr = NULL;
+ uint16_t attrlen = (uint16_t)skb->len;
+ uint32_t padlen = (uint32_t)nla_padlen(attrlen);
+
+ nlahdr = (struct nlattr *)skb_push(skb, NLA_HDRLEN);
+ nlahdr->nla_len = (uint16_t)nla_attr_size(attrlen);
+ nlahdr->nla_type = type;
+
+ if ((skb->end - skb->tail) >= padlen) {
+ (void)skb_put(skb, padlen);
+ }
+}
+
+static struct nlmsghdr *nlmsg_push(struct sk_buff *skb, uint32_t portid,
+ uint32_t seq, uint16_t type, uint32_t len,
+ uint16_t flags)
+{
+ struct nlmsghdr *nlh = NULL;
+ uint32_t size = (uint32_t)nlmsg_msg_size(len);
+
+ nlh = (struct nlmsghdr *)skb_push(skb, NLMSG_ALIGN(size));
+ if (nlh != NULL) {
+ nlh->nlmsg_type = type;
+ nlh->nlmsg_len = skb->len;
+ nlh->nlmsg_flags = flags;
+ nlh->nlmsg_pid = portid;
+ nlh->nlmsg_seq = seq;
+ if (!__builtin_constant_p(size) ||
+ NLMSG_ALIGN(size) - size != 0) {
+ (void)memset_s((char *)nlmsg_data(nlh) + len,
+ NLMSG_ALIGN(size) - size, 0,
+ NLMSG_ALIGN(size) - size);
+ }
+ }
+
+ return nlh;
+}
+
+static inline struct nlmsghdr *roce5_nlmsg_push(struct sk_buff *skb,
+ uint32_t portid, uint32_t seq,
+ uint16_t type, uint32_t payload,
+ uint16_t flags)
+{
+ if (unlikely(skb_headroom(skb) <
+ (unsigned int)nlmsg_total_size(payload))) {
+ return NULL;
+ }
+
+ return nlmsg_push(skb, portid, seq, type, payload, flags);
+}
+
+static void *roce5_genlmsg_push(struct sk_buff *skb, uint32_t portid,
+ uint32_t seq, const struct genl_family *family,
+ uint16_t flags, uint8_t cmd)
+{
+ struct nlmsghdr *nlh = NULL;
+ struct genlmsghdr *hdr = NULL;
+
+ nlh = roce5_nlmsg_push(skb, portid, seq, (int)family->id,
+ (int)(GENL_HDRLEN + family->hdrsize), flags);
+ if (nlh == NULL) {
+ return NULL;
+ }
+
+ hdr = nlmsg_data(nlh);
+ hdr->cmd = cmd;
+ hdr->version = (uint8_t)family->version;
+ hdr->reserved = 0;
+
+ return (void *)nlh;
+}
+
+static inline roce5_netlink_cmd_excute_callback
+roce5_netlink_get_callback(uint16_t cmd)
+{
+ roce5_netlink_cmd_excute_callback cb = NULL;
+
+ if (cmd >= USRNL_ROCE_CMD_NUM) {
+ ROCE_ERR("Invalid command(%u).", cmd);
+ return NULL;
+ }
+
+ read_lock(&g_cmd_process_rwlock);
+ cb = cmd_cbs[cmd];
+ read_unlock(&g_cmd_process_rwlock);
+
+ return cb;
+}
+
+static int32_t
+roce5_netlink_buf_handler(struct nlattr *cmd_attr,
+ roce5_netlink_cmd_excute_callback callback,
+ struct roce5_device *rdev, struct genl_info *nl_info,
+ struct sk_buff *reply)
+{
+ int32_t ret = 0;
+ uint16_t buf_in_len = 0;
+ uint16_t max_buf_out_len = 0;
+ uint16_t buf_out_len = 0;
+ usrnl_drv_msg_hdr_s *in_msg_hdr = NULL;
+
+ in_msg_hdr = (usrnl_drv_msg_hdr_s *)nla_data(cmd_attr);
+ if (in_msg_hdr->msg_len < ROCE_DRV_MSG_HDRLEN) {
+ ROCE_DEV_ERR(rdev, "Invalid parameter: msg_len(%d).",
+ in_msg_hdr->msg_len);
+ return -EINVAL;
+ }
+
+ buf_in_len = in_msg_hdr->msg_len - ROCE_DRV_MSG_HDRLEN;
+ max_buf_out_len =
+ NLMSG_DEFAULT_SIZE -
+ (NLMSG_HDRLEN + GENL_HDRLEN + NLA_HDRLEN + ROCE_DRV_MSG_HDRLEN);
+
+ if (buf_in_len == 0) {
+ ret = callback(rdev, NULL, 0, reply->data, max_buf_out_len,
+ &buf_out_len);
+ } else {
+ ret = callback(rdev, nla_data(cmd_attr) + ROCE_DRV_MSG_HDRLEN,
+ buf_in_len, reply->data, max_buf_out_len,
+ &buf_out_len);
+ }
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Do netlink %u cmd failed, errcode:%d",
+ nl_info->genlhdr->cmd, ret);
+ nlmsg_free(reply);
+ return -EIO;
+ }
+
+ if (buf_out_len != 0) {
+ skb_put(reply, buf_out_len);
+ }
+
+ roce5_drv_msg_hdr_push(reply, in_msg_hdr, buf_out_len);
+
+ return 0;
+}
+
+static int roce5_netlink_cmd_dispatch(struct sk_buff *skb,
+ struct genl_info *nl_info)
+{
+ int32_t ret = 0;
+ struct sk_buff *reply = NULL;
+ struct nlattr *cmd_attr = NULL;
+ roce5_drv_msg_hdr_s *in_msg_hdr = NULL;
+ roce5_netlink_cmd_excute_callback callback = NULL;
+ struct roce5_device *rdev = NULL;
+
+ cmd_attr = nl_info->attrs[USRNL_GENL_ATTR];
+ if (cmd_attr == NULL) {
+ ROCE_ERR("Do netlink cmd from portid:%u failed for NULL attr",
+ nl_info->snd_portid);
+ return -EINVAL;
+ } else if (nla_len(cmd_attr) < ROCE_DRV_MSG_HDRLEN) {
+ ROCE_ERR("Invalid parameter: nla_len(%d).", nla_len(cmd_attr));
+ return -EINVAL;
+ }
+
+ in_msg_hdr = (roce5_drv_msg_hdr_s *)nla_data(cmd_attr);
+
+ rdev = roce5_get_rdev_by_card_func_id(
+ in_msg_hdr->card_id, in_msg_hdr->common_hdr.src_func_idx);
+ if (rdev == NULL) {
+ ROCE_ERR("Invalid param: src_func_idx: %u, card_id: %llu",
+ in_msg_hdr->common_hdr.src_func_idx,
+ in_msg_hdr->card_id);
+ return -EINVAL;
+ }
+
+ callback = roce5_netlink_get_callback(in_msg_hdr->common_hdr.cmd);
+ if (callback == NULL) {
+ ROCE_DEV_ERR(rdev, "Unable to handle cmd: %u",
+ in_msg_hdr->common_hdr.cmd);
+ return -EINVAL;
+ }
+
+ reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (reply == NULL) {
+ ROCE_DEV_ERR(rdev, "Alloc reply buf for netlink cmd failed");
+ return -ENOMEM;
+ }
+
+ skb_reserve(reply, NLMSG_HDRLEN + GENL_HDRLEN + NLA_HDRLEN +
+ ROCE_DRV_MSG_HDRLEN);
+
+ ret = roce5_netlink_buf_handler(cmd_attr, callback, rdev, nl_info,
+ reply);
+ if (ret != 0) {
+ return ret;
+ }
+
+ roce5_nlahdr_push(reply, USRNL_GENL_ATTR);
+ roce5_genlmsg_push(reply, nl_info->snd_portid, nl_info->snd_seq,
+ &roce5_genl_family, 0, nl_info->genlhdr->cmd);
+
+ genlmsg_reply(reply, nl_info);
+
+ return 0;
+}
+
+int32_t roce5_netlink_init(void)
+{
+ int ret;
+
+ ret = roce5_netlink_init_cbs();
+ if (ret != 0) {
+ ROCE_ERR("Failed to init netlink callbacks, ret(%d).", ret);
+ return ret;
+ }
+
+ ret = genl_register_family(&roce5_genl_family);
+ if (ret != 0) {
+ ROCE_ERR("Failed to register netlink, ret(%d).", ret);
+ return ret;
+ }
+
+ ROCE_INFO("netlink init successfully.");
+ return 0;
+}
+
+void roce5_netlink_deinit(void)
+{
+ genl_unregister_family(&roce5_genl_family);
+ ROCE_INFO("netlink deinit successfully.");
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.h b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.h
new file mode 100644
index 000000000..9c4cfff02
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink.h
@@ -0,0 +1,53 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
+
+
+#ifndef ROCE5_NETLINK_H
+#define ROCE5_NETLINK_H
+
+#include <linux/types.h>
+#include "roce_drv_msg_intf.h"
+#include "roce.h"
+
+#define ROCE_GENL_FAMILY_NAME "roce5_genl"
+#define ROCE_DRV_MSG_HDRLEN (sizeof(roce5_drv_msg_hdr_s))
+#define CMD_BUF_LEN_MAX 2048
+
+typedef int32_t (*roce5_netlink_cmd_excute_callback)(struct roce5_device *rdev,
+ void *in, uint16_t in_len,
+ void *out,
+ uint16_t out_len,
+ uint16_t *out_size);
+
+enum roce_usrnl_cmd {
+ USRNL_ROCE_CMD_QUERY_QP_TX_PORT,
+ USRNL_ROCE_CMD_SET_QP_TX_PORT,
+ USRNL_ROCE_CMD_QUERY_QP_RX_PORT,
+ USRNL_ROCE_CMD_QUERY_BOND_PORT_INFO,
+ USRNL_ROCE_CMD_SET_QP_UDP_SRC_PORT,
+ USRNL_ROCE_CMD_QUERY_QP_UDP_SRC_PORT,
+ USRNL_ROCE_CMD_QUERY_NEXT_WQE_IDX,
+ USRNL_ROCE_CMD_QUERY_QPC,
+ USRNL_ROCE_CMD_QUERY_CQC,
+ USRNL_ROCE_CMD_QP_HASH_VALUE_PROCESS,
+ USRNL_ROCE_CMD_ULD, /* uld use */
+
+ /* Command number for HyperRoCE */
+ USRNL_ROCE_HYPER_ROCE_START = 16,
+ USRNL_ROCE_CMD_HYPER_QP_SET = USRNL_ROCE_HYPER_ROCE_START,
+ USRNL_ROCE_CMD_MODIFY_QP_EXTEND,
+ USRNL_ROCE_HYPER_ROCE_END = 31,
+ USRNL_ROCE_CMD_NUM
+};
+
+typedef struct {
+ enum roce_usrnl_cmd cmd;
+ roce5_netlink_cmd_excute_callback callback;
+} roce5_netlink_cmd_process;
+
+int32_t roce5_netlink_init(void);
+void roce5_netlink_deinit(void);
+int roce5_netlink_register_cbs(roce5_netlink_cmd_process cmd_procs[],
+ u8 cmd_num);
+
+#endif /* ROCE5_NETLINK_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.c b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.c
new file mode 100644
index 000000000..8b7445ab0
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.c
@@ -0,0 +1,832 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/types.h>
+#include <linux/semaphore.h>
+
+#include "hinic5_cqm.h"
+#include "hinic5_mt.h"
+#include "roce_cqm_cmd.h"
+#include "roce_cmd.h"
+#include "roce_com.h"
+#include "roce_dfx.h"
+#include "roce_main_extension.h"
+#include "roce_mix.h"
+#include "roce_npu_cmd.h"
+#include "roce_npu_cmd_defs.h"
+#include "roce_qp.h"
+#include "roce_restore.h"
+#include "roce_srq.h"
+#include "roce_uld_inner.h"
+#include "roce_uld_kernel_api.h"
+#include "roce_netlink_process.h"
+#ifdef ROCE_BONDING_EN
+#include "roce_bond.h"
+#endif
+
+static int32_t roce5_set_hash_value(struct roce5_device *rdev, uint32_t qpn,
+ uint32_t hash_type, uint32_t new_hash_value)
+{
+ int32_t ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ void *modify_hash_value = NULL;
+ size_t buf_size = 0;
+
+ if (ROCE5_SUPPORT_SET_HASH_VALUE_MSG_V2(rdev) != 0) {
+ buf_size = sizeof(roce_uni_cmd_modify_hash_s);
+ }
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(rdev->hwdev, &cqm_cmd_inbuf,
+ (uint16_t)buf_size, NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+ modify_hash_value = cqm_cmd_inbuf->buf;
+
+ if (ROCE5_SUPPORT_SET_HASH_VALUE_MSG_V2(rdev) != 0) {
+ roce_uni_cmd_modify_hash_s *cmd =
+ (roce_uni_cmd_modify_hash_s *)modify_hash_value;
+ cmd->com.index = cpu_to_be32(qpn);
+ cmd->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ cmd->info.type = cpu_to_be32(hash_type);
+ cmd->info.hash_value = cpu_to_be32(new_hash_value);
+ }
+
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_MODIFY_HASH_VALUE_QP,
+ cqm_cmd_inbuf, NULL, ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send MODIFY_HASH_VALUE_QP command, func_id(%d), qpn(%u), type(%u), hash_value(%u), ret=%d",
+ rdev->glb_func_id, qpn, hash_type, new_hash_value, ret);
+ ret = -1;
+ }
+
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int32_t roce5_get_hash_value(struct roce5_device *rdev, uint32_t qpn,
+ uint32_t hash_type, uint32_t *hash_value)
+{
+ int32_t ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_get_hash_s *get_hash_value = NULL;
+ roce_verbs_qp_hash_info_s *get_hash_value_out = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (uint16_t)sizeof(roce_uni_cmd_get_hash_s), &cqm_cmd_outbuf,
+ (uint16_t)sizeof(roce_verbs_qp_hash_info_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ get_hash_value = (roce_uni_cmd_get_hash_s *)cqm_cmd_inbuf->buf;
+ get_hash_value->com.index = cpu_to_be32(qpn);
+ get_hash_value->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ get_hash_value->info.type = cpu_to_be32(hash_type);
+
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_GET_HASH_VALUE_QP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf,
+ ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send ROCE_CMD_GET_HASH_VALUE_QP command, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -1;
+ goto out;
+ }
+
+ get_hash_value_out = (roce_verbs_qp_hash_info_s *)cqm_cmd_outbuf->buf;
+ *hash_value = be32_to_cpu(get_hash_value_out->hash_value);
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+#ifdef ROCE_BONDING_EN
+int32_t roce5_genl_query_qp_tx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ int32_t ret = 0;
+ uint32_t slave_cnt = 0;
+ struct roce5_qp *rqp = NULL;
+ uint32_t func_tbl_value = 0;
+ struct roce5_qp_in *msg_in = NULL;
+ struct roce5_port_out *msg_out = NULL;
+
+ if (in == NULL || in_len == 0 || in_len < sizeof(struct roce5_qp_in) ||
+ out == NULL || out_len == 0 ||
+ out_len < sizeof(struct roce5_port_out) || out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_in *)in;
+ *out_size = sizeof(struct roce5_port_out);
+ msg_out = (struct roce5_port_out *)out;
+
+ if (!roce5_bond_is_active(rdev)) {
+ msg_out->port = 0;
+ return 0;
+ }
+
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp");
+ return -EINVAL;
+ }
+
+ read_lock(&rdev->rwlock_func_tbl_bond);
+ func_tbl_value = rdev->func_tbl_bond;
+ slave_cnt = func_tbl_value & 0xfU;
+ if (slave_cnt != 0) {
+ msg_out->port = (func_tbl_value >>
+ (ROCE_BOND_FWD_ID_TBL_ALL_BITS -
+ ((rqp->tx_hash_value % slave_cnt + 1) *
+ ROCE_BOND_FWD_ID_TBL_PER_BITS))) &
+ ROCE_BOND_FWD_ID_TBL_PER_BITS_MASK;
+ }
+ read_unlock(&rdev->rwlock_func_tbl_bond);
+
+ if (slave_cnt == 0) {
+ ROCE_ERR("slave_cnt is 0");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+err_out:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int32_t roce5_set_new_tx_hash_value(struct roce5_device *rdev,
+ struct roce5_qp *rqp,
+ struct roce5_qp_port_in *msg_in)
+{
+ int32_t ret = 0;
+ uint32_t func_tbl_value = 0;
+ uint32_t slave_cnt = 0;
+ uint32_t target_hash_port = 0;
+ uint32_t old_hash_port = 0;
+ uint32_t new_tx_hash_value;
+
+ read_lock(&rdev->rwlock_func_tbl_bond);
+ func_tbl_value = rdev->func_tbl_bond;
+ read_unlock(&rdev->rwlock_func_tbl_bond);
+
+ slave_cnt = func_tbl_value & 0xfU;
+ if (slave_cnt == 0) {
+ ROCE_DEV_ERR(rdev, "slave_cnt is 0.");
+ return -EINVAL;
+ }
+ target_hash_port = msg_in->port & ROCE_BOND_FWD_ID_TBL_PER_BITS_MASK;
+ old_hash_port =
+ (func_tbl_value >> (ROCE_BOND_FWD_ID_TBL_ALL_BITS -
+ ((rqp->tx_hash_value % slave_cnt + 1) *
+ ROCE_BOND_FWD_ID_TBL_PER_BITS))) &
+ ROCE_BOND_FWD_ID_TBL_PER_BITS_MASK;
+
+ if (target_hash_port == old_hash_port) {
+ return 0;
+ }
+
+ new_tx_hash_value =
+ rqp->tx_hash_value +
+ (((slave_cnt - old_hash_port) + target_hash_port) % slave_cnt);
+ ret = roce5_set_hash_value(rdev, rqp->qpn, ROCE_VERBS_QP_HASH_TYPE_BOND,
+ new_tx_hash_value);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify QP(0x%06x) Bond hash value, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ rqp->tx_hash_value = new_tx_hash_value;
+
+ return 0;
+}
+
+int32_t roce5_genl_set_qp_tx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_qp_port_in *msg_in = NULL;
+ struct roce5_qp *rqp = NULL;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_qp_port_in) || out_size == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid param, in:%d, in_len:%u, out_size:%d",
+ !!in, in_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_port_in *)in;
+
+ if (!roce5_bond_is_active(rdev)) {
+ return 0;
+ }
+
+ /* check qp exist */
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp");
+ return -EINVAL;
+ }
+
+ ret = roce5_set_new_tx_hash_value(rdev, rqp, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set new tx hash value, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_out;
+ }
+
+err_out:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int roce5_uni_cmd_get_qp_rx_port(struct roce5_device *rdev, uint32_t qpn,
+ uint32_t *rx_port)
+{
+ int32_t ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_get_port_info_s *get_rx_port_inbuf = NULL;
+ roce_uni_cmd_get_port_info_outbuf_s *get_rx_port_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (uint16_t)sizeof(roce_uni_cmd_get_port_info_s), &cqm_cmd_outbuf,
+ (uint16_t)sizeof(roce_uni_cmd_get_port_info_outbuf_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ get_rx_port_inbuf = (roce_uni_cmd_get_port_info_s *)cqm_cmd_inbuf->buf;
+ get_rx_port_inbuf->com.index = cpu_to_be32(qpn);
+ get_rx_port_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_GET_RX_PORT_QP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf,
+ ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send ROCE_CMD_GET_RX_PORT_QP command, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -1;
+ goto out;
+ }
+ get_rx_port_outbuf =
+ (roce_uni_cmd_get_port_info_outbuf_s *)cqm_cmd_outbuf->buf;
+ *rx_port = be32_to_cpu(get_rx_port_outbuf->value.rx_port);
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static int32_t roce5_get_qp_rx_port(struct roce5_device *rdev, uint32_t qpn,
+ uint32_t *rx_port)
+{
+ if (ROCE5_SUPPORT_GET_QP_RX_PORT_MSG_V2(rdev) != 0) {
+ return roce5_uni_cmd_get_qp_rx_port(rdev, qpn, rx_port);
+ }
+ return -EINVAL;
+}
+
+int32_t roce5_genl_query_qp_rx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ int32_t ret = 0;
+ uint32_t rx_port = 0;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_qp_in *msg_in = NULL;
+ struct roce5_port_out *msg_out = NULL;
+
+ if (in == NULL || in_len == 0 || in_len < sizeof(struct roce5_qp_in) ||
+ out == NULL || out_len == 0 ||
+ out_len < sizeof(struct roce5_port_out) || out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_in *)in;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp");
+ return -EINVAL;
+ }
+
+ if (rqp->qp_type != IB_QPT_RC) {
+ ROCE_DEV_ERR(rdev, "not support qp type(%d), only support RC.",
+ rqp->qp_type);
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ *out_size = sizeof(struct roce5_port_out);
+ msg_out = (struct roce5_port_out *)out;
+
+ if (!roce5_bond_is_active(rdev)) {
+ msg_out->port = 0;
+ ret = 0;
+ goto err_out;
+ }
+
+ ret = roce5_get_qp_rx_port(rdev, msg_in->qpn, &rx_port);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get QP(0x%06x) rx port",
+ msg_in->qpn);
+ goto err_out;
+ }
+
+ msg_out->port = rx_port;
+
+err_out:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+int32_t roce5_genl_query_bond_port_info(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ uint32_t func_tbl_value = 0;
+ struct roce5_bond_device *bond_dev = NULL;
+ struct roce5_bond_port_info_out *msg_out = NULL;
+ uint32_t alive_port_num;
+ uint32_t i;
+
+ if (out == NULL || out_len == 0 ||
+ out_len < sizeof(struct roce5_bond_port_info_out) ||
+ out_size == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid param, out:%d, out_len:%u, out_size:%d",
+ !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ *out_size = sizeof(struct roce5_bond_port_info_out);
+ msg_out = (struct roce5_bond_port_info_out *)out;
+
+ if (!roce5_bond_is_active(rdev)) {
+ return 0;
+ }
+
+ bond_dev = rdev->bond_dev;
+
+ /* Read func_tbl_bond and derive alive port info under lock to prevent data race */
+ read_lock(&rdev->rwlock_func_tbl_bond);
+ func_tbl_value = rdev->func_tbl_bond;
+ alive_port_num = func_tbl_value & 0xfU;
+ for (i = 0; i < alive_port_num; i++) {
+ msg_out->alive_port[i] =
+ (func_tbl_value >>
+ (ROCE_BOND_FWD_ID_TBL_ALL_BITS -
+ ((i + 1) * ROCE_BOND_FWD_ID_TBL_PER_BITS))) &
+ ROCE_BOND_FWD_ID_TBL_PER_BITS_MASK;
+ }
+ read_unlock(&rdev->rwlock_func_tbl_bond);
+ msg_out->alive_port_num =
+ (int32_t)alive_port_num; /* netlink protocol field */
+
+ /* Read slave info under slave_lock (separate from rwlock to avoid sleeping in atomic context) */
+ msg_out->original_port_num =
+ (int32_t)bond_dev->slave_cnt; /* netlink protocol field */
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ msg_out->original_port[i] = bond_dev->slaves[i].func_id;
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+
+ return 0;
+}
+
+static int32_t roce5_uni_cmd_modify_udp_src_port(struct roce5_device *rdev,
+ uint32_t qpn,
+ uint32_t new_udp_src_port)
+{
+ int32_t ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_set_udp_src_port_s *modify_udp_src_port = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (uint16_t)sizeof(roce_uni_cmd_set_udp_src_port_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ modify_udp_src_port =
+ (roce_uni_cmd_set_udp_src_port_s *)cqm_cmd_inbuf->buf;
+ modify_udp_src_port->com.index = cpu_to_be32(qpn);
+ modify_udp_src_port->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ modify_udp_src_port->info.udp_src_port = cpu_to_be32(new_udp_src_port);
+
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_MODIFY_UDP_SRC_PORT_QP,
+ cqm_cmd_inbuf, NULL, ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send MODIFY_HASH_VALUE_QP command, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -1;
+ }
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int32_t roce5_modify_udp_src_port(struct roce5_device *rdev,
+ uint32_t qpn,
+ uint32_t new_udp_src_port)
+{
+ if (ROCE5_SUPPORT_MODIFY_UDP_SRC_PORT_MSG_V2(rdev) != 0) {
+ return roce5_uni_cmd_modify_udp_src_port(rdev, qpn,
+ new_udp_src_port);
+ }
+ return -EINVAL;
+}
+
+int32_t roce5_genl_set_qp_udp_src_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_qp_udp_src_port_in *msg_in = NULL;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_qp_udp_src_port_in) ||
+ out_size == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid param, in:%d, in_len:%u, out_size:%d",
+ !!in, in_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_udp_src_port_in *)in;
+
+ /* check qp exist */
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp");
+ return -EINVAL;
+ }
+
+ ret = roce5_modify_udp_src_port(rdev, rqp->qpn, msg_in->udp_src_port);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to modify QP(0x%06x) hash value, func_id(%d)",
+ rqp->qpn, rdev->glb_func_id);
+ ret = -EIO;
+ goto err_out;
+ }
+
+err_out:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int32_t roce5_uni_cmd_get_qp_udp_src_port(struct roce5_device *rdev,
+ uint32_t qpn,
+ uint32_t *udp_src_port)
+{
+ int32_t ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_get_port_info_s *get_udp_src_port = NULL;
+ roce_uni_cmd_get_port_info_outbuf_s *get_udp_src_port_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (uint16_t)sizeof(roce_uni_cmd_get_port_info_outbuf_s),
+ &cqm_cmd_outbuf,
+ (uint16_t)sizeof(roce_uni_cmd_get_port_info_outbuf_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ get_udp_src_port = (roce_uni_cmd_get_port_info_s *)cqm_cmd_inbuf->buf;
+ get_udp_src_port->com.index = cpu_to_be32(qpn);
+ get_udp_src_port->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_QP_BITMASK));
+
+ ret = roce5_send_qp_lb_cmd(qpn, rdev, ROCE_CMD_GET_UDP_SRC_PORT_QP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf,
+ ROCE_CMD_TIME_CLASS_A);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send ROCE_CMD_GET_UDP_SRC_PORT_QP command, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -1;
+ goto out;
+ }
+
+ get_udp_src_port_outbuf =
+ (roce_uni_cmd_get_port_info_outbuf_s *)cqm_cmd_outbuf->buf;
+ *udp_src_port =
+ be32_to_cpu(get_udp_src_port_outbuf->value.udp_src_port);
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int32_t roce5_get_qp_udp_src_port(struct roce5_device *rdev,
+ uint32_t qpn, uint32_t *udp_src_port)
+{
+ if (ROCE5_SUPPORT_GET_QP_UDP_SRC_PORT_MSG_V2(rdev) != 0) {
+ return roce5_uni_cmd_get_qp_udp_src_port(rdev, qpn,
+ udp_src_port);
+ }
+ return -EINVAL;
+}
+
+int32_t roce5_genl_query_qp_udp_src_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ int32_t ret = 0;
+ uint32_t udp_src_port = 0;
+ struct roce5_qp_in *msg_in = NULL;
+ struct roce5_port_out *msg_out = NULL;
+
+ if (in == NULL || in_len == 0 || in_len < sizeof(struct roce5_qp_in) ||
+ out == NULL || out_len == 0 ||
+ out_len < sizeof(struct roce5_port_out) || out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_in *)in;
+
+ ret = roce5_get_qp_udp_src_port(rdev, msg_in->qpn, &udp_src_port);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to get QP(0x%06x) udp src port",
+ msg_in->qpn);
+ return ret;
+ }
+
+ *out_size = sizeof(struct roce5_port_out);
+ msg_out = (struct roce5_port_out *)out;
+
+ msg_out->port = udp_src_port;
+
+ return 0;
+}
+#endif
+
+int32_t roce5_genl_query_next_wqe_idx(struct roce5_device *rdev, void *in,
+ u16 in_len, void *out, u16 out_len,
+ u16 *out_size)
+{
+ int32_t ret = 0;
+ int32_t next_wqe_idx = 0;
+ uint32_t container_mode = 0;
+ uint32_t container_size = 0;
+ struct roce5_next_wqe_idx_in *msg_in = NULL;
+ struct roce5_next_wqe_idx_out *msg_out = NULL;
+ roce_verbs_srq_attr_s *srq_attr = NULL;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_next_wqe_idx_in) || out == NULL ||
+ out_len == 0 || out_len < sizeof(struct roce5_next_wqe_idx_out) ||
+ out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ srq_attr = kmalloc(sizeof(roce_verbs_srq_attr_s), GFP_KERNEL);
+ if (srq_attr == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to allocate memory for dfx_query_outbuf");
+ return -ENOMEM;
+ }
+
+ msg_in = (struct roce5_next_wqe_idx_in *)in;
+ msg_out = (struct roce5_next_wqe_idx_out *)out;
+ ret = roce5_dfx_cmd_query_srq(rdev, msg_in->srqn, srq_attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to do roce5_dfx_cmd_query_srq, ret(%d)",
+ ret);
+ ret = -EINVAL;
+ goto free_outbuf;
+ }
+
+ srq_attr->dw2.value = be32_to_cpu(srq_attr->dw2.value);
+ srq_attr->dw3.value = be32_to_cpu(srq_attr->dw3.value);
+ srq_attr->cont.dw2.value = be32_to_cpu(srq_attr->cont.dw2.value);
+ if (srq_attr->dw3.bs.container == 0) {
+ next_wqe_idx = (int32_t)(srq_attr->dw2.bs.next_wqe_idx);
+ } else {
+ container_mode = MAX_SUPPORT_CONTAINER_MODE -
+ srq_attr->cont.dw2.bs.cont_size;
+ container_size = roce5_get_container_sz(container_mode);
+ next_wqe_idx = (int32_t)(container_size *
+ srq_attr->cont.dw2.bs.head_idx);
+ }
+
+ msg_out->next_wqe_idx = next_wqe_idx;
+ *out_size = sizeof(struct roce5_next_wqe_idx_out);
+ ret = 0;
+
+free_outbuf:
+ kfree(srq_attr);
+ return ret;
+}
+
+int32_t roce5_genl_query_qpc(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_qp_in *msg_in = NULL;
+ roce_verbs_qp_attr_s *verbs_qp_attr = NULL;
+
+ if (in == NULL || in_len == 0 || in_len < sizeof(struct roce5_qp_in) ||
+ out == NULL || out_len == 0 ||
+ out_len < sizeof(roce_verbs_qp_attr_s) || out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_in *)in;
+ verbs_qp_attr = (roce_verbs_qp_attr_s *)out;
+
+ ret = roce5_qp_query(rdev, msg_in->qpn, (u32 *)(void *)verbs_qp_attr,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query qpc, ret(%0x)", ret);
+ return ret;
+ }
+
+ *out_size = sizeof(roce_verbs_qp_attr_s);
+ return 0;
+}
+
+int32_t roce5_genl_query_cqc(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_cq_in *msg_in = NULL;
+ roce_verbs_cq_attr_s *verbs_cq_attr = NULL;
+
+ if (in == NULL || in_len == 0 || in_len < sizeof(struct roce5_cq_in) ||
+ out == NULL || out_len == 0 ||
+ out_len < sizeof(roce_verbs_cq_attr_s) || out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid param, in:%d, in_len:%u, out:%d, out_len:%u, out_size:%d",
+ !!in, in_len, !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_cq_in *)in;
+ verbs_cq_attr = (roce_verbs_cq_attr_s *)out;
+
+ ret = roce5_dfx_query_cq(rdev, msg_in->cqn,
+ (u32 *)(void *)verbs_cq_attr,
+ sizeof(roce_verbs_cq_attr_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query cqc, ret(%0x)", ret);
+ return ret;
+ }
+
+ *out_size = sizeof(roce_verbs_cq_attr_s);
+ return 0;
+}
+
+int32_t roce5_genl_qp_hash_value_process(struct roce5_device *rdev, void *in,
+ u16 in_len, void *out, u16 out_len,
+ u16 *out_size)
+{
+ uint32_t hash_value = 0;
+ struct roce5_qp_hash_value_in *msg_in = NULL;
+ struct roce5_qp_hash_value_out *msg_out = NULL;
+ int32_t ret;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_qp_hash_value_in)) {
+ ROCE_DEV_ERR(rdev, "Invalid input param, in:%d, in_len:%u",
+ !!in, in_len);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_qp_hash_value_in *)in;
+
+ if (msg_in->type == ROCE_QP_HASH_VALUE_GET) {
+ if (out == NULL || out_len == 0 ||
+ out_len < sizeof(struct roce5_qp_hash_value_out) ||
+ out_size == NULL) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Invalid output param, out:%d, out_len:%u, out_size:%d",
+ !!out, out_len, !!out_size);
+ return -EINVAL;
+ }
+ ret = roce5_get_hash_value(rdev, msg_in->qpn,
+ ROCE_VERBS_QP_HASH_TYPE_UBC,
+ &hash_value);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to get QP(0x%06x) hash value, func_id(%d)",
+ msg_in->qpn, rdev->glb_func_id);
+ return ret;
+ }
+
+ *out_size = sizeof(struct roce5_qp_hash_value_out);
+ msg_out = (struct roce5_qp_hash_value_out *)out;
+ msg_out->hash_value = hash_value;
+ } else {
+ ret = roce5_set_hash_value(rdev, msg_in->qpn,
+ ROCE_VERBS_QP_HASH_TYPE_UBC,
+ msg_in->hash_value);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set QP(0x%06x) hash value, func_id(%d)",
+ msg_in->qpn, rdev->glb_func_id);
+ }
+ }
+
+ return ret;
+}
+
+int32_t roce5_netlink_uld_process(struct roce5_device *rdev, void *buf_in,
+ u16 buf_in_len, void *buf_out,
+ u16 buf_out_len, u16 *buf_out_size)
+{
+ int32_t ret = 0;
+ roce_user_handle_t handle;
+
+ handle.rdev = rdev;
+ handle.magic = ROCE_ULD_HANDLE_MAGIC_NUM;
+
+ ret = roce5_uld_user2kernel_msg_handle((void *)&handle, buf_in,
+ buf_in_len, buf_out, buf_out_len,
+ buf_out_size);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "ULD process err, func_id(%d)",
+ rdev->glb_func_id);
+ }
+ return ret;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.h b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.h
new file mode 100644
index 000000000..d09bcf733
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/netlink/roce_netlink_process.h
@@ -0,0 +1,133 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_NETLINK_PROCESS_H
+#define ROCE_NETLINK_PROCESS_H
+
+#include "roce.h"
+#include "roce_compat.h"
+
+typedef enum {
+ ROCE_QP_HASH_VALUE_SET,
+ ROCE_QP_HASH_VALUE_GET,
+} ROCE_QP_HASH_VALUE_PROC_TYPE;
+
+#ifdef ROCE_BONDING_EN
+/* and above next data structure is adaptation V100 use */
+struct roce5_get_rx_port {
+ __be32 rx_port;
+};
+
+struct roce5_get_udp_src_port {
+ __be32 udp_src_port;
+};
+
+typedef struct tag_roce_get_qp_rx_port {
+ roce_verbs_cmd_com_s com;
+} roce_get_qp_rx_port_s;
+
+typedef struct tag_roce_modify_hash_value {
+ roce_verbs_cmd_com_s com;
+ u32 hash_value;
+} roce_modify_hash_value_s;
+
+typedef struct tag_roce_modify_udp_src_port {
+ roce_verbs_cmd_com_s com;
+ u32 udp_src_port;
+} roce_modify_udp_src_port_s;
+
+typedef struct roce_get_qp_udp_src_port {
+ roce_verbs_cmd_com_s com;
+} roce_get_qp_udp_src_port_s;
+
+struct roce5_qp_port_in {
+ uint32_t qpn;
+ uint32_t port;
+};
+
+struct roce5_port_out {
+ uint32_t port;
+};
+
+struct roce5_bond_port_info_out {
+ int32_t original_port_num;
+ uint8_t original_port[8];
+ int32_t rsvd1;
+
+ int32_t alive_port_num;
+ uint8_t alive_port[8];
+ int32_t rsvd2;
+};
+
+struct roce5_qp_udp_src_port_in {
+ uint32_t qpn;
+ uint32_t udp_src_port;
+};
+
+#endif
+
+struct roce5_qp_in {
+ uint32_t qpn;
+};
+
+struct roce5_cq_in {
+ uint32_t cqn;
+};
+
+struct roce5_next_wqe_idx_in {
+ uint32_t srqn;
+};
+
+struct roce5_next_wqe_idx_out {
+ int32_t next_wqe_idx;
+};
+
+struct roce5_qp_hash_value_in {
+ uint32_t type;
+ uint32_t qpn;
+ uint32_t hash_value;
+};
+
+struct roce5_qp_hash_value_out {
+ uint32_t hash_value;
+};
+
+#ifdef ROCE_BONDING_EN
+
+int32_t roce5_genl_query_qp_tx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size);
+int32_t roce5_genl_set_qp_tx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size);
+int32_t roce5_genl_query_qp_rx_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size);
+int32_t roce5_genl_query_bond_port_info(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size);
+int32_t roce5_genl_set_qp_udp_src_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size);
+int32_t roce5_genl_query_qp_udp_src_port(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size);
+
+#endif
+
+int32_t roce5_genl_query_next_wqe_idx(struct roce5_device *rdev, void *in,
+ u16 in_len, void *out, u16 out_len,
+ u16 *out_size);
+int32_t roce5_genl_query_qpc(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size);
+int32_t roce5_genl_query_cqc(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out, uint16_t out_len,
+ uint16_t *out_size);
+int32_t roce5_genl_qp_hash_value_process(struct roce5_device *rdev, void *in,
+ u16 in_len, void *out, u16 out_len,
+ u16 *out_size);
+int32_t roce5_netlink_uld_process(struct roce5_device *rdev, void *buf_in,
+ u16 buf_in_len, void *buf_out,
+ u16 buf_out_len, u16 *buf_out_size);
+#endif /* ROCE_NETLINK_PROCESS_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.c b/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.c
new file mode 100644
index 000000000..69549fbe3
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.c
@@ -0,0 +1,74 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "securec.h"
+
+#include "roce_cqm_cmd.h"
+
+void roce5_cqm5_cmd_free_inoutbuf(void *ex_handle, cqm_cmd_buf_s *cqm_cmd_inbuf,
+ cqm_cmd_buf_s *cqm_cmd_outbuf)
+{
+ if (cqm_cmd_outbuf != NULL) {
+ cqm5_cmd_free(ex_handle, cqm_cmd_outbuf);
+ }
+
+ if (cqm_cmd_inbuf != NULL) {
+ cqm5_cmd_free(ex_handle, cqm_cmd_inbuf);
+ }
+}
+
+int roce5_cqm_cmd_zalloc_inoutbuf(void *ex_handle,
+ cqm_cmd_buf_s **cqm_cmd_inbuf, u16 inbuf_size,
+ cqm_cmd_buf_s **cqm_cmd_outbuf,
+ u16 outbuf_size)
+{
+ int ret;
+
+ if (cqm_cmd_inbuf != NULL) {
+ *cqm_cmd_inbuf = cqm5_cmd_alloc(ex_handle);
+
+ if (*cqm_cmd_inbuf == NULL) {
+ ret = -ENOMEM;
+ goto inbuf_err;
+ }
+ (*cqm_cmd_inbuf)->size = inbuf_size;
+
+ ret = memset_s((*cqm_cmd_inbuf)->buf, inbuf_size, 0,
+ inbuf_size);
+ if (ret != 0) {
+ ret = -EINVAL;
+ goto inbuf_err;
+ }
+ }
+
+ if (cqm_cmd_outbuf != NULL) {
+ *cqm_cmd_outbuf = cqm5_cmd_alloc(ex_handle);
+
+ if (*cqm_cmd_outbuf == NULL) {
+ ret = -ENOMEM;
+ goto outbuf_err;
+ }
+ (*cqm_cmd_outbuf)->size = outbuf_size;
+
+ ret = memset_s((*cqm_cmd_outbuf)->buf, outbuf_size, 0,
+ outbuf_size);
+ if (ret != 0) {
+ ret = -EINVAL;
+ goto outbuf_err;
+ }
+ }
+
+ return 0;
+outbuf_err:
+ if (cqm_cmd_outbuf != NULL) {
+ roce5_cqm5_cmd_free_inoutbuf(ex_handle, NULL, *cqm_cmd_outbuf);
+ *cqm_cmd_outbuf = NULL;
+ }
+inbuf_err:
+ if (cqm_cmd_inbuf != NULL) {
+ roce5_cqm5_cmd_free_inoutbuf(ex_handle, *cqm_cmd_inbuf, NULL);
+ *cqm_cmd_inbuf = NULL;
+ }
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.h b/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.h
new file mode 100644
index 000000000..0130fa320
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sdk_api/roce_cqm_cmd.h
@@ -0,0 +1,21 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_CQM_CMD_H
+#define ROCE_CQM_CMD_H
+#ifdef ROCE_KNL_DT
+#include <linux/compiler_types.h>
+#endif
+#include "hinic5_cqm.h"
+
+#include "roce.h"
+
+void roce5_cqm5_cmd_free_inoutbuf(void *ex_handle, cqm_cmd_buf_s *cqm_cmd_inbuf,
+ cqm_cmd_buf_s *cqm_cmd_outbuf);
+int roce5_cqm_cmd_zalloc_inoutbuf(void *ex_handle,
+ cqm_cmd_buf_s **cqm_cmd_inbuf, u16 inbuf_size,
+ cqm_cmd_buf_s **cqm_cmd_outbuf,
+ u16 outbuf_size);
+
+#endif //ROCE_CQM_CMD_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.c b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.c
new file mode 100644
index 000000000..3000c6b97
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.c
@@ -0,0 +1,240 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+#include "roce.h"
+#include "roce_sysfs.h"
+#include "roce_cc_format.h"
+
+#include "roce_cmd.h"
+#include "roce_multipath_sysfs.h"
+
+#define MAX_STRING_FORMAT_LEN 64
+#define to_roce5_ecn_multipath_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_multipath_ctx, ecn_multipath_root)
+
+static void roce_ecn_multipath_sysfs_release(struct kobject *kobj)
+{
+}
+
+static ssize_t roce5_show_slow_path_psn_threshold(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx =
+ to_roce5_ecn_multipath_ctx(kobj);
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%u\n",
+ (u32)ecn_multipath_ctx->slow_path_psn_threshold);
+}
+
+static ssize_t roce5_store_slow_path_psn_threshold(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx =
+ to_roce5_ecn_multipath_ctx(kobj);
+ u32 old_slow_path_psn_threshold = 0;
+ int slow_path_psn_threshold = 0;
+ int ret;
+ char remaining;
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ ret = sscanf_s(buf, "%d %c", &slow_path_psn_threshold, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, slow_path_psn_threshold should be unsigned int\n");
+ return -EIO;
+ }
+
+ if (slow_path_psn_threshold >
+ ROCE_MULTIPATH_DEFAULT_SLOW_PATH_PSN_THRESHOLD_MAX) {
+ ROCE_ERR(
+ "Invalid input, slow_path_psn_threshold(%d) over max slow_path_psn_threshold(%u), slow_path_psn_threshold",
+ slow_path_psn_threshold,
+ (u32)ROCE_MULTIPATH_DEFAULT_SLOW_PATH_PSN_THRESHOLD_MAX);
+ return -EIO;
+ }
+
+ if (ecn_multipath_ctx->slow_path_psn_threshold !=
+ (u32)slow_path_psn_threshold) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_slow_path_psn_threshold =
+ ecn_multipath_ctx->slow_path_psn_threshold;
+ ecn_multipath_ctx->slow_path_psn_threshold =
+ (u32)slow_path_psn_threshold;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Fail to update slow_path_psn_threshold(%d), ret(%d).",
+ slow_path_psn_threshold, ret);
+ ecn_multipath_ctx->slow_path_psn_threshold =
+ old_slow_path_psn_threshold;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t roce5_show_rtt_req_event_mode(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx =
+ to_roce5_ecn_multipath_ctx(kobj);
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_multipath_ctx->rtt_req_event_mode);
+}
+
+static ssize_t roce5_store_rtt_req_event_mode(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ u32 old_rtt_req_event_mode = 0;
+ u32 rtt_req_event_mode = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx =
+ to_roce5_ecn_multipath_ctx(kobj);
+ char remaining;
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ ret = sscanf_s(buf, "%u %c", &rtt_req_event_mode, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, rtt_req_event_mode should be unsigned int ret(%d), rtt_req_event_mode(%u)\n",
+ ret, rtt_req_event_mode);
+ return -EIO;
+ }
+
+ if ((rtt_req_event_mode & ROCE_MULTIPATH_RTT_EN_MASK) != 0) {
+ ROCE_ERR(
+ "Invalid input, rtt_req_event_mode (%u)only 0 and 1 supported\n",
+ rtt_req_event_mode);
+ return -EIO;
+ }
+
+ if (ecn_multipath_ctx->rtt_req_event_mode != (u32)rtt_req_event_mode) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_rtt_req_event_mode = ecn_multipath_ctx->rtt_req_event_mode;
+ ecn_multipath_ctx->rtt_req_event_mode = (u32)rtt_req_event_mode;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Fail to update rtt_req_event_mode(%d), ret(%d).",
+ rtt_req_event_mode, ret);
+ ecn_multipath_ctx->rtt_req_event_mode =
+ old_rtt_req_event_mode;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+ROCE_ATTR_RW(slow_path_psn_threshold, roce5_show_slow_path_psn_threshold,
+ roce5_store_slow_path_psn_threshold);
+ROCE_ATTR_RW(rtt_req_event_mode, roce5_show_rtt_req_event_mode,
+ roce5_store_rtt_req_event_mode);
+
+static struct attribute *ecn_multipath_ctx_attrs[] = {
+ ROCE_ATTR_PTR(rtt_req_event_mode),
+ ROCE_ATTR_PTR(slow_path_psn_threshold),
+ NULL,
+};
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_multipath_ctx_attr_grp = {
+ .attrs = ecn_multipath_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_multipath_ctx_groups[] = {
+ &ecn_multipath_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static struct kobj_type roce_ecn_multipath_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_multipath_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_multipath_ctx_groups,
+#else
+ .default_attrs = ecn_multipath_ctx_attrs,
+#endif
+};
+
+int roce5_init_ecn_multipath_sysfs(
+ struct roce5_device *rdev, struct kobject *kobj,
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx)
+{
+ int ret = 0;
+
+ if (rdev->device_type != ROCE_DEV_TYPE_HI1825_V100) {
+ return 0;
+ }
+ if (ecn_multipath_ctx == NULL) {
+ pr_err_ratelimited(
+ "[ROCE, ERR] %s: ecn_multipath_ctx is null\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ecn_multipath_ctx->rtt_req_event_mode =
+ ROCE_MULTIPATH_DEFAULT_RTT_EVENT_MODE;
+ ecn_multipath_ctx->slow_path_psn_threshold =
+ ROCE_MULTIPATH_DEFAULT_SLOW_PATH_PSN_THRESHOLD;
+
+ ret = kobject_init_and_add(&ecn_multipath_ctx->ecn_multipath_root,
+ &roce_ecn_multipath_ktype, kobj,
+ "roce5_multipath");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject roce5_ultipath.(ret:%d)\n",
+ ret);
+ kobject_put(&ecn_multipath_ctx->ecn_multipath_root);
+ return ret;
+ }
+
+ return 0;
+}
+
+void roce5_remove_ecn_multipath_sysfs(
+ struct roce5_device *rdev, struct kobject *kobj,
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx)
+{
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ if (ecn_multipath_ctx == NULL) {
+ ROCE_ERR("ecn_multipath_ctx is null\n");
+ return;
+ }
+
+ kobject_put(&ecn_multipath_ctx->ecn_multipath_root);
+ }
+
+ return;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.h b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.h
new file mode 100644
index 000000000..2a26de8e2
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_multipath_sysfs.h
@@ -0,0 +1,30 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifndef ROCE_MULTIPATH_SYSFS_H
+#define ROCE_MULTIPATH_SYSFS_H
+
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/kobject.h>
+
+struct roce5_device;
+
+#define ROCE_MULTIPATH_DEFAULT_RTT_EVENT_MODE 0
+#define ROCE_MULTIPATH_RTT_EN_MASK 0xfffffffe
+#define ROCE_MULTIPATH_DEFAULT_SLOW_PATH_PSN_THRESHOLD 1
+#define ROCE_MULTIPATH_DEFAULT_SLOW_PATH_PSN_THRESHOLD_MAX 255
+
+struct roce5_ecn_multipath_ctx {
+ struct kobject ecn_multipath_root;
+ u32 slow_path_psn_threshold;
+ u32 rtt_req_event_mode;
+};
+int roce5_init_ecn_multipath_sysfs(
+ struct roce5_device *rdev, struct kobject *kobj,
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx);
+void roce5_remove_ecn_multipath_sysfs(
+ struct roce5_device *rdev, struct kobject *kobj,
+ struct roce5_ecn_multipath_ctx *ecn_multipath_ctx);
+#endif /* ROCE_MULTIPATH_SYSFS_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.c b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.c
new file mode 100644
index 000000000..869a97571
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.c
@@ -0,0 +1,2157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/stat.h>
+
+#include "roce.h"
+#include "ccp_algo_format.h"
+#include "hinic5_hw.h"
+#include "roce_cc_format.h"
+#include "roce_cmd.h"
+#include "roce_com.h"
+#include "roce_dfx.h"
+#include "roce_infra.h"
+#include "roce_kernel_compat_gen.h"
+#include "roce_mix.h"
+#include "roce_mpu_cmd.h"
+#include "roce_multipath_sysfs.h"
+#include "roce_npu_cmd_srq_defs.h"
+#include "roce_qp.h"
+#include "roce_ucc_sysfs.h"
+#include "securec.h"
+#include "roce_sysfs.h"
+
+#define MAX_STRING_FORMAT_LEN 64
+
+/* generic macro template: generate show/store function, used for rp_ctx parameters (with range check) */
+#define ROCE5_PARAM_SHOW_STORE_RP(_name, _member, _min_macro, _max_macro) \
+ static ssize_t roce5_show_##_name( \
+ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
+ { \
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx = \
+ to_roce5_ecn_rp_ctx(kobj); \
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n", \
+ (int)ecn_rp_ctx->_member); \
+ } \
+ static ssize_t roce5_store_##_name(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ int ret, _val; \
+ u32 _old; \
+ struct roce5_ecn_ctx *ecn_ctx = \
+ to_roce5_ecn_ctx(kobj->parent); \
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx = \
+ to_roce5_ecn_rp_ctx(kobj); \
+ struct roce5_device *rdev = \
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx); \
+ ret = sscanf_s(buf, "%d", &_val); \
+ if (ret != 1) \
+ return -EIO; \
+ if (ROCE5_PARAM_CHECK_BOUND( \
+ _val, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._min_macro, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._max_macro)) \
+ return -EIO; \
+ if (ecn_rp_ctx->_member != (u32)_val) { \
+ mutex_lock(&ecn_ctx->ecn_mutex); \
+ _old = ecn_rp_ctx->_member; \
+ ecn_rp_ctx->_member = (u32)_val; \
+ ret = roce5_update_ecn_param(ecn_ctx); \
+ if (ret != 0) { \
+ ecn_rp_ctx->_member = _old; \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ return -EIO; \
+ } \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ } \
+ return (ssize_t)count; \
+ }
+
+/* generic macro template: generate show/store function, used for np_ctx parameters (with range check) */
+#define ROCE5_PARAM_SHOW_STORE_NP(_name, _member, _min_macro, _max_macro) \
+ static ssize_t roce5_show_##_name( \
+ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
+ { \
+ struct roce5_ecn_np_ctx *ecn_np_ctx = \
+ to_roce5_ecn_np_ctx(kobj); \
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n", \
+ (int)ecn_np_ctx->_member); \
+ } \
+ static ssize_t roce5_store_##_name(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ int ret, _val; \
+ u32 _old; \
+ struct roce5_ecn_ctx *ecn_ctx = \
+ to_roce5_ecn_ctx(kobj->parent); \
+ struct roce5_ecn_np_ctx *ecn_np_ctx = \
+ to_roce5_ecn_np_ctx(kobj); \
+ struct roce5_device *rdev = \
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx); \
+ ret = sscanf_s(buf, "%d", &_val); \
+ if (ret != 1) \
+ return -EIO; \
+ if (ROCE5_PARAM_CHECK_BOUND( \
+ _val, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._min_macro, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._max_macro)) \
+ return -EIO; \
+ if (ecn_np_ctx->_member != (u32)_val) { \
+ mutex_lock(&ecn_ctx->ecn_mutex); \
+ _old = ecn_np_ctx->_member; \
+ ecn_np_ctx->_member = (u32)_val; \
+ ret = roce5_update_ecn_param(ecn_ctx); \
+ if (ret != 0) { \
+ ecn_np_ctx->_member = _old; \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ return -EIO; \
+ } \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ } \
+ return (ssize_t)count; \
+ }
+
+/* generic macro template: generate show/store function, used for ldcp_ctx parameters (with range check) */
+#define ROCE5_PARAM_SHOW_STORE_LDCP(_name, _member, _min_macro, _max_macro) \
+ static ssize_t roce5_show_##_name( \
+ struct kobject *kobj, struct kobj_attribute *attr, char *buf) \
+ { \
+ struct roce5_ecn_ldcp_ctx *ecn_ldcp_ctx = \
+ to_roce5_ecn_ldcp_ctx(kobj); \
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n", \
+ (int)ecn_ldcp_ctx->_member); \
+ } \
+ static ssize_t roce5_store_##_name(struct kobject *kobj, \
+ struct kobj_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ int ret, _val; \
+ u32 _old; \
+ struct roce5_ecn_ctx *ecn_ctx = \
+ to_roce5_ecn_ctx(kobj->parent); \
+ struct roce5_ecn_ldcp_ctx *ecn_ldcp_ctx = \
+ to_roce5_ecn_ldcp_ctx(kobj); \
+ struct roce5_device *rdev = \
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx); \
+ ret = sscanf_s(buf, "%d", &_val); \
+ if (ret != 1) { \
+ ROCE_ERR("Failed to get " #_member ", ret(%d).", ret); \
+ return -EIO; \
+ } \
+ if (ROCE5_PARAM_CHECK_BOUND( \
+ _val, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._min_macro, \
+ g_roce_cc_ecn_param[rdev->cc_param_version] \
+ ._max_macro)) { \
+ ROCE_ERR(#_member "(%u) param is out bound.", _val); \
+ return -EIO; \
+ } \
+ if (ecn_ldcp_ctx->_member != (u32)_val) { \
+ mutex_lock(&ecn_ctx->ecn_mutex); \
+ _old = ecn_ldcp_ctx->_member; \
+ ecn_ldcp_ctx->_member = (u32)_val; \
+ ret = roce5_update_ecn_param(ecn_ctx); \
+ if (ret != 0) { \
+ ecn_ldcp_ctx->_member = _old; \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ return -EIO; \
+ } \
+ mutex_unlock(&ecn_ctx->ecn_mutex); \
+ } \
+ return (ssize_t)count; \
+ }
+
+const struct roce_cc_ecn_param g_roce_cc_ecn_param[] = {
+ { 0 }, // invalid
+ { .default_ip_enable_en = 1,
+ .default_bypass = 0,
+ .default_min_cnp_period = 16,
+ .default_alpha_dec_period = 160,
+ .default_rate_dec_period = 32,
+ .default_rate_inc_period = 480,
+ .default_factor_gita = 7,
+ .default_initial_alpha = 1023,
+ .default_rate_inc_ai = 2,
+ .default_rate_inc_hai = 8,
+ .default_rate_first_set = 1024,
+ .default_rate_target_clamp = 1,
+ .default_cnp_prio_enable = 0,
+ .default_cnp_prio = 0,
+ .default_token_period = 16,
+ .default_min_rate = 1,
+ .default_ecn_cnp_enable = 1,
+ .default_flow_ctrl_unit = 0,
+ .default_rtt_rsp_prio = 0,
+ .default_rtt_rsp_prio_enable = 0,
+ .default_rtt_version = 0,
+ .max_rtt_version = 0,
+ .min_bypass = 0,
+ .max_bypass = 0,
+ .min_rate_inc_hai = 1,
+ .max_rate_inc_hai = 255,
+ .min_rate_inc_ai = 1,
+ .max_rate_inc_ai = 63,
+ .min_initial_alpha = 1,
+ .max_initial_alpha = 1023,
+ .min_rate_inc_period = 1,
+ .max_rate_inc_period = 1023,
+ .min_alpha_dec_period = 1,
+ .max_alpha_dec_period = 1023,
+ .min_token_period = 4,
+ .max_token_period = 255,
+ .min_flow_min_rate = 1,
+ .max_flow_min_rate = 63,
+ .min_rate_dec_period = 1,
+ .max_rate_dec_period = 255,
+ .min_min_cnp_period = 1,
+ .max_min_cnp_period = 255,
+ .min_factor_gita = 1,
+ .max_factor_gita = 15,
+ .min_rate_first_set = 128,
+ .max_rate_first_set = 8191,
+ .default_ldcp_wnd_min = 5,
+ .default_ldcp_wnd_default = 1024,
+ .default_ldcp_alpha = 2,
+ .default_ldcp_beta = 12,
+ .default_ldcp_gamma = 9,
+ .default_ldcp_eta = 3,
+ .min_ldcp_wnd_min = 1,
+ .max_ldcp_wnd_min = 0x8,
+ .min_ldcp_wnd_default = 1024,
+ .max_ldcp_wnd_default = 32768,
+ .min_ldcp_alpha = 0,
+ .max_ldcp_alpha = 0xf,
+ .min_ldcp_beta = 0,
+ .max_ldcp_beta = 0xf,
+ .min_ldcp_gamma = 0,
+ .max_ldcp_gamma = 0xf,
+ .min_ldcp_eta = 0,
+ .max_ldcp_eta = 0xf }, // v1
+ { .default_ip_enable_en = 1,
+ .default_bypass = 0,
+ .default_min_cnp_period = 16,
+ .default_alpha_dec_period = 160,
+ .default_rate_dec_period = 48,
+ .default_rate_inc_period = 480,
+ .default_factor_gita = 7,
+ .default_initial_alpha = 1023,
+ .default_rate_inc_ai = 2,
+ .default_rate_inc_hai = 12,
+ .default_rate_first_set = 1024,
+ .default_rate_target_clamp = 1,
+ .default_cnp_prio_enable = 0,
+ .default_cnp_prio = 0,
+ .default_token_period = 16,
+ .default_min_rate = 1,
+ .default_ecn_cnp_enable = 1,
+ .default_flow_ctrl_unit = 0,
+ .default_rtt_rsp_prio = 0,
+ .default_rtt_rsp_prio_enable = 0,
+ .default_rtt_version = 0,
+ .max_rtt_version = 0,
+ .min_bypass = 0,
+ .max_bypass = 2,
+ .min_rate_inc_hai = 1,
+ .max_rate_inc_hai = 255,
+ .min_rate_inc_ai = 1,
+ .max_rate_inc_ai = 255,
+ .min_initial_alpha = 1,
+ .max_initial_alpha = 1023,
+ .min_rate_inc_period = 1,
+ .max_rate_inc_period = 1023,
+ .min_alpha_dec_period = 1,
+ .max_alpha_dec_period = 1023,
+ .min_token_period = 4,
+ .max_token_period = 255,
+ .min_flow_min_rate = 1,
+ .max_flow_min_rate = 4095,
+ .min_rate_dec_period = 1,
+ .max_rate_dec_period = 255,
+ .min_min_cnp_period = 1,
+ .max_min_cnp_period = 255,
+ .min_factor_gita = 1,
+ .max_factor_gita = 15,
+ .min_rate_first_set = 128,
+ .max_rate_first_set = 50000,
+ .default_ldcp_wnd_min = 5,
+ .default_ldcp_wnd_default = 1024,
+ .default_ldcp_alpha = 2,
+ .default_ldcp_beta = 9,
+ .default_ldcp_gamma = 6,
+ .default_ldcp_eta = 6,
+ .min_ldcp_wnd_min = 1,
+ .max_ldcp_wnd_min = 0x8,
+ .min_ldcp_wnd_default = 1024,
+ .max_ldcp_wnd_default = 32768,
+ .min_ldcp_alpha = 0,
+ .max_ldcp_alpha = 0xf,
+ .min_ldcp_beta = 0,
+ .max_ldcp_beta = 0xf,
+ .min_ldcp_gamma = 0,
+ .max_ldcp_gamma = 0xf,
+ .min_ldcp_eta = 0,
+ .max_ldcp_eta = 0xf }, // v2
+};
+
+static int roce5_update_ver_check(struct roce5_device *rdev, u32 cc_algo)
+{
+ u32 algo_bitmap = 0;
+ /* driver intercept not support algorithm. 1823V200 only supports LDCP algorithm, 1825V100 current only supports DCQCN, IPQCN, user custom A & B algorithm */
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ algo_bitmap = BIT(ROCE_CC_DISABLE);
+ if (ROCE5_SUPPORT_CC_GET_DCQCN_ENABLE(rdev) != 0) {
+ algo_bitmap |= BIT(ROCE_CC_DCQCN_ALGO);
+ }
+ if (ROCE5_SUPPORT_CC_GET_LDCP_ENABLE(rdev) != 0) {
+ algo_bitmap |= BIT(ROCE_CC_LDCP_ALGO);
+ }
+ if (ROCE5_SUPPORT_CC_GET_IPQCN_ENABLE(rdev) != 0) {
+ algo_bitmap |= BIT(ROCE_CC_IPQCN_ALGO);
+ }
+ if (ROCE5_SUPPORT_CC_GET_USER_ALGO_ENABLE(rdev) != 0) {
+ algo_bitmap |= BIT(ROCE_CC_USER_A_ALGO);
+ algo_bitmap |= BIT(ROCE_CC_USER_B_ALGO);
+ }
+ }
+
+ if (ROCE_CC_ALGO_TEST_BIT(algo_bitmap, cc_algo) == 0) {
+ ROCE_DEV_ERR(rdev, "func_id(0x%x), cc algo(0x%x) not support!",
+ rdev->glb_func_id, cc_algo);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int roce5_update_cfg_cc_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx)
+{
+ roce_cc_param_s cc_param;
+ int ret;
+
+ ret = roce5_update_ver_check(rdev, ecn_ctx->cc_algo);
+ if (ret != 0) {
+ return ret;
+ }
+
+ (void)memset_s(&cc_param, sizeof(cc_param), 0, sizeof(cc_param));
+
+ cc_param.dw0.bs.bypass = ecn_ctx->rp_ctx.bypass;
+ cc_param.dw0.bs.rtt_rsp_prio = ecn_ctx->np_ctx.rtt_rsp_prio;
+ cc_param.dw0.bs.rtt_rsp_prio_enable =
+ ecn_ctx->np_ctx.rtt_rsp_prio_enable;
+ cc_param.dw0.bs.rtt_version = ecn_ctx->np_ctx.rtt_version;
+ cc_param.dw0.bs.ecn_cnp_en = ecn_ctx->np_ctx.ecn_cnp_en;
+ cc_param.dw0.bs.min_cnp_period = ecn_ctx->np_ctx.min_cnp_period;
+ cc_param.dw0.bs.cnp_prio_enable = ecn_ctx->np_ctx.cnp_prio_enable;
+ cc_param.dw0.bs.slow_path_psn_threshold =
+ ecn_ctx->multipath_ctx.slow_path_psn_threshold;
+ cc_param.dw0.bs.rtt_req_event_mode =
+ ecn_ctx->multipath_ctx.rtt_req_event_mode;
+ cc_param.dw1.bs.cnp_prio = ecn_ctx->np_ctx.cnp_prio;
+ cc_param.dw1.bs.cnp_cos =
+ roce5_get_db_cos_from_vlan_pri(rdev, cc_param.dw1.bs.cnp_prio);
+ cc_param.dw1.bs.cc_appid = ecn_ctx->cc_algo;
+
+ if (cc_param.dw1.bs.cc_appid == ROCE_CC_LDCP_ALGO) {
+ cc_param.dw0.bs.algo_mode = CCP_ALGO_MODE_CWND;
+ } else if (cc_param.dw1.bs.cc_appid == ROCE_CC_DCQCN_ALGO ||
+ cc_param.dw1.bs.cc_appid == ROCE_CC_IPQCN_ALGO) {
+ cc_param.dw0.bs.algo_mode = CCP_ALGO_MODE_RATE;
+ } else {
+ cc_param.dw0.bs.algo_mode = ecn_ctx->ucc_ctx.algo_mode;
+ }
+
+ if (cc_param.dw0.bs.algo_mode == CCP_ALGO_MODE_CWND) {
+ cc_param.dw0.bs.flow_ctrl_unit = FLOW_CTRL_UNIT_QP;
+ } else {
+ cc_param.dw0.bs.flow_ctrl_unit = ecn_ctx->np_ctx.flow_ctrl_unit;
+ }
+
+ ROCE_DEV_INFO(rdev, "set cc_appid(%u), func_id(%u).",
+ cc_param.dw1.bs.cc_appid, rdev->glb_func_id);
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)&cc_param,
+ sizeof(roce_cc_param_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_CC_PARAM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set cc param, func_id(%d) ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ return ret;
+}
+
+static int roce5_update_dcqcn_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx)
+{
+ ccp_dcqcn_para_s dcqcn_param;
+ int ret;
+
+ if (ecn_ctx->cc_algo != ROCE_CC_DCQCN_ALGO) {
+ ROCE_DEV_INFO(
+ rdev,
+ "func_id(%d) cc_algo(%u) is not dcqcn, ignore update.",
+ rdev->glb_func_id, ecn_ctx->cc_algo);
+ return 0;
+ }
+
+ (void)memset_s(&dcqcn_param, sizeof(dcqcn_param), 0,
+ sizeof(dcqcn_param));
+
+ dcqcn_param.dw0.bs.token_period = ecn_ctx->rp_ctx.token_period;
+ dcqcn_param.dw0.bs.min_rate = ecn_ctx->rp_ctx.min_rate;
+ dcqcn_param.dw1.bs.rate_inc_period = ecn_ctx->rp_ctx.rate_inc_period;
+ dcqcn_param.dw1.bs.alpha_dec_period = ecn_ctx->rp_ctx.alpha_dec_period;
+ dcqcn_param.dw2.bs.rate_inc_ai = ecn_ctx->rp_ctx.rate_inc_ai;
+ dcqcn_param.dw2.bs.rate_inc_hai = ecn_ctx->rp_ctx.rate_inc_hai;
+ dcqcn_param.dw2.bs.rate_dec_period = ecn_ctx->rp_ctx.rate_dec_period;
+ dcqcn_param.dw2.bs.min_cnp_period = ecn_ctx->np_ctx.min_cnp_period;
+ dcqcn_param.dw3.bs.gita_shift = ecn_ctx->rp_ctx.factor_gita;
+ dcqcn_param.dw3.bs.rate_target_clamp =
+ ecn_ctx->rp_ctx.rate_target_clamp;
+ dcqcn_param.dw3.bs.initial_alpha = ecn_ctx->rp_ctx.initial_alpha;
+ // adjust_en
+ dcqcn_param.dw3.bs.rate_first_set = ecn_ctx->rp_ctx.rate_first_set;
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)(void *)&dcqcn_param,
+ sizeof(ccp_dcqcn_para_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_DCQCN_PARAM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set dcqcn param, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ return ret;
+}
+
+static int roce5_update_ldcp_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx)
+{
+ roce_ldcp_param_s ldcp_param;
+ int ret;
+
+ if (ecn_ctx->cc_algo != ROCE_CC_LDCP_ALGO) {
+ ROCE_DEV_INFO(
+ rdev,
+ "func_id(%d) cc_algo(%u) is not ldcp, ignore update.",
+ rdev->glb_func_id, ecn_ctx->cc_algo);
+ return 0;
+ }
+
+ ROCE_DEV_INFO(
+ rdev,
+ "update ldcp param, func_id(%d), alpha(%u), beta(%u), gamma(%u), eta(%u) wnd_min(%u) wnd_default(%u)",
+ rdev->glb_func_id, ecn_ctx->ldcp_ctx.alpha,
+ ecn_ctx->ldcp_ctx.beta, ecn_ctx->ldcp_ctx.gamma,
+ ecn_ctx->ldcp_ctx.eta, ecn_ctx->ldcp_ctx.wnd_min,
+ ecn_ctx->ldcp_ctx.wnd_default);
+
+ (void)memset_s(&ldcp_param, sizeof(ldcp_param), 0, sizeof(ldcp_param));
+
+ ldcp_param.dw0.bs.alpha = ecn_ctx->ldcp_ctx.alpha;
+ ldcp_param.dw0.bs.beta = ecn_ctx->ldcp_ctx.beta;
+ ldcp_param.dw0.bs.gamma = ecn_ctx->ldcp_ctx.gamma;
+ ldcp_param.dw0.bs.eta = ecn_ctx->ldcp_ctx.eta;
+ ldcp_param.dw0.bs.wnd_min = ecn_ctx->ldcp_ctx.wnd_min;
+ ldcp_param.dw1.bs.wnd_default = ecn_ctx->ldcp_ctx.wnd_default;
+ ldcp_param.dw0.bs.set_flag = 1;
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)(void *)&ldcp_param,
+ sizeof(roce_ldcp_param_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_LDCP_PARAM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set ldcp param, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ return ret;
+}
+
+static int roce5_update_ipqcn_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx)
+{
+ roce_ipqcn_param_s ipqcn_param;
+ int ret;
+
+ if (ecn_ctx->cc_algo != ROCE_CC_IPQCN_ALGO) {
+ ROCE_DEV_INFO(
+ rdev,
+ "func_id(%d) cc_algo(%u) is not ipqcn, ignore update.",
+ rdev->glb_func_id, ecn_ctx->cc_algo);
+ return 0;
+ }
+
+ (void)memset_s(&ipqcn_param, sizeof(ipqcn_param), 0,
+ sizeof(ipqcn_param));
+
+ ipqcn_param.dw0.bs.token_period = ecn_ctx->rp_ctx.token_period;
+ ipqcn_param.dw0.bs.flow_min_rate = ecn_ctx->rp_ctx.min_rate;
+ ipqcn_param.dw1.bs.rate_inc_period = ecn_ctx->rp_ctx.rate_inc_period;
+ ipqcn_param.dw1.bs.alpha_dec_period = ecn_ctx->rp_ctx.alpha_dec_period;
+ ipqcn_param.dw2.bs.rate_inc_ai = ecn_ctx->rp_ctx.rate_inc_ai;
+ ipqcn_param.dw2.bs.rate_inc_hai = ecn_ctx->rp_ctx.rate_inc_hai;
+ ipqcn_param.dw2.bs.rate_dec_period = ecn_ctx->rp_ctx.rate_dec_period;
+ ipqcn_param.dw2.bs.min_cnp_period = ecn_ctx->np_ctx.min_cnp_period;
+ ipqcn_param.dw3.bs.factor_gita = ecn_ctx->rp_ctx.factor_gita;
+ ipqcn_param.dw3.bs.rt_clamp = ecn_ctx->rp_ctx.rate_target_clamp;
+ ipqcn_param.dw3.bs.initial_alpha = ecn_ctx->rp_ctx.initial_alpha;
+ ipqcn_param.dw3.bs.rate_first_set = ecn_ctx->rp_ctx.rate_first_set;
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)(void *)&ipqcn_param,
+ sizeof(roce_ipqcn_param_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_IPQCN_PARAM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to set ipqcn param, func_id(%d) ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ return ret;
+}
+
+typedef int (*roce5_update_param_t)(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx);
+
+static roce5_update_param_t roce5_update_param_funcs[] = {
+ roce5_update_cfg_cc_param, roce5_update_dcqcn_param,
+ roce5_update_ipqcn_param, roce5_update_ldcp_param,
+ roce5_update_ucc_param,
+};
+
+int roce5_update_ecn_param(const struct roce5_ecn_ctx *ecn_ctx)
+{
+ unsigned int i;
+ int ret = 0;
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+
+ /* current only supports LDCP algorithm, its remaining algorithm can only modify its algorithm parameters, cannot switch */
+ for (i = 0; i < (sizeof(roce5_update_param_funcs) /
+ sizeof(roce5_update_param_t));
+ i++) {
+ ret = roce5_update_param_funcs[i](rdev, ecn_ctx);
+ if (ret != 0) {
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static ssize_t roce5_show_cc_algo(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ switch ((int)ecn_ctx->cc_algo) {
+ case ROCE_CC_DISABLE:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n", "disable");
+ case ROCE_CC_DCQCN_ALGO:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n", "dcqcn");
+ case ROCE_CC_LDCP_ALGO:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n", "ldcp");
+ case ROCE_CC_IPQCN_ALGO:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n",
+ "hc3_1/ipqcn");
+ case ROCE_CC_USER_A_ALGO:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n",
+ "user_cc_6");
+ case ROCE_CC_USER_B_ALGO:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n",
+ "user_cc_7");
+ default:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n",
+ "error_type");
+ }
+}
+
+static ssize_t roce5_store_cc_algo(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+ u32 old_cc_algo = 0;
+ int cc_algo = 0;
+ const char *ptr = NULL;
+ int ret;
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ /* dcqcn -> 0x0, ldcp -> 0x2, hc3_1 -> 0x80 */
+ if (strncmp(buf, "disable", strlen("disable")) == 0) {
+ cc_algo = ROCE_CC_DISABLE;
+ } else if (strncmp(buf, "dcqcn", strlen("dcqcn")) == 0) {
+ cc_algo = ROCE_CC_DCQCN_ALGO;
+ } else if ((strncmp(buf, "ipqcn", strlen("ipqcn")) == 0) ||
+ (strncmp(buf, "hc3_1", strlen("hc3_1")) == 0)) {
+ cc_algo = ROCE_CC_IPQCN_ALGO;
+ } else if (strncmp(buf, "ldcp", strlen("ldcp")) == 0) {
+ cc_algo = ROCE_CC_LDCP_ALGO;
+ } else if (strncmp(buf, "user_cc_", strlen("user_cc_")) == 0) {
+ if (strlen(buf) > ROCE_USER_CC_ID_MAX_LEN) {
+ ROCE_ERR(
+ "Invalid buffer length, expected <= %d, got %zu, Buffer: '%s'",
+ ROCE_USER_CC_ID_MAX_LEN, strlen(buf), buf);
+ return -EINVAL;
+ }
+ ptr = buf + strlen("user_cc_");
+ cc_algo = (unsigned char)(*ptr) - CHAR_0;
+ if (cc_algo != ROCE_CC_USER_A_ALGO &&
+ cc_algo != ROCE_CC_USER_B_ALGO) {
+ ROCE_ERR("Invalid cc_algo(%d),buf(%s)", cc_algo, buf);
+ return -EINVAL;
+ }
+ } else {
+ ROCE_ERR("Invalid cc_algo(%d),buf(%s)", cc_algo, buf);
+ return -EIO;
+ }
+
+ if (ecn_ctx->cc_algo != (u32)cc_algo) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_cc_algo = ecn_ctx->cc_algo;
+ ecn_ctx->cc_algo = (u32)cc_algo;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Failed to update cc_algo(%d), ret(%d).",
+ cc_algo, ret);
+ ecn_ctx->cc_algo = old_cc_algo;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t roce5_show_ecn_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_prio_enable_ctx *prio_enable_ctx =
+ container_of(attr, struct roce5_prio_enable_ctx, enable);
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)prio_enable_ctx->prio_en);
+}
+
+static ssize_t roce5_store_ecn_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ int prio_en = 0;
+ u32 old_prio_en = 0;
+ struct roce5_ecn_rp_ctx *rp_ctx = NULL;
+ struct roce5_ecn_np_ctx *np_ctx = NULL;
+ struct roce5_ecn_ctx *ecn_ctx = NULL;
+ struct roce5_prio_enable_ctx *prio_enable_ctx =
+ container_of(attr, struct roce5_prio_enable_ctx, enable);
+ struct roce5_ecn_enable_ctx *ecn_enable_ctx =
+ (struct roce5_ecn_enable_ctx *)prio_enable_ctx->ecn_enable_ctx;
+
+ if (ecn_enable_ctx->np_rp == ROCE_DCQCN_NP) {
+ np_ctx = container_of(ecn_enable_ctx, struct roce5_ecn_np_ctx,
+ enable_ctx);
+ ecn_ctx = container_of(np_ctx, struct roce5_ecn_ctx, np_ctx);
+ } else {
+ rp_ctx = container_of(ecn_enable_ctx, struct roce5_ecn_rp_ctx,
+ enable_ctx);
+ ecn_ctx = container_of(rp_ctx, struct roce5_ecn_ctx, rp_ctx);
+ }
+
+ ret = sscanf_s(buf, "%d", &prio_en);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (((u32)prio_en & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (prio_enable_ctx->prio_en != (u32)prio_en) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_prio_en = prio_enable_ctx->prio_en;
+ prio_enable_ctx->prio_en = (u32)prio_en;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update prio_en(%d), ret(%d).",
+ prio_en, ret);
+ prio_enable_ctx->prio_en = old_prio_en;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t roce5_show_ecn_ip_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ip_prio_enable_ctx *ip_prio_enable_ctx =
+ container_of(attr, struct roce5_ip_prio_enable_ctx, ip_enable);
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ip_prio_enable_ctx->prio_en);
+}
+
+static ssize_t roce5_store_ecn_ip_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ int prio_en = 0;
+ u32 old_prio_en = 0;
+ struct roce5_ip_prio_enable_ctx *ip_prio_enable_ctx =
+ container_of(attr, struct roce5_ip_prio_enable_ctx, ip_enable);
+ struct roce5_ecn_ip_enable_ctx *ip_enable_ctx =
+ (struct roce5_ecn_ip_enable_ctx *)
+ ip_prio_enable_ctx->ecn_ip_enable_ctx;
+ struct roce5_ecn_ctx *ecn_ctx = container_of(
+ ip_enable_ctx, struct roce5_ecn_ctx, ip_enable_ctx);
+
+ ret = sscanf_s(buf, "%d", &prio_en);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (((u32)prio_en & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ip_prio_enable_ctx->prio_en != (u32)prio_en) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_prio_en = ip_prio_enable_ctx->prio_en;
+ ip_prio_enable_ctx->prio_en = (u32)prio_en;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update prio_en(%d), ret(%d).",
+ prio_en, ret);
+ ip_prio_enable_ctx->prio_en = old_prio_en;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* rp_ctx parameters use macro generate show/store function */
+ROCE5_PARAM_SHOW_STORE_RP(bypass, bypass, min_bypass, max_bypass)
+ROCE5_PARAM_SHOW_STORE_RP(rate_inc_hai, rate_inc_hai, min_rate_inc_hai,
+ max_rate_inc_hai)
+ROCE5_PARAM_SHOW_STORE_RP(rate_inc_ai, rate_inc_ai, min_rate_inc_ai,
+ max_rate_inc_ai)
+ROCE5_PARAM_SHOW_STORE_RP(initial_alpha, initial_alpha, min_initial_alpha,
+ max_initial_alpha)
+ROCE5_PARAM_SHOW_STORE_RP(factor_gita, factor_gita, min_factor_gita,
+ max_factor_gita)
+ROCE5_PARAM_SHOW_STORE_RP(rate_inc_period, rate_inc_period, min_rate_inc_period,
+ max_rate_inc_period)
+ROCE5_PARAM_SHOW_STORE_RP(rate_dec_period, rate_dec_period, min_rate_dec_period,
+ max_rate_dec_period)
+ROCE5_PARAM_SHOW_STORE_RP(token_period, token_period, min_token_period,
+ max_token_period)
+ROCE5_PARAM_SHOW_STORE_RP(min_rate, min_rate, min_flow_min_rate,
+ max_flow_min_rate)
+ROCE5_PARAM_SHOW_STORE_RP(alpha_dec_period, alpha_dec_period,
+ min_alpha_dec_period, max_alpha_dec_period)
+ROCE5_PARAM_SHOW_STORE_RP(rate_first_set, rate_first_set, min_rate_first_set,
+ max_rate_first_set)
+
+/* rate_target_clamp special handle: use ROCE_ENABLE_CHECK_MASK but non- range check */
+static ssize_t roce5_show_rate_target_clamp(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx = to_roce5_ecn_rp_ctx(kobj);
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_rp_ctx->rate_target_clamp);
+}
+
+static ssize_t roce5_store_rate_target_clamp(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ int rate_target_clamp = 0;
+ u32 old_rate_target_clamp = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx = to_roce5_ecn_rp_ctx(kobj);
+
+ ret = sscanf_s(buf, "%d", &rate_target_clamp);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (((u32)rate_target_clamp & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ecn_rp_ctx->rate_target_clamp != (u32)rate_target_clamp) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_rate_target_clamp = ecn_rp_ctx->rate_target_clamp;
+ ecn_rp_ctx->rate_target_clamp = (u32)rate_target_clamp;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Fail to update rate_target_clamp(%d), ret(%d).",
+ rate_target_clamp, ret);
+ ecn_rp_ctx->rate_target_clamp = old_rate_target_clamp;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* np_ctx parameters use macro generate show/store function */
+ROCE5_PARAM_SHOW_STORE_NP(min_cnp_period, min_cnp_period, min_min_cnp_period,
+ max_min_cnp_period)
+
+/* flow_ctrl_unit special handle: use ROCE_ENABLE_CHECK_MASK check */
+static ssize_t roce5_show_flow_ctrl_unit(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_np_ctx->flow_ctrl_unit);
+}
+static ssize_t roce5_store_flow_ctrl_unit(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret, _val;
+ u32 _old;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ char remaining;
+
+ ret = sscanf_s(buf, "%d %c", &_val, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, flow_ctrl_unit should be unsigned int, ret(%d), flow_ctrl_unit(%d)",
+ ret, _val);
+ return -EIO;
+ }
+
+ if (((u32)_val & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->flow_ctrl_unit != (u32)_val) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ _old = ecn_np_ctx->flow_ctrl_unit;
+ ecn_np_ctx->flow_ctrl_unit = (u32)_val;
+ ret = roce5_update_ecn_param(ecn_ctx);
+
+ if (ret != 0) {
+ ecn_np_ctx->flow_ctrl_unit = _old;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+ return (ssize_t)count;
+}
+
+/* rtt_version special handle: only check maximum value */
+static ssize_t roce5_show_rtt_version(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_np_ctx->rtt_version);
+}
+static ssize_t roce5_store_rtt_version(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ u32 _val, _old;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+ char remaining;
+
+ ret = sscanf_s(buf, "%u %c", &_val, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, rtt_version should be unsigned int, ret(%d), rtt_version(%u)",
+ ret, _val);
+ return -EIO;
+ }
+
+ if (_val >
+ g_roce_cc_ecn_param[rdev->cc_param_version].max_rtt_version) {
+ ROCE_ERR("Invalid input, rtt_version(%u) over max rtt version",
+ _val);
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->rtt_version != _val) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ _old = ecn_np_ctx->rtt_version;
+ ecn_np_ctx->rtt_version = _val;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ecn_np_ctx->rtt_version = _old;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+ return (ssize_t)count;
+}
+
+/* rtt_rsp_prio special handle: use PRI_ARRAY_LEN - 1 check */
+static ssize_t roce5_show_rtt_rsp_prio(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%u\n",
+ ecn_np_ctx->rtt_rsp_prio);
+}
+
+static ssize_t roce5_store_rtt_rsp_prio(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ u32 rtt_rsp_prio = 0;
+ u32 old_rtt_rsp_prio = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+
+ char remaining;
+ ret = sscanf_s(buf, "%u %c", &rtt_rsp_prio, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, rtt_rsp_prio should be unsigned int, ret(%d), rtt_rsp_prio(%u)\n",
+ ret, rtt_rsp_prio);
+ return -EIO;
+ }
+
+ if (rtt_rsp_prio > (PRI_ARRAY_LEN - 1)) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->rtt_rsp_prio != (u32)rtt_rsp_prio) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_rtt_rsp_prio = ecn_np_ctx->rtt_rsp_prio;
+ ecn_np_ctx->rtt_rsp_prio = (u32)rtt_rsp_prio;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update rtt_rsp_prio(%d), ret(%d).",
+ rtt_rsp_prio, ret);
+ ecn_np_ctx->rtt_rsp_prio = old_rtt_rsp_prio;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* rtt_rsp_prio_enable special handle: use ROCE_ENABLE_CHECK_MASK check */
+static ssize_t roce5_show_rtt_rsp_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%u\n",
+ ecn_np_ctx->rtt_rsp_prio_enable);
+}
+
+static ssize_t roce5_store_rtt_rsp_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ u32 rtt_rsp_prio_enable = 0;
+ u32 old_rtt_rsp_prio_enable = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+
+ char remaining;
+ ret = sscanf_s(buf, "%u %c", &rtt_rsp_prio_enable, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, rtt_rsp_prio_enable should be unsigned int, ret(%d), rtt_rsp_prio_enable(%u)",
+ ret, rtt_rsp_prio_enable);
+ return -EIO;
+ }
+
+ if ((rtt_rsp_prio_enable & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->rtt_rsp_prio_enable != (u32)rtt_rsp_prio_enable) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_rtt_rsp_prio_enable = ecn_np_ctx->rtt_rsp_prio_enable;
+ ecn_np_ctx->rtt_rsp_prio_enable = (u32)rtt_rsp_prio_enable;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Fail to update rtt_rsp_prio_enable(%d), ret(%d).",
+ rtt_rsp_prio_enable, ret);
+ ecn_np_ctx->rtt_rsp_prio_enable =
+ old_rtt_rsp_prio_enable;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* ecn_cnp_en special handle: use ROCE_ENABLE_CHECK_MASK check */
+static ssize_t roce5_show_ecn_cnp_en(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_np_ctx->ecn_cnp_en);
+}
+
+static ssize_t roce5_store_ecn_cnp_en(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ u32 ecn_cnp_en = 0;
+ u32 old_ecn_cnp_en = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+
+ char remaining;
+ ret = sscanf_s(buf, "%u %c", &ecn_cnp_en, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR(
+ "Invalid input, ecn_cnp_en should be unsigned int, ret(%d), ecn_cnp_en(%u)",
+ ret, ecn_cnp_en);
+ return -EIO;
+ }
+
+ if ((ecn_cnp_en & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->ecn_cnp_en != (u32)ecn_cnp_en) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_ecn_cnp_en = ecn_np_ctx->ecn_cnp_en;
+ ecn_np_ctx->ecn_cnp_en = (u32)ecn_cnp_en;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update ecn_cnp_en(%d), ret(%d).",
+ ecn_cnp_en, ret);
+ ecn_np_ctx->ecn_cnp_en = old_ecn_cnp_en;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* cnp_prio_enable special handle: use ROCE_ENABLE_CHECK_MASK check */
+static ssize_t roce5_show_cnp_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_np_ctx->cnp_prio_enable);
+}
+
+static ssize_t roce5_store_cnp_prio_enable(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ int cnp_prio_enable = 0;
+ u32 old_cnp_prio_enable = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+
+ ret = sscanf_s(buf, "%d", &cnp_prio_enable);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (((u32)cnp_prio_enable & ROCE_ENABLE_CHECK_MASK) != 0) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->cnp_prio_enable != (u32)cnp_prio_enable) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_cnp_prio_enable = ecn_np_ctx->cnp_prio_enable;
+ ecn_np_ctx->cnp_prio_enable = (u32)cnp_prio_enable;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update cnp_prio_enable(%d), ret(%d).",
+ cnp_prio_enable, ret);
+ ecn_np_ctx->cnp_prio_enable = old_cnp_prio_enable;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+/* cnp_prio special handle: use PRI_ARRAY_LEN - 1 check */
+static ssize_t roce5_show_cnp_prio(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_np_ctx->cnp_prio);
+}
+
+static ssize_t roce5_store_cnp_prio(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ int cnp_prio = 0;
+ u32 old_cnp_prio = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_np_ctx *ecn_np_ctx = to_roce5_ecn_np_ctx(kobj);
+
+ ret = sscanf_s(buf, "%d", &cnp_prio);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (((u32)cnp_prio) > (PRI_ARRAY_LEN - 1)) {
+ return -EIO;
+ }
+
+ if (ecn_np_ctx->cnp_prio != (u32)cnp_prio) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_cnp_prio = ecn_np_ctx->cnp_prio;
+ ecn_np_ctx->cnp_prio = (u32)cnp_prio;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update cnp_prio(%d), ret(%d).",
+ cnp_prio, ret);
+ ecn_np_ctx->cnp_prio = old_cnp_prio;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+static int
+roce5_init_ecn_enable_sysfs(struct kobject *kobj,
+ struct roce5_ecn_enable_ctx *ecn_enable_ctx)
+{
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+ const char *prio_arr[8] = { "0", "1", "2", "3", "4", "5", "6", "7" };
+ struct roce5_prio_enable_ctx *prio_enable = NULL;
+
+ ecn_enable_ctx->enable_root = kobject_create_and_add("enable", kobj);
+ if (ecn_enable_ctx->enable_root == NULL) {
+ ROCE_ERR("Failed to create kobject for ecn enable.(ret:%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < PRI_ARRAY_LEN; i++) {
+ prio_enable = &ecn_enable_ctx->prio_enable[i];
+ prio_enable->ecn_enable_ctx = (void *)ecn_enable_ctx;
+ prio_enable->prio = (u32)i;
+ prio_enable->prio_en = 1;
+ sysfs_attr_init(&prio_enable->enable.attr);
+ prio_enable->enable.attr.name = prio_arr[i];
+ prio_enable->enable.attr.mode = (S_IWUSR | S_IRUSR | S_IRGRP);
+ prio_enable->enable.show = roce5_show_ecn_prio_enable;
+ prio_enable->enable.store = roce5_store_ecn_prio_enable;
+ ret = sysfs_create_file(ecn_enable_ctx->enable_root,
+ &prio_enable->enable.attr);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to create file for ecn enable.(ret:%d)",
+ ret);
+ goto err_create_file;
+ }
+ }
+
+ return 0;
+
+err_create_file:
+ for (j = i - 1; j >= 0; j--) {
+ sysfs_remove_file(ecn_enable_ctx->enable_root,
+ &ecn_enable_ctx->prio_enable[i].enable.attr);
+ }
+
+ kobject_put(ecn_enable_ctx->enable_root);
+
+ return ret;
+}
+
+static void
+roce5_remove_ecn_enable_sysfs(struct kobject *kobj,
+ struct roce5_ecn_enable_ctx *ecn_enable_ctx)
+{
+ int i;
+
+ for (i = 0; i < PRI_ARRAY_LEN; i++) {
+ sysfs_remove_file(ecn_enable_ctx->enable_root,
+ &ecn_enable_ctx->prio_enable[i].enable.attr);
+ }
+
+ kobject_put(ecn_enable_ctx->enable_root);
+}
+
+static int
+roce5_init_ecn_ip_enable_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ip_enable_ctx *ip_enable_ctx)
+{
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+ const char *prio_arr[8] = { "0", "1", "2", "3", "4", "5", "6", "7" };
+ struct roce5_ip_prio_enable_ctx *ip_prio_enable = NULL;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+ ip_enable_ctx->ip_enable_root =
+ kobject_create_and_add("ip_enable", kobj);
+ if (ip_enable_ctx->ip_enable_root == NULL) {
+ ROCE_ERR("Failed to create kobject for ecn ip enable.(ret:%d)",
+ ret);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < PRI_ARRAY_LEN; i++) {
+ ip_prio_enable = &ip_enable_ctx->ip_prio_enable[i];
+ ip_prio_enable->ecn_ip_enable_ctx = (void *)ip_enable_ctx;
+ ip_prio_enable->prio = (u32)i;
+ ip_prio_enable->prio_en =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_ip_enable_en;
+ sysfs_attr_init(&ip_prio_enable->ip_enable.attr);
+ ip_prio_enable->ip_enable.attr.name = prio_arr[i];
+ ip_prio_enable->ip_enable.attr.mode =
+ (S_IWUSR | S_IRUSR | S_IRGRP);
+ ip_prio_enable->ip_enable.show = roce5_show_ecn_ip_prio_enable;
+ ip_prio_enable->ip_enable.store =
+ roce5_store_ecn_ip_prio_enable;
+ ret = sysfs_create_file(ip_enable_ctx->ip_enable_root,
+ &ip_prio_enable->ip_enable.attr);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to create file for ecn ip enable.(ret:%d)",
+ ret);
+ goto err_create_file;
+ }
+ }
+
+ return 0;
+
+err_create_file:
+ for (j = i - 1; j >= 0; j--) {
+ sysfs_remove_file(
+ ip_enable_ctx->ip_enable_root,
+ &ip_enable_ctx->ip_prio_enable[i].ip_enable.attr);
+ }
+
+ kobject_put(ip_enable_ctx->ip_enable_root);
+
+ return ret;
+}
+
+static void
+roce5_remove_ecn_ip_enable_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ip_enable_ctx *ip_enable_ctx)
+{
+ int i;
+
+ for (i = 0; i < PRI_ARRAY_LEN; i++) {
+ sysfs_remove_file(
+ ip_enable_ctx->ip_enable_root,
+ &ip_enable_ctx->ip_prio_enable[i].ip_enable.attr);
+ }
+
+ kobject_put(ip_enable_ctx->ip_enable_root);
+}
+
+ROCE_ATTR_RW(bypass, roce5_show_bypass, roce5_store_bypass);
+ROCE_ATTR_RW(alpha_dec_period, roce5_show_alpha_dec_period,
+ roce5_store_alpha_dec_period);
+ROCE_ATTR_RW(rate_dec_period, roce5_show_rate_dec_period,
+ roce5_store_rate_dec_period);
+ROCE_ATTR_RW(rate_inc_period, roce5_show_rate_inc_period,
+ roce5_store_rate_inc_period);
+ROCE_ATTR_RW(factor_gita, roce5_show_factor_gita, roce5_store_factor_gita);
+ROCE_ATTR_RW(initial_alpha, roce5_show_initial_alpha,
+ roce5_store_initial_alpha);
+ROCE_ATTR_RW(rate_inc_ai, roce5_show_rate_inc_ai, roce5_store_rate_inc_ai);
+ROCE_ATTR_RW(rate_inc_hai, roce5_show_rate_inc_hai, roce5_store_rate_inc_hai);
+ROCE_ATTR_RW(rate_first_set, roce5_show_rate_first_set,
+ roce5_store_rate_first_set);
+ROCE_ATTR_RW(rate_target_clamp, roce5_show_rate_target_clamp,
+ roce5_store_rate_target_clamp);
+ROCE_ATTR_RW(token_period, roce5_show_token_period, roce5_store_token_period);
+ROCE_ATTR_RW(min_rate, roce5_show_min_rate, roce5_store_min_rate);
+
+static struct attribute *ecn_rp_ctx_attrs[] = {
+ ROCE_ATTR_PTR(bypass),
+ ROCE_ATTR_PTR(alpha_dec_period),
+ ROCE_ATTR_PTR(rate_dec_period),
+ ROCE_ATTR_PTR(rate_inc_period),
+ ROCE_ATTR_PTR(factor_gita),
+ ROCE_ATTR_PTR(initial_alpha),
+ ROCE_ATTR_PTR(rate_inc_ai),
+ ROCE_ATTR_PTR(rate_inc_hai),
+ ROCE_ATTR_PTR(rate_first_set),
+ ROCE_ATTR_PTR(rate_target_clamp),
+ ROCE_ATTR_PTR(token_period),
+ ROCE_ATTR_PTR(min_rate),
+ NULL,
+};
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_rp_ctx_attr_grp = {
+ .attrs = ecn_rp_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_rp_ctx_attr_grps[] = {
+ &ecn_rp_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static void roce_ecn_rp_sysfs_release(struct kobject *kobj)
+{
+}
+
+static struct kobj_type roce_ecn_rp_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_rp_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_rp_ctx_attr_grps,
+#else
+ .default_attrs = ecn_rp_ctx_attrs,
+#endif
+};
+
+static int roce5_init_ecn_rp_sysfs(struct kobject *kobj,
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx)
+{
+ int ret = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+
+ ecn_rp_ctx->bypass =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_bypass;
+ ecn_rp_ctx->alpha_dec_period =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_alpha_dec_period;
+ ecn_rp_ctx->rate_dec_period =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_rate_dec_period;
+ ecn_rp_ctx->rate_inc_period =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_rate_inc_period;
+ ecn_rp_ctx->factor_gita =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_factor_gita;
+ ecn_rp_ctx->initial_alpha = g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_initial_alpha;
+ ecn_rp_ctx->rate_inc_ai =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_rate_inc_ai;
+ ecn_rp_ctx->rate_inc_hai =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_rate_inc_hai;
+ ecn_rp_ctx->rate_first_set = g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_rate_first_set;
+ ecn_rp_ctx->rate_target_clamp =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_rate_target_clamp;
+ ecn_rp_ctx->token_period =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_token_period;
+ ecn_rp_ctx->min_rate =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_min_rate;
+ ret = kobject_init_and_add(&ecn_rp_ctx->ecn_rp_root, &roce_ecn_rp_ktype,
+ kobj, "roce5_rp");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject roce5_rp.(ret:%d)", ret);
+ kobject_put(&ecn_rp_ctx->ecn_rp_root);
+ return ret;
+ }
+
+ ecn_rp_ctx->enable_ctx.np_rp = ROCE_DCQCN_RP;
+ ret = roce5_init_ecn_enable_sysfs(&ecn_rp_ctx->ecn_rp_root,
+ &ecn_rp_ctx->enable_ctx);
+ if (ret != 0) {
+ goto err_init_prio_enable_sysfs;
+ }
+
+ return 0;
+
+err_init_prio_enable_sysfs:
+ kobject_put(&ecn_rp_ctx->ecn_rp_root);
+
+ return ret;
+}
+
+static void roce5_remove_ecn_rp_sysfs(struct kobject *kobj,
+ struct roce5_ecn_rp_ctx *ecn_rp_ctx)
+{
+ roce5_remove_ecn_enable_sysfs(&ecn_rp_ctx->ecn_rp_root,
+ &ecn_rp_ctx->enable_ctx);
+
+ kobject_put(&ecn_rp_ctx->ecn_rp_root);
+}
+
+ROCE_ATTR_RW(rtt_rsp_prio, roce5_show_rtt_rsp_prio, roce5_store_rtt_rsp_prio);
+ROCE_ATTR_RW(rtt_rsp_prio_enable, roce5_show_rtt_rsp_prio_enable,
+ roce5_store_rtt_rsp_prio_enable);
+ROCE_ATTR_RW(rtt_version, roce5_show_rtt_version, roce5_store_rtt_version);
+ROCE_ATTR_RW(ecn_cnp_en, roce5_show_ecn_cnp_en, roce5_store_ecn_cnp_en);
+ROCE_ATTR_RW(flow_ctrl_unit, roce5_show_flow_ctrl_unit,
+ roce5_store_flow_ctrl_unit);
+ROCE_ATTR_RW(min_cnp_period, roce5_show_min_cnp_period,
+ roce5_store_min_cnp_period);
+ROCE_ATTR_RW(cnp_prio_enable, roce5_show_cnp_prio_enable,
+ roce5_store_cnp_prio_enable);
+ROCE_ATTR_RW(cnp_prio, roce5_show_cnp_prio, roce5_store_cnp_prio);
+
+static struct attribute *ecn_np_ctx_attrs[] = {
+ ROCE_ATTR_PTR(min_cnp_period),
+ ROCE_ATTR_PTR(cnp_prio_enable),
+ ROCE_ATTR_PTR(cnp_prio),
+ ROCE_ATTR_PTR(rtt_rsp_prio),
+ ROCE_ATTR_PTR(rtt_rsp_prio_enable),
+ ROCE_ATTR_PTR(rtt_version),
+ ROCE_ATTR_PTR(ecn_cnp_en),
+ ROCE_ATTR_PTR(flow_ctrl_unit),
+ NULL,
+};
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_np_ctx_attr_grp = {
+ .attrs = ecn_np_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_np_ctx_attr_grps[] = {
+ &ecn_np_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static void roce_ecn_np_sysfs_release(struct kobject *kobj)
+{
+}
+
+static struct kobj_type roce_ecn_np_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_np_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_np_ctx_attr_grps,
+#else
+ .default_attrs = ecn_np_ctx_attrs,
+#endif
+};
+
+static int roce5_init_ecn_np_sysfs(struct kobject *kobj,
+ struct roce5_ecn_np_ctx *ecn_np_ctx)
+{
+ int ret = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+
+ ecn_np_ctx->min_cnp_period = g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_min_cnp_period;
+ ecn_np_ctx->cnp_prio_enable =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_cnp_prio_enable;
+ ecn_np_ctx->cnp_prio =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_cnp_prio;
+ ecn_np_ctx->ecn_cnp_en = g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_ecn_cnp_enable;
+ ecn_np_ctx->flow_ctrl_unit = g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_flow_ctrl_unit;
+ ecn_np_ctx->rtt_rsp_prio =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_rtt_rsp_prio;
+ ecn_np_ctx->rtt_rsp_prio_enable =
+ g_roce_cc_ecn_param[rdev->cc_param_version]
+ .default_rtt_rsp_prio_enable;
+ ecn_np_ctx->rtt_version =
+ g_roce_cc_ecn_param[rdev->cc_param_version].default_rtt_version;
+ ret = kobject_init_and_add(&ecn_np_ctx->ecn_np_root, &roce_ecn_np_ktype,
+ kobj, "roce5_np");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject roce5_np.(ret:%d)", ret);
+ kobject_put(&ecn_np_ctx->ecn_np_root);
+ return ret;
+ }
+
+ ecn_np_ctx->enable_ctx.np_rp = ROCE_DCQCN_NP;
+ ret = roce5_init_ecn_enable_sysfs(&ecn_np_ctx->ecn_np_root,
+ &ecn_np_ctx->enable_ctx);
+ if (ret != 0) {
+ goto err_init_prio_enable_sysfs;
+ }
+
+ return 0;
+
+err_init_prio_enable_sysfs:
+ kobject_put(&ecn_np_ctx->ecn_np_root);
+ return ret;
+}
+
+/* ldcp_ctx parameters use macro generate show/store function */
+ROCE5_PARAM_SHOW_STORE_LDCP(wnd_min, wnd_min, min_ldcp_wnd_min,
+ max_ldcp_wnd_min);
+ROCE5_PARAM_SHOW_STORE_LDCP(wnd_default, wnd_default, min_ldcp_wnd_default,
+ max_ldcp_wnd_default);
+ROCE5_PARAM_SHOW_STORE_LDCP(alpha, alpha, min_ldcp_alpha, max_ldcp_alpha);
+ROCE5_PARAM_SHOW_STORE_LDCP(beta, beta, min_ldcp_beta, max_ldcp_beta);
+ROCE5_PARAM_SHOW_STORE_LDCP(gamma, gamma, min_ldcp_gamma, max_ldcp_gamma);
+ROCE5_PARAM_SHOW_STORE_LDCP(eta, eta, min_ldcp_eta, max_ldcp_eta);
+
+ROCE_ATTR_RW(wnd_min, roce5_show_wnd_min, roce5_store_wnd_min);
+ROCE_ATTR_RW(wnd_default, roce5_show_wnd_default, roce5_store_wnd_default);
+ROCE_ATTR_RW(alpha, roce5_show_alpha, roce5_store_alpha);
+ROCE_ATTR_RW(beta, roce5_show_beta, roce5_store_beta);
+ROCE_ATTR_RW(gamma, roce5_show_gamma, roce5_store_gamma);
+ROCE_ATTR_RW(eta, roce5_show_eta, roce5_store_eta);
+
+static struct attribute *ecn_ldcp_ctx_attrs[] = {
+ ROCE_ATTR_PTR(wnd_min),
+ ROCE_ATTR_PTR(wnd_default),
+ ROCE_ATTR_PTR(alpha),
+ ROCE_ATTR_PTR(beta),
+ ROCE_ATTR_PTR(gamma),
+ ROCE_ATTR_PTR(eta),
+ NULL,
+};
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_ldcp_ctx_attr_grp = {
+ .attrs = ecn_ldcp_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_ldcp_ctx_attr_grps[] = {
+ &ecn_ldcp_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static void roce_ecn_ldcp_sysfs_release(struct kobject *kobj)
+{
+}
+
+static struct kobj_type roce_ecn_ldcp_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_ldcp_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_ldcp_ctx_attr_grps,
+#else
+ .default_attrs = ecn_ldcp_ctx_attrs,
+#endif
+};
+
+static int roce5_init_ecn_ldcp_sysfs(struct kobject *kobj,
+ roce5_ecn_ldcp_ctx_t *ecn_ldcp_ctx)
+{
+ int ret;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+ struct roce5_device *rdev =
+ container_of(ecn_ctx, struct roce5_device, ecn_ctx);
+
+ ecn_ldcp_ctx->wnd_min =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_wnd_min;
+ ecn_ldcp_ctx->wnd_default =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_wnd_default;
+ ecn_ldcp_ctx->alpha =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_alpha;
+ ecn_ldcp_ctx->beta =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_beta;
+ ecn_ldcp_ctx->gamma =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_gamma;
+ ecn_ldcp_ctx->eta =
+ g_roce_cc_ecn_param[rdev->cc_param_version].min_ldcp_eta;
+ ret = kobject_init_and_add(&ecn_ldcp_ctx->ecn_ldcp_root,
+ &roce_ecn_ldcp_ktype, kobj, "roce5_ldcp");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject roce5_ldcp.(ret:%d)", ret);
+ kobject_put(&ecn_ldcp_ctx->ecn_ldcp_root);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_remove_ecn_ldcp_sysfs(roce5_ecn_ldcp_ctx_t *ecn_ldcp_ctx)
+{
+ kobject_put(&ecn_ldcp_ctx->ecn_ldcp_root);
+}
+
+static void roce5_remove_ecn_np_sysfs(struct kobject *kobj,
+ struct roce5_ecn_np_ctx *ecn_np_ctx)
+{
+ roce5_remove_ecn_enable_sysfs(&ecn_np_ctx->ecn_np_root,
+ &ecn_np_ctx->enable_ctx);
+
+ kobject_put(&ecn_np_ctx->ecn_np_root);
+}
+
+static ssize_t roce5_show_ecn_ver(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%d\n",
+ (int)ecn_ctx->ecn_ver);
+}
+
+static ssize_t roce5_store_ecn_ver(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret = 0;
+ int ecn_ver = 0;
+ u32 old_ecn_ver = 0;
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj);
+
+ ret = sscanf_s(buf, "%d", &ecn_ver);
+ if (ret != 1) {
+ return -EIO;
+ }
+
+ if (ROCE5_PARAM_CHECK_BOUND(ecn_ver, ECN_VER_DCQCN, ECN_VER_PATHQCN)) {
+ return -EIO;
+ }
+
+ if (ecn_ctx->ecn_ver != (u32)ecn_ver) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_ecn_ver = ecn_ctx->ecn_ver;
+ ecn_ctx->ecn_ver = (u32)ecn_ver;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Fail to update ecn_ver(%d), ret(%d).",
+ ecn_ver, ret);
+ ecn_ctx->ecn_ver = old_ecn_ver;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+ROCE_ATTR_RW(ecn_ver, roce5_show_ecn_ver, roce5_store_ecn_ver);
+ROCE_ATTR_RW(cc_algo, roce5_show_cc_algo, roce5_store_cc_algo);
+
+static struct attribute *ecn_ctx_attrs[] = {
+ ROCE_ATTR_PTR(ecn_ver),
+ ROCE_ATTR_PTR(cc_algo),
+ NULL,
+};
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_ctx_attr_grp = {
+ .attrs = ecn_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_ctx_attr_grps[] = {
+ &ecn_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static void roce_ecn_sysfs_release(struct kobject *kobj)
+{
+}
+
+static struct kobj_type roce_ecn_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_ctx_attr_grps,
+#else
+ .default_attrs = ecn_ctx_attrs,
+#endif
+};
+
+static void roce5_init_cc_algo(struct roce5_device *rdev,
+ struct roce5_ecn_ctx *ecn_ctx)
+{
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ ecn_ctx->cc_algo = ROCE_CC_DCQCN_ALGO;
+ } else {
+ ecn_ctx->cc_algo = ROCE_CC_DISABLE;
+ }
+}
+
+static void roce5_init_cc_param_version(struct roce5_device *rdev)
+{
+ rdev->cc_param_version =
+ ROCE5_SUPPORT_CC_PARAM_V1(rdev) != 0 ? ROCE_CC_PARAM_V1 :
+ ROCE5_SUPPORT_CC_PARAM_V2(rdev) != 0 ? ROCE_CC_PARAM_V2 :
+ ROCE_CC_PARAM_INVALID;
+}
+
+static int roce5_init_ecn_sysfs(struct roce5_device *rdev,
+ struct roce5_ecn_ctx *ecn_ctx)
+{
+ int ret = 0;
+ struct net_device *ndev = rdev->ndev;
+
+ ret = memset_s(ecn_ctx, sizeof(*ecn_ctx), 0, sizeof(*ecn_ctx));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset ecn_ctx.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ mutex_init(&ecn_ctx->ecn_mutex);
+
+ ecn_ctx->ecn_ver = ECN_VER_DCQCN;
+ roce5_init_cc_algo(rdev, ecn_ctx);
+ roce5_init_cc_param_version(rdev);
+
+ ret = kobject_init_and_add(&ecn_ctx->ecn_root, &roce_ecn_ktype,
+ &ndev->dev.kobj, "ecn");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject ecn.(ret:%d)", ret);
+ kobject_put(&ecn_ctx->ecn_root);
+ return ret;
+ }
+
+ ret = roce5_init_ecn_ldcp_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->ldcp_ctx);
+ if (ret != 0) {
+ goto err_init_ldcp_sysfs;
+ }
+
+ ret = roce5_init_ecn_np_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->np_ctx);
+ if (ret != 0) {
+ goto err_init_np_sysfs;
+ }
+
+ ret = roce5_init_ecn_rp_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->rp_ctx);
+ if (ret != 0) {
+ goto err_init_rp_sysfs;
+ }
+
+ ret = roce5_init_ecn_ip_enable_sysfs(&ecn_ctx->ecn_root,
+ &ecn_ctx->ip_enable_ctx);
+ if (ret != 0) {
+ goto err_init_ip_enable_sysfs;
+ }
+
+ ret = roce5_init_ecn_ucc_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->ucc_ctx);
+ if (ret != 0) {
+ goto err_init_ecn_ucc_sysfs;
+ }
+
+ ret = roce5_init_ecn_multipath_sysfs(rdev, &ecn_ctx->ecn_root,
+ &ecn_ctx->multipath_ctx);
+ if (ret != 0) {
+ goto err_init_multipath_sysfs;
+ }
+
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ goto err_update;
+ }
+
+ return 0;
+
+err_update:
+ roce5_remove_ecn_multipath_sysfs(rdev, &ecn_ctx->ecn_root,
+ &ecn_ctx->multipath_ctx);
+err_init_multipath_sysfs:
+ roce5_remove_ecn_ucc_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->ucc_ctx);
+err_init_ecn_ucc_sysfs:
+ roce5_remove_ecn_ip_enable_sysfs(&ecn_ctx->ecn_root,
+ &ecn_ctx->ip_enable_ctx);
+err_init_ip_enable_sysfs:
+ roce5_remove_ecn_rp_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->rp_ctx);
+err_init_rp_sysfs:
+ roce5_remove_ecn_np_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->np_ctx);
+err_init_np_sysfs:
+ roce5_remove_ecn_ldcp_sysfs(&ecn_ctx->ldcp_ctx);
+err_init_ldcp_sysfs:
+ kobject_put(&ecn_ctx->ecn_root);
+ return ret;
+}
+
+static void roce5_prase_qpc(roce_verbs_qp_attr_s *qp_attr)
+{
+ qp_attr->com_info.rsvd = be32_to_cpu(qp_attr->com_info.rsvd);
+ qp_attr->ext_seg.dfx_info.dw0.value =
+ be32_to_cpu(qp_attr->ext_seg.dfx_info.dw0.value);
+ qp_attr->ext_seg.dfx_info.dw2.value =
+ be32_to_cpu(qp_attr->ext_seg.dfx_info.dw2.value);
+ qp_attr->ext_seg.dfx_info.dw4.value =
+ be32_to_cpu(qp_attr->ext_seg.dfx_info.dw4.value);
+}
+
+static ssize_t roce5_store_dfx_qpc(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ u32 qpn;
+ struct roce5_dfx_qpc_ctx *qpc_ctx = NULL;
+ struct roce5_dfx_ctx *dfx_ctx = NULL;
+ struct roce5_device *rdev = NULL;
+ roce_verbs_qp_attr_s qp_attr;
+ struct rdma_service_cap *rdma_cap = NULL;
+
+ if (kobj == NULL || attr == NULL || buf == NULL || count == 0) {
+ ROCE_ERR("Invalid input para.");
+ return -EINVAL;
+ }
+
+ qpc_ctx = container_of(attr, struct roce5_dfx_qpc_ctx, kattr);
+ dfx_ctx = container_of(qpc_ctx, struct roce5_dfx_ctx, qpc_ctx);
+ rdev = container_of(dfx_ctx, struct roce5_device, dfx_ctx);
+
+ (void)memset_s(&qp_attr, sizeof(roce_verbs_qp_attr_s), 0,
+ sizeof(roce_verbs_qp_attr_s));
+
+ ret = (int)sscanf_s(buf, "%u", &qpn);
+ if (ret != 1) {
+ ROCE_DEV_ERR(rdev, "Failed to do sscanf_s, ret(%d)", ret);
+ return -EIO;
+ }
+
+ rdma_cap = &rdev->rdma_cap;
+ if ((qpn >= rdma_cap->dev_rdma_cap.roce_own_cap.max_qps) ||
+ (qpn < ROCE_MIN_QPN)) {
+ ROCE_DEV_ERR(rdev, "Invalid qpn(%u), max_qps(%u)", qpn,
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_qps);
+ return -EIO;
+ }
+
+ ret = roce5_qp_query(rdev, qpn, (u32 *)(void *)&qp_attr,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query qp_attr, ret(%d)", ret);
+ return (ssize_t)ret;
+ }
+
+ roce5_prase_qpc(&qp_attr);
+
+ roce5_dfx_print("qpn(0x%x): sqc pi(0x%x), sqc ci(0x%x).", qpn,
+ qp_attr.ext_seg.dfx_info.dw0.bs.sq_pi,
+ qp_attr.ext_seg.dfx_info.dw0.bs.sq_ci);
+ roce5_dfx_print(
+ "sqac ci(0x%x), sqac wqe_prefetch_ci(0x%x), rqc pi(0x%x), rqc ci(0x%x).",
+ qp_attr.ext_seg.dfx_info.dw2.bs.sqa_ci,
+ qp_attr.ext_seg.dfx_info.dw2.bs.sqa_wqe_prefetch_ci,
+ qp_attr.ext_seg.dfx_info.dw4.bs.rq_pi,
+ qp_attr.ext_seg.dfx_info.dw4.bs.rq_ci);
+
+ return (ssize_t)count;
+}
+
+static ssize_t roce5_store_dfx_cqc(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ u32 cqn;
+ struct roce5_dfx_cqc_ctx *cqc_ctx = NULL;
+ struct roce5_dfx_ctx *dfx_ctx = NULL;
+ struct roce5_device *rdev = NULL;
+ roce_verbs_cq_attr_s cq_attr;
+ roce5_cq_query_outbuf_s cq_query;
+ struct rdma_service_cap *rdma_cap = NULL;
+
+ if (kobj == NULL || attr == NULL || buf == NULL || count == 0) {
+ ROCE_ERR("Invalid input para.");
+ return -EINVAL;
+ }
+
+ cqc_ctx = container_of(attr, struct roce5_dfx_cqc_ctx, kattr);
+ dfx_ctx = container_of(cqc_ctx, struct roce5_dfx_ctx, cqc_ctx);
+ rdev = container_of(dfx_ctx, struct roce5_device, dfx_ctx);
+
+ (void)memset_s(&cq_query, sizeof(roce5_cq_query_outbuf_s), 0,
+ sizeof(roce5_cq_query_outbuf_s));
+
+ ret = (int)sscanf_s(buf, "%u", &cqn);
+ if (ret != 1) {
+ ROCE_DEV_ERR(rdev, "Failed to do sscanf_s, ret(%d)", ret);
+ return -EIO;
+ }
+
+ rdma_cap = &rdev->rdma_cap;
+ if (cqn >= rdma_cap->dev_rdma_cap.roce_own_cap.max_cqs) {
+ ROCE_DEV_ERR(rdev, "Invalid cqn(%u), max_cqs(%u)", cqn,
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_cqs);
+ return -EIO;
+ }
+
+ ret = roce5_dfx_query_cq(rdev, cqn, (u32 *)(void *)&cq_query,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query cqc, ret(%d)", ret);
+ return (ssize_t)ret;
+ }
+
+ if (rdev->device_type == ROCE_DEV_TYPE_HI1825_V100) {
+ (void)memcpy_s(&cq_attr, sizeof(roce_verbs_cq_attr_s),
+ &cq_query, sizeof(roce_verbs_cq_attr_s));
+ cq_attr.dfx_info.dw0.value =
+ be32_to_cpu(cq_attr.dfx_info.dw0.value);
+ cq_attr.dfx_info.dw1.value =
+ be32_to_cpu(cq_attr.dfx_info.dw1.value);
+ roce5_dfx_print("cqn(0x%x): pi(0x%x), ci(0x%x).", cqn,
+ cq_attr.dfx_info.dw1.bs.pi,
+ cq_attr.dfx_info.dw0.bs.ci);
+ } else {
+ ROCE_DEV_ERR(rdev,
+ "Unsupport rdev device_type, device_type(%d)",
+ rdev->device_type);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t roce5_store_dfx_srqc(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ u32 srqn;
+ struct roce5_dfx_srqc_ctx *srqc_ctx = NULL;
+ struct roce5_dfx_ctx *dfx_ctx = NULL;
+ struct roce5_device *rdev = NULL;
+ roce_verbs_srq_attr_s srq_attr;
+ struct rdma_service_cap *rdma_cap = NULL;
+
+ if (kobj == NULL || attr == NULL || buf == NULL || count == 0) {
+ ROCE_ERR("Invalid input para.");
+ return -EINVAL;
+ }
+
+ srqc_ctx = container_of(attr, struct roce5_dfx_srqc_ctx, kattr);
+ dfx_ctx = container_of(srqc_ctx, struct roce5_dfx_ctx, srqc_ctx);
+ rdev = container_of(dfx_ctx, struct roce5_device, dfx_ctx);
+
+ (void)memset_s(&srq_attr, sizeof(roce_verbs_srq_attr_s), 0,
+ sizeof(roce_verbs_srq_attr_s));
+
+ ret = (int)sscanf_s(buf, "%u", &srqn);
+ if (ret != 1) {
+ ROCE_DEV_ERR(rdev, "Failed to do sscanf_s, ret(%d)", ret);
+ return -EIO;
+ }
+
+ rdma_cap = &rdev->rdma_cap;
+ if (srqn >= rdma_cap->dev_rdma_cap.roce_own_cap.max_srqs) {
+ ROCE_DEV_ERR(rdev, "Invalid srqn(%u), max_srqs(%u)", srqn,
+ rdma_cap->dev_rdma_cap.roce_own_cap.max_srqs);
+ return -EIO;
+ }
+
+ ret = roce5_dfx_cmd_query_srq(rdev, srqn, &srq_attr);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to query srq_attr, ret(%d)", ret);
+ return (ssize_t)ret;
+ }
+
+ srq_attr.dfx_info.dw0.value = be32_to_cpu(srq_attr.dfx_info.dw0.value);
+
+ roce5_dfx_print("srqn(0x%x): pcnt(0x%x), ccnt(0x%x).", srqn,
+ srq_attr.dfx_info.dw0.bs.pcnt,
+ srq_attr.dfx_info.dw0.bs.ccnt);
+
+ return (ssize_t)count;
+}
+
+static int roce5_init_dfx_sub_ctx_sysfs(struct kobject *kobj,
+ struct roce5_dfx_ctx *dfx_ctx)
+{
+ int ret;
+ struct kobj_attribute *qpc_kattr = NULL;
+ struct kobj_attribute *cqc_kattr = NULL;
+ struct kobj_attribute *srqc_kattr = NULL;
+
+ if (kobj == NULL || dfx_ctx == NULL) {
+ ROCE_ERR("Invalid kobj or dfx_ctx.");
+ return -EINVAL;
+ }
+
+ qpc_kattr = &dfx_ctx->qpc_ctx.kattr;
+ cqc_kattr = &dfx_ctx->cqc_ctx.kattr;
+ srqc_kattr = &dfx_ctx->srqc_ctx.kattr;
+
+ sysfs_attr_init(&qpc_kattr->attr);
+ qpc_kattr->attr.name = "qpc";
+ qpc_kattr->attr.mode = (S_IWUSR | S_IRUSR | S_IRGRP);
+ qpc_kattr->store = roce5_store_dfx_qpc;
+ ret = sysfs_create_file(kobj, &qpc_kattr->attr);
+ if (ret != 0) {
+ ROCE_ERR("QPC failed to do sysfs_create_file, ret(%d)", ret);
+ return ret;
+ }
+
+ sysfs_attr_init(&cqc_kattr->attr);
+ cqc_kattr->attr.name = "cqc";
+ cqc_kattr->attr.mode = (S_IWUSR | S_IRUSR | S_IRGRP);
+ cqc_kattr->store = roce5_store_dfx_cqc;
+ ret = sysfs_create_file(kobj, &cqc_kattr->attr);
+ if (ret != 0) {
+ ROCE_ERR("CQC failed to do sysfs_create_file, ret(%d)", ret);
+ goto err_create_cqc_sysfs;
+ }
+
+ sysfs_attr_init(&srqc_kattr->attr);
+ srqc_kattr->attr.name = "srqc";
+ srqc_kattr->attr.mode = (S_IWUSR | S_IRUSR | S_IRGRP);
+ srqc_kattr->store = roce5_store_dfx_srqc;
+ ret = sysfs_create_file(kobj, &srqc_kattr->attr);
+ if (ret != 0) {
+ ROCE_ERR("SRQC failed to do sysfs_create_file, ret(%d)", ret);
+ goto err_create_srqc_sysfs;
+ }
+
+ return 0;
+
+err_create_srqc_sysfs:
+ sysfs_remove_file(kobj, &cqc_kattr->attr);
+
+err_create_cqc_sysfs:
+ sysfs_remove_file(kobj, &qpc_kattr->attr);
+
+ return ret;
+}
+
+static int roce5_init_dfx_sysfs(struct net_device *ndev,
+ struct roce5_dfx_ctx *dfx_ctx)
+{
+ int ret;
+
+ (void)memset_s(dfx_ctx, sizeof(*dfx_ctx), 0, sizeof(*dfx_ctx));
+
+ dfx_ctx->dfx_root =
+ kobject_create_and_add("roce5_dfx", &ndev->dev.kobj);
+ if (dfx_ctx->dfx_root == NULL) {
+ ROCE_ERR("Failed to do kobject_create_and_add.");
+ return -ENOMEM;
+ }
+
+ ret = roce5_init_dfx_sub_ctx_sysfs(dfx_ctx->dfx_root, dfx_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Failed to init dfx sub ctx sysfs, ret(%d)", ret);
+ kobject_put(dfx_ctx->dfx_root);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_remove_ecn_sysfs(struct roce5_device *rdev)
+{
+ struct roce5_ecn_ctx *ecn_ctx = &rdev->ecn_ctx;
+ roce5_remove_ecn_multipath_sysfs(rdev, &ecn_ctx->ecn_root,
+ &ecn_ctx->multipath_ctx);
+
+ roce5_remove_ecn_ucc_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->ucc_ctx);
+
+ roce5_remove_ecn_ip_enable_sysfs(&ecn_ctx->ecn_root,
+ &ecn_ctx->ip_enable_ctx);
+
+ roce5_remove_ecn_rp_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->rp_ctx);
+
+ roce5_remove_ecn_np_sysfs(&ecn_ctx->ecn_root, &ecn_ctx->np_ctx);
+
+ roce5_remove_ecn_ldcp_sysfs(&ecn_ctx->ldcp_ctx);
+
+ kobject_put(&ecn_ctx->ecn_root);
+}
+
+int roce5_init_sysfs(struct roce5_device *rdev)
+{
+ int ret;
+
+ ret = roce5_init_ecn_sysfs(rdev, &rdev->ecn_ctx);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init ecn sysfs, ret(%d)", ret);
+ return ret;
+ }
+
+ ret = roce5_init_dfx_sysfs(rdev->ndev, &rdev->dfx_ctx);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to init dfx sysfs, ret(%d)", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void roce5_remove_dfx_sub_sysfs(struct roce5_dfx_ctx *dfx_ctx)
+{
+ if (dfx_ctx->dfx_root != NULL) {
+ sysfs_remove_file(dfx_ctx->dfx_root,
+ &dfx_ctx->srqc_ctx.kattr.attr);
+
+ sysfs_remove_file(dfx_ctx->dfx_root,
+ &dfx_ctx->cqc_ctx.kattr.attr);
+
+ sysfs_remove_file(dfx_ctx->dfx_root,
+ &dfx_ctx->qpc_ctx.kattr.attr);
+
+ kobject_put(dfx_ctx->dfx_root);
+
+ dfx_ctx->dfx_root = NULL;
+ }
+}
+
+void roce5_remove_sysfs(struct roce5_device *rdev)
+{
+ roce5_remove_dfx_sub_sysfs(&rdev->dfx_ctx);
+ roce5_remove_ecn_sysfs(rdev);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.h b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.h
new file mode 100644
index 000000000..814f29ddc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_sysfs.h
@@ -0,0 +1,241 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_SYSFS_H
+#define ROCE_SYSFS_H
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/kobject.h>
+#include "roce_ucc_sysfs.h"
+#include "roce_multipath_sysfs.h"
+
+#define ROCE_MIN_QPN 2
+#define BYTE_TO_BIT 8
+
+#define PRI_ARRAY_LEN 8
+
+#define ROCE_MAX_PORT_CNT 8
+#define ROCE_MAX_PF_NUM 32
+
+#define ROCE_ENABLE_CHECK_MASK 0xfffffffe
+
+/* ECN VER */
+#define ECN_VER_DCQCN 0
+#define ECN_VER_PATHQCN 1
+
+#define FLOW_CTRL_UNIT_QP 0
+#define FLOW_CTRL_UNIT_IP 1
+
+enum { ROCE_DCQCN_NP = 0, ROCE_DCQCN_RP = 1 };
+
+enum {
+ ROCE_CC_PARAM_INVALID = 0,
+ ROCE_CC_PARAM_V1 = 1,
+ ROCE_CC_PARAM_V2 = 2,
+};
+
+#define HRN0_K_MAGIC_NUM_3_SYSFS 3
+#define HRN0_K_MAGIC_NUM_7_SYSFS 7
+#define HRN0_K_MAGIC_NUM_8_SYSFS 8
+#define HRN0_K_MAGIC_NUM_M_SYSFS 1000000
+
+#define to_roce5_ecn_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_ctx, ecn_root)
+#define to_roce5_ecn_np_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_np_ctx, ecn_np_root)
+#define to_roce5_ecn_rp_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_rp_ctx, ecn_rp_root)
+#define to_roce5_ecn_ldcp_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_ldcp_ctx, ecn_ldcp_root)
+
+#define ROCE5_PARAM_CHECK_BOUND(val, min, max) \
+ ((val) < (min)) || ((val) > (max))
+
+#define INIT_ROCE_KOBJ_ATTR(_name, _mode, _show, _store) \
+ { \
+ .attr = { .name = __stringify(_name), .mode = _mode }, \
+ .show = (_show), .store = (_store), \
+ }
+
+#define ROCE_ATTR_RW(_name, _show, _store) \
+ static struct kobj_attribute roce_attr_##_name = INIT_ROCE_KOBJ_ATTR( \
+ _name, (S_IWUSR | S_IRUSR | S_IRGRP), (_show), (_store))
+
+#define ROCE_ATTR_PTR(_name) (&roce_attr_##_name.attr)
+
+#define ROCE_CC_ALGO_TEST_BIT(bitmap, cc_algo) (!!(bitmap & (1U << cc_algo)))
+
+struct roce5_prio_enable_ctx {
+ struct kobj_attribute enable;
+ void *ecn_enable_ctx;
+ u32 prio_en;
+ u32 prio;
+};
+
+struct roce5_ip_prio_enable_ctx {
+ struct kobj_attribute ip_enable;
+ void *ecn_ip_enable_ctx;
+ u32 prio_en;
+ u32 prio;
+};
+
+struct roce5_ecn_ip_enable_ctx {
+ struct kobject *ip_enable_root;
+ struct roce5_ip_prio_enable_ctx ip_prio_enable[PRI_ARRAY_LEN];
+};
+
+struct roce5_ecn_enable_ctx {
+ struct kobject *enable_root;
+ struct roce5_prio_enable_ctx prio_enable[PRI_ARRAY_LEN];
+ u32 np_rp;
+};
+
+struct roce5_dfx_qpc_ctx {
+ struct kobj_attribute kattr;
+};
+
+struct roce5_dfx_cqc_ctx {
+ struct kobj_attribute kattr;
+};
+
+struct roce5_dfx_srqc_ctx {
+ struct kobj_attribute kattr;
+};
+
+struct roce5_dfx_ctx {
+ struct kobject *dfx_root;
+ struct roce5_dfx_qpc_ctx qpc_ctx;
+ struct roce5_dfx_cqc_ctx cqc_ctx;
+ struct roce5_dfx_srqc_ctx srqc_ctx;
+};
+
+struct roce5_ecn_rp_ctx {
+ struct kobject ecn_rp_root;
+ u32 alpha_dec_period;
+ u32 rate_dec_period;
+ u32 rate_inc_period;
+ u32 factor_gita;
+ u32 initial_alpha;
+ u32 rate_inc_ai;
+ u32 rate_inc_hai;
+ u32 rate_first_set;
+ u32 rate_target_clamp;
+ u32 token_period;
+ u32 min_rate;
+ u32 bypass;
+ struct roce5_ecn_enable_ctx enable_ctx;
+};
+
+struct roce5_ecn_np_ctx {
+ struct kobject ecn_np_root;
+ u32 min_cnp_period;
+ u32 cnp_prio_enable;
+ u32 cnp_prio;
+ u32 rtt_rsp_prio;
+ u32 rtt_rsp_prio_enable;
+ u32 rtt_version;
+ u32 ecn_cnp_en;
+ u32 flow_ctrl_unit;
+ struct roce5_ecn_enable_ctx enable_ctx;
+};
+
+typedef struct roce5_ecn_ldcp_ctx {
+ struct kobject ecn_ldcp_root;
+ u32 wnd_min;
+ u32 wnd_default; /* initial default window size, unit: Byte */
+ u32 alpha;
+ u32 beta;
+ u32 gamma;
+ u32 eta;
+} roce5_ecn_ldcp_ctx_t;
+
+struct roce5_ecn_ctx {
+ struct kobject ecn_root;
+ struct mutex ecn_mutex;
+ u32 ecn_ver;
+ u32 cc_algo;
+ roce5_ecn_ldcp_ctx_t ldcp_ctx;
+ struct roce5_ecn_np_ctx np_ctx;
+ struct roce5_ecn_rp_ctx rp_ctx;
+ struct roce5_ecn_ip_enable_ctx ip_enable_ctx;
+ struct roce5_ecn_ucc_ctx ucc_ctx;
+ struct roce5_ecn_multipath_ctx multipath_ctx;
+};
+
+struct roce_cc_ecn_param {
+ u32 default_ip_enable_en;
+ u32 default_bypass;
+ u32 default_min_cnp_period;
+ u32 default_alpha_dec_period;
+ u32 default_rate_dec_period;
+ u32 default_rate_inc_period;
+ u32 default_factor_gita;
+ u32 default_initial_alpha;
+ u32 default_rate_inc_ai;
+ u32 default_rate_inc_hai;
+ u32 default_rate_first_set;
+ u32 default_rate_target_clamp;
+ u32 default_cnp_prio_enable;
+ u32 default_cnp_prio;
+ u32 default_token_period;
+ u32 default_min_rate;
+ u32 default_ecn_cnp_enable;
+ u32 default_flow_ctrl_unit;
+ u32 default_rtt_rsp_prio;
+ u32 default_rtt_rsp_prio_enable;
+ u32 default_rtt_version;
+
+ u32 max_rtt_version;
+ u32 min_bypass;
+ u32 max_bypass;
+ u32 min_rate_inc_hai;
+ u32 max_rate_inc_hai;
+ u32 min_rate_inc_ai;
+ u32 max_rate_inc_ai;
+ u32 min_initial_alpha;
+ u32 max_initial_alpha;
+ u32 min_rate_inc_period;
+ u32 max_rate_inc_period;
+ u32 min_alpha_dec_period;
+ u32 max_alpha_dec_period;
+ u32 min_token_period;
+ u32 max_token_period;
+ u32 min_flow_min_rate;
+ u32 max_flow_min_rate;
+ u32 min_rate_dec_period;
+ u32 max_rate_dec_period;
+ u32 min_min_cnp_period;
+ u32 max_min_cnp_period;
+ u32 min_factor_gita;
+ u32 max_factor_gita;
+ u32 min_rate_first_set;
+ u32 max_rate_first_set;
+
+ u32 default_ldcp_wnd_min;
+ u32 default_ldcp_wnd_default;
+ u32 default_ldcp_alpha;
+ u32 default_ldcp_beta;
+ u32 default_ldcp_gamma;
+ u32 default_ldcp_eta;
+
+ u32 min_ldcp_wnd_min;
+ u32 max_ldcp_wnd_min;
+ u32 min_ldcp_wnd_default;
+ u32 max_ldcp_wnd_default;
+ u32 min_ldcp_alpha;
+ u32 max_ldcp_alpha;
+ u32 min_ldcp_beta;
+ u32 max_ldcp_beta;
+ u32 min_ldcp_gamma;
+ u32 max_ldcp_gamma;
+ u32 min_ldcp_eta;
+ u32 max_ldcp_eta;
+};
+
+int roce5_update_ecn_param(const struct roce5_ecn_ctx *ecn_ctx);
+
+#endif //ROCE_SYSFS_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.c b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.c
new file mode 100644
index 000000000..e163f895b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.c
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "roce_sysfs.h"
+#include "roce_cc_format.h"
+#include "roce_mpu_cmd.h"
+#include "roce_cmd.h"
+#include "ccp_algo_format.h"
+#include "roce_kernel_compat_gen.h"
+
+#define MAX_STRING_FORMAT_LEN 64
+#define to_roce5_ecn_ucc_ctx(_kobj) \
+ container_of(_kobj, struct roce5_ecn_ucc_ctx, ecn_ucc_root)
+
+static char g_param_buffer[ROCE_UCC_MAX_PARAM_NUM][ROCE_UCC_PARAM_BUFF_LEN];
+static char g_param_show_tmp[ROCE_UCC_MAX_PARAM_NUM][ROCE_UCC_PARAM_BUFF_LEN];
+static char g_param_show_format[ROCE_UCC_MAX_PARAM_NUM][ROCE_UCC_PARAM_BUFF_LEN];
+
+static int roce5_ucc_store_input_check(struct kobject *kobj, const char *buf,
+ u8 param_index)
+{
+ if (kobj == NULL || buf == NULL) {
+ ROCE_ERR("kobj or buf is null\n");
+ return -EINVAL;
+ }
+
+ if (param_index >= ROCE_UCC_MAX_PARAM_NUM) {
+ ROCE_ERR("invalid index:%hhu.\n", param_index);
+ return -EINVAL;
+ }
+
+ if (strlen(buf) > (ROCE_UCC_PARAM_BUFF_LEN - 1)) {
+ ROCE_ERR("input buffer is beyond 1022.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int roce5_init_ucc_global_buffer(u8 param_index, const char *buf)
+{
+ int ret;
+ ret = memset_s(g_param_show_tmp[param_index],
+ sizeof(g_param_show_tmp[param_index]), 0,
+ sizeof(g_param_show_tmp[param_index]));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset buffer.(ret:%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = strncpy_s(g_param_buffer[param_index],
+ sizeof(g_param_buffer[param_index]), buf,
+ sizeof(g_param_buffer[param_index]) - 1);
+ if (ret != 0) {
+ ROCE_ERR("Failed to strncpy buffer.(ret:%d)\n", ret);
+ return -EIO;
+ }
+
+ g_param_buffer[param_index][ROCE_UCC_PARAM_BUFF_LEN - 1] = '\0';
+
+ return 0;
+}
+
+static int check_key_unique(char (*pkey)[ROCE_UCC_MAX_KEY_SIZE], u8 key_num)
+{
+ u8 key_index = 0;
+
+ if (key_num >= ROCE_UCC_MAX_KEY_SIZE) {
+ ROCE_ERR("invalid key value:%hhu.\n", key_num);
+ return -EINVAL;
+ }
+
+ for (key_index = 0; key_index < key_num; key_index++) {
+ if (strcmp(pkey[key_index], pkey[key_num]) == 0) {
+ ROCE_ERR("key:%s is not unique.\n", pkey[key_num]);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int parse_each_line(char *param_line,
+ char (*pkey)[ROCE_UCC_MAX_KEY_SIZE], u8 key_num,
+ u32 *param_value, u8 *param_bits, u16 *sum_bits)
+{
+ u64 temp_value = 0;
+ u64 temp_bits = 0;
+ u64 temp_bit_sum = *sum_bits;
+ char extra = 0;
+ char value_str[ROCE_UCC_PARAM_VALUE_LEN] = { 0 };
+ char bits_str[ROCE_UCC_PARAM_BITS_LEN] = { 0 };
+
+ if (key_num >= ROCE_UCC_MAX_KEY_SIZE) {
+ ROCE_ERR("invalid key value:%hhu.\n", key_num);
+ return -EINVAL;
+ }
+
+ /* input of each line per per key:value:length perform parse, obtain value and length size, and check key whether repeat */
+ if (sscanf_s(param_line, " %31[^: ] : %10[0-9] : %2[0-9] %c",
+ pkey[key_num], (unsigned)sizeof(pkey[key_num]), value_str,
+ (unsigned)sizeof(value_str), bits_str,
+ (unsigned)sizeof(bits_str), &extra,
+ 1) == ROCE_UCC_LINE_PARAM_TH) {
+ if (kstrtoull(value_str, NUM_10, &temp_value) < 0) {
+ ROCE_ERR("invalid input value:%s.\n", value_str);
+ return -EINVAL;
+ }
+
+ if (kstrtoull(bits_str, NUM_10, &temp_bits) < 0) {
+ ROCE_ERR("invalid input bits:%s.\n", bits_str);
+ return -EINVAL;
+ }
+
+ if ((temp_bits == 0) || (temp_bits > TYPE_BITS(u32)) ||
+ (temp_value > BITS_VALUE(temp_bits))) {
+ ROCE_ERR("bits:%llu or value:%llu is invalid.\n",
+ temp_bits, temp_value);
+ return -EINVAL;
+ }
+
+ temp_bit_sum += temp_bits;
+ if (temp_bit_sum > TYPE_BITS(u32)) {
+ ROCE_ERR("the length of bits:%llu beyond 32.\n",
+ temp_bit_sum);
+ return -EINVAL;
+ }
+
+ if (check_key_unique(pkey, key_num) != 0) {
+ return -EINVAL;
+ }
+
+ *param_value = (u32)temp_value;
+ *param_bits = (u8)temp_bits;
+ *sum_bits = (u16)temp_bit_sum;
+ return 0;
+ }
+
+ ROCE_ERR("param format is wrong, please enter key:value:length param, "
+ "value less than 4294967296, length less than 33.\n");
+ return -EINVAL;
+}
+
+static int roce5_parse_ucc_param(u32 *ucc_param, char *param_buffer,
+ char *show_tmpkey)
+{
+ u8 key_num = 0;
+ u32 temp_param = 0;
+ /* param_value\param_bits used to store each line parse of values size and so occupy bit width result */
+ u32 param_value = 0;
+ u8 param_bits = 0;
+ u16 sum_bits = 0;
+ /* param_line\ppbuffer used for input parameters partinterval parse */
+ char *param_line = NULL;
+ char **ppbuffer = ¶m_buffer;
+
+ char(*pkey)[ROCE_UCC_MAX_KEY_SIZE] = NULL;
+ char arr_tempkey[ROCE_UCC_MAX_KEY_NUM][ROCE_UCC_MAX_KEY_SIZE] = { 0 };
+ char append_buff[ROCE_UCC_LINE_MAX_LEN] = { 0 };
+ pkey = arr_tempkey;
+
+ while ((param_line = strsep(ppbuffer, "\n")) != NULL) {
+ if (*param_line == '\0') {
+ break;
+ }
+ /* per per key:value:length parse input of each one line */
+ if (parse_each_line(param_line, pkey, key_num, ¶m_value,
+ ¶m_bits, &sum_bits) != 0) {
+ return -EIO;
+ }
+
+ if (snprintf_s(append_buff, ROCE_UCC_LINE_MAX_LEN,
+ ROCE_UCC_LINE_MAX_LEN - 1, "%s:%u:%hhu\n",
+ pkey[key_num], param_value, param_bits) < 0) {
+ ROCE_ERR("snprintf_s err!\n");
+ return -EIO;
+ }
+
+ if (strncat_s(show_tmpkey, ROCE_UCC_PARAM_BUFF_LEN, append_buff,
+ ROCE_UCC_PARAM_BUFF_LEN - strlen(show_tmpkey) -
+ 1) != 0) {
+ ROCE_ERR("strncat_s err!\n");
+ return -EIO;
+ }
+ key_num++;
+ temp_param = key_num > 1 ? ((temp_param << param_bits) +
+ param_value) :
+ param_value;
+ }
+
+ if (sum_bits < TYPE_BITS(u32)) {
+ temp_param = temp_param << (TYPE_BITS(u32) - sum_bits);
+ }
+
+ if (ucc_param != NULL) {
+ *ucc_param = temp_param;
+ }
+ return 0;
+}
+
+static int roce5_store_ucc_param_inner(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, u8 param_index)
+{
+ int ret = 0;
+ u32 ucc_param = 0;
+ u32 old_ucc_param = 0;
+ struct roce5_ecn_ctx *ecn_ctx = NULL;
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx = NULL;
+
+ if (roce5_ucc_store_input_check(kobj, buf, param_index) != 0) {
+ return -EINVAL;
+ }
+
+ ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ ecn_ucc_ctx = to_roce5_ecn_ucc_ctx(kobj);
+
+ if (roce5_init_ucc_global_buffer(param_index, buf) != 0) {
+ return -EIO;
+ }
+
+ if (roce5_parse_ucc_param(&ucc_param, g_param_buffer[param_index],
+ g_param_show_tmp[param_index]) != 0) {
+ return -EIO;
+ }
+
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ if (strncpy_s(g_param_show_format[param_index],
+ sizeof(g_param_show_format[param_index]),
+ g_param_show_tmp[param_index],
+ sizeof(g_param_show_format[param_index]) - 1) != 0) {
+ ROCE_ERR("Failed to strncpy buffer.\n");
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+
+ if ((ecn_ucc_ctx != NULL) &&
+ (ecn_ucc_ctx->param[param_index] != ucc_param)) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_ucc_param = ecn_ucc_ctx->param[param_index];
+ ecn_ucc_ctx->param[param_index] = ucc_param;
+ ret = (ssize_t)roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ecn_ucc_ctx->param[param_index] = old_ucc_param;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return 0;
+}
+
+ssize_t roce5_show_ucc_param(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ struct roce5_ucc_param_ctx *ucc_param =
+ (struct roce5_ucc_param_ctx *)to_roce5_ucc_param_ctx(attr);
+ return sprintf_s(buf, sizeof(g_param_show_format[ucc_param->param_id]),
+ "%s", g_param_show_format[ucc_param->param_id]);
+}
+
+ssize_t roce5_store_ucc_param(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct roce5_ucc_param_ctx *ucc_param =
+ (struct roce5_ucc_param_ctx *)to_roce5_ucc_param_ctx(attr);
+ return (roce5_store_ucc_param_inner(kobj, attr, buf,
+ ucc_param->param_id) == 0) ?
+ (ssize_t)count :
+ -EIO;
+}
+
+static ssize_t roce5_show_algo_mode(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx = to_roce5_ecn_ucc_ctx(kobj);
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ switch ((int)ecn_ucc_ctx->algo_mode) {
+ case CCP_ALGO_MODE_CWND:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%u\n",
+ (u32)CCP_ALGO_MODE_CWND);
+ case CCP_ALGO_MODE_RATE:
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%u\n",
+ (u32)CCP_ALGO_MODE_RATE);
+ default:
+ break;
+ }
+ return sprintf_s(buf, MAX_STRING_FORMAT_LEN, "%s\n", "error_type");
+}
+
+static ssize_t roce5_store_algo_mode(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct roce5_ecn_ctx *ecn_ctx = to_roce5_ecn_ctx(kobj->parent);
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx = to_roce5_ecn_ucc_ctx(kobj);
+ u32 old_algo_mode = 0;
+ int algo_mode = 0;
+ int ret;
+ char remaining;
+
+ if ((attr == NULL) || (buf == NULL)) {
+ ROCE_ERR("attr or buf is null");
+ return -EINVAL;
+ }
+
+ ret = sscanf_s(buf, "%d %c", &algo_mode, &remaining, 1);
+ if (ret != 1) {
+ ROCE_ERR("Invalid input, algo_mode should be unsigned int\n");
+ return -EIO;
+ }
+
+ if (algo_mode != CCP_ALGO_MODE_CWND &&
+ algo_mode != CCP_ALGO_MODE_RATE) {
+ ROCE_ERR("Invalid algo_mode(%d),buf(%s)\n", algo_mode, buf);
+ return -EIO;
+ }
+
+ if (ecn_ucc_ctx->algo_mode != (u32)algo_mode) {
+ mutex_lock(&ecn_ctx->ecn_mutex);
+ old_algo_mode = ecn_ucc_ctx->algo_mode;
+ ecn_ucc_ctx->algo_mode = (u32)algo_mode;
+ ret = roce5_update_ecn_param(ecn_ctx);
+ if (ret != 0) {
+ ROCE_ERR("Failed to update algo_mode(%d), ret(%d).",
+ algo_mode, ret);
+ ecn_ucc_ctx->algo_mode = old_algo_mode;
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ return -EIO;
+ }
+ mutex_unlock(&ecn_ctx->ecn_mutex);
+ }
+
+ return (ssize_t)count;
+}
+
+ROCE_UCC_PARAM_RW(param0, 0);
+ROCE_UCC_PARAM_RW(param1, 1);
+ROCE_UCC_PARAM_RW(param2, 2);
+ROCE_UCC_PARAM_RW(param3, 3);
+ROCE_UCC_PARAM_RW(param4, 4);
+ROCE_UCC_PARAM_RW(param5, 5);
+ROCE_UCC_PARAM_RW(param6, 6);
+ROCE_UCC_PARAM_RW(param7, 7);
+ROCE_UCC_PARAM_RW(param8, 8);
+ROCE_UCC_PARAM_RW(param9, 9);
+ROCE_UCC_PARAM_RW(param10, 10);
+ROCE_UCC_PARAM_RW(param11, 11);
+ROCE_UCC_PARAM_RW(param12, 12);
+ROCE_UCC_PARAM_RW(param13, 13);
+ROCE_UCC_PARAM_RW(param14, 14);
+ROCE_UCC_PARAM_RW(param15, 15);
+ROCE_ATTR_RW(algo_mode, roce5_show_algo_mode, roce5_store_algo_mode);
+
+static struct attribute *ecn_ucc_ctx_attrs[] = {
+ ROCE_UCC_PARAM_ATTR_PTR(param0), ROCE_UCC_PARAM_ATTR_PTR(param1),
+ ROCE_UCC_PARAM_ATTR_PTR(param2), ROCE_UCC_PARAM_ATTR_PTR(param3),
+ ROCE_UCC_PARAM_ATTR_PTR(param4), ROCE_UCC_PARAM_ATTR_PTR(param5),
+ ROCE_UCC_PARAM_ATTR_PTR(param6), ROCE_UCC_PARAM_ATTR_PTR(param7),
+ ROCE_UCC_PARAM_ATTR_PTR(param8), ROCE_UCC_PARAM_ATTR_PTR(param9),
+ ROCE_UCC_PARAM_ATTR_PTR(param10), ROCE_UCC_PARAM_ATTR_PTR(param11),
+ ROCE_UCC_PARAM_ATTR_PTR(param12), ROCE_UCC_PARAM_ATTR_PTR(param13),
+ ROCE_UCC_PARAM_ATTR_PTR(param14), ROCE_UCC_PARAM_ATTR_PTR(param15),
+ ROCE_ATTR_PTR(algo_mode), NULL,
+};
+
+static void roce_ecn_ucc_sysfs_release(struct kobject *kobj)
+{
+}
+
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+static const struct attribute_group ecn_ucc_ctx_attr_grp = {
+ .attrs = ecn_ucc_ctx_attrs,
+};
+
+static const struct attribute_group *ecn_ucc_ctx_groups[] = {
+ &ecn_ucc_ctx_attr_grp,
+ NULL,
+};
+#endif
+
+static struct kobj_type roce_ecn_ucc_ktype = {
+ .sysfs_ops = &kobj_sysfs_ops,
+ .release = roce_ecn_ucc_sysfs_release,
+#if defined(KBOJ_TYPE_HAVE_ATTRS_GROUP)
+ .default_groups = ecn_ucc_ctx_groups,
+#else
+ .default_attrs = ecn_ucc_ctx_attrs,
+#endif
+};
+
+int roce5_update_ucc_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx)
+{
+ roce_ucc_param_s ucc_param;
+ int ret;
+ int param_idx = 0;
+
+ if (ecn_ctx->cc_algo != ROCE_CC_USER_A_ALGO &&
+ ecn_ctx->cc_algo != ROCE_CC_USER_B_ALGO) {
+ ROCE_DEV_INFO(
+ rdev,
+ "func_id(%d) cc_algo(%u) is not user algo, ignore update.",
+ rdev->glb_func_id, ecn_ctx->cc_algo);
+ return 0;
+ }
+ (void)memset_s(&ucc_param, sizeof(ucc_param), 0, sizeof(ucc_param));
+
+ for (; param_idx < ROCE_UCC_MAX_PARAM_NUM; param_idx++) {
+ ucc_param.param[param_idx] = ecn_ctx->ucc_ctx.param[param_idx];
+ }
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)(void *)&ucc_param,
+ sizeof(roce_ucc_param_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_UCC_PARAM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set user algo param, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ }
+
+ return ret;
+}
+
+int roce5_init_ecn_ucc_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx)
+{
+ int ret = 0;
+ int param_idx = 0;
+
+ if (ecn_ucc_ctx == NULL) {
+ pr_err_ratelimited("[ROCE, ERR] %s: ecn_ucc_ctx is null\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ecn_ucc_ctx->algo_mode = CCP_ALGO_MODE_CWND;
+ for (; param_idx < ROCE_UCC_MAX_PARAM_NUM; param_idx++) {
+ ecn_ucc_ctx->param[param_idx] = ROCE_DEFAULT_UCC_PARAM;
+ }
+
+ ret = kobject_init_and_add(&ecn_ucc_ctx->ecn_ucc_root,
+ &roce_ecn_ucc_ktype, kobj, "roce5_ucc");
+ if (ret != 0) {
+ ROCE_ERR("Failed to add kobject roce5_ucc.(ret:%d)\n", ret);
+ kobject_put(&ecn_ucc_ctx->ecn_ucc_root);
+ return ret;
+ }
+
+ return 0;
+}
+
+void roce5_remove_ecn_ucc_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx)
+{
+ if (ecn_ucc_ctx == NULL) {
+ ROCE_ERR("ecn_ucc_ctx is null\n");
+ return;
+ }
+
+ kobject_put(&ecn_ucc_ctx->ecn_ucc_root);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.h b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.h
new file mode 100644
index 000000000..bbbe92b30
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/dev/sysfs/roce_ucc_sysfs.h
@@ -0,0 +1,73 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef ROCE_UCC_SYSFS_H
+#define ROCE_UCC_SYSFS_H
+
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/kobject.h>
+
+#define ROCE_UCC_MAX_PARAM_NUM 16
+#define ROCE_UCC_PARAM_BUFF_LEN 1024
+#define ROCE_DEFAULT_UCC_PARAM 0
+#define ROCE_UCC_MAX_KEY_SIZE 32
+#define ROCE_UCC_MAX_KEY_NUM 32
+#define ROCE_UCC_LINE_MAX_LEN 64
+#define ROCE_UCC_PARAM_VALUE_LEN 11
+#define ROCE_UCC_PARAM_BITS_LEN 3
+#define ROCE_UCC_LINE_PARAM_TH 3
+
+#define CHAR_0 '0'
+#define CHAR_9 '9'
+#define NUM_10 10
+#define ROCE_USER_CC_ID_LABLE_LEN 8
+#define ROCE_USER_CC_ID_MAX_LEN (ROCE_USER_CC_ID_LABLE_LEN + 2)
+
+#define TYPE_BITS(type) (sizeof(type) * 8)
+#define BITS_VALUE(bits) (((u64)1 << (bits)) - 1)
+
+/* forward-declaration */
+struct roce5_device;
+struct roce5_ecn_ctx;
+
+typedef struct roce_ucc_param {
+ u32 param[ROCE_UCC_MAX_PARAM_NUM];
+} roce_ucc_param_s;
+
+struct roce5_ecn_ucc_ctx {
+ struct kobject ecn_ucc_root;
+ u32 algo_mode;
+ u32 param[ROCE_UCC_MAX_PARAM_NUM];
+};
+
+struct roce5_ucc_param_ctx {
+ struct kobj_attribute param;
+ u32 param_id;
+};
+
+ssize_t roce5_show_ucc_param(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf);
+ssize_t roce5_store_ucc_param(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count);
+#define ROCE_UCC_PARAM_RW(_name, _idx) \
+ static struct roce5_ucc_param_ctx roce_ucc_attr_##_name = { \
+ .param = INIT_ROCE_KOBJ_ATTR( \
+ _name, (S_IWUSR | S_IRUSR | S_IRGRP), \
+ roce5_show_ucc_param, roce5_store_ucc_param), \
+ .param_id = (_idx), \
+ }
+
+#define ROCE_UCC_PARAM_ATTR_PTR(_name) (&roce_ucc_attr_##_name.param.attr)
+#define to_roce5_ucc_param_ctx(_kattr) \
+ container_of(_kattr, struct roce5_ucc_param_ctx, param)
+
+int roce5_update_ucc_param(struct roce5_device *rdev,
+ const struct roce5_ecn_ctx *ecn_ctx);
+int roce5_init_ecn_ucc_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx);
+void roce5_remove_ecn_ucc_sysfs(struct kobject *kobj,
+ struct roce5_ecn_ucc_ctx *ecn_ucc_ctx);
+
+#endif /* ROCE_UCC_SYSFS_H */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.c b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.c
new file mode 100644
index 000000000..145904486
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.c
@@ -0,0 +1,13 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2020-2024. All rights reserved.
+
+
+#include "roce_main_extension.h"
+#include "roce_mr_chip_ext.h"
+
+void roce5_init_dev_ext_handlers(struct roce5_device *rdev)
+{
+ rdev->ib_dev.check_mr_status = roce5_check_mr_status;
+ rdev->ib_dev.reg_user_fast_mr = roce5_reg_user_fast_mr;
+ rdev->ib_dev.map_frmr_sg = roce5_map_user_frmr_sg;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.h b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.h
new file mode 100644
index 000000000..a5f0847f8
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_main_chip_ext.h
@@ -0,0 +1,17 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_MAIN_CHIP_EXT_C
+#define ROCE_MAIN_CHIP_EXT_C
+
+#define ROCE_UVERBS_CMD_EXT_MASK \
+ ((1ULL << IB_USER_VERBS_CMD_CREATE_DCT) | \
+ (1ULL << IB_USER_VERBS_CMD_QUERY_DCT) | \
+ (1ULL << IB_USER_VERBS_CMD_ARM_DCT) | \
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_DCT) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_MR) | \
+ (1ULL << IB_USER_VERBS_CMD_REG_FAST_MR) | \
+ (1ULL << IB_USER_VERBS_CMD_DEREG_FAST_MR) | \
+ (1ULL << IB_USER_VERBS_CMD_MAP_FRMR_SG))
+
+#endif /* ROCE_MAIN_CHIP_EXT_C */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.c b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.c
new file mode 100644
index 000000000..c460ca8a5
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.c
@@ -0,0 +1,348 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "roce_mr.h"
+#include "roce_infra.h"
+#include "roce_mr_extension.h"
+#include "roce_main_extension.h"
+#include "roce_restore.h"
+#include "hmm_common.h"
+#include "roce_user.h"
+
+int roce5_check_alloc_mr_type(enum ib_mr_type mr_type)
+{
+ int ret = 0;
+
+ if (mr_type != IB_MR_TYPE_MEM_REG && mr_type != IB_MR_INDIRECT_REG &&
+ mr_type != IB_MR_TYPE_FAST_MR) {
+ ret = -EINVAL;
+ ROCE_ERR("mr_type is invalid. mr_type:%u", mr_type);
+ }
+
+ return ret;
+}
+
+enum rdma_mr_type roce5_get_mrtype(enum ib_mr_type ib_mr_type)
+{
+ switch (ib_mr_type) {
+ case IB_MR_TYPE_MEM_REG:
+ return RDMA_DMA_MR;
+
+ case IB_MR_INDIRECT_REG:
+ return RDMA_INDIRECT_MR;
+
+ case IB_MR_TYPE_FAST_MR:
+ return RDMA_FRMR;
+
+ default:
+ return RDMA_DMA_MR;
+ }
+}
+
+static int roce5_alloc_usr_frmr(struct ib_pd *ibpd, struct ib_udata *udata,
+ struct roce5_reg_frmr_cmd *ucmd,
+ struct roce5_device **rdev,
+ struct roce5_mr **rmr)
+{
+ struct ib_umem **fumem = NULL;
+ if (ibpd == NULL) {
+ ROCE_ERR("Ibpd is null");
+ return -EINVAL;
+ }
+
+ if (udata == NULL) {
+ ROCE_ERR("Udata is null");
+ return -EINVAL;
+ }
+
+ *rdev = to_roce5_dev(ibpd->device);
+
+ if (ib_copy_from_udata(ucmd, udata, sizeof(*ucmd))) {
+ ROCE_DEV_ERR((*rdev),
+ "Failed to copy_from_udata while creating frmr");
+ return -EFAULT;
+ }
+
+ *rmr = (struct roce5_mr *)kzalloc(sizeof(struct roce5_mr), GFP_KERNEL);
+ if (*rmr == NULL) {
+ ROCE_DEV_ERR((*rdev), "Failed to alloc memory for roce mr");
+ return -ENOMEM;
+ }
+
+ fumem = (struct ib_umem **)kzalloc(
+ sizeof(struct ib_umem *) * ROCE5_FRMR_UMEM_NUM, GFP_KERNEL);
+ if (fumem == NULL) {
+ ROCE_DEV_ERR((*rdev), "Failed to alloc memory for frmr umem");
+ kfree(*rmr);
+ return -ENOMEM;
+ }
+ (*rmr)->fumem = fumem;
+ return 0;
+}
+
+static int roce5_get_frmr_umem(struct roce5_mr *rmr, struct ib_pd *ibpd,
+ struct roce5_reg_frmr_cmd *ucmd,
+ struct roce5_device *rdev)
+{
+ rmr->umem = ib_umem_get(ibpd->uobject->context, ucmd->pbl_vaddr,
+ PAGE_SIZE_4K, 0, 0);
+ if (rmr->umem == NULL) {
+ ROCE_DEV_ERR(rdev, "Rmr->umem is null");
+ return -ENOMEM;
+ }
+
+ if (IS_ERR(rmr->umem)) {
+ ROCE_DEV_ERR(rdev, "Failed to get ib umem, func_id(%d)",
+ rdev->glb_func_id);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int roce5_init_frmr_attr(u64 *pbl_paddr, struct roce5_mr *rmr,
+ struct roce5_device *rdev, struct ib_pd *ibpd)
+{
+ int ret;
+ u32 mpt_xid_mode;
+ struct roce5_pd *rpd = NULL;
+
+ *pbl_paddr = sg_dma_address(rmr->umem->sg_head.sgl);
+ if (*pbl_paddr == 0ULL) {
+ ROCE_DEV_ERR(rdev, "Invalid pbl_paddr");
+ return -EINVAL;
+ }
+
+ rmr->rdmamr.mtt.mtt_type = MTT_DMTT_TYPE;
+ mpt_xid_mode = roce5_get_mpt_xid_mode(rdev);
+ ret = roce5_alloc_tpt(rdev, &rmr->rdmamr, ROCE_FRMR_MAX_PAGES,
+ PAGE_SHIFT, mpt_xid_mode);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc mpt and mtt, ret(%d)", ret);
+ return ret;
+ }
+
+ rpd = to_roce5_pd(ibpd);
+ roce5_set_rdma_mr(&rmr->rdmamr, RDMA_FRMR, rpd->pdn, 0ULL, 0ULL,
+ ROCE5_MR_DEFAULT_ACCESS);
+
+ return 0;
+}
+
+struct ib_mr *roce5_reg_user_fast_mr(struct ib_pd *ibpd, struct ib_udata *udata)
+{
+ int ret;
+ struct roce5_device *rdev = NULL;
+ struct roce5_mr *rmr = NULL;
+ struct roce5_reg_frmr_cmd ucmd;
+ u64 pbl_paddr;
+
+ ret = roce5_alloc_usr_frmr(ibpd, udata, &ucmd, &rdev, &rmr);
+ if (ret != 0) {
+ ROCE_ERR("Failed to pre check, ret(%d)", ret);
+ goto err_out;
+ }
+
+ ret = roce5_get_frmr_umem(rmr, ibpd, &ucmd, rdev);
+ if (ret != 0) {
+ goto err_ib_umem_get;
+ }
+
+ /* Use valloc to allocate a page of memory, just need to get the first physical address */
+ ret = roce5_init_frmr_attr(&pbl_paddr, rmr, rdev, ibpd);
+ if (ret != 0) {
+ goto err_pbl_addr;
+ }
+
+ ret = hmm_rdma_enable_mpt(rdev->lld_dev, rdev->hwdev, &(rmr->rdmamr),
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to enable mpt of frmr, ret(%d)",
+ ret);
+ goto err_enable_mpt;
+ }
+
+ /* User mode also needs to send out pbl_paddr */
+ if (ib_copy_to_udata(udata, &pbl_paddr, sizeof(u64)) != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to copy data to user space, func_id(%d)",
+ rdev->glb_func_id);
+ ret = -EFAULT;
+ goto err_enable_mpt;
+ }
+
+ rmr->ibmr.lkey = rmr->rdmamr.key;
+ rmr->ibmr.rkey = rmr->rdmamr.key;
+
+ return &rmr->ibmr;
+
+err_enable_mpt:
+ roce5_free_tpt(rdev, &rmr->rdmamr);
+
+err_pbl_addr:
+ ib_umem_release(rmr->umem);
+
+err_ib_umem_get:
+ kfree(rmr->fumem, sizeof(struct ib_umem *) * ROCE5_FRMR_UMEM_NUM);
+ kfree(rmr);
+
+err_out:
+ return (struct ib_mr *)ERR_PTR((long)ret);
+}
+
+int roce5_frmr_check_user_param(struct ib_mr *ibmr, unsigned int page_num,
+ struct ib_udata *udata)
+{
+ if (ibmr == NULL) {
+ ROCE_ERR("Ibmr is null");
+ return -EINVAL;
+ }
+
+ if (page_num == 0 || page_num > ROCE5_FRMR_UMEM_NUM) {
+ ROCE_ERR("page_num(%d) is invalid", page_num);
+ return -EINVAL;
+ }
+
+ if (udata == NULL) {
+ ROCE_ERR("udata is NULL");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void roce5_frmr_free_addr_list(unsigned long long *va_list,
+ unsigned long long *pa_list)
+{
+ vfree(va_list);
+ vfree(pa_list);
+}
+
+int roce5_frmr_alloc_addr_list(struct roce5_device *rdev,
+ unsigned long long **va_list,
+ unsigned long long **pa_list, u32 len)
+{
+ int ret;
+ unsigned long long *val = NULL;
+ unsigned long long *pal = NULL;
+
+ val = (unsigned long long *)vmalloc(len);
+ if (val == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to vmalloc va_list");
+ return -EAGAIN;
+ }
+ pal = (unsigned long long *)vmalloc(len);
+ if (pal == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to vmalloc pa_list");
+ vfree(val);
+ return -EAGAIN;
+ }
+ ret = memset_s(val, len, 0, len);
+ if (ret) {
+ ROCE_DEV_ERR(rdev, "Failed to memset va_list.(ret:%d)", ret);
+ ret = -ENOMEM;
+ goto err_free;
+ }
+ ret = memset_s(pal, len, 0, len);
+ if (ret) {
+ ROCE_DEV_ERR(rdev, "Failed to memset pa_list.(ret:%d)", ret);
+ ret = -ENOMEM;
+ goto err_free;
+ }
+
+ *va_list = val;
+ *pa_list = pal;
+ return 0;
+
+err_free:
+ roce5_frmr_free_addr_list(val, pal);
+ return ret;
+}
+
+static int process_va_list_and_allocate_umem(
+ struct roce5_mr *rmr, struct roce5_device *rdev, struct ib_mr *ibmr,
+ unsigned long long *va_list, unsigned long long *pa_list, u32 page_num)
+{
+ u32 i;
+ int ret;
+ for (i = 0; i < page_num; i++) {
+ ROCE_DEV_INFO(rdev, "i:%d, va(%llu)", i, va_list[i]);
+ rmr->fumem[i] = ib_umem_get(ibmr->pd->uobject->context,
+ va_list[i], FRMR_PAGE_SIZE, 0, 0);
+ if (IS_ERR(rmr->fumem[i])) {
+ ret = (int)PTR_ERR(rmr->fumem[i]);
+ roce5_free_frmr_umem(rmr->fumem, i - 1);
+ ROCE_DEV_ERR(rdev,
+ "Alloc umem failed, func_id(%d) err:%d",
+ rdev->glb_func_id, ret);
+ return ret;
+ }
+
+ /* use valloc allocate a page of memory, only needs need get the a physical address */
+ pa_list[i] = sg_dma_address(rmr->fumem[i]->sg_head.sgl);
+ ROCE_DEV_INFO(rdev, "PA_LIST:%llu", pa_list[i]);
+ if (pa_list[i] == 0ULL) {
+ ret = -EINVAL;
+ roce5_free_frmr_umem(rmr->fumem, i);
+ ROCE_DEV_ERR(rdev, "Invalid physicaL addr index(%d)",
+ i);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int roce5_map_user_frmr_sg(struct ib_mr *ibmr, unsigned int page_num,
+ struct ib_udata *udata)
+{
+ struct roce5_mr *rmr = NULL;
+ struct roce5_device *rdev = NULL;
+ int ret;
+ unsigned long long *va_list = NULL;
+ unsigned long long *pa_list = NULL;
+ u32 len;
+
+ ret = roce5_frmr_check_user_param(ibmr, page_num, udata);
+ if (ret) {
+ return ret;
+ }
+
+ len = page_num * sizeof(unsigned long long);
+ rmr = to_roce5_mr(ibmr);
+ rdev = to_roce5_dev(ibmr->device);
+ ret = roce5_frmr_alloc_addr_list(rdev, &va_list, &pa_list, len);
+ if (ret) {
+ return ret;
+ }
+
+ ROCE_DEV_INFO(rdev, "func_id(%d), page_num(%u)", rdev->glb_func_id,
+ page_num);
+
+ ret = ib_copy_from_udata((void *)va_list, udata, len);
+ if (ret) {
+ ROCE_DEV_ERR(rdev, "Failed to copy udata, ret(%d)", ret);
+ goto err_free;
+ }
+
+ ret = process_va_list_and_allocate_umem(rmr, rdev, ibmr, va_list,
+ pa_list, page_num);
+ if (ret != 0) {
+ goto err_free;
+ }
+
+ /* 讲 pa information pass to user mode */
+ if (ib_copy_to_udata(udata, pa_list, len)) {
+ ret = -EFAULT;
+ ROCE_DEV_ERR(rdev, "Failed to copy udata, func_id(%d)",
+ rdev->glb_func_id);
+ goto err_free;
+ }
+
+ rmr->fumem_nr = page_num;
+ roce5_frmr_free_addr_list(va_list, pa_list);
+ return 0;
+
+err_free:
+ rmr->fumem_nr = 0;
+ roce5_frmr_free_addr_list(va_list, pa_list);
+ return ret;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.h b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.h
new file mode 100644
index 000000000..c206ca7f6
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_mr_chip_ext.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_MR_CHIP_EXT_H
+#define ROCE_MR_CHIP_EXT_H
+
+#include <linux/types.h>
+#include <linux/io-mapping.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+int roce5_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
+ struct ib_mr_status *mr_status);
+struct ib_mr *roce5_reg_user_fast_mr(struct ib_pd *ibpd,
+ struct ib_udata *udata);
+int roce5_map_user_frmr_sg(struct ib_mr *ibmr, unsigned int page_num,
+ struct ib_udata *udata);
+
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_qp_chip_ext.c b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_qp_chip_ext.c
new file mode 100644
index 000000000..903da9898
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_qp_chip_ext.c
@@ -0,0 +1,44 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+
+
+#include "roce_qp_extension.h"
+
+void roce5_set_qp_dif_attr(struct roce5_qp *rqp,
+ const struct ib_qp_init_attr *init_attr,
+ const struct roce5_device *rdev)
+{
+ if (((unsigned int)init_attr->create_flags &
+ IB_QP_CREATE_SIGNATURE_EN) != 0) {
+ rqp->signature_en = true;
+ ROCE_DEV_INFO(rdev,
+ "func(%d) qp(%u) roce5_create_qp signature_en.",
+ rdev->glb_func_id, rqp->qpn);
+ }
+
+ if (((unsigned int)init_attr->create_flags &
+ IB_QP_CREATE_SIGNATURE_DOUBLE_SGL) != 0) {
+ rqp->double_sgl_mode = 1;
+ ROCE_DEV_INFO(
+ rdev,
+ "func(%d) qp(%u) roce5_create_qp double_sgl_mode.",
+ rdev->glb_func_id, rqp->qpn);
+ }
+
+ if (((unsigned int)init_attr->create_flags &
+ IB_QP_CREATE_SIGNATURE_EXT_MTU) != 0) {
+ rqp->ext_mtu = 1;
+ ROCE_DEV_INFO(rdev, "func(%d) qp(%u) roce5_create_qp ext_mtu.",
+ rdev->glb_func_id, rqp->qpn);
+ }
+
+ if (((unsigned int)init_attr->create_flags &
+ IB_QP_CREATE_SIGNATURE_EXT_MTU_MODE) != 0) {
+ rqp->ext_mtu_mode = 1;
+ ROCE_DEV_INFO(rdev,
+ "func(%d) qp(%u) roce5_create_qp ext_mtu_mode.",
+ rdev->glb_func_id, rqp->qpn);
+ }
+
+ return;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_srq_chip_ext.c b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_srq_chip_ext.c
new file mode 100644
index 000000000..a6323afd0
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/chip_ext/roce_srq_chip_ext.c
@@ -0,0 +1,26 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2020-2024. All rights reserved.
+
+
+#include "roce_srq_extension.h"
+
+void roce5_srq_container_init(struct ib_srq_init_attr *init_attr,
+ struct roce5_srq *rsrq, struct roce5_device *rdev)
+{
+ u8 srq_cont_en = 0;
+ srq_cont_en = init_attr->container_flag;
+
+ rsrq->xrc_en = (init_attr->srq_type == IB_SRQT_XRC);
+ rsrq->container_flag = srq_cont_en ? init_attr->container_flag :
+ rdev->cfg_info.srq_container_en;
+ rsrq->container_mode =
+ srq_cont_en ?
+ init_attr->container_mode :
+ (rsrq->xrc_en ? rdev->cfg_info.xrc_srq_container_mode :
+ rdev->cfg_info.srq_container_mode);
+ rsrq->container_warn_th = init_attr->attr.srq_limit;
+ rsrq->rqe_cnt_th = srq_cont_en ? init_attr->container_warn_th :
+ rdev->cfg_info.warn_th;
+
+ rsrq->container_size = roce5_get_container_sz(rsrq->container_mode);
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_common.h b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_common.h
new file mode 100644
index 000000000..b956ce82c
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_common.h
@@ -0,0 +1,13 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef HYPER_ROCE_COMMON
+#define HYPER_ROCE_COMMON
+
+enum roce5_hyper_mode {
+ ROCE_HYPER_MODE_DISABLE,
+ ROCE_HYPER_MODE_UDP,
+ ROCE_HYPER_MODE_AR,
+};
+
+#endif /* HYPER_ROCE_COMMON */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.c b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.c
new file mode 100644
index 000000000..ca38186cc
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.c
@@ -0,0 +1,511 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/types.h>
+#include "hinic5_rdma.h"
+#include "rdma_comp.h"
+#include "roce_hyper_npu_cmd.h"
+#include "roce_npu_cmd.h"
+#include "roce_hyper_npu_cmd.h"
+#include "comm_defs.h"
+
+#include "roce.h"
+#include "comm_defs.h"
+#include "roce_qp.h"
+#include "roce_qp_ext.h"
+#include "roce_netlink.h"
+#include "roce_cqm_cmd.h"
+#include "hyper_roce_common.h"
+#include "hyper_roce_qp.h"
+#include "hyper_roce_netlink.h"
+
+#define HYPER_ROCE_RDMARC_ENTRY_SIZE_BYTES 32
+
+static int roce5_send_cmd_set_qp_hyper_mode(struct roce5_device *rdev,
+ struct roce5_hyper_set_in *msg_in)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_enable_hyper_roce_s *input = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_enable_hyper_roce_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ input = (roce_uni_cmd_enable_hyper_roce_s *)cqm_cmd_inbuf->buf;
+ input->com.index = cpu_to_be32(msg_in->qpn);
+ input->com.dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ input->com.opt = cpu_to_be32(RoCE_CMD_ENABLE_HYPER_ROCE_QP);
+
+ input->cmd_info.dw0.bs.hyper_mode = msg_in->mode;
+ input->cmd_info.dw0.bs.srp_en = msg_in->sack_en;
+ input->cmd_info.dw0.value = cpu_to_be32(input->cmd_info.dw0.value);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ RoCE_CMD_HYPER_ROCE, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RoCE_CMD_ENABLE_HYPER_ROCE_QP command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int
+roce5_send_cmd_modify_qp_extend(struct roce5_device *rdev,
+ struct roce5_hyper_extend_config_in *msg_in)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_enable_hyper_roce_s *input = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_enable_hyper_roce_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ input = (roce_uni_cmd_enable_hyper_roce_s *)cqm_cmd_inbuf->buf;
+ input->com.index = cpu_to_be32(msg_in->qpn);
+ input->com.dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ input->com.opt = cpu_to_be32(RoCE_CMD_ENABLE_HYPER_ROCE_QP);
+
+ switch (msg_in->attr_mask) {
+ case IBV_QP_ATTR_EXTEND_UDP_SRC_PORT:
+ input->cmd_info.dw0.bs.base_src_port = msg_in->udp_src_port;
+ break;
+ case IBV_QP_ATTR_EXTEND_HYROCE_FEATURE:
+ input->cmd_info.dw0.bs.hyper_mode = msg_in->feature.type;
+ input->cmd_info.dw0.bs.srp_en = msg_in->feature.sack_enable;
+ break;
+ case IBV_QP_ATTR_EXTEND_LB_MODE:
+ input->cmd_info.dw0.bs.lb_mode = msg_in->lb_mode;
+ break;
+ case IBV_QP_ATTR_EXTEND_MP_CONFIG:
+ input->cmd_info.dw1.bs.sport_repeat_num =
+ msg_in->mp.flowlet_pkg_num;
+ input->cmd_info.dw1.bs.path_num = msg_in->mp.path_num;
+ input->cmd_info.dw1.bs.sport_interval = msg_in->mp.interval;
+ input->cmd_info.dw1.bs.path_rr_enable =
+ msg_in->mp.path_rr_enable;
+ input->cmd_info.dw1.bs.cc_mode = msg_in->mp.cc_mode;
+ break;
+ case IBV_QP_ATTR_EXTEND_AR_CONFIG:
+ input->cmd_info.dw1.bs.port_rr_enable =
+ msg_in->ar.port_rr_enable;
+ break;
+ case IBV_QP_ATTR_EXTEND_SACK_CONFIG:
+ input->cmd_info.dw2.bs.oor_range_m = msg_in->sack.oor_range;
+ input->cmd_info.dw2.bs.srp_range_n = msg_in->sack.srp_range;
+ break;
+ default:
+ ROCE_DEV_ERR(rdev, "Unsupport attr mask!\n");
+ break;
+ }
+
+ input->cmd_info.dw0.bs.attr_ext_mask = msg_in->attr_mask;
+ input->cmd_info.dw0.value = cpu_to_be32(input->cmd_info.dw0.value);
+ input->cmd_info.dw1.value = cpu_to_be32(input->cmd_info.dw1.value);
+ input->cmd_info.dw2.value = cpu_to_be32(input->cmd_info.dw2.value);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ RoCE_CMD_HYPER_ROCE, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RoCE_CMD_ENABLE_HYPER_ROCE_QP command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int
+roce5_send_cmd_set_qp_msnc(struct roce5_device *rdev, u32 qpn,
+ struct roce5_qp_hyper_extend *rqp_hyper_ext)
+{
+ int ret = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_init_msnc_s *input = NULL;
+ u64 bitmap_addr = 0;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_init_msnc_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ input = (roce_uni_cmd_init_msnc_s *)cqm_cmd_inbuf->buf;
+ input->com.index = cpu_to_be32(qpn);
+ input->com.dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ input->com.opt = cpu_to_be32(RoCE_CMD_INIT_MSNC_QP);
+
+ input->cmd_info.dw0.bs.sack_bitmap_size =
+ HYPER_ROCE_TX_SACK_BITMAP_SIZE;
+ input->cmd_info.dw0.bs.txmsn_entry_size = HYPER_ROCE_MSN_ENTRY_SIZE;
+ input->cmd_info.dw0.bs.txmsn_table_size = HYPER_ROCE_MSN_TABLE_SIZE;
+ input->cmd_info.dw0.bs.txmsn_table_gpa_h =
+ (rqp_hyper_ext->tx_msnc.dma_addr >> ROCE5_RDMARC_GPA_H_SHIFT) &
+ 0xffffff;
+ input->cmd_info.dw0.value = cpu_to_be32(input->cmd_info.dw0.value);
+
+ input->cmd_info.txmsn_table_gpa_l =
+ cpu_to_be32((u32)(rqp_hyper_ext->tx_msnc.dma_addr >>
+ ROCE5_RDMARC_GPA_L_SHIFT));
+
+ input->cmd_info.dw2.bs.rxmsn_entry_size0 = HYPER_ROCE_MSN_ENTRY_SIZE;
+ input->cmd_info.dw2.bs.rxmsn_table_size0 = HYPER_ROCE_MSN_TABLE_SIZE;
+ input->cmd_info.dw2.bs.rxmsn_table_gpa0_h =
+ (rqp_hyper_ext->rx_msnc.dma_addr >> ROCE5_RDMARC_GPA_H_SHIFT) &
+ 0xffffff;
+ input->cmd_info.dw2.value = cpu_to_be32(input->cmd_info.dw2.value);
+
+ input->cmd_info.rxmsn_table_gpa0_l =
+ cpu_to_be32((u32)(rqp_hyper_ext->rx_msnc.dma_addr >>
+ ROCE5_RDMARC_GPA_L_SHIFT));
+
+ bitmap_addr = (u64)rqp_hyper_ext->rx_msnc.dma_addr +
+ HYPER_ROCE_MSN_RDMARC_ALLOC_SIZE *
+ HYPER_ROCE_RDMARC_ENTRY_SIZE_BYTES;
+
+ input->cmd_info.dw4.bs.sack_bitmap_size =
+ HYPER_ROCE_RX_SACK_BITMAP_SIZE;
+ input->cmd_info.dw4.bs.rxmsn_entry_size1 = HYPER_ROCE_MSN_ENTRY_SIZE;
+ input->cmd_info.dw4.bs.rxmsn_table_size1 = HYPER_ROCE_MSN_TABLE_SIZE;
+ input->cmd_info.dw4.bs.rxmsn_table_gpa1_h =
+ (bitmap_addr >> ROCE5_RDMARC_GPA_H_SHIFT) & 0xffffff;
+ input->cmd_info.dw4.value = cpu_to_be32(input->cmd_info.dw4.value);
+
+ input->cmd_info.rxmsn_table_gpa1_l =
+ cpu_to_be32((u32)(bitmap_addr >> ROCE5_RDMARC_GPA_L_SHIFT));
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ RoCE_CMD_HYPER_ROCE, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RoCE_CMD_INIT_MSNC_QP command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int roce5_alloc_msnc(struct roce5_device *rdev,
+ struct roce5_qp_hyper_extend *rqp_hyper_ext)
+{
+ int ret;
+ ret = roce5_rdma_rdmarc_alloc(rdev->hwdev,
+ HYPER_ROCE_MSN_RDMARC_ALLOC_SIZE,
+ &rqp_hyper_ext->tx_msnc);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma rdmarc, func_id(%u).",
+ rdev->glb_func_id);
+ return ret;
+ }
+
+ ret = roce5_rdma_rdmarc_alloc(
+ rdev->hwdev,
+ HYPER_ROCE_MSN_RDMARC_ALLOC_SIZE +
+ HYPER_ROCE_RXMSN_BITMAP_RDMARC_ALLOC_SIZE,
+ &rqp_hyper_ext->rx_msnc);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc rdma rdmarc, func_id(%u).",
+ rdev->glb_func_id);
+ roce5_rdma_rdmarc_free(rdev->hwdev, &rqp_hyper_ext->tx_msnc);
+ return ret;
+ }
+
+ rqp_hyper_ext->msnc_en = true;
+
+ return 0;
+}
+
+static int32_t roce5_genl_set_qp_hyper_mode(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len,
+ uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_hyper_set_in *msg_in = NULL;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_qp_hyper_extend *rqp_hyper_ext = NULL;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_hyper_set_in) || out_size == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid param, in:%d, in_len:%u, out_size:%d",
+ !!in, in_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_hyper_set_in *)in;
+
+ if (msg_in->qpn == ROCE_QP_SMI_QP_NUM ||
+ msg_in->qpn == ROCE_QP_GSI_QP_NUM) {
+ ROCE_DEV_ERR(rdev, "Invalid qpn(%u).", msg_in->qpn);
+ return -EINVAL;
+ }
+
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp.");
+ return -EINVAL;
+ }
+
+ mutex_lock(&rqp->mutex);
+
+ if (rqp->qp_state >= IB_QPS_RTR) {
+ ROCE_DEV_ERR(rdev, "Invalid qp state, current state(%u).",
+ rqp->qp_state);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = roce5_send_cmd_set_qp_hyper_mode(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ goto out;
+ }
+
+ rqp_hyper_ext = (struct roce5_qp_hyper_extend *)roce5_qp_get_ext_buf(
+ rqp, ROCE_EXT_HYPER_ROCE);
+ if (rqp_hyper_ext == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to the buf of qp hyper extend, qpn(%u).",
+ rqp->qpn);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ rqp_hyper_ext->mode = msg_in->mode;
+ rqp_hyper_ext->sack_en = msg_in->sack_en;
+
+ /* ROCE_HYPER_MODE_DISABLE indicates not enable out-of-order receive, not need allocate rdmarc resource; enable sack_en selective retransmission, must enable out-of-order receive */
+ if (rqp_hyper_ext->mode != ROCE_HYPER_MODE_DISABLE) {
+ ret = roce5_alloc_msnc(rdev, rqp_hyper_ext);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to alloc msnc, ret(%d).",
+ ret);
+ goto out;
+ }
+
+ ret = roce5_send_cmd_set_qp_msnc(rdev, msg_in->qpn,
+ rqp_hyper_ext);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&rqp->mutex);
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int32_t roce5_genl_set_default_multipath_config(
+ struct roce5_device *rdev, struct roce5_hyper_extend_config_in *msg_in)
+{
+ int ret = 0;
+
+ msg_in->lb_mode = HYPER_ROCE_DEFAULT_LB_MODE;
+ msg_in->mp.flowlet_pkg_num = HYPER_ROCE_DEFAULT_MULTI_PKG_NUM;
+ msg_in->mp.path_num = HYPER_ROCE_DEFAULT_MULTI_PATH_NUM;
+ msg_in->mp.interval = HYPER_ROCE_DEFAULT_MULTI_INTERVAL;
+ msg_in->mp.path_rr_enable = HYPER_ROCE_DEFAULT_MULTI_PATHRR_ENABLE;
+ msg_in->mp.cc_mode = HYPER_ROCE_DEFAULT_MULTI_CC_MODE;
+
+ msg_in->attr_mask = IBV_QP_ATTR_EXTEND_LB_MODE;
+ ret = roce5_send_cmd_modify_qp_extend(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ return ret;
+ }
+
+ msg_in->attr_mask = IBV_QP_ATTR_EXTEND_MP_CONFIG;
+ ret = roce5_send_cmd_modify_qp_extend(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int32_t roce5_modify_hyper_config(
+ struct roce5_device *rdev, struct roce5_hyper_extend_config_in *msg_in,
+ struct roce5_qp_hyper_extend *rqp_hyper_ext, struct roce5_qp *rqp)
+{
+ int ret = 0;
+
+ if (msg_in->attr_mask == IBV_QP_ATTR_EXTEND_HYROCE_FEATURE) {
+ ret = roce5_send_cmd_modify_qp_extend(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ return ret;
+ }
+
+ rqp_hyper_ext->mode = (u8)msg_in->feature.type;
+ rqp_hyper_ext->version = (u8)msg_in->feature.version;
+ rqp_hyper_ext->sack_en = (u8)msg_in->feature.sack_enable;
+
+ /* ROCE_HYPER_MODE_DISABLE indicates not enable out-of-order receive, not need allocate rdmarc resource; enable sack_en selective retransmission, must enable out-of-order receive */
+ if (rqp_hyper_ext->mode != ROCE_HYPER_MODE_DISABLE) {
+ ret = roce5_alloc_msnc(rdev, rqp_hyper_ext);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to alloc msnc, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ ret = roce5_send_cmd_set_qp_msnc(rdev, msg_in->qpn,
+ rqp_hyper_ext);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to send CMDQ, ret(%d)",
+ ret);
+ return ret;
+ }
+ }
+
+ ret = roce5_genl_set_default_multipath_config(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to set default mp config, ret(%d).",
+ ret);
+ return ret;
+ }
+ } else {
+ if (rqp_hyper_ext->mode == ROCE_HYPER_MODE_DISABLE) {
+ ROCE_DEV_ERR(rdev,
+ "Hyper_roce is disable, current mode(%u).",
+ rqp_hyper_ext->mode);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = roce5_send_cmd_modify_qp_extend(rdev, msg_in);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send CMDQ, ret(%d)", ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int32_t roce5_genl_modify_qp_extend(struct roce5_device *rdev, void *in,
+ uint16_t in_len, void *out,
+ uint16_t out_len, uint16_t *out_size)
+{
+ int32_t ret = 0;
+ struct roce5_hyper_extend_config_in *msg_in = NULL;
+ struct roce5_qp *rqp = NULL;
+ struct roce5_qp_hyper_extend *rqp_hyper_ext = NULL;
+
+ if (in == NULL || in_len == 0 ||
+ in_len < sizeof(struct roce5_hyper_extend_config_in) ||
+ out_size == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Invalid param, in:%d, in_len:%u, out_size:%d",
+ !!in, in_len, !!out_size);
+ return -EINVAL;
+ }
+
+ msg_in = (struct roce5_hyper_extend_config_in *)in;
+
+ if (msg_in->qpn == ROCE_QP_SMI_QP_NUM ||
+ msg_in->qpn == ROCE_QP_GSI_QP_NUM) {
+ ROCE_DEV_ERR(rdev, "Invalid qpn(%u).", msg_in->qpn);
+ return -EINVAL;
+ }
+
+ rqp = roce5_get_rqp_by_qpn(rdev, msg_in->qpn);
+ if (rqp == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to look up rqp.");
+ return -EINVAL;
+ }
+
+ mutex_lock(&rqp->mutex);
+
+ if (rqp->qp_state >= IB_QPS_RTR) {
+ ROCE_DEV_ERR(rdev, "Invalid qp state, current state(%u).",
+ rqp->qp_state);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ rqp_hyper_ext = (struct roce5_qp_hyper_extend *)roce5_qp_get_ext_buf(
+ rqp, ROCE_EXT_HYPER_ROCE);
+ if (rqp_hyper_ext == NULL) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to the buf of qp hyper extend, qpn(%u).",
+ rqp->qpn);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = roce5_modify_hyper_config(rdev, msg_in, rqp_hyper_ext, rqp);
+ if (ret) {
+ ROCE_DEV_ERR(rdev, "Failed to modify hyper roce config.");
+ }
+out:
+ mutex_unlock(&rqp->mutex);
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static roce5_netlink_cmd_process g_cmd_process[] = {
+ { USRNL_ROCE_CMD_HYPER_QP_SET, roce5_genl_set_qp_hyper_mode },
+ { USRNL_ROCE_CMD_MODIFY_QP_EXTEND, roce5_genl_modify_qp_extend },
+};
+
+int roce5_hyper_netlink_init(void)
+{
+ int ret;
+
+ ret = roce5_netlink_register_cbs(
+ g_cmd_process,
+ sizeof(g_cmd_process) / sizeof(roce5_netlink_cmd_process));
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to register hyper roce netlink callbacks, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.h b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.h
new file mode 100644
index 000000000..27de1b070
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_netlink.h
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef HYPER_ROCE_NETLINK_H
+#define HYPER_ROCE_NETLINK_H
+
+#include <linux/types.h>
+
+#define HYPER_ROCE_DEFAULT_LB_MODE 1
+#define HYPER_ROCE_DEFAULT_MULTI_PKG_NUM 4
+#define HYPER_ROCE_DEFAULT_MULTI_PATH_NUM 4
+#define HYPER_ROCE_DEFAULT_MULTI_INTERVAL 1
+#define HYPER_ROCE_DEFAULT_MULTI_PATHRR_ENABLE 0
+#define HYPER_ROCE_DEFAULT_MULTI_CC_MODE 2
+
+struct roce5_hyper_set_in {
+ uint32_t qpn;
+ uint8_t mode; /* @see enum roce_hyper_mode */
+ uint8_t sack_en;
+ uint8_t rsvd[2];
+};
+
+int roce5_hyper_netlink_init(void);
+
+enum ibv_qp_attr_extend_mask {
+ IBV_QP_ATTR_EXTEND_UDP_SRC_PORT = 1 << 0, /* source UDP port number */
+ IBV_QP_ATTR_EXTEND_HYROCE_FEATURE = 1 << 1, /* high-order RoCE of feature */
+ IBV_QP_ATTR_EXTEND_LB_MODE = 1 << 2, /* load balance mode */
+ IBV_QP_ATTR_EXTEND_MP_CONFIG = 1 << 3, /* Multi-Path multipath mode configuration */
+ IBV_QP_ATTR_EXTEND_AR_CONFIG =
+ 1 << 4, /* Adaptive-Routing multipath mode configuration */
+ IBV_QP_ATTR_EXTEND_SACK_CONFIG =
+ 1 << 5, /* Selective Ack selective retransmission parameters configuration */
+};
+
+/* high-order RoCE feature configuration structure */
+struct ibv_hyroce_feature {
+ uint32_t type; /* high-order RoCE type, value range: enum ibv_hyroce_feature_type */
+ uint32_t version; /* high-order RoCE version, value range: enum ibv_hyroce_feature_version */
+ uint32_t sack_enable; /* selective retransmission switch, 0- disable, 1- enable */
+
+ uint32_t resv[32]; /* reserved field, used for not to extension feature */
+};
+
+/* multipath (Multi-Path) configuration parameters structure */
+struct ibv_mp_config {
+ uint32_t flowlet_pkg_num; /* each sub-flow (flowlet) of packet count, used for flow splitting */
+ uint32_t path_num; /* multipath of path count */
+ uint32_t interval; /* UDP port number increment interval, used for distinguish different path */
+ uint32_t path_rr_enable; /* path whether supports poll (RR) select network port, 0- not support, 1- supports */
+ uint32_t cc_mode;
+
+ uint32_t resv[32]; /* reserved field, used for not to extension */
+};
+
+/* adaptive path by (Adaptive Routing) configuration structure */
+struct ibv_ar_config {
+ uint32_t port_rr_enable; /* whether enable network port side port poll (RR) per-packet function, 0- disable, 1- enable */
+
+ uint32_t resv[32]; /* reserved field, used for not to extension */
+};
+
+/* selective retransmission (SACK - Selective Ack) configuration structure */
+struct ibv_sack_config {
+ uint32_t srp_range; /* TX(send) direction maximum repass packet count */
+ uint32_t oor_range; /* RX(receive) direction out-of-order repass window of packet count */
+
+ uint32_t resv[32]; /* reserved field, used for not to extension */
+};
+
+struct roce5_hyper_extend_config_in {
+ uint32_t qpn;
+ uint32_t udp_src_port; /* source UDP port number */
+ struct ibv_hyroce_feature feature; /* high-order RoCE feature */
+ uint32_t lb_mode; /* load balance mode, value range: enum ibv_lb_mode type */
+ struct ibv_mp_config mp; /* multipath (Multi-Path) configuration */
+ struct ibv_ar_config ar; /* adaptive path by (Adaptive Routing) configuration */
+ struct ibv_sack_config sack; /* selective retransmission (SACK) configuration */
+ enum ibv_qp_attr_extend_mask attr_mask;
+};
+
+#endif /* HYPER_ROCE_NETLINK_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.c b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.c
new file mode 100644
index 000000000..1cc831f16
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.c
@@ -0,0 +1,29 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include "roce_qp.h"
+#include "roce_restore.h"
+#include "hyper_roce_common.h"
+#include "hyper_roce_qp.h"
+
+int roce5_hyper_qp_init(void *parent, void *ext_data)
+{
+ struct roce5_qp_hyper_extend *hyper_qp_ext =
+ (struct roce5_qp_hyper_extend *)ext_data;
+ hyper_qp_ext->mode = ROCE_HYPER_MODE_DISABLE;
+ hyper_qp_ext->sack_en = false;
+ return 0;
+}
+
+void roce5_hyper_qp_cleanup(void *parent, void *ext_data)
+{
+ struct roce5_qp *rqp = (struct roce5_qp *)parent;
+ struct roce5_device *rdev = to_roce5_dev(rqp->ibqp.device);
+ struct roce5_qp_hyper_extend *hyper_qp_ext =
+ (struct roce5_qp_hyper_extend *)ext_data;
+
+ if (hyper_qp_ext->msnc_en) {
+ roce5_rdma_rdmarc_free(rdev->hwdev, &(hyper_qp_ext->tx_msnc));
+ roce5_rdma_rdmarc_free(rdev->hwdev, &(hyper_qp_ext->rx_msnc));
+ }
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.h b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.h
new file mode 100644
index 000000000..52c38f0a4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/hyper_roce_qp.h
@@ -0,0 +1,35 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef HYPER_ROCE_QP_H
+#define HYPER_ROCE_QP_H
+
+#include <linux/types.h>
+#include "base_type.h"
+#include "hinic5_rdma.h"
+
+/* Entry_size for TXMSN/RXMSN Table 00: 32B 01: 64B Others: reserved. */
+#define HYPER_ROCE_MSN_ENTRY_SIZE 0u
+/* Entry number for TXMSN/RXMSN Table 00: 256 01: 512 10: 1024 11: 2048 Others: reserved. */
+#define HYPER_ROCE_MSN_TABLE_SIZE 0u
+/* 000: 128bit 001: 256bit 010: 512bit 011: 1024bit 100: 2048bit Others: reserved. */
+#define HYPER_ROCE_TX_SACK_BITMAP_SIZE 0u
+/* 011: 1024bit 100: 2048bit Others: reserved. */
+#define HYPER_ROCE_RX_SACK_BITMAP_SIZE 3u
+#define HYPER_ROCE_MSN_RDMARC_ALLOC_SIZE \
+ (256u << (HYPER_ROCE_MSN_ENTRY_SIZE & 0x3))
+#define HYPER_ROCE_RXMSN_BITMAP_RDMARC_ALLOC_SIZE (4)
+
+struct roce5_qp_hyper_extend {
+ u8 mode; /* @see enum roce_hyper_mode */
+ u8 version;
+ u8 sack_en;
+ struct rdma_rdmarc tx_msnc;
+ struct rdma_rdmarc rx_msnc;
+ bool msnc_en;
+};
+
+int roce5_hyper_qp_init(void *parent, void *ext_data);
+void roce5_hyper_qp_cleanup(void *parent, void *ext_data);
+
+#endif /* HYPER_ROCE_QP_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.c b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.c
new file mode 100644
index 000000000..fe4e5cf64
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.c
@@ -0,0 +1,60 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include "roce.h"
+#include "roce_dfx.h"
+#include "hyper_roce_tool_pktdrop.h"
+#include "hyper_roce_tool.h"
+
+enum roce5_hyper_cmds {
+ ROCE_HYPER_CMD_START = 1,
+ ROCE_HYPER_CMD_START_DROP_QP,
+ ROCE_HYPER_CMD_STOP_DROP_QP,
+ ROCE_HYPER_CMD_MAX
+};
+
+const roce5_adm_func_t hyper_roce5_adm_func[] = {
+ [ROCE_HYPER_CMD_START_DROP_QP] = roce5_hyper_tool_start_drop_qp,
+ [ROCE_HYPER_CMD_STOP_DROP_QP] = roce5_hyper_tool_stop_drop_qp,
+};
+
+int roce5_hyper_tool_dispatch(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct roce5_hyper_cmd_head *head = NULL;
+ const void *data_ptr = NULL;
+ u32 data_len;
+ int ret;
+
+ if (in_size < ROCE_HYPER_CMD_HEAD_SIZE) {
+ ROCE_DEV_ERR(rdev, "Invalid command length(%d).", in_size);
+ return -EINVAL;
+ }
+
+ data_ptr = (void *)((char *)buf_in + ROCE_HYPER_CMD_HEAD_SIZE);
+ data_len = in_size - ROCE_HYPER_CMD_HEAD_SIZE;
+ head = data_ptr;
+
+ if (head->sub_cmd < ROCE_HYPER_CMD_START ||
+ head->sub_cmd >= ROCE_HYPER_CMD_MAX) {
+ ROCE_DEV_ERR(rdev, "Unknown hyper roce command(%d).",
+ head->sub_cmd);
+ return -EINVAL;
+ }
+
+ if (hyper_roce5_adm_func[head->sub_cmd] == NULL) {
+ ROCE_DEV_ERR(rdev, "The callback of cmd(%d) is NULL.",
+ head->sub_cmd);
+ return -EINVAL;
+ }
+
+ ret = hyper_roce5_adm_func[head->sub_cmd](rdev, buf_in, in_size,
+ buf_out, out_size);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to execute the callback of cmd(%d)",
+ head->sub_cmd);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.h b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.h
new file mode 100644
index 000000000..2438bbb78
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool.h
@@ -0,0 +1,21 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef HYPER_ROCE_TOOL_H
+#define HYPER_ROCE_TOOL_H
+
+#include "base_type.h"
+#include "roce.h"
+
+#define ROCE_CMD_HYPER 0x220
+
+struct roce5_hyper_cmd_head {
+ u32 sub_cmd;
+};
+
+#define ROCE_HYPER_CMD_HEAD_SIZE sizeof(struct roce5_hyper_cmd_head)
+
+int roce5_hyper_tool_dispatch(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* HYPER_ROCE_TOOL_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.c b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.c
new file mode 100644
index 000000000..7d305e069
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.c
@@ -0,0 +1,142 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/types.h>
+#include "hinic5_rdma.h"
+#include "rdma_comp.h"
+#include "roce_npu_cmd.h"
+#include "roce_hyper_npu_cmd.h"
+#include "comm_defs.h"
+
+#include "roce.h"
+#include "roce_qp.h"
+#include "roce_qp_ext.h"
+#include "roce_netlink.h"
+#include "roce_cqm_cmd.h"
+#include "hyper_roce_tool_pktdrop.h"
+
+int roce5_hyper_tool_start_drop_qp(struct roce5_device *rdev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ int ret = 0;
+ u32 drop_pkt_ratio = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_modify_qp_drop_percent_s *input = NULL;
+ struct pktdrop_cmd_inbuf *in = NULL;
+
+ if (in_size < sizeof(struct pktdrop_cmd_inbuf)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(struct pktdrop_cmd_inbuf));
+ return -EINVAL;
+ }
+
+ if (*out_size < sizeof(union pktdrop_outbuf)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Input parameter(out_size: %dB) is shorter than allocated buffer(allocated: %dB)",
+ (int)*out_size, (int)sizeof(union pktdrop_outbuf));
+ return -ENOMEM;
+ }
+
+ in = (struct pktdrop_cmd_inbuf *)buf_in;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_modify_qp_drop_percent_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ drop_pkt_ratio = in->data.attr.dw15.bs.drop_pkt_ratio;
+ input = (roce_uni_cmd_modify_qp_drop_percent_s *)cqm_cmd_inbuf->buf;
+ input->com.index = cpu_to_be32(in->qpn);
+ input->com.dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ input->com.opt = cpu_to_be32(RoCE_CMD_MODIFY_QP_DROP_PERCENT);
+
+ input->cmd_info.dw0.bs.drop_precent = drop_pkt_ratio;
+ input->cmd_info.dw0.value = cpu_to_be32(input->cmd_info.dw0.value);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ RoCE_CMD_HYPER_ROCE, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RoCE_CMD_ENABLE_HYPER_ROCE_QP command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+int roce5_hyper_tool_stop_drop_qp(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ int ret = 0;
+ u32 drop_pkt_ratio = 0;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ roce_uni_cmd_modify_qp_drop_percent_s *input = NULL;
+ struct pktdrop_cmd_inbuf *in = NULL;
+
+ if (in_size < sizeof(struct pktdrop_cmd_inbuf)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(struct pktdrop_cmd_inbuf));
+ return -EINVAL;
+ }
+
+ if (*out_size < sizeof(union pktdrop_outbuf)) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Input parameter(out_size: %dB) is shorter than allocated buffer(allocated: %dB)",
+ (int)*out_size, (int)sizeof(union pktdrop_outbuf));
+ return -ENOMEM;
+ }
+
+ in = (struct pktdrop_cmd_inbuf *)buf_in;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_modify_qp_drop_percent_s), NULL, 0);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to alloc cqm_cmd_inoutbuf, func_id(%d), ret(%d)",
+ rdev->glb_func_id, ret);
+ return -ENOMEM;
+ }
+
+ input = (roce_uni_cmd_modify_qp_drop_percent_s *)cqm_cmd_inbuf->buf;
+ input->com.index = cpu_to_be32(in->qpn);
+ input->com.dw0.bs.cmd_bitmask = cpu_to_be16(VERBS_CMD_TYPE_QP_BITMASK);
+ input->com.opt = cpu_to_be32(RoCE_CMD_MODIFY_QP_DROP_PERCENT);
+
+ input->cmd_info.dw0.bs.drop_precent = drop_pkt_ratio;
+ input->cmd_info.dw0.value = cpu_to_be32(input->cmd_info.dw0.value);
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ RoCE_CMD_HYPER_ROCE, cqm_cmd_inbuf, NULL, NULL,
+ ROCE_CMD_TIME_CLASS_A, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(
+ rdev,
+ "Failed to send RoCE_CMD_ENABLE_HYPER_ROCE_QP command, ret(%d), func_id(%d)",
+ ret, rdev->glb_func_id);
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.h b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.h
new file mode 100644
index 000000000..4d3dbd1d5
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/extern/hyper_roce/tool/hyper_roce_tool_pktdrop.h
@@ -0,0 +1,23 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef HYPER_ROCE_TOOL_PKTDROP_H
+#define HYPER_ROCE_TOOL_PKTDROP_H
+#include "hyper_roce_pub_cmd.h"
+#include "roce.h"
+
+struct pktdrop_cmd_inbuf {
+ u32 cmd_type;
+ u32 hyper_roce_sub_cmd;
+ u32 mode;
+ u32 qpn;
+ u32 drop_level;
+ struct pktdrop_l2d_tbl_dfx data;
+};
+
+int roce5_hyper_tool_start_drop_qp(struct roce5_device *rdev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
+int roce5_hyper_tool_stop_drop_qp(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+#endif
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce.h
new file mode 100644
index 000000000..3fbc3343b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce.h
@@ -0,0 +1,665 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_H
+#define ROCE_H
+
+#include <linux/types.h>
+#include <linux/io-mapping.h>
+#include <linux/list.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+#include <rdma/uverbs_ioctl.h>
+#include "roce_verbs_compat.h"
+
+#include "hinic5_hw.h"
+#include "hinic5_crm.h"
+#include "hinic5_hw_cfg.h"
+#include "hinic5_lld.h"
+#include "hinic5_cqm.h"
+#include "hinic5_rdma.h"
+#include "nic_cfg_comm.h"
+#include "hmm_common.h"
+
+#include "roce_infra.h"
+#include "roce_db.h"
+#include "roce_sysfs.h"
+
+#include "roce_uld_kernel_api.h"
+#include "roce_npu_cmd_defs.h"
+#include "roce_npu_cmd_ext_defs.h"
+
+#define HIROCE5_DRV_NAME "roce5_drv"
+#define HIROCE5_DRV_AUTHOR "Huawei Technologies CO., Ltd"
+#define HIROCE5_DRV_DESC \
+ "Huawei(R) Intelligent Network Interface Card, RoCE Driver"
+#define HIROCE5_DRV_VERSION GLOBAL_VERSION_STR
+
+#define RDMA_DRIVER_HRN 8395
+#define ROCE_IB_UVERBS_ABI_VERSION 1
+#define ROCE_ULD_DEV_NAME_LEN 16
+
+#define MAX_CEQ_NEED 256
+
+#define DEV_ADDR_FIRST_BYTE_VAL_MASK 2
+
+#define ROCE_NODE_DESC_LEN 5
+
+#define ROCE_SQ_WQEBB_SIZE 64
+
+#define ROCE_GID_LEN 16
+
+#define ROCE_PCI_CFG_REGS_BAR0 0
+#define ROCE_PCI_CFG_REGS_BAR3 3
+
+#define DEFAULT_ROCE_DEV_NODE_PRI 0666
+
+#define ROCE_MAX_PORT_NUM 8
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 0x4321
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 0x1234
+#endif
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#define MAX_ROCE_DEV (28 * 4)
+
+#define CHECK_1LAYER_IS_NULL(ptr) ((ptr) == NULL)
+#define CHECK_2LAYER_IS_NULL(ptr, l2_member) \
+ (CHECK_1LAYER_IS_NULL(ptr) || (((ptr)->l2_member) == NULL))
+
+static inline bool roce5_func_is_vf(void *hwdev)
+{
+ return hinic5_func_type(hwdev) == TYPE_VF;
+}
+
+static inline bool roce5_func_is_pf(void *hwdev)
+{
+ return hinic5_func_type(hwdev) == TYPE_PF;
+}
+
+enum {
+ ROCE5_1_PORT_NUM = 1, //EVB single die 形mode
+ ROCE5_2_PORT_NUM = 2,
+ ROCE5_4_PORT_NUM = 4
+};
+
+enum {
+ ROCE5_25G_PORT_SPEED = 25,
+ ROCE5_100G_PORT_SPEED = 100,
+ ROCE5_200G_PORT_SPEED = 200,
+ ROCE5_400G_PORT_SPEED =
+ 201, //because MPU bit width not 够衍generate of custom enum, refer to port_speed_mode_e
+ ROCE5_800G_PORT_SPEED = 202
+};
+
+enum {
+ ROCE5_INVALID_HCA = -1,
+ ROCE5_2_100G_HCA = 0,
+ ROCE5_4_25G_HCA = 1,
+ ROCE5_2_25G_HCA = 2,
+ ROCE5_2_200G_HCA = 3,
+ ROCE5_1_100G_HCA = 4,
+ ROCE5_2_400G_HCA = 5,
+ ROCE5_4_200G_HCA = 6
+};
+
+enum ROCE5_100G_BW_PARAM_E {
+ ROCE5_100G_CIR = 46500000,
+ ROCE5_100G_PIR = 52500000,
+ ROCE5_100G_CNP = 100
+};
+
+enum ROCE5_25G_BW_PARAM_E {
+ ROCE5_25G_CIR = 23200000,
+ ROCE5_25G_PIR = 25500000,
+ ROCE5_25G_CNP = 3
+};
+
+enum roce_bitshift_e {
+ BYTES_TO_2B_SHIFT = 1,
+ BYTES_TO_4B_SHIFT,
+ BYTES_TO_8B_SHIFT,
+ BYTES_TO_16B_SHIFT,
+ BYTES_TO_32B_SHIFT
+};
+
+/* BIG/LITTLE ENGIAN switch */
+#ifdef HW_CONVERT_ENDIAN
+#define roce5_convert_be32(val) (val)
+#define roce5_convert_cpu32(val) (val)
+#else
+#define roce5_convert_be32(val) cpu_to_be32(val)
+#define roce5_convert_cpu32(val) be32_to_cpu(val)
+#endif
+
+enum roce5_aeq_type {
+ /* ofed err */
+ OFED_ET_PATH_MIG = 0,
+ OFED_ET_COMM_EST,
+ OFED_ET_SQ_DRAINED,
+ OFED_ET_SRQ_QP_LAST_WQE,
+ OFED_ET_WQ_CATAS_ERR,
+
+ OFED_ET_PATH_MIG_FAILED = 5,
+ OFED_ET_WQ_INVAL_REQ_ERR,
+ OFED_ET_WQ_ACCESS_ERR,
+ OFED_ET_CQ_ERR,
+ OFED_ET_SRQ_LIMIT,
+ OFED_ET_SRQ_CATAS_ERR,
+
+ /* non ofed err */
+ NON_OFED_ET_QPC_LOOKUP_ERR = 11,
+ NON_OFED_ET_OTHER_TYPE_ERR,
+
+ /* non ofed extend err */
+ NON_OFED_ET_DEBUG_ERR = 32,
+
+ /* NOF AA err */
+ OFED_NOF_AA_QP_DISCONNECT = 64,
+ OFED_NOF_AA_MASTER_CHANGE,
+
+ INVAL_ET_ERR
+};
+
+enum {
+ ROCE_CMD_TIME_CLASS_A = 30000, //30s, TODO: use ASIC card after need modify is 3s
+ ROCE_CMD_TIME_CLASS_B = 40000, //40s, TODO: use ASIC card after need modify is 4s
+ ROCE_CMD_TIME_CLASS_C = 50000 //50s, TODO: use ASIC card after need modify is 5s
+};
+
+enum roce5_ctrl_status { ROCE5_PORT_EVENT = BIT(0) };
+
+#define ROCE_DEFAULT_PORT_NUM 1
+
+#define ROCE_UVERBS_CMD_BASE_MASK \
+ ((1ULL << IB_USER_VERBS_CMD_GET_CONTEXT) | \
+ (1ULL << IB_USER_VERBS_CMD_QUERY_DEVICE) | \
+ (1ULL << IB_USER_VERBS_CMD_QUERY_PORT) | \
+ (1ULL << IB_USER_VERBS_CMD_ALLOC_PD) | \
+ (1ULL << IB_USER_VERBS_CMD_DEALLOC_PD) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_AH) | \
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_AH) | \
+ (1ULL << IB_USER_VERBS_CMD_REG_MR) | \
+ (1ULL << IB_USER_VERBS_CMD_DEREG_MR) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_CQ) | \
+ (1ULL << IB_USER_VERBS_CMD_RESIZE_CQ) | \
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_CQ) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_QP) | \
+ (1ULL << IB_USER_VERBS_CMD_MODIFY_QP) | \
+ (1ULL << IB_USER_VERBS_CMD_QUERY_QP) | \
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_QP) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_SRQ) | \
+ (1ULL << IB_USER_VERBS_CMD_MODIFY_SRQ) | \
+ (1ULL << IB_USER_VERBS_CMD_QUERY_SRQ) | \
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_SRQ) | \
+ (1ULL << IB_USER_VERBS_CMD_CREATE_XSRQ) | \
+ (1ULL << IB_USER_VERBS_CMD_ALLOC_MW) | \
+ (1ULL << IB_USER_VERBS_CMD_DEALLOC_MW) | \
+ (1ULL << IB_USER_VERBS_CMD_OPEN_XRCD) | \
+ (1ULL << IB_USER_VERBS_CMD_CLOSE_XRCD) | \
+ (1ULL << IB_USER_VERBS_CMD_OPEN_QP))
+
+#define ROCE_UVERBS_EXT_CMD_MASK \
+ ((1ULL << IB_USER_VERBS_EX_CMD_MODIFY_CQ) | \
+ (1ULL << IB_USER_VERBS_EX_CMD_MODIFY_QP))
+
+enum roce5_load_balance_mode_e {
+ ROCE_LB_MODE_0 = 0,
+ ROCE_LB_MODE_1,
+ ROCE_LB_MODE_2,
+ ROCE_LB_MODE_N,
+};
+
+enum push_ofed_device_status {
+ ROCE_DEV_STATUS_NORMAL = 0,
+ ROCE_DEV_STATUS_CMDQ_TIMEOUT
+};
+
+enum roce5_func_state { ROCE_FUNC_DISABLE = 0, ROCE_FUNC_ENABLE };
+
+enum {
+ ROCE_Cl_TYPE_QPC = 0x0, /* cl_start: 0x0, cl_end: 0x7f, cl_size: 0 */
+ ROCE_CL_TYPE_MPT = 0x1, /* cl_start: 0x150, cl_end: 0x15f, cl_size: 0 */
+ ROCE_CL_TYPE_SQ_WQE =
+ 0x2, /* cl_start: 0x80, cl_end: 0xff, cl_size: 0 */
+ ROCE_CL_TYPE_RQ_WQE =
+ 0x3, /* cl_start: 0x80, cl_end: 0xff, cl_size: 0 */
+ ROCE_CL_TYPE_CQC_SRQC =
+ 0x4, /* cl_start: 0x120, cl_end: 0x13f, cl_size: 0 */
+ ROCE_CL_TYPE_RDMARC =
+ 0x5, /* cl_start: 0x120, cl_end: 0x13f, cl_size: 0 */
+ ROCE_CL_TYPE_CMTT =
+ 0x6, /* cl_start: 0x100, cl_end: 0x11f, cl_size: 0 */
+ ROCE_CL_TYPE_DMTT = 0x7 /* cl_start: 0x100, cl_end: 0x11f, cl_size: 0 */
+};
+
+#define XRC_CONTAINER_FLAG ((u32)(1L << 20))
+
+struct roce5_buf_list {
+ void *buf;
+ dma_addr_t map;
+};
+
+struct roce5_buf {
+ struct roce5_buf_list direct;
+ struct roce5_buf_list *page_list;
+ int nbufs;
+
+ int npages;
+ int page_shift;
+};
+
+struct shadow_hw_db {
+ u32 page_idx;
+ u32 refcnt;
+};
+
+struct roce5_ucontext {
+ struct ib_ucontext ibucontext;
+ void __iomem *db_map;
+ void __iomem *dwqe_map;
+ u64 db_dma_addr;
+ u64 dwqe_dma_addr;
+ struct list_head db_page_list;
+ struct mutex db_page_mutex;
+
+ struct shadow_hw_db shadow_db_ctx;
+};
+
+struct roce5_qp_cnt {
+ struct mutex cur_qps_mutex;
+ u32 alloc_qp_cnt;
+ u32 del_qp_cnt;
+};
+
+struct roce5_dev_hw_info {
+ int config_num_ports; /* Number of ports from configuration file */
+ int hca_type; /* HCA version: 4x25G or 2x100G */
+ u8 phy_port;
+ u8 ep_id; /* EP ID */
+ u8 cpu_endian;
+ u8 rsvd;
+
+ bool is_vf;
+};
+
+struct roce5_dev_cfg_info {
+ u8 scence_id; /* load scenes ID as aa_en */
+ u8 lb_en; /* load balance enable */
+ u8 lb_mode; /* load balance mode */
+ struct {
+ u8 pcie_atomic_en : 1;
+ u8 rsvd : 7;
+ };
+
+ u8 srq_container_en;
+ u8 srq_container_mode;
+ u8 xrc_srq_container_mode;
+ u8 warn_th;
+
+ u8 fake_en;
+ u8 page_bit;
+ u8 pf_start_bit;
+ u8 pf_end_bit;
+
+ u8 port_num; /* cfg data port num */
+ u8 host_num; /* cfg data host num */
+ u8 rsvd1[2];
+ roce_get_chip_ability_s feature_cap;
+};
+#define ROCE_LB_QPN_MAX \
+ 1 //less qp, same a smf on of qp will distribution to same a icq queue, because this decrease low lb of qp count
+struct roce5_qp_lb_scqn_ctrl {
+ struct mutex qp_lb_scqn_ctrl_mutex;
+ //record device in lb of qpn
+ u32 qp[ROCE_LB_QPN_MAX];
+};
+
+struct roce5_cq_ctrl {
+ struct mutex cq_ctrl_mutex;
+ u8 alloc_cq_cnt;
+ u8 high_perf_cq_cnt;
+ u8 rsvd_cq_step;
+ unsigned long cq_bitmap;
+};
+
+enum roce5_device_type { ROCE_DEV_TYPE_UNKNOWN, ROCE_DEV_TYPE_HI1825_V100 };
+
+enum roce5_perf_cq_step { ROCE_1825V100_STEP = 8 };
+
+#define ROCE_IS_DEV_1825V100(rdev) \
+ (((rdev)->device_type) == ROCE_DEV_TYPE_HI1825_V100)
+
+#ifdef __ROCE_DFX__
+struct roce5_list {
+ struct list_head node;
+ struct mutex node_lock;
+};
+struct roce5_device_res {
+ struct roce5_list mr_list;
+};
+#endif //__ROCE_DFX__
+
+//uld service can extension structure space
+#define ROCE_DEVICE_ULD_DEF_LEN 64
+#define ROCE_DEVICE_MAGIC 0xaabacada
+struct roce5_device_uld_def {
+ u8 self_def[ROCE_DEVICE_ULD_DEF_LEN];
+};
+
+struct roce5_device {
+ struct ib_device ib_dev;
+ struct hinic5_lld_dev *lld_dev;
+ struct net_device *ndev;
+ struct device *dev;
+ void *hwdev;
+ void *hwdev_hdl;
+ //struct dev_version_info dev_ver; /*version info */
+ struct hinic5_board_info board_info;
+
+ void __iomem *kernel_db_map;
+ void __iomem *kernel_dwqe_map;
+
+ spinlock_t node_desc_lock;
+ struct mutex cap_mask_mutex;
+ struct rdma_service_cap rdma_cap;
+
+ u8 mac[6]; /* Mac addr. */
+ u16 glb_func_id;
+ unsigned long status;
+ int ceq_num;
+ int ceqn[MAX_CEQ_NEED];
+ int try_times;
+ int destory_flow_timeout;
+ bool ib_active;
+ enum roce5_device_type device_type;
+
+ u8 group_rc_cos;
+ u8 group_ud_cos;
+ u8 group_xrc_cos;
+ u8 mpt_xid_mode;
+ struct roce5_qp_lb_scqn_ctrl qp_lb_scqn_ctrl;
+ struct roce5_dev_hw_info hw_info; /* Hw info read from nic/pcie */
+ struct roce5_dev_cfg_info cfg_info; /* Cfg data info read from MPU */
+
+#ifdef ROCE_BONDING_EN
+ enum ib_port_state port_state;
+ struct roce5_bond_device *bond_dev;
+ atomic_t next_port;
+#endif
+
+ struct mutex mac_vlan_mutex;
+ struct list_head mac_vlan_list_head;
+ struct net_device **gid_dev;
+
+ struct roce5_ecn_ctx ecn_ctx;
+ struct roce5_dfx_ctx dfx_ctx;
+
+ struct roce5_qp_cnt qp_cnt;
+ struct roce5_cq_ctrl cqn_ctrl;
+
+ struct srcu_struct mr_srcu;
+ atomic_t num_prefetch;
+ struct completion comp_prefetch;
+ enum push_ofed_device_status dev_status_to_ofed;
+
+ spinlock_t reset_flow_resource_lock;
+ struct list_head qp_list;
+
+ void *fake_data_buf;
+ dma_addr_t fake_data_page_addr;
+ void *pri_roce_dev
+ [ROCE_MAX_PORT_NUM]; //mailbox, ppf store all pf's roce device, to improve the effiency.
+ int hca_vf_mode; //HCA uses mode to init MAC/IP vf table
+ bool local_en; //STUB local
+ bool full_qp_spec;
+ bool huge_page_en;
+ bool is_vroce;
+ u8 cc_param_version;
+ u8 shadow;
+ u8 rsvd[2];
+ u32 shadow_vfid;
+ u16 shadow_vf_num;
+
+ rwlock_t rwlock_func_tbl_bond;
+ u32 func_tbl_bond;
+
+#ifdef __ROCE_DFX__
+ struct roce5_device_res *device_res;
+ struct roce5_ucontext *ucontext;
+#endif //__ROCE_DFX__
+
+ struct roce5_device_uld_def uld_def;
+ u32 rdev_magic; /* used for uld check, preventstop踩踏 */
+};
+
+int roce5_db_map_user(struct roce5_ucontext *context, unsigned long virt,
+ struct roce5_db *db, u8 shadow_db);
+void roce5_db_unmap_user(struct roce5_ucontext *context, struct roce5_db *db,
+ u8 shadow_db);
+
+int roce5_buf_write_mtt(struct roce5_device *rdev, struct mtt *mtt,
+ struct tag_cqm_buf *buf);
+int roce5_umem_write_mtt(struct roce5_device *rdev, struct mtt *mtt,
+ struct ib_umem *umem, bool use_huge);
+
+int roce5_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
+ struct ib_udata *uhw);
+
+int roce5_query_port_compat(struct ib_device *ibdev, u8 port,
+ struct ib_port_attr *props);
+
+int roce5_query_port(struct ib_device *ibdev, u32 port,
+ struct ib_port_attr *props);
+
+enum rdma_link_layer roce5_port_link_layer_compat(struct ib_device *ibdev,
+ u8 port_num);
+
+enum rdma_link_layer roce5_port_link_layer(struct ib_device *ibdev,
+ u32 port_num);
+
+int roce5_query_gid_compat(struct ib_device *ibdev, u8 port, int index,
+ union ib_gid *gid);
+
+int roce5_query_gid(struct ib_device *ibdev, u32 port, int index,
+ union ib_gid *gid);
+
+int roce5_query_pkey_compat(struct ib_device *ibdev, u8 port, u16 index,
+ u16 *pkey);
+
+int roce5_query_pkey(struct ib_device *ibdev, u32 port, u16 index, u16 *pkey);
+
+int roce5_modify_device(struct ib_device *ibdev, int mask,
+ struct ib_device_modify *props);
+
+int roce5_modify_port_compat(struct ib_device *ibdev, u8 port, int mask,
+ struct ib_port_modify *props);
+
+int roce5_modify_port(struct ib_device *ibdev, u32 port, int mask,
+ struct ib_port_modify *props);
+
+int roce5_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma);
+
+int roce5_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
+
+int roce5_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
+
+int roce5_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata);
+
+int roce5_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
+
+int roce5_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
+
+void roce5_dealloc_ucontext(struct ib_ucontext *ibcontext);
+
+int roce5_alloc_ucontext(struct ib_ucontext *ibucontext,
+ struct ib_udata *udata);
+
+int roce5_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata);
+
+int roce5_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata);
+
+int roce5_dealloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata);
+int roce5_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata);
+
+int roce5_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata);
+
+int roce5_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
+int roce5_modify_cq(struct ib_cq *ibcq, u16 cq_count, u16 cq_period);
+
+int roce5_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
+
+int roce5_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+
+int roce5_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
+
+struct ib_qp *roce5_create_qp_compat(struct ib_pd *ibpd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata);
+
+int roce5_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata);
+
+int roce5_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata);
+
+int roce5_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
+
+int roce5_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
+
+int roce5_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
+ struct ib_udata *udata);
+
+int roce5_destroy_ah(struct ib_ah *ibah, u32 flags);
+
+int roce5_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
+ const struct ib_recv_wr **bad_wr);
+
+int roce5_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
+ const struct ib_recv_wr **bad_wr);
+
+int roce5_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+ enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
+
+int roce5_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr);
+
+struct ib_mr *roce5_get_dma_mr(struct ib_pd *ibpd, int access);
+struct ib_mr *roce5_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ u32 max_num_sg);
+struct ib_mr *roce5_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length,
+ u64 virt_addr, int access,
+ struct ib_udata *udata);
+
+int roce5_map_kernel_frmr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
+ int sg_nents, unsigned int *sg_offset);
+
+int roce5_dealloc_mw(struct ib_mw *ibmw);
+
+int roce5_port_immutable_compat(struct ib_device *ibdev, u8 port_num,
+ struct ib_port_immutable *immutable);
+int roce5_port_immutable(struct ib_device *ibdev, u32 port_num,
+ struct ib_port_immutable *immutable);
+int roce5_query_device_status(struct ib_device *ibdev, int *dev_status);
+
+int roce5_init_sysfs(struct roce5_device *rdev);
+void roce5_remove_sysfs(struct roce5_device *rdev);
+
+struct net_device *roce5_ib_get_netdev_compat(struct ib_device *ibdev,
+ u8 port_num);
+struct net_device *roce5_ib_get_netdev(struct ib_device *ibdev, u32 port_num);
+
+void roce5_async_event(void *svc_hd, u8 event_type, u8 *val);
+u8 roce5_async_event_level(void *svc_hd, u8 event_type, u8 *val);
+void roce5_ifconfig_up_down_event_report(struct roce5_device *rdev,
+ u8 net_event);
+int roce5_register_netdev_notifier(void);
+void roce5_unregister_netdev_notifier(void);
+void roce5_clean_vlan_device_mac(struct roce5_device *rdev);
+void roce5_clean_real_device_mac(struct roce5_device *rdev);
+
+int roce5_ib_add_gid(const struct ib_gid_attr *attr,
+ __always_unused void **context);
+
+int roce5_ib_del_gid(const struct ib_gid_attr *attr,
+ __always_unused void **context);
+
+/* OFA - OpenFabrics Alliance */
+struct ib_pd *roce5_alloc_pd_ofa(struct ib_device *ibdev,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata);
+
+int roce5_dealloc_pd_ofa(struct ib_pd *ibpd);
+
+struct ib_srq *roce5_create_srq_ofa(struct ib_pd *ibpd,
+ struct ib_srq_init_attr *init_attr,
+ struct ib_udata *udata);
+
+struct ib_ucontext *roce5_alloc_ucontext_ofa(struct ib_device *ibdev,
+ struct ib_udata *udata);
+
+int roce5_dealloc_ucontext_ofa(struct ib_ucontext *ibcontext);
+
+struct ib_xrcd *roce5_alloc_xrcd_ofa(struct ib_device *ibdev,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata);
+
+int roce5_dealloc_xrcd_ofa(struct ib_xrcd *ibxrcd);
+
+int roce5_destroy_srq_ofa(struct ib_srq *ibsrq);
+
+int roce5_post_srq_recv_ofa(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr);
+
+int roce5_post_recv_ofa(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr);
+
+struct ib_cq *roce5_create_cq_ofa(struct ib_device *ibdev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *ibcontext,
+ struct ib_udata *udata);
+
+int roce5_destroy_cq_ofa(struct ib_cq *ibcq);
+
+struct ib_ah *roce5_create_ah_ofa(struct ib_pd *pd,
+ struct rdma_ah_attr *ah_attr,
+ struct ib_udata *udata);
+
+int roce5_destroy_ah_ofa(struct ib_ah *ibah);
+
+struct ib_mw *roce5_alloc_mw_ofa(struct ib_pd *ibpd, enum ib_mw_type type,
+ struct ib_udata *udata);
+
+int roce5_dealloc_mw_ofa(struct ib_mw *ibmw);
+
+int roce5_dereg_mr_ofa(struct ib_mr *ibmr);
+
+int roce5_destroy_qp_ofa(struct ib_qp *ibqp);
+
+int roce5_ib_add_gid_ofa(const union ib_gid *gid,
+ const struct ib_gid_attr *attr,
+ __always_unused void **context);
+
+int roce5_g_rdev_add(struct roce5_device *rdev);
+
+void roce5_g_rdev_remove(struct roce5_device *rdev);
+
+struct roce5_device *roce5_get_rdev_by_card_func_id(uint64_t card_id,
+ uint16_t func_id);
+
+struct roce5_device *roce5_get_rdev_by_name(const char *dev_name);
+
+#endif //ROCE_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_compat.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_compat.h
new file mode 100644
index 000000000..da2b4f65a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_compat.h
@@ -0,0 +1,87 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_COMPAT_H
+#define ROCE_COMPAT_H
+
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#define ROCE_LIKELY(x) likely(x)
+
+#define ROCE_UNLIKELY(x) unlikely(x)
+
+static inline u32 roce_ilog2(u32 n)
+{
+ return ilog2(n);
+}
+#define ROCE_ILOG2(n) roce_ilog2(n)
+
+static inline u32 roce_roundup_pow_of_two(u32 n)
+{
+ return roundup_pow_of_two(n);
+}
+#define ROCE_ROUNDUP_POW_OF_TWO(n) roce_roundup_pow_of_two(n)
+
+#ifndef _lint
+#define ROCE_MDELAY(n) mdelay(n)
+#define ROCE_UDELAY(n) udelay(n)
+#else
+#define ROCE_MDELAY(n) ((void)n)
+#define ROCE_UDELAY(n) ((void)n)
+#endif
+
+#define US_PERF_DELAY 100
+#define ROCE_DELAY() ROCE_UDELAY(US_PERF_DELAY)
+
+#define ROCE_ALIGN(a, b) ALIGN(a, b)
+#define ROCE_MAX(a, b) max(a, b)
+#define ROCE_MIN(a, b) min(a, b)
+#define ROCE_DIV_ROUND_UP(a, b) DIV_ROUND_UP(a, b)
+#define ROCE_FLS(n) fls(n)
+
+#define ROCE_MEMCMP(a, b, count) memcmp(a, b, count)
+#define ROCE_IO_MAPPING_MAP_WC(mapping, offset) \
+ io_mapping_map_wc(mapping, offset)
+#define ROCE_IOREMAP(phys_addr, size) ioremap(phys_addr, size)
+#define ROCE_IOUNMAP(addr) iounmap(addr)
+#define ROCE_IO_MAPPING_UNMAP(vaddr) io_mapping_unmap(vaddr)
+
+#ifndef wc_wmb
+
+#if defined(__i386__)
+#define wc_wmb() asm volatile("lock; addl $0,0(%%esp) " ::: "memory")
+#elif defined(__x86_64__)
+#define wc_wmb() asm volatile("sfence" ::: "memory")
+#elif defined(__ia64__)
+#define wc_wmb() asm volatile("fwb" ::: "memory")
+#else
+#define wc_wmb() wmb()
+#endif
+
+#endif
+
+typedef struct tag_roce_verbs_cmd_com {
+ union {
+ u32 value;
+
+ struct {
+ u32 version : 8;
+ u32 rsvd : 8;
+ u32 cmd_bitmask : 16; //CMD_TYPE_BITMASK_E
+ } bs;
+ } dw0;
+
+ u32 index; //qpn/cqn/srqn/mpt_index/gid idx
+} roce_verbs_cmd_com_s;
+
+typedef struct tag_roce_xq_mtt_info {
+ u32 mtt_flags; /* Indicates whether to kick out cache. by queue (0) or VF(1). */
+ u32 mtt_num; /* Number of cmtt, which needs to be assigned by the driver when the is kicked out by queue. */
+ u32 mtt_cache_line_start; /* The driver needs to read the driver from the configuration file. */
+ u32 mtt_cache_line_end; /* The driver needs to read the driver from the configuration file. */
+ u32 mtt_cache_line_size; /* 0:256B,1:512B */
+} roce_xq_mtt_info_s;
+
+#endif //ROCE_COMPAT_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_event_extension.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_event_extension.h
new file mode 100644
index 000000000..649a4275b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_event_extension.h
@@ -0,0 +1,17 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+
+
+#ifndef ROCE_EVENT_EXTENSION_H
+#define ROCE_EVENT_EXTENSION_H
+
+#include "roce.h"
+#include "roce_event.h"
+
+int to_unkown_event_str_index(uint8_t event_type, const uint8_t *val);
+void roce5_event_report_extend(const struct roce5_device *rdev, u8 *val,
+ int event_str_index);
+int roce5_async_event_handle_extend(u8 event_type, u8 *val,
+ struct roce5_device *rdev);
+
+#endif /* ROCE_EVENT_EXTENSION_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_gid.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_gid.h
new file mode 100644
index 000000000..54cfc7bf6
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_gid.h
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+
+
+#ifndef ROCE_GID_H
+#define ROCE_GID_H
+
+#include <linux/types.h>
+
+struct rdma_gid_entry {
+ union {
+ u8 raw[16];
+ struct {
+ __be64 subnet_prefix;
+ __be64 interface_id;
+ } global;
+ };
+ union {
+ struct {
+ u32 rsvd : 8;
+ u32 cvlan : 12; /* in layer vlan customer vlan */
+ u32 svlan : 12; /* outside layer vlan */
+ } bs;
+ u32 value;
+ } dw4;
+
+ union {
+ u32 hdr_len_value;
+ };
+
+ union {
+ struct {
+ u16 tag : 2; /* 0: no has vlan; 1: one layer vlan; 2: 2 layer vlan; 3: stag */
+ u16 tunnel : 1; // rsvd for ppe, don't use. 'tunnel'
+ u16 gid_type : 2;
+ u16 ppe_rsvd1 : 1;
+ u16 outer_tag : 2; // rsvd for ppe, don't use. 'outer_tag'
+ u16 ppe_rsvd3 : 1; // rsvd for ppe, don't use. 'stag'
+ u16 gid_update : 1;
+ u16 rsvd : 6;
+ } bs;
+ u16 value;
+ } dw6_h;
+
+ u8 smac[6];
+};
+
+#endif // ROCE_GID_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_infra.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_infra.h
new file mode 100644
index 000000000..b055d5c92
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_infra.h
@@ -0,0 +1,77 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
+
+
+#ifndef ROCE_INFRA_H
+#define ROCE_INFRA_H
+
+#include <linux/kern_levels.h>
+#include <linux/sched.h>
+
+#define ROCE_INFO(format, ...) \
+ printk(KERN_INFO "[ROCE, INFO][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_WARN(format, ...) \
+ printk(KERN_WARNING "[ROCE, WARN][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_ERR(format, ...) \
+ printk(KERN_ERR "[ROCE, ERR][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+
+#define ROCE_INFO_LIMIT(format, ...) \
+ printk_ratelimited(KERN_INFO "[ROCE, INFO][tid:%x][%s,%d]:" format \
+ "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_WARN_LIMIT(format, ...) \
+ printk_ratelimited(KERN_WARNING "[ROCE, WARN][tid:%x][%s,%d]:" format \
+ "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_ERR_LIMIT(format, ...) \
+ printk_ratelimited(KERN_ERR "[ROCE, ERR][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+
+#define ROCE_INFO_ONCE(format, ...) \
+ printk_once(KERN_INFO "[ROCE, INFO][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_WARN_ONCE(format, ...) \
+ printk_once(KERN_WARNING "[ROCE, WARN][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_ERR_ONCE(format, ...) \
+ printk_once(KERN_ERR "[ROCE, ERR][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+
+/* Importent, ensure dev is not null pointer when using ROCE_DEV_XXX() !!! */
+#define ROCE_DEV_INFO(dev, format, ...) \
+ dev_info((dev)->hwdev_hdl, "[ROCE, INFO][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_DEV_WARN(dev, format, ...) \
+ dev_warn((dev)->hwdev_hdl, "[ROCE, WARN][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_DEV_ERR(dev, format, ...) \
+ dev_err((dev)->hwdev_hdl, "[ROCE, ERR][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+
+#define ROCE_DEV_INFO_LIMIT(dev, format, ...) \
+ dev_info_ratelimited((dev)->hwdev_hdl, \
+ "[ROCE, INFO][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_DEV_WARN_LIMIT(dev, format, ...) \
+ dev_warn_ratelimited((dev)->hwdev_hdl, \
+ "[ROCE, WARN][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+#define ROCE_DEV_ERR_LIMIT(dev, format, ...) \
+ dev_err_ratelimited((dev)->hwdev_hdl, \
+ "[ROCE, ERR][tid:%x][%s,%d]:" format "\n", \
+ current->pid, __func__, __LINE__, ##__VA_ARGS__)
+
+#define ROCE_PRINT_GID(dev, raw, format, ...) \
+ ROCE_DEV_WARN( \
+ (dev), \
+ "gid:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x==>" format, \
+ *((u16 *)(raw) + IP_INDEX_0), *((u16 *)(raw) + IP_INDEX_1), \
+ *((u16 *)(raw) + IP_INDEX_2), *((u16 *)(raw) + IP_INDEX_3), \
+ *((u16 *)(raw) + IP_INDEX_4), *((u16 *)(raw) + IP_INDEX_5), \
+ *((u16 *)(raw) + IP_INDEX_6), *((u16 *)(raw) + IP_INDEX_7), \
+ ##__VA_ARGS__)
+
+#endif //ROCE_INFRA_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_kernel_compat_gen.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_kernel_compat_gen.h
new file mode 100644
index 000000000..b1bca23b0
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_kernel_compat_gen.h
@@ -0,0 +1,6 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_KERNEL_COMPAT_GEN_H
+#define ROCE_KERNEL_COMPAT_GEN_H
+#endif /* ROCE_KERNEL_COMPAT_GEN_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_main_extension.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_main_extension.h
new file mode 100644
index 000000000..2244bb236
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_main_extension.h
@@ -0,0 +1,77 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_MAIN_EXTENSION_H
+#define ROCE_MAIN_EXTENSION_H
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "hinic5_crm.h"
+#include "hinic5_lld.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce.h"
+#include "roce_mix.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_qp.h"
+#include "roce_dfx.h"
+#include "roce_cmd.h"
+#include "roce_user.h"
+#include "rdma_comp.h"
+#ifdef ROCE_CHIP_TEST
+#include "roce_main_chip_ext.h"
+#endif
+
+#define ROCE_MAX_WQES_COMPUTE (4 * K_UNIT - 1)
+#define RDMA_MAX_SQ_DESC_SZ_COMPUTE 512
+#define ROCE_MAX_SQ_INLINE_DATA_SZ_COMPUTE 448
+
+#define ROCE5_ULP_CMD(rdev, bitmask) \
+ (((rdev)->is_vroce) ? (VERBS_CMD_TYPE_VROCE_BITMASK) : (bitmask))
+
+static inline u64 roce5_get_uverbs_cmd_mask(void)
+{
+ u64 mask = 0;
+ mask |= ROCE_UVERBS_CMD_BASE_MASK;
+#ifdef ROCE_CHIP_TEST
+ mask |= ROCE_UVERBS_CMD_EXT_MASK;
+#endif
+ return mask;
+}
+
+struct hinic5_uld_info *roce5_info_get(void);
+
+void roce5_service_init_pre(void);
+
+void roce5_lock_rdev(void);
+
+void roce5_unlock_rdev(void);
+
+int roce5_get_rdev_by_uld(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ struct roce5_device **rdev,
+ struct hinic5_event_info *event);
+
+void roce5_init_dev_ext_handlers(struct roce5_device *rdev);
+
+int roce5_board_cfg_check(struct roce5_device *rdev);
+
+void roce5_remove_clean_res_ext(struct roce5_device *rdev);
+
+int roce5_set_comm_event(const struct roce5_device *rdev,
+ const struct hinic5_event_info *event);
+
+void *roce5_rdev_alloc_ext(void);
+
+void roce5_fill_gid_entry_ext(const struct roce5_device *rdev,
+ struct rdma_gid_entry *gid_entry);
+
+void roce5_cfg_info_update_ext(struct roce5_device *rdev,
+ roce_get_cfg_info_resp_s *resp);
+
+int roce5_add_check_ext(const struct hinic5_lld_dev *lld_dev);
+
+#endif /* ROCE_MAIN_EXTENSION_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_mr_extension.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_mr_extension.h
new file mode 100644
index 000000000..ff0464a31
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_mr_extension.h
@@ -0,0 +1,14 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_MR_EXTEND_H
+#define ROCE_MR_EXTEND_H
+
+#include <rdma/ib_verbs.h>
+#include "roce.h"
+
+int roce5_check_alloc_mr_type(enum ib_mr_type mr_type);
+enum rdma_mr_type roce5_get_mrtype(enum ib_mr_type ib_mr_type);
+
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_os_compat.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_os_compat.h
new file mode 100644
index 000000000..6b8a3113a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_os_compat.h
@@ -0,0 +1,237 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_OS_COMPAT_H
+#define ROCE_OS_COMPAT_H
+#include <rdma/ib_verbs.h>
+#include "roce.h"
+#include "roce_restore.h"
+#include "roce_verbs_compat.h"
+#include "roce_kernel_compat_gen.h"
+#if defined(UVERBS_IOCTL_HAVE_RDMA_UDATA_TO_DRV_CONTEXT)
+#include <rdma/uverbs_ioctl.h>
+#endif
+
+#define PAGE_SIZE_4KB (1ULL << PAGE_SHIFT_4KB)
+#define PAGE_SIZE_64KB (1ULL << PAGE_SHIFT_64KB)
+#define PAGE_SIZE_2MB (1ULL << PAGE_SHIFT_2MB)
+
+#define BIT_NUM_PER_BYTE (8)
+#define PAGE_SHIFT_4KB (12)
+#define PAGE_SHIFT_64KB (16)
+#define PAGE_SHIFT_2MB (21)
+
+#if !defined(HAVE_IB_UMEM_NUM_DMA_BLOCKS)
+static inline size_t ib_umem_num_dma_blocks(struct ib_umem *umem,
+ unsigned long pgsz)
+{
+ return (size_t)((ALIGN(umem->address + umem->length, pgsz) -
+ ALIGN_DOWN(umem->address, pgsz))) /
+ pgsz;
+}
+#endif
+
+#if !defined(HAVE_RDMA_UMEM_FOR_EACH_DMA_BLOCK)
+#define rdma_umem_for_each_dma_block(umem, biter, pgsz) \
+ for (__rdma_umem_block_iter_start(biter, umem, pgsz); \
+ __rdma_block_iter_next(biter);)
+
+static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
+ struct ib_umem *umem,
+ unsigned long pgsz)
+{
+ __rdma_block_iter_start(biter, umem->sg_head.sgl, umem->nmap, pgsz);
+}
+static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
+{
+ return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
+}
+#endif
+
+#if defined(IB_UMEM_NEED_IB_UMEM_FIND_BEST_PGSZ)
+static inline unsigned int rdma_find_pg_bit(unsigned long addr,
+ unsigned long pgsz_bitmap)
+{
+ unsigned long align;
+ unsigned long pgsz;
+
+ align = addr & -addr;
+
+ pgsz = pgsz_bitmap & ~(-align << 1);
+ if (!pgsz)
+ return __ffs(pgsz_bitmap);
+
+ return __fls(pgsz);
+}
+
+static inline unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
+ unsigned long pgsz_bitmap,
+ unsigned long virt)
+{
+ struct scatterlist *sg;
+ unsigned int best_pg_bit;
+ unsigned long va, pgoff;
+ dma_addr_t mask;
+ int i;
+
+ if (WARN_ON(!(pgsz_bitmap & GENMASK(PAGE_SHIFT, 0))))
+ return 0;
+
+ va = virt;
+ mask = roundup_pow_of_two(umem->length);
+ pgoff = umem->address & ~PAGE_MASK;
+
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) {
+ mask |= (sg_dma_address(sg) + pgoff) ^ va;
+ if (i && i != (umem->nmap - 1))
+ mask |= sg_dma_len(sg);
+ va += sg_dma_len(sg) - pgoff;
+ pgoff = 0;
+ }
+ best_pg_bit = rdma_find_pg_bit(mask, pgsz_bitmap);
+
+ return BIT_ULL(best_pg_bit);
+}
+#endif
+
+static inline u32 roce5_umem_get_page_count(struct ib_umem *umem)
+{
+#if defined(HAVE_IB_UMEM_PAGE_COUNT)
+ return (u32)ib_umem_page_count(umem);
+#elif defined(HAVE_IB_UMEM_NUM_PAGES)
+ return (u32)ib_umem_num_pages(umem);
+#endif
+}
+
+static inline u32 roce5_umem_get_page_shift(struct ib_umem *umem)
+{
+#if defined(UMEM_HAVE_PAGE_SHIFT)
+ return umem->page_shift;
+#else
+ return PAGE_SHIFT;
+#endif
+}
+
+static inline u32 roce5_umem_get_page_size(struct ib_umem *umem)
+{
+#if defined(UMEM_HAVE_PAGE_SHIFT)
+ return BIT((unsigned int)umem->page_shift);
+#else
+ return PAGE_SIZE;
+#endif
+}
+
+static inline u32 roce5_get_page_size(struct roce5_device *rdev, bool use_huge)
+{
+ if (use_huge && rdev->huge_page_en) {
+ return PAGE_SIZE_2MB;
+ }
+ return PAGE_SIZE;
+}
+
+static inline size_t roce5_get_page_size_cap(size_t page_size_cap,
+ size_t length)
+{
+ size_t max_shift;
+
+ if (length == 0) {
+ return 0;
+ }
+
+ max_shift = fls_long(length) - 1;
+ if (max_shift == sizeof(size_t) * BIT_NUM_PER_BYTE - 1)
+ return page_size_cap;
+ else
+ return page_size_cap & (((size_t)1 << (max_shift + 1)) - 1);
+}
+
+static inline u32 roce5_umem_get_buf_page_shift(struct roce5_device *rdev,
+ struct ib_umem *umem,
+ u64 buf_addr)
+{
+ u32 real_page_size_cap, page_shift;
+
+ real_page_size_cap = (u32)roce5_get_page_size_cap(
+ (size_t)rdev->rdma_cap.page_size_cap, umem->length);
+
+ if (rdev->huge_page_en) {
+ page_shift = (u32)order_base_2(ib_umem_find_best_pgsz(
+ umem, real_page_size_cap, buf_addr));
+ } else {
+ page_shift = roce5_umem_get_page_shift(umem);
+ }
+
+ return page_shift;
+}
+
+static inline u32 roce5_umem_get_mtt_npages(struct roce5_device *rdev,
+ struct ib_umem *umem,
+ u32 page_shift)
+{
+ u32 npages;
+
+ if (rdev->huge_page_en) {
+ npages = ib_umem_num_dma_blocks(umem, BIT(page_shift));
+ } else {
+ npages = roce5_umem_get_page_count(umem);
+ }
+
+ return npages;
+}
+
+/* These APIs can be reused by different OSs */
+static inline struct ib_umem *roce5_umem_get(struct ib_device *ibdev,
+ struct ib_ucontext *context,
+ unsigned long addr, size_t size,
+ int access, int dmasync)
+{
+#if (!defined(IB_UMEM_GET_HAVE_IB_UCONTEXT) && \
+ !defined(MMU_INTERVAL_NOTIFIER)) || \
+ (!defined(IB_UMEM_GET_HAVE_IB_UCONTEXT) && \
+ !defined(IB_UMEM_GET_HAVE_IB_DEVICE))
+ struct uverbs_attr_bundle *attrs;
+#endif
+
+#if (!defined(IB_UMEM_GET_HAVE_IB_UCONTEXT) && \
+ !defined(MMU_INTERVAL_NOTIFIER)) || \
+ (!defined(IB_UMEM_GET_HAVE_IB_UCONTEXT) && \
+ !defined(IB_UMEM_GET_HAVE_IB_DEVICE))
+ attrs = container_of(&context, struct uverbs_attr_bundle, context);
+#endif
+
+#if defined(IB_UMEM_GET_HAVE_IB_UCONTEXT)
+ return ib_umem_get(context, addr, size, access, dmasync);
+#elif defined(IB_UMEM_GET_HAVE_IB_DEVICE) && defined(MMU_INTERVAL_NOTIFIER)
+ return ib_umem_get(ibdev, addr, size, access);
+#elif defined(IB_UMEM_GET_HAVE_DMASYNC)
+ return ib_umem_get(&attrs->driver_udata, addr, size, access, dmasync);
+#else
+ return ib_umem_get(&attrs->driver_udata, addr, size, access);
+#endif
+}
+
+#if defined(IB_UMEM_GET_PEER)
+static inline struct ib_umem *
+roce5_mr_umem_get_peer(struct roce5_device *rdev, size_t length, int access,
+ u64 addr, struct ib_udata *udata, bool use_huge)
+{
+ u64 page_size = PAGE_SIZE;
+ size_t buf_size = length;
+
+ page_size = roce5_get_page_size(rdev, use_huge);
+ buf_size = (size_t)ROCE_ALIGN(buf_size, page_size);
+
+#if defined(IB_UMEM_GET_PEER_HAVE_IBDEVICE) && defined(MMU_INTERVAL_NOTIFIER)
+ return ib_umem_get_peer(&rdev->ib_dev, addr, buf_size, access,
+ (IB_PEER_MEM_ALLOW | IB_PEER_MEM_INVAL_SUPP));
+#else
+ return ib_umem_get_peer(udata, addr, buf_size, access,
+ (IB_PEER_MEM_ALLOW | IB_PEER_MEM_INVAL_SUPP));
+#endif
+}
+#endif
+
+struct roce5_ucontext *
+roce5_queue_to_ucontext(void *ibq, struct ib_udata *udata, int q_type);
+
+#endif
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_qp_extension.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_qp_extension.h
new file mode 100644
index 000000000..2cbcd5d71
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_qp_extension.h
@@ -0,0 +1,61 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_QP_EXTENSION_H
+#define ROCE_QP_EXTENSION_H
+
+#include <rdma/ib_verbs.h>
+
+#include "roce_qp.h"
+#include "roce_qp_exp.h"
+
+int to_roce5_qp_type(enum ib_qp_type qp_type);
+
+bool roce5_check_qp_modify_ok(enum ib_qp_state cur_state,
+ enum ib_qp_state next_state, enum ib_qp_type type,
+ enum ib_qp_attr_mask mask,
+ enum rdma_link_layer ll);
+
+int roce5_is_qp_normal(struct roce5_qp *rqp, struct ib_qp_init_attr *init_attr);
+
+void roce5_set_qp_dif_attr(struct roce5_qp *rqp,
+ const struct ib_qp_init_attr *init_attr,
+ const struct roce5_device *rdev);
+
+#ifdef ROCE_EXTEND
+
+#define ROCE_QP_VBS_FLAG (1U << 22)
+#define ROCE_QP_OSD_FLAG (1U << 23)
+#define QPC_ROCE_VBS_QPC_OFFSET_FOR_SQPC 204800 //200K
+
+struct roce5_set_qp_ext_attr_cmd {
+ u32 qpn;
+ u32 attr_mask;
+};
+
+struct roce5_modify_qp_vbs_cmd {
+ u32 qpn;
+ u64 ci_record_addr;
+};
+
+struct roce5_vbs_qp {
+ cqm_qpc_mpt_s *vbs_sqpc_info; /* vbs private data */
+ struct roce5_db db; /* to record ci_record_pa */
+};
+
+long roce5_vbs_create_sqpc(struct roce5_device *rdev, void *buf);
+#endif
+
+void roce5_destroy_pcqc_ext(struct roce5_qp *rqp);
+int roce5_modify_qp_pre_ext(struct roce5_device *rdev, struct roce5_qp *rqp,
+ struct ib_qp_attr *attr, int attr_mask,
+ struct ib_udata *udata);
+void roce5_set_attr_ext(struct roce5_qp *rqp, const struct ib_qp_attr *attr,
+ roce_verbs_qp_attr_s *qp_attr, int attr_mask);
+void roce5_transmit_ci_record_addr_ext(struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr);
+void roce5_cos_update_ext(struct roce5_device *rdev, u8 *cos,
+ enum ib_qp_type qp_type);
+
+#endif /* ROCE_QP_EXTENSION_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_restore.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_restore.h
new file mode 100644
index 000000000..c772472a6
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_restore.h
@@ -0,0 +1,88 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_RESTORE_H
+#define ROCE_RESTORE_H
+#include <rdma/ib_verbs.h>
+
+#include "roce.h"
+#include "roce_qp.h"
+#include "roce_srq.h"
+#include "roce_cq.h"
+#include "roce_mr.h"
+#include "roce_mix.h"
+#include "roce_pd.h"
+#include "roce_xrc.h"
+#include "hinic5_cqm.h"
+
+static inline struct roce5_device *to_roce5_dev(const struct ib_device *ibdev)
+{
+ return container_of(ibdev, struct roce5_device, ib_dev);
+}
+
+static inline struct roce5_ucontext *
+to_roce5_ucontext(const struct ib_ucontext *ibucontext)
+{
+ return container_of(ibucontext, struct roce5_ucontext, ibucontext);
+}
+
+static inline struct roce5_qp *to_roce5_qp(const struct ib_qp *ibqp)
+{
+ return container_of(ibqp, struct roce5_qp, ibqp);
+}
+
+static inline struct roce5_qp *cqmobj_to_roce_qp(const cqm_object_s *object)
+{
+ cqm_qpc_mpt_s *qpc_info = NULL;
+ qpc_info = container_of(object, cqm_qpc_mpt_s, object);
+ return (struct roce5_qp *)qpc_info->priv;
+}
+
+static inline struct roce5_srq *to_roce5_srq(const struct ib_srq *ibsrq)
+{
+ return container_of(ibsrq, struct roce5_srq, ibsrq);
+}
+
+static inline struct roce5_srq *cqmobj_to_roce5_srq(const cqm_object_s *object)
+{
+ cqm_queue_s *cqm_srq = NULL;
+ cqm_srq = container_of(object, cqm_queue_s, object);
+ return (struct roce5_srq *)cqm_srq->priv;
+}
+
+static inline struct roce5_cq *to_roce5_cq(const struct ib_cq *ibcq)
+{
+ return container_of(ibcq, struct roce5_cq, ibcq);
+}
+
+static inline struct roce5_mr *to_roce5_mr(const struct ib_mr *ibmr)
+{
+ return container_of(ibmr, struct roce5_mr, ibmr);
+}
+
+static inline struct roce5_mw *to_roce5_mw(const struct ib_mw *ibmw)
+{
+ return container_of(ibmw, struct roce5_mw, ibmw);
+}
+
+static inline struct roce5_mr *
+rdma_mr_to_roce5_mr(const struct hmm_rdma *rdmamr)
+{
+ return container_of(rdmamr, struct roce5_mr, rdmamr);
+}
+
+static inline struct roce5_ah *to_roce5_ah(const struct ib_ah *ibah)
+{
+ return container_of(ibah, struct roce5_ah, ibah);
+}
+
+static inline struct roce5_pd *to_roce5_pd(const struct ib_pd *ibpd)
+{
+ return container_of(ibpd, struct roce5_pd, ibpd);
+}
+
+static inline struct roce5_xrcd *to_roce5_xrcd(const struct ib_xrcd *ibxrcd)
+{
+ return container_of(ibxrcd, struct roce5_xrcd, ibxrcd);
+}
+#endif
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_srq_extension.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_srq_extension.h
new file mode 100644
index 000000000..b931f9426
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_srq_extension.h
@@ -0,0 +1,38 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_SRQ_EXTENSION_H
+#define ROCE_SRQ_EXTENSION_H
+
+#include <linux/types.h>
+#include "roce_srq.h"
+
+/**
+ * container_mode:
+ * mode: 0 -> container_size: 16
+ * mode: 1 -> container_size: 8
+ * mode: 2 -> container_size: 4
+ * mode: 3 -> container_size: 2
+ */
+enum roce5_srq_mode {
+ ROCE_SRQ_MODE_0 = 0,
+ ROCE_SRQ_MODE_1,
+ ROCE_SRQ_MODE_2,
+ ROCE_SRQ_MODE_3
+};
+
+enum roce5_srq_cont_num_mode {
+ ROCE_SRQ_CONT_NUM_MODE3 = 2,
+ ROCE_SRQ_CONT_NUM_MODE2 = 4,
+ ROCE_SRQ_CONT_NUM_MODE1 = 8,
+ ROCE_SRQ_CONT_NUM_MODE0 = 16
+};
+
+u8 roce5_get_container_sz(u32 container_mode);
+u8 roce5_calculate_cont_th(u32 srq_limit);
+void roce5_srq_container_init(struct ib_srq_init_attr *init_attr,
+ struct roce5_srq *rsrq,
+ struct roce5_device *rdev);
+
+#endif /* ROCE_SRQ_EXTENSION_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_user.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_user.h
new file mode 100644
index 000000000..81effef16
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_user.h
@@ -0,0 +1,100 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_USER_H
+#define ROCE_USER_H
+
+#include <linux/types.h>
+
+struct roce5_alloc_ucontext_resp {
+ uint32_t num_qps; /* the maximum of qps */
+ uint32_t num_xsrqs; /* the maximum of xsrqs */
+ uint32_t cqe_size; /* the cqe entry size that device support, the valid value is 32B or 64B; */
+ uint32_t wqebb_size; /* the wqebb entry size that device support, the valid value is 64B or 128B */
+ uint32_t dwqe_size; /* the direct maximum wqe size that device support, 256B */
+ uint32_t max_msg_size; /* the maximum message size that device support, (2G -1)B */
+ uint32_t max_comp_vector; /* the maximum completion vector */
+ uint32_t max_inline_size; /* the maximum of qp inline size that device support */
+ uint32_t dev_caps;
+ uint8_t phy_port;
+ uint8_t storage_aa_en;
+ uint16_t func_id;
+ uint64_t card_id;
+ uint16_t db_offset;
+ uint16_t dwqe_offset;
+ struct {
+ uint16_t pcie_atomic_en : 1;
+ uint16_t rsvd1 : 15;
+ };
+ uint8_t srq_container_en;
+ uint8_t srq_container_mode;
+ uint8_t xrc_srq_container_mode;
+ uint8_t warn_th;
+ uint8_t huge_page_en;
+ uint8_t rsvd;
+ uint8_t max_send_sge; /* the maximum of sq sge */
+ uint8_t max_recv_sge; /* the maximum of rq sge */
+ uint32_t max_sq_wqe_len; /* the maximum sq wqe length that device support */
+ uint64_t roce_user_ext_ability;
+ uint64_t roce_uld_ext_ability;
+};
+
+struct roce5_create_cq_cmd {
+ u64 buf_addr;
+ u64 db_addr;
+};
+
+struct roce5_resize_cq_cmd {
+ u64 buf_addr; /* resize cq's 'buf va */
+ u64 stage; /* describe the resize stage,0 or 1; */
+};
+
+struct roce5_create_srq_cmd {
+ u64 buf_addr;
+ u64 db_addr;
+ u32 rsvd;
+};
+
+struct create_qp_cmd {
+ u64 buf_addr; /* describe the qp buf address that used to store cqe; */
+ u64 db_addr; /* describe the qp sw db address */
+ u32 comp_mask; /* kernel can judge whether handle receive inline through comp_mask */
+ u8 log_sq_bb_count; /* wqebb number = 2 << log_sq_bb_count */
+ u8 log_sq_stride; /* wqebb size = 2 << log_sq_stride */
+ u16 reserved; /* reserved is used to aligned cmd */
+};
+
+struct roce5_modify_srq_cmd {
+ u8 container_flag;
+ u8 container_warn_th;
+ u16 rsvd;
+};
+
+struct roce5_reg_frmr_cmd {
+ u64 pbl_vaddr;
+};
+
+struct roce5_modify_qp_ex_resp_data {
+ u8 is_cos_valid;
+ u8 cos;
+ u8 is_ssn_valid;
+ u8 rsvd0;
+ u32 ssn;
+ u32 rsvd[6];
+#ifdef ROCE_LATENCY_PROF_EN
+ uint8_t latency_prof_en;
+ uint8_t rsvd1[3];
+ uint32_t frequency_reduction_ratio;
+ uint64_t non_ptp_time_diff;
+#endif
+};
+
+struct roce5_create_ah_resp {
+ u8 dmac[ETH_ALEN];
+ u16 vlan_id;
+ u8 cos;
+ u8 rsvd[3];
+};
+
+#endif //ROCE_USER_H
diff --git a/drivers/infiniband/hw/hiroce5/kernel/include/roce_verbs_compat.h b/drivers/infiniband/hw/hiroce5/kernel/include/roce_verbs_compat.h
new file mode 100644
index 000000000..cd87856ea
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/include/roce_verbs_compat.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_VERBS_COMPAT_H
+#define ROCE_VERBS_COMPAT_H
+
+#include <rdma/ib_verbs.h>
+#include "roce_kernel_compat_gen.h"
+
+enum { ROCE_Q_TYPE_QP, ROCE_Q_TYPE_SRQ, ROCE_Q_TYPE_CQ };
+
+#if !defined(HAVE_RDMA_AH_INIT_ATTR)
+/* kernel 4.19 not defined but kernel 5.10 defined, reused for ah creating */
+struct rdma_ah_init_attr {
+ struct rdma_ah_attr *ah_attr;
+};
+
+enum ib_wr_opcode_compat {
+ IB_WR_REG_MR_INTEGRITY = IB_WR_REG_SIG_MR,
+};
+
+#endif
+
+#endif /* ROCE_VERBS_COMPAT_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond.h b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond.h
new file mode 100644
index 000000000..099b76a1a
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond.h
@@ -0,0 +1,79 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef ROCE_BOND_H
+#define ROCE_BOND_H
+
+#include <net/bonding.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_lld.h"
+#include "drv_bond_api.h"
+
+#include "roce.h"
+#include "roce_qp.h"
+#include "roce_cmd.h"
+
+#define ROCE_BOND_MIN_SLAVE 1
+#define ROCE_BOND_MAX_SLAVE BOND_PORT_MAX_NUM
+
+#define ROCE_BOND_RSVD_VLAN_ID 4095
+
+#define ROCE_BOND_FWD_ID_TBL_ALL_BITS 32U
+#define ROCE_BOND_FWD_ID_TBL_PER_BITS 3U
+#define ROCE_BOND_FWD_ID_TBL_PER_BITS_MASK 0x7U
+
+struct roce5_bond_slave {
+ struct net_device *netdev;
+ struct hinic5_lld_dev *lld_dev;
+ struct netdev_lag_lower_state_info netdev_state;
+ u32 update_cnt;
+ u16 func_id;
+ u8 er_id;
+};
+
+struct roce5_bond_transition_res {
+ struct hinic5_lld_dev *ppf_lld;
+};
+
+struct roce5_bond_device {
+ char name[IFNAMSIZ]; /* the name of nic bond device */
+ struct list_head entry;
+ struct hinic5_lld_dev *bond_lld_dev;
+ struct roce5_bond_slave slaves[ROCE_BOND_MAX_SLAVE];
+ struct mutex slave_lock; /* lock for slaves */
+ u32 slave_cnt;
+ atomic_t next_port;
+ struct work_struct detach_work;
+ struct roce5_device *attached_rdev;
+ struct bond_attr attr;
+ struct roce5_bond_transition_res transition_res;
+ u8 need_clean_on_remove;
+};
+
+bool roce5_bond_is_active(struct roce5_device *rdev);
+void roce5_bond_detach(struct roce5_device *rdev);
+struct net_device *roce5_bond_get_netdev(struct roce5_device *rdev);
+
+int roce5_add_bond_real_slave_mac(struct roce5_device *rdev, u8 *mac);
+int roce5_add_bond_vlan_slave_mac(struct roce5_device *rdev, u8 *mac,
+ u16 vlan_id);
+void roce5_del_bond_real_slave_mac(struct roce5_device *rdev);
+void roce5_del_bond_vlan_slave_mac(struct roce5_device *rdev, u8 *mac,
+ u16 vlan_id);
+
+void roce5_bond_rr_set_flow(struct roce5_device *rdev, struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr);
+
+int roce5_bond_event_cfg_rdev(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ struct roce5_device **rdev, bool hold_rdev);
+void roce5_handle_bonded_port_state_event(struct roce5_device *rdev);
+
+bool roce5_get_bond_ipsurx_en(void);
+void roce5_set_bond_ipsurx_en(bool ipsurx_en);
+
+int roce5_bond_attach(struct roce5_device *rdev);
+int roce5_bond_init(void);
+void roce5_bond_exit(void);
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_cfm.c b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_cfm.c
new file mode 100644
index 000000000..f295f241d
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_cfm.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifdef ROCE_BONDING_EN
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <net/bonding.h>
+
+#include "securec.h"
+
+#include "bond_common_defs.h"
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce_bond.h"
+#include "roce_bond_internal.h"
+#include "roce_cmd.h"
+#include "roce_mpu_cmd.h"
+#include "roce_netdev.h"
+#include "roce_infra.h"
+
+static int roce5_bond_check_slave_port(struct hinic5_lld_dev *lld_dev,
+ u8 slave_ports[], u8 slave_ports_num,
+ bool *result)
+{
+ int ret, i;
+ roce_bond_check_slave_port_req_s req = { 0 };
+ roce_bond_check_slave_port_rsp_s rsp = { 0 };
+ u16 out_size = (u16)sizeof(rsp);
+
+ for (i = 0; i < slave_ports_num; ++i) {
+ req.slave_ports[i] = slave_ports[i];
+ }
+ req.slave_ports_num = slave_ports_num;
+
+ ret = roce5_msg_to_mgmt_sync(lld_dev->hwdev,
+ ROCE_MPU_CMD_BOND_CHECK_SLAVE_PORT, &req,
+ sizeof(req), &rsp, &out_size);
+ if ((ret != 0) || (out_size == 0) || (rsp.head.status != 0)) {
+ ROCE_ERR(
+ "Failed to check slave port, ret(%d), out size(%u), status(%u)",
+ ret, out_size, rsp.head.status);
+ return -EINVAL;
+ }
+
+ *result = false;
+ for (i = 0; i < slave_ports_num; ++i) {
+ *result |= (rsp.slave_ports_result[i] != false) ? true : false;
+ }
+
+ return 0;
+}
+
+/*
+ * roce5_can_do_bond - Check if RoCE can attach to bond device
+ * @bond: bond device to check
+ * Return: true if can attach, false otherwise
+ */
+bool roce5_can_do_bond(struct bonding *bond)
+{
+ bool ret = false;
+ int slave_cnt = 0;
+ int err;
+ struct slave *slave = NULL;
+ struct list_head *iter = NULL;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ char chip_name[IFNAMSIZ] = { 0 };
+ u8 slave_ports[ROCE_BOND_PORT_MAX_NUM];
+ bool result;
+
+ if (bond == NULL) {
+ ROCE_ERR("Invalid Parameter, ptr is NULL.");
+ return false;
+ }
+
+ if (roce5_bond_mode_is_supported(bond->params.mode) == false) {
+ ROCE_ERR("Invalid bond mode(%u).", bond->params.mode);
+ return false;
+ }
+
+ rcu_read_lock();
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ lld_dev = hinic5_get_lld_dev_by_netdev(slave->dev);
+ if (lld_dev == NULL) {
+ goto out;
+ }
+
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
+ ROCE_WARN("VF device %s skipped", slave->dev->name);
+ continue;
+ }
+
+ err = roce5_bond_slave_check(lld_dev, chip_name,
+ sizeof(chip_name));
+ if (err != 0) {
+ ROCE_ERR("Bond slave check err %d.", err);
+ goto out;
+ }
+
+ if (slave_cnt < ROCE_BOND_PORT_MAX_NUM) {
+ slave_ports[slave_cnt] =
+ hinic5_physical_port_id(lld_dev->hwdev);
+ }
+
+ slave_cnt++;
+ ROCE_INFO("can do bond? slave_cnt(%d), slave_name(%s).",
+ slave_cnt, slave->dev->name);
+ }
+
+ if (((slave_cnt >= ROCE_BOND_MIN_SLAVE) &&
+ (slave_cnt <= ROCE_BOND_MAX_SLAVE)) == false) {
+ goto out;
+ }
+
+ if (lld_dev == NULL) {
+ ROCE_INFO("lld dev is NULL.");
+ goto out;
+ }
+
+ err = roce5_bond_check_slave_port(lld_dev, slave_ports, slave_cnt,
+ &result);
+ if (err != 0) {
+ ROCE_ERR("Failed to check slave ports, err(%d).", err);
+ goto out;
+ }
+
+ if (result == false) {
+ ROCE_INFO("Ports don't meet requirements.");
+ goto out;
+ }
+
+ ret = true;
+
+out:
+ rcu_read_unlock();
+ return ret;
+}
+
+static int
+roce5_bond_create_transition_store(struct roce5_bond_device *bond_dev,
+ const struct bond_tracker *tracker)
+{
+ int ret;
+ struct hinic5_lld_dev *ppf_lld = NULL;
+
+ ppf_lld = roce5_bond_get_ppf_lld(tracker);
+ if (ppf_lld == NULL) {
+ ROCE_ERR("Failed to get lld of the PPF.");
+ return -EINVAL;
+ }
+
+ ret = roce5_bond_transition_store(bond_dev, ppf_lld);
+ if (ret != 0) {
+ ROCE_ERR("Failed to store resources of transition, ret(%d).",
+ ret);
+ hinic5_lld_dev_put(ppf_lld);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+roce5_bond_create_transition_free(struct roce5_bond_device *bond_dev)
+{
+ roce5_bond_transition_free(bond_dev);
+}
+
+/*
+ * roce5_before_bond_active - Pre-active callback for bond creation
+ * @bond_name: name of bond device
+ * @attr: bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_before_bond_active(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ struct roce5_bond_device *bond_dev = NULL;
+ struct bond_tracker tracker;
+ u16 bond_id;
+ int i, slave_cnt;
+ int ret;
+
+ if (bond_name == NULL || attr == NULL) {
+ ROCE_ERR(
+ "Invalid parameter, roce bond_name(%d) or attr(%d) is NULL.",
+ !!bond_name, !!attr);
+ return;
+ }
+
+ bond_id = attr->bond_id;
+ ret = hinic5_bond_get_tracker_by_name(bond_name, &tracker);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get bond tracker, bond name(%s), ret(%d).",
+ bond_name, ret);
+ goto err;
+ }
+
+ if (roce5_bond_before_active_check(&tracker, attr) == false) {
+ ROCE_ERR("Failed to check before active bond.");
+ goto err;
+ }
+
+ bond_dev = roce5_bond_create_bond_device(bond_name);
+ if (IS_ERR(bond_dev)) {
+ ROCE_ERR("Failed to create roce bond device.");
+ goto err;
+ }
+
+ /* Store transition resources during the bond creating period to prevent abnormal resources using. */
+ ret = roce5_bond_create_transition_store(bond_dev, &tracker);
+ if (ret != 0) {
+ ROCE_ERR("Failed to store resources of transition.");
+ goto err;
+ }
+
+ /* Remove the functions of slaves. */
+ for (i = 0, slave_cnt = 0;
+ i < BOND_PORT_MAX_NUM && slave_cnt < tracker.cnt; ++i) {
+ if (tracker.ndev[i] == NULL) {
+ continue;
+ }
+
+ ret = roce5_bond_add_slave(bond_dev, tracker.ndev[i],
+ &tracker.netdev_state[i], false);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to add slave, name(%s), slave name(%s).",
+ bond_dev->name, tracker.ndev[i]->name);
+ goto err_with_transition;
+ }
+
+ ++slave_cnt;
+ }
+
+ /* Free transition resources during the bond creating period. */
+ roce5_bond_create_transition_free(bond_dev);
+ bond_dev->attr = *attr;
+
+ return;
+
+err_with_transition:
+ roce5_bond_create_transition_free(bond_dev);
+err:
+ roce5_bond_destroy(bond_name, bond_id);
+}
+
+/*
+ * roce5_after_bond_active - Post-active callback for bond creation
+ * @bond_name: name of bond device
+ * @attr: bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_after_bond_active(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ struct roce5_bond_device *bond_dev = NULL;
+
+ if (bond_name == NULL || attr == NULL) {
+ ROCE_ERR(
+ "Invalid parameter, bond name(%d) or attr(%d) is NULL.",
+ !!bond_name, !!attr);
+ return;
+ }
+
+ bond_dev = roce5_get_bond_dev_by_name(bond_name);
+ if (bond_dev == NULL) {
+ ROCE_ERR("Can't find roce bond device by name(%s).", bond_name);
+ return;
+ }
+
+ roce5_update_rdev_func_val(bond_dev);
+}
+
+/*
+ * roce5_before_bond_modify - Pre-modify callback for bond modification
+ * @bond_name: name of bond device
+ * @attr: new bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_before_bond_modify(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ int ret;
+ struct roce5_bond_device *bond_dev = NULL;
+ struct bond_tracker tracker;
+
+ if (bond_name == NULL || attr == NULL) {
+ ROCE_ERR("roce bond_name or attr is NULL.");
+ return;
+ }
+
+ bond_dev = roce5_get_bond_dev_by_name(bond_name);
+ if (bond_dev == NULL) {
+ ROCE_ERR("Can't find roce bond device by name(%s).", bond_name);
+ return;
+ }
+
+ ret = hinic5_bond_get_tracker_by_name(bond_name, &tracker);
+ if (ret != 0) {
+ ROCE_ERR("Failed to get bond tracker, bond name(%s), ret(%d).",
+ bond_name, ret);
+ return;
+ }
+
+ ret = roce5_handle_diff_slave(bond_dev, &tracker);
+ if (ret != 0) {
+ ROCE_ERR("Failed to handle different slave.");
+ return;
+ }
+
+ return;
+}
+
+/*
+ * roce5_after_bond_modify - Post-modify callback for bond modification
+ * @bond_name: name of bond device
+ * @attr: new bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_after_bond_modify(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ struct roce5_bond_device *bond_dev = NULL;
+
+ if (bond_name == NULL || attr == NULL) {
+ ROCE_ERR("roce bond_name or attr is NULL.");
+ return;
+ }
+
+ bond_dev = roce5_get_bond_dev_by_name(bond_name);
+ if (bond_dev == NULL) {
+ ROCE_ERR("can't find bond device by name(%s).", bond_name);
+ return;
+ }
+
+ bond_dev->attr = *attr;
+
+ roce5_update_rdev_func_val(bond_dev);
+}
+
+/*
+ * roce5_before_bond_deactive - Pre-deactive callback for bond deletion
+ * @bond_name: name of bond device
+ * @attr: bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_before_bond_deactive(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ struct roce5_bond_device *bond_dev = NULL;
+
+ bond_dev = roce5_get_bond_dev_by_name(bond_name);
+ if (bond_dev == NULL) {
+ ROCE_ERR("can't find bond device by name(%s).", bond_name);
+ return;
+ }
+
+ roce5_bond_destroy(bond_dev->name, attr->bond_id);
+}
+
+/*
+ * roce5_after_bond_deactive - Post-deactive callback for bond deletion
+ * @bond_name: name of bond device
+ * @attr: bond attributes
+ * @err: error code from previous operation
+ */
+void roce5_after_bond_deactive(const char *bond_name, struct bond_attr *attr,
+ int err)
+{
+ /* destroy switch thread handle, bond device may already be delete, current thread not disable care handle result */
+}
+
+/*
+ * roce5_bond_mode_is_supported - Check if bond mode is supported
+ * @bond_mode: bond mode to check
+ * Return: true if supported, false otherwise
+ */
+bool roce5_bond_mode_is_supported(u16 bond_mode)
+{
+ if (bond_mode != BOND_MODE_8023AD && bond_mode != BOND_MODE_XOR &&
+ bond_mode != BOND_MODE_ACTIVEBACKUP) {
+ ROCE_ERR(
+ "Bond mode only support 802.3ad/xor/active-backup, current bond mode(%u).",
+ bond_mode);
+ return false;
+ }
+ return true;
+}
+
+/*
+ * roce5_bond_slave_check - Check if slave device is valid for RoCE bond
+ * @lld_dev: LLD device to check
+ * @chip_name: buffer to store chip name
+ * @chip_name_size: size of chip_name buffer
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_slave_check(struct hinic5_lld_dev *lld_dev, char *chip_name,
+ size_t chip_name_size)
+{
+ int err;
+ char tmp_name[IFNAMSIZ] = { 0 };
+
+ if (lld_dev == NULL) {
+ ROCE_ERR("get lld dev err.");
+ return -ENODEV;
+ }
+
+ if (roce5_func_is_vf(lld_dev->hwdev)) {
+ ROCE_ERR("Bond Slave device is VF.");
+ return -EINVAL;
+ }
+
+ err = hinic5_get_chip_name(lld_dev, tmp_name, sizeof(tmp_name));
+ if (err != 0) {
+ ROCE_ERR("Bond Slave get chip name err %d.", err);
+ return err;
+ }
+
+ if (strlen(chip_name) == 0) {
+ err = memcpy_s(chip_name, chip_name_size, tmp_name,
+ sizeof(tmp_name));
+ if (err != 0) {
+ ROCE_ERR("Failed to memcpy chip_name.(ret:%d)", err);
+ return -ENOMEM;
+ }
+ } else if (strcmp(tmp_name, chip_name) != 0) {
+ ROCE_ERR(
+ "Creating bond cross cards is not supported, bond dev chip_name %s, slave chip name %s.",
+ chip_name, tmp_name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * roce5_bond_before_active_check - Pre-active check for bond creation
+ * @tracker: bond tracker from CFM framework
+ * @attr: bond attributes
+ * Return: true if check passes, false otherwise
+ */
+bool roce5_bond_before_active_check(struct bond_tracker *tracker,
+ struct bond_attr *attr)
+{
+ int i, slave_cnt;
+ int err;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ char chip_name[IFNAMSIZ] = { 0 };
+
+ if (roce5_bond_mode_is_supported(attr->bond_mode) == false) {
+ ROCE_ERR("Invalid bond mode(%u).", attr->bond_mode);
+ return false;
+ }
+
+ if (tracker->cnt < ROCE_BOND_MIN_SLAVE ||
+ tracker->cnt > ROCE_BOND_MAX_SLAVE) {
+ ROCE_ERR("Not support the slave number(%u) of the bond.",
+ tracker->cnt);
+ return false;
+ }
+
+ for (i = 0, slave_cnt = 0;
+ i < BOND_PORT_MAX_NUM && slave_cnt < tracker->cnt; ++i) {
+ if (tracker->ndev[i] == NULL) {
+ continue;
+ }
+
+ lld_dev = hinic5_get_lld_dev_by_netdev(tracker->ndev[i]);
+ if (lld_dev == NULL) {
+ ROCE_ERR("get lld dev err.");
+ return false;
+ }
+
+ err = roce5_bond_slave_check(lld_dev, chip_name,
+ sizeof(chip_name));
+ if (err != 0) {
+ ROCE_ERR("Bond slave check err %d.", err);
+ return false;
+ }
+
+ ++slave_cnt;
+ }
+ return true;
+}
+
+#endif /* ROCE_BONDING_EN */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_device.c b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_device.c
new file mode 100644
index 000000000..cb3612778
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_device.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifdef ROCE_BONDING_EN
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <net/bonding.h>
+
+#include "securec.h"
+
+#include "bond_common_defs.h"
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce_bond.h"
+#include "roce_bond_internal.h"
+#include "roce_cmd.h"
+#include "roce_netdev.h"
+#include "roce_infra.h"
+
+/* Global variables: g_roce5_bond_mutex protects g_roce5_bond_list */
+LIST_HEAD(g_roce5_bond_list);
+DEFINE_MUTEX(g_roce5_bond_mutex);
+
+static bool g_roce5_bond_ipsurx_en = true;
+
+int roce5_bond_transition_store(struct roce5_bond_device *bond_dev,
+ struct hinic5_lld_dev *ppf_lld)
+{
+ int ret = 0;
+
+ ret = hinic5_stateful_init(ppf_lld->hwdev);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to init stateful resource of the PPF, ret(%d).",
+ ret);
+ goto out;
+ }
+
+ bond_dev->transition_res.ppf_lld = ppf_lld;
+out:
+ return ret;
+}
+
+void roce5_bond_transition_free(struct roce5_bond_device *bond_dev)
+{
+ if (bond_dev->transition_res.ppf_lld == NULL) {
+ return;
+ }
+
+ hinic5_stateful_deinit(bond_dev->transition_res.ppf_lld->hwdev);
+ hinic5_lld_dev_put(bond_dev->transition_res.ppf_lld);
+ bond_dev->transition_res.ppf_lld = NULL;
+}
+
+/*
+ * Caller has to call hinic5_lld_dev_put() to free resource when finish using ppf lld.
+ * There's no need to call hinic5_lld_dev_put() to free resource when this function return NULL.
+ */
+struct hinic5_lld_dev *
+roce5_bond_get_ppf_lld(const struct bond_tracker *tracker)
+{
+ int i;
+ struct net_device *first_slave = NULL;
+ struct hinic5_lld_dev *first_slave_lld = NULL, *ppf_lld = NULL;
+
+ for (i = 0; i < BOND_PORT_MAX_NUM; ++i) {
+ if (tracker->ndev[i] != NULL) {
+ first_slave = tracker->ndev[i];
+ break;
+ }
+ }
+
+ if (first_slave == NULL) {
+ ROCE_ERR("Failed to get net device of the first slave.");
+ return NULL;
+ }
+
+ first_slave_lld = hinic5_get_lld_dev_by_netdev(first_slave);
+ if (first_slave_lld == NULL) {
+ ROCE_ERR("Failed to get lld of the first slave.");
+ return NULL;
+ }
+
+ ppf_lld = hinic5_get_ppf_lld_dev(first_slave_lld);
+ if (ppf_lld == NULL) {
+ ROCE_ERR("Failed to get lld of the PPF.");
+ return NULL;
+ }
+
+ return ppf_lld;
+}
+
+/*
+ * roce5_get_bond_dev - Get bond device by name (internal)
+ * @bond_name: name of bond device
+ * Return: pointer to roce5_bond_device if found, NULL otherwise
+ * Lock: caller must hold g_roce5_bond_mutex
+ */
+struct roce5_bond_device *roce5_get_bond_dev(const char *bond_name)
+{
+ struct roce5_bond_device *bdev = NULL;
+
+ list_for_each_entry(bdev, &g_roce5_bond_list, entry) {
+ if (strcmp(bdev->name, bond_name) == 0) {
+ return bdev;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * roce5_get_bond_dev_by_name - Get bond device by name (public wrapper)
+ * @bond_name: name of bond device
+ * Return: pointer to roce5_bond_device if found, NULL otherwise
+ */
+struct roce5_bond_device *roce5_get_bond_dev_by_name(const char *bond_name)
+{
+ struct roce5_bond_device *bdev = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ bdev = roce5_get_bond_dev(bond_name);
+ mutex_unlock(&g_roce5_bond_mutex);
+ return bdev;
+}
+
+struct roce5_bond_device *roce5_bond_create_bond_device(const char *bond_name)
+{
+ struct roce5_bond_device *rbdev = NULL;
+ errno_t ret;
+
+ if (bond_name == NULL) {
+ ROCE_ERR("Invalid parameter, ptr is NULL.");
+ return ERR_PTR(-EINVAL);
+ }
+
+ rbdev = roce5_get_bond_dev_by_name(bond_name);
+ if (rbdev != NULL) {
+ ROCE_ERR("Bond device(%s) already exists.", bond_name);
+ return ERR_PTR(-EINVAL);
+ }
+
+ rbdev = kzalloc(sizeof *rbdev, GFP_KERNEL);
+ if (rbdev == NULL) {
+ ROCE_ERR("Failed to alloc memory.");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ret = strncpy_s(rbdev->name, IFNAMSIZ, bond_name, strlen(bond_name));
+ if (ret != EOK) {
+ ROCE_ERR("Failed to copy string, ret(%d).", ret);
+ kfree(rbdev);
+ return ERR_PTR(-EFAULT);
+ }
+
+ rbdev->need_clean_on_remove = true;
+ mutex_init(&rbdev->slave_lock);
+
+ mutex_lock(&g_roce5_bond_mutex);
+ list_add_tail(&rbdev->entry, &g_roce5_bond_list);
+ mutex_unlock(&g_roce5_bond_mutex);
+
+ return rbdev;
+}
+
+static int
+roce5_bond_destroy_transition_store(struct roce5_bond_device *bond_dev)
+{
+ int ret;
+ struct hinic5_lld_dev *ppf_lld = NULL;
+
+ if (bond_dev->slave_cnt == 0) {
+ ROCE_WARN("There's no slave in roce bond.");
+ return 0;
+ }
+
+ ppf_lld = hinic5_get_ppf_lld_dev(bond_dev->slaves[0].lld_dev);
+ if (ppf_lld == NULL) {
+ ROCE_ERR("Failed to get lld of the PPF.");
+ return -EINVAL;
+ }
+
+ ret = roce5_bond_transition_store(bond_dev, ppf_lld);
+ if (ret != 0) {
+ ROCE_ERR("Failed to store resources of transition, ret(%d).",
+ ret);
+ hinic5_lld_dev_put(ppf_lld);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+roce5_bond_destroy_transition_free(struct roce5_bond_device *bond_dev)
+{
+ roce5_bond_transition_free(bond_dev);
+}
+/*
+ * roce5_bond_destroy - Destroy bond device
+ * @bond_name: name of bond device
+ * @bond_id: bond ID
+ */
+void roce5_bond_destroy(const char *bond_name, u16 bond_id)
+{
+ int ret;
+ u32 i;
+ struct roce5_bond_device *bond_dev = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ bond_dev = roce5_get_bond_dev(bond_name);
+ if (bond_dev == NULL) {
+ /* destroy switch thread handle, bond device may already be delete, current thread not disable care handle result */
+ ROCE_INFO("bond name(%s) has been detached", bond_name);
+ mutex_unlock(&g_roce5_bond_mutex);
+ return;
+ }
+
+ list_del(&bond_dev->entry);
+ mutex_unlock(&g_roce5_bond_mutex);
+
+ if (bond_dev->bond_lld_dev != NULL) {
+ ret = roce5_bond_destroy_transition_store(bond_dev);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to store transition resources on destroy.");
+ }
+
+ bond_dev->need_clean_on_remove = false;
+ hinic5_detach_service(bond_dev->bond_lld_dev, SERVICE_T_ROCE);
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ ret = hinic5_attach_service(bond_dev->slaves[i].lld_dev,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to attach roce device, ret(%d).",
+ ret);
+ }
+ }
+ bond_dev->slave_cnt = 0;
+ roce5_bond_destroy_transition_free(bond_dev);
+ mutex_unlock(&bond_dev->slave_lock);
+ }
+
+ kfree(bond_dev);
+ return;
+}
+
+/*
+ * roce5_bond_attach - Attach bond device to RoCE
+ * @rdev: RoCE device to attach
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_attach(struct roce5_device *rdev)
+{
+ u32 i;
+ int ret = 0;
+ struct roce5_bond_device *bond_dev = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ list_for_each_entry(bond_dev, &g_roce5_bond_list, entry) {
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ if (rdev->ndev != bond_dev->slaves[i].netdev) {
+ continue;
+ }
+
+ if (bond_dev->attached_rdev == NULL) {
+ bond_dev->attached_rdev = rdev;
+ rdev->bond_dev = bond_dev;
+ } else {
+ ret = -EEXIST;
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ goto out;
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ }
+out:
+ mutex_unlock(&g_roce5_bond_mutex);
+ return ret;
+}
+
+/*
+ * roce5_bond_is_active - Check if bond is active for RoCE device
+ * @rdev: RoCE device to check
+ * Return: true if bond is active, false otherwise
+ */
+bool roce5_bond_is_active(struct roce5_device *rdev)
+{
+ return (rdev->bond_dev != NULL);
+}
+
+void roce5_bond_detach(struct roce5_device *rdev)
+{
+ int ret;
+ u32 i;
+ struct roce5_bond_device *bond_dev = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ bond_dev = rdev->bond_dev;
+ if (bond_dev == NULL) {
+ mutex_unlock(&g_roce5_bond_mutex);
+ ROCE_INFO("bond_dev is NULL.");
+ return;
+ }
+
+ if (bond_dev->need_clean_on_remove == false) {
+ mutex_unlock(&g_roce5_bond_mutex);
+ ROCE_INFO("bond_dev no need to detached on roce remove.");
+ return;
+ }
+
+ if (roce5_get_bond_dev(bond_dev->name) == bond_dev) {
+ list_del(&bond_dev->entry);
+ }
+
+ mutex_unlock(&g_roce5_bond_mutex);
+ ret = roce5_bond_destroy_transition_store(bond_dev);
+ if (ret != 0) {
+ ROCE_ERR("Failed to store transition resources on destroy.");
+ }
+ hinic5_bond_detach(bond_dev->attr.bond_id, HINIC5_BOND_USER_ROCE);
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ if (bond_dev->bond_lld_dev == bond_dev->slaves[i].lld_dev) {
+ continue;
+ }
+ ret = hinic5_attach_service(bond_dev->slaves[i].lld_dev,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Failed to attach roce device, ret(%d).", ret);
+ }
+ }
+ bond_dev->slave_cnt = 0;
+ mutex_unlock(&bond_dev->slave_lock);
+ roce5_bond_destroy_transition_free(bond_dev);
+ mutex_lock(&g_roce5_bond_mutex);
+ kfree(bond_dev);
+ rdev->bond_dev = NULL;
+ mutex_unlock(&g_roce5_bond_mutex);
+}
+/*
+ * roce5_bond_event_cfg_rdev - Configure RoCE device for bond events
+ * @lld_dev: LLD device
+ * @uld_dev: ULD device
+ * @rdev: pointer to RoCE device pointer (output)
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_event_cfg_rdev(struct hinic5_lld_dev *lld_dev, void *uld_dev,
+ struct roce5_device **rdev, bool hold_rdev)
+{
+ u32 i = 0;
+ struct roce5_bond_device *bond_dev = NULL;
+
+ if (lld_dev == NULL) {
+ ROCE_ERR("lld_dev is null.");
+ return -EINVAL;
+ }
+
+ if (uld_dev != NULL) {
+ *rdev = (struct roce5_device *)uld_dev;
+ return 0;
+ }
+
+ mutex_lock(&g_roce5_bond_mutex);
+ list_for_each_entry(bond_dev, &g_roce5_bond_list, entry) {
+ if (bond_dev == NULL) {
+ ROCE_ERR("bond_dev is null");
+ continue;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ if (bond_dev->slaves[i].lld_dev == lld_dev) {
+ *rdev = bond_dev->attached_rdev;
+ if (hold_rdev == true && *rdev != NULL) {
+ uld5_dev_hold((*rdev)->lld_dev,
+ SERVICE_T_ROCE);
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ goto out;
+ }
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ }
+
+out:
+ mutex_unlock(&g_roce5_bond_mutex);
+ return *rdev ? 0 : -EINVAL;
+}
+
+/*
+ * roce5_update_rdev_func_val - Update function table values for RoCE device
+ * @bond_dev: bond device
+ */
+void roce5_update_rdev_func_val(struct roce5_bond_device *bond_dev)
+{
+ struct roce5_device *rdev = NULL;
+ u32 func_tbl_bond;
+ int ret;
+
+ if (bond_dev->bond_lld_dev == NULL) {
+ return;
+ }
+
+ rdev = hinic5_get_uld_dev(bond_dev->bond_lld_dev, SERVICE_T_ROCE);
+ if (rdev == NULL) {
+ ROCE_ERR("Failed to find roce device.");
+ return;
+ }
+
+ ret = roce5_get_func_table(rdev->hwdev, rdev->glb_func_id,
+ &func_tbl_bond);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev,
+ "Failed to get func table value, func_id(%d).",
+ rdev->glb_func_id);
+ uld5_dev_put(bond_dev->bond_lld_dev, SERVICE_T_ROCE);
+ return;
+ }
+
+ write_lock(&rdev->rwlock_func_tbl_bond);
+ rdev->func_tbl_bond = func_tbl_bond;
+ write_unlock(&rdev->rwlock_func_tbl_bond);
+
+ uld5_dev_put(bond_dev->bond_lld_dev, SERVICE_T_ROCE);
+}
+
+bool roce5_get_bond_ipsurx_en(void)
+{
+ return g_roce5_bond_ipsurx_en;
+}
+
+void roce5_set_bond_ipsurx_en(bool ipsurx_en)
+{
+ g_roce5_bond_ipsurx_en = ipsurx_en;
+}
+
+/*
+ * roce5_bond_init - Initialize RoCE bond module
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_init(void)
+{
+ int ret;
+ struct bond_srv_func roce_func = {
+ .before_active = roce5_before_bond_active,
+ .after_active = roce5_after_bond_active,
+ .before_modify = roce5_before_bond_modify,
+ .after_modify = roce5_after_bond_modify,
+ .before_deactive = roce5_before_bond_deactive,
+ .after_deactive = roce5_after_bond_deactive,
+ .can_attach = roce5_can_do_bond,
+ };
+
+ ret = hinic5_bond_register(HINIC5_BOND_USER_ROCE, &roce_func);
+ if (ret != 0) {
+ ROCE_ERR("Failed to register bond, ret(%d).", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void roce5_bond_exit(void)
+{
+ int ret;
+ struct roce5_bond_device *bond_dev = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ list_for_each_entry(bond_dev, &g_roce5_bond_list, entry) {
+ bond_dev->need_clean_on_remove = false;
+ }
+ mutex_unlock(&g_roce5_bond_mutex);
+
+ ret = hinic5_bond_unregister(HINIC5_BOND_USER_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Failed to unregister service func, ret(%d).", ret);
+ }
+}
+
+#endif /* ROCE_BONDING_EN */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_internal.h b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_internal.h
new file mode 100644
index 000000000..fd9853215
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_internal.h
@@ -0,0 +1,97 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifndef ROCE_BOND_INTERNAL_H
+#define ROCE_BOND_INTERNAL_H
+
+#ifdef ROCE_BONDING_EN
+
+#include <net/bonding.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include "hinic5_lld.h"
+#include "drv_bond_api.h"
+#include "bond_common_defs.h"
+#include "roce_bond.h"
+
+/* Slave synchronization structure for bond modify */
+struct roce5_bond_slave_sync {
+ bool exist_arr
+ [ROCE_BOND_MAX_SLAVE]; /* Indicate which slave need to be deleted */
+ struct net_device *
+ new_ndev[ROCE_BOND_MAX_SLAVE]; /* New slaves need to be added */
+ struct netdev_lower_state_info new_ndev_state[BOND_PORT_MAX_NUM];
+ u32 new_ndev_num;
+};
+
+/* Global variables declaration */
+extern struct list_head g_roce5_bond_list; //TODO: later via interface access
+extern struct mutex g_roce5_bond_mutex; //TODO: later via interface access
+extern struct workqueue_struct *g_bond_wq; //TODO: later via interface access
+
+/* CFM Interface Layer - Internal Functions */
+bool roce5_bond_mode_is_supported(u16 bond_mode);
+int roce5_bond_slave_check(struct hinic5_lld_dev *lld_dev, char *chip_name,
+ size_t chip_name_size);
+bool roce5_bond_before_active_check(struct bond_tracker *tracker,
+ struct bond_attr *attr);
+bool roce5_can_do_bond(struct bonding *bond);
+
+/* CFM Callback Functions (called by CFM framework) */
+void roce5_before_bond_active(const char *bond_name, struct bond_attr *attr,
+ int err);
+void roce5_after_bond_active(const char *bond_name, struct bond_attr *attr,
+ int err);
+void roce5_before_bond_modify(const char *bond_name, struct bond_attr *attr,
+ int err);
+void roce5_after_bond_modify(const char *bond_name, struct bond_attr *attr,
+ int err);
+void roce5_before_bond_deactive(const char *bond_name, struct bond_attr *attr,
+ int err);
+void roce5_after_bond_deactive(const char *bond_name, struct bond_attr *attr,
+ int err);
+
+/* Device Management Layer - Internal Functions */
+struct roce5_bond_device *roce5_get_bond_dev(const char *bond_name);
+struct roce5_bond_device *roce5_get_bond_dev_by_name(const char *bond_name);
+void roce5_bond_destroy(const char *bond_name, u16 bond_id);
+void roce5_update_rdev_func_val(struct roce5_bond_device *bond_dev);
+struct hinic5_lld_dev *
+roce5_bond_get_ppf_lld(const struct bond_tracker *tracker);
+struct roce5_bond_device *roce5_bond_create_bond_device(const char *bond_name);
+
+/* Slave Management Layer - Internal Functions */
+struct roce5_bond_slave *
+roce5_find_next_slave_slot(struct roce5_bond_device *rbdev);
+int roce5_get_bond_slave_index_by_ndev(struct roce5_bond_device *rbdev,
+ struct net_device *ndev);
+int roce5_bond_add_slave(struct roce5_bond_device *rbdev,
+ struct net_device *ndev,
+ struct netdev_lower_state_info *ndev_info,
+ bool is_update_table);
+int roce5_bond_del_slave(struct roce5_bond_device *rbdev, u32 slave_index);
+int roce5_find_same_slave_and_update(struct roce5_bond_device *rbdev,
+ struct bond_tracker *tracker,
+ struct roce5_bond_slave_sync *slave_sync);
+int roce5_handle_diff_slave(struct roce5_bond_device *rbdev,
+ struct bond_tracker *tracker);
+
+/* MAC Table Operation Layer - Internal Functions */
+int roce5_bond_add_slave_table(struct roce5_bond_device *rbdev, u8 slave_er_id,
+ u16 slave_func_id);
+int roce5_bond_del_slave_table(struct roce5_bond_device *rbdev, u8 slave_er_id,
+ u16 slave_func_id);
+
+/* TX Port Selection Layer - Internal Functions (declared in roce_bond.h as public) */
+
+int roce5_bond_transition_store(struct roce5_bond_device *bond_dev,
+ struct hinic5_lld_dev *ppf_lld);
+void roce5_bond_transition_free(struct roce5_bond_device *bond_dev);
+
+#endif /* ROCE_BONDING_EN */
+
+#endif /* ROCE_BOND_INTERNAL_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_mac.c b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_mac.c
new file mode 100644
index 000000000..75264917f
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_mac.c
@@ -0,0 +1,260 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifdef ROCE_BONDING_EN
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <net/bonding.h>
+
+#include "securec.h"
+
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce_bond.h"
+#include "roce_bond_internal.h"
+#include "roce_cmd.h"
+#include "roce_netdev.h"
+#include "roce_infra.h"
+
+/*
+ * roce5_add_bond_real_slave_mac - Add real slave MAC to table
+ * @rdev: RoCE device
+ * @mac: MAC address to add
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_add_bond_real_slave_mac(struct roce5_device *rdev, u8 *mac)
+{
+ struct roce5_bond_device *bond_dev = rdev->bond_dev;
+ struct roce5_bond_slave *slave = NULL;
+ int ret;
+ u32 i;
+
+ if (bond_dev == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to find bond_dev, func_id(%u).",
+ rdev->glb_func_id);
+ return -EINVAL;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ slave = &bond_dev->slaves[i];
+
+ ret = roce5_add_mac_tbl_mac_entry(rdev, mac, ETH_ALEN,
+ ROCE_BOND_RSVD_VLAN_ID,
+ slave->func_id);
+ if (ret != 0) {
+ mutex_unlock(&bond_dev->slave_lock);
+ ROCE_DEV_ERR(rdev,
+ "Failed to add mac_vlan entry, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ if (slave->func_id != rdev->glb_func_id) {
+ /* The IPSU MAC table is used for fast forwarding. Even if the addition fails, the forwarding information
+ can still be obtained by checking the MAC table later, without judging the execution result. */
+ roce5_add_ipsu_tbl_mac_entry(rdev, mac, 0,
+ rdev->glb_func_id,
+ slave->er_id,
+ slave->func_id);
+ }
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+
+ return 0;
+}
+
+/*
+ * roce5_add_bond_vlan_slave_mac - Add VLAN slave Mac to table
+ * @rdev: RoCE device
+ * @mac: MAC address to add
+ * @vlan_id: VLAN ID
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_add_bond_vlan_slave_mac(struct roce5_device *rdev, u8 *mac,
+ u16 vlan_id)
+{
+ struct roce5_bond_device *bond_dev = rdev->bond_dev;
+ struct roce5_bond_slave *slave = NULL;
+ int ret;
+ u32 i;
+
+ if (bond_dev == NULL) {
+ ROCE_DEV_ERR(rdev, "Failed to find bond_dev");
+ return -EINVAL;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ slave = &bond_dev->slaves[i];
+ if (slave->func_id == rdev->glb_func_id) {
+ continue;
+ }
+
+ ret = roce5_add_mac_tbl_mac_entry(rdev, mac, ETH_ALEN, vlan_id,
+ slave->func_id);
+ if (ret != 0) {
+ mutex_unlock(&bond_dev->slave_lock);
+ ROCE_DEV_ERR(rdev,
+ "Failed to add mac_vlan entry, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ /* The IPSU MAC table is used for fast forwarding. Even if the addition fails, the forwarding information
+ can still be obtained by checking the MAC table later, without judging the execution result. */
+ roce5_add_ipsu_tbl_mac_entry(rdev, mac, vlan_id,
+ rdev->glb_func_id, slave->er_id,
+ slave->func_id);
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+
+ return 0;
+}
+
+/*
+ * roce5_del_bond_real_slave_mac - Delete real slave Mac from table
+ * @rdev: RoCE device
+ */
+void roce5_del_bond_real_slave_mac(struct roce5_device *rdev)
+{
+ u32 i;
+ struct roce5_bond_slave *slave = NULL;
+ struct roce5_bond_device *bond_dev = rdev->bond_dev;
+
+ if (bond_dev == NULL) {
+ return;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ slave = &bond_dev->slaves[i];
+ if (slave->func_id != rdev->glb_func_id) {
+ roce5_del_ipsu_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN,
+ 0, slave->er_id,
+ slave->func_id);
+ }
+
+ (void)roce5_del_mac_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN,
+ ROCE_BOND_RSVD_VLAN_ID,
+ slave->func_id);
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+}
+
+/*
+ * roce5_del_bond_vlan_slave_mac - Delete VLAN slave Mac from table
+ * @rdev: RoCE device
+ * @mac: MAC address to delete
+ * @vlan_id: VLAN ID
+ */
+void roce5_del_bond_vlan_slave_mac(struct roce5_device *rdev, u8 *mac,
+ u16 vlan_id)
+{
+ u32 i;
+ struct roce5_bond_slave *slave = NULL;
+ struct roce5_bond_device *bond_dev = rdev->bond_dev;
+
+ if (bond_dev == NULL) {
+ return;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ slave = &bond_dev->slaves[i];
+ if (slave->func_id == rdev->glb_func_id) {
+ continue;
+ }
+
+ roce5_del_ipsu_tbl_mac_entry(rdev, mac, ETH_ALEN, vlan_id,
+ slave->er_id, slave->func_id);
+
+ (void)roce5_del_mac_tbl_mac_entry(rdev, mac, ETH_ALEN, vlan_id,
+ slave->func_id);
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+}
+
+/*
+ * roce5_bond_add_slave_table - Add slave table entry
+ * @rbdev: bond device
+ * @slave_er_id: slave ER ID
+ * @slave_func_id: slave function ID
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_add_slave_table(struct roce5_bond_device *rbdev, u8 slave_er_id,
+ u16 slave_func_id)
+{
+ struct roce5_device *rdev = rbdev->attached_rdev;
+ struct roce5_vlan_dev_list *vlan_dev_list = NULL;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL)) {
+ ROCE_ERR("Missing attached roce device.");
+ return -EINVAL;
+ }
+
+ /* Add entry of non-vlan device */
+ roce5_add_ipsu_tbl_mac_entry(rdev, (u8 *)rdev->mac, 0,
+ rdev->glb_func_id, slave_er_id,
+ slave_func_id);
+ /* Add entries of vlan device */
+ mutex_lock(&rdev->mac_vlan_mutex);
+ if (rdev->mac_vlan_list_head.next == NULL) {
+ ROCE_ERR("mac vlan list not init.");
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ return -EINVAL;
+ }
+ list_for_each_entry(vlan_dev_list, &rdev->mac_vlan_list_head, list) {
+ roce5_add_ipsu_tbl_mac_entry(rdev, (u8 *)rdev->mac,
+ vlan_dev_list->vlan_id,
+ rdev->glb_func_id, slave_er_id,
+ slave_func_id);
+ }
+ mutex_unlock(&rdev->mac_vlan_mutex);
+
+ return 0;
+}
+
+/*
+ * roce5_bond_del_slave_table - Delete slave table entry
+ * @rbdev: bond device
+ * @slave_er_id: slave ER ID
+ * @slave_func_id: slave function ID
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_bond_del_slave_table(struct roce5_bond_device *rbdev, u8 slave_er_id,
+ u16 slave_func_id)
+{
+ struct roce5_device *rdev = rbdev->attached_rdev;
+ struct roce5_vlan_dev_list *vlan_dev_list = NULL;
+
+ if ((rdev == NULL) || (rdev->hwdev == NULL)) {
+ ROCE_ERR("Missing attached roce device.");
+ return -EINVAL;
+ }
+
+ /* Delete entry of non-vlan device */
+ roce5_del_ipsu_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN, 0, slave_er_id,
+ slave_func_id);
+ /* Delete entries of vlan device */
+ mutex_lock(&rdev->mac_vlan_mutex);
+ if (rdev->mac_vlan_list_head.next == NULL) {
+ ROCE_ERR("mac vlan list not init.");
+ mutex_unlock(&rdev->mac_vlan_mutex);
+ return -EINVAL;
+ }
+ list_for_each_entry(vlan_dev_list, &rdev->mac_vlan_list_head, list) {
+ roce5_del_ipsu_tbl_mac_entry(rdev, rdev->mac, ETH_ALEN,
+ vlan_dev_list->vlan_id,
+ slave_er_id, slave_func_id);
+ }
+ mutex_unlock(&rdev->mac_vlan_mutex);
+
+ return 0;
+}
+
+#endif /* ROCE_BONDING_EN */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_slave.c b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_slave.c
new file mode 100644
index 000000000..a0fee96a4
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_slave.c
@@ -0,0 +1,459 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifdef ROCE_BONDING_EN
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <net/bonding.h>
+
+#include "securec.h"
+
+#include "bond_common_defs.h"
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce_bond.h"
+#include "roce_bond_internal.h"
+#include "roce_cmd.h"
+#include "roce_netdev.h"
+#include "roce_infra.h"
+
+/*
+ * roce5_find_next_slave_slot - Find next available slave slot
+ * @rbdev: bond device
+ * Return: pointer to available slave slot, NULL if no slot available
+ * Lock: caller must hold rbdev->slave_lock
+ */
+struct roce5_bond_slave *
+roce5_find_next_slave_slot(struct roce5_bond_device *rbdev)
+{
+ if (rbdev->slave_cnt >= ROCE_BOND_MAX_SLAVE) {
+ ROCE_ERR(
+ "RoCE bond device slave slots are full, max number of slaves is %d.",
+ ROCE_BOND_MAX_SLAVE);
+ return NULL;
+ }
+
+ if (rbdev->slaves[rbdev->slave_cnt].netdev != NULL) {
+ ROCE_ERR("Error occur! Slave slot is broken, slot index(%d).",
+ rbdev->slave_cnt);
+ return NULL;
+ }
+
+ return &rbdev->slaves[rbdev->slave_cnt];
+}
+
+/*
+ * roce5_get_bond_slave_index_by_ndev - Get slave index by netdev
+ * @rbdev: bond device
+ * @ndev: netdev to search for
+ * Return: slave index if found, negative error code otherwise
+ * Lock: caller must hold rbdev->slave_lock
+ */
+int roce5_get_bond_slave_index_by_ndev(struct roce5_bond_device *rbdev,
+ struct net_device *ndev)
+{
+ u32 index;
+
+ for (index = 0; index < rbdev->slave_cnt; ++index) {
+ if (rbdev->slaves[index].netdev == ndev) {
+ return (int)index;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static void roce5_bond_slave_init(struct roce5_bond_slave *slave,
+ struct net_device *ndev,
+ struct hinic5_lld_dev *ndev_lld,
+ struct netdev_lower_state_info *ndev_info,
+ bool is_update_table,
+ struct roce5_bond_device *rbdev)
+{
+ int ret;
+
+ slave->netdev = ndev;
+ slave->netdev_state.link_up = ndev_info->link_up;
+ slave->netdev_state.tx_enabled = ndev_info->tx_enabled;
+
+ slave->lld_dev = ndev_lld;
+ slave->func_id = hinic5_global_func_id(slave->lld_dev->hwdev);
+ slave->er_id = hinic5_er_id(slave->lld_dev->hwdev);
+
+ hinic5_detach_service(slave->lld_dev, SERVICE_T_ROCE);
+
+ if (is_update_table) {
+ ret = roce5_bond_add_slave_table(rbdev, slave->er_id,
+ slave->func_id);
+ if (ret != 0) {
+ ROCE_WARN(
+ "Failed to add table entries of slave(%u), ret(%d).",
+ slave->func_id, ret);
+ }
+ }
+}
+
+static void roce5_bond_slave_deinit(struct roce5_bond_slave *slave,
+ bool is_update_table,
+ struct roce5_bond_device *rbdev)
+{
+ int ret;
+
+ if (is_update_table) {
+ ret = roce5_bond_del_slave_table(rbdev, slave->er_id,
+ slave->func_id);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to delete slave table entries, ret(%d).",
+ ret);
+ }
+ }
+
+ ret = hinic5_attach_service(slave->lld_dev, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to attach roce function, func_id(%u), ret(%d).",
+ slave->func_id, ret);
+ }
+}
+
+/*
+ * roce5_bond_add_slave - Add slave to bond device
+ * @rbdev: bond device
+ * @ndev: slave netdev
+ * @ndev_info: slave state info
+ * @is_update_table: whether to update MAC table
+ * Return: 0 on success, negative error code on failure
+ * Lock: caller must hold rbdev->slave_lock
+ */
+int roce5_bond_add_slave(struct roce5_bond_device *rbdev,
+ struct net_device *ndev,
+ struct netdev_lower_state_info *ndev_info,
+ bool is_update_table)
+{
+ int ret, err_ret;
+ struct hinic5_lld_dev *ndev_lld = NULL;
+ struct roce5_bond_slave *slave = NULL;
+ struct roce5_bond_slave slave_temp;
+
+ ndev_lld = hinic5_get_lld_dev_by_netdev(ndev);
+ if (ndev_lld == NULL) {
+ ROCE_ERR("Failed to get lld dev by netdev %s.", ndev->name);
+ return -ENODEV;
+ }
+
+ if (hinic5_support_roce(ndev_lld->hwdev, NULL) == false) {
+ return 0;
+ }
+
+ roce5_bond_slave_init(&slave_temp, ndev, ndev_lld, ndev_info,
+ is_update_table, rbdev);
+
+ /* Add slave to roce bond device. */
+ mutex_lock(&rbdev->slave_lock);
+
+ slave = roce5_find_next_slave_slot(rbdev);
+ if (slave == NULL) {
+ ROCE_ERR("Failed to find next slave slot.");
+ ret = -ENXIO;
+ mutex_unlock(&rbdev->slave_lock);
+ goto err_without_slot;
+ }
+
+ *slave = slave_temp;
+ ++rbdev->slave_cnt;
+
+ mutex_unlock(&rbdev->slave_lock);
+
+ /* Try to attach roce device to roce bond device. */
+ if (rbdev->attached_rdev == NULL) {
+ if (rbdev->bond_lld_dev != NULL) {
+ ROCE_ERR("Impossible situation! bond lld isn't NULL.");
+ ret = -EINVAL;
+ goto err_check;
+ }
+
+ rbdev->bond_lld_dev = ndev_lld;
+
+ ret = hinic5_attach_service(rbdev->bond_lld_dev,
+ SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to attach roce service, ret(%d), bond name(%s).",
+ ret, rbdev->name);
+ ret = -EINVAL;
+ goto err_attach;
+ }
+
+ if (rbdev->attached_rdev == NULL) {
+ ROCE_ERR(
+ "Failed to attach roce bond device with roce device, bond name(%s).",
+ rbdev->name);
+ ret = -EINVAL;
+ goto err_attach_bond;
+ }
+ }
+
+ return 0;
+
+err_attach_bond:
+ hinic5_detach_service(rbdev->bond_lld_dev, SERVICE_T_ROCE);
+err_attach:
+ rbdev->bond_lld_dev = NULL;
+err_check:
+ mutex_lock(&rbdev->slave_lock);
+ err_ret = memset_s(slave, sizeof(struct roce5_bond_slave), 0,
+ sizeof(struct roce5_bond_slave));
+ if (err_ret != 0) {
+ ROCE_ERR("Failed to clean memory of slave, ret(%d).", err_ret);
+ }
+ --rbdev->slave_cnt;
+ mutex_unlock(&rbdev->slave_lock);
+err_without_slot:
+ roce5_bond_slave_deinit(&slave_temp, is_update_table, rbdev);
+ return ret;
+}
+
+/*
+ * roce5_bond_del_slave - Delete slave from bond device
+ * @rbdev: bond device
+ * @slave_index: index of slave to delete
+ * Return: 0 on success, negative error code on failure
+ * Lock: caller must hold rbdev->slave_lock
+ */
+int roce5_bond_del_slave(struct roce5_bond_device *rbdev, u32 slave_index)
+{
+ int ret;
+ struct roce5_bond_slave *slave = NULL;
+ struct roce5_bond_slave slave_temp;
+ size_t mem_copy_len;
+
+ mutex_lock(&rbdev->slave_lock);
+
+ if (slave_index >= rbdev->slave_cnt) {
+ ROCE_ERR("Invalid parameter, slave index(%u), slave count(%u).",
+ slave_index, rbdev->slave_cnt);
+ ret = -EINVAL;
+ mutex_unlock(&rbdev->slave_lock);
+ goto err_out;
+ }
+
+ slave = &rbdev->slaves[slave_index];
+ if (rbdev->bond_lld_dev != NULL &&
+ slave->lld_dev == rbdev->bond_lld_dev) {
+ ROCE_WARN(
+ "Slave(%s) lld dev is the same as the roce bond device(%s), skip removing.",
+ slave->netdev->name,
+ (rbdev->attached_rdev != NULL) ?
+ rbdev->attached_rdev->ib_dev.name :
+ "NULL");
+ ret = 0;
+ mutex_unlock(&rbdev->slave_lock);
+ goto err_out;
+ }
+
+ slave_temp = *slave;
+
+ ret = memset_s(slave, sizeof(struct roce5_bond_slave), 0,
+ sizeof(struct roce5_bond_slave));
+ if (ret != 0) {
+ ROCE_WARN("Failed to clear slave information.");
+ }
+
+ if (slave_index != ROCE_BOND_MAX_SLAVE - 1) {
+ mem_copy_len = sizeof(struct roce5_bond_slave) *
+ (ROCE_BOND_MAX_SLAVE - slave_index - 1);
+ ret = memmove_s((void *)&rbdev->slaves[slave_index],
+ mem_copy_len,
+ (void *)&rbdev->slaves[slave_index + 1],
+ mem_copy_len);
+ if (ret != EOK) {
+ ROCE_ERR("Failed to execute memmove, ret(%d).", ret);
+ mutex_unlock(&rbdev->slave_lock);
+ goto err_out;
+ }
+ }
+
+ ret = memset_s((void *)&rbdev->slaves[ROCE_BOND_MAX_SLAVE - 1],
+ sizeof(struct roce5_bond_slave), 0,
+ sizeof(struct roce5_bond_slave));
+ if (ret != 0) {
+ ROCE_ERR("Failed to execute memmove, ret(%d).", ret);
+ mutex_unlock(&rbdev->slave_lock);
+ goto err_out;
+ }
+
+ --rbdev->slave_cnt;
+
+ mutex_unlock(&rbdev->slave_lock);
+
+ if (rbdev->slave_cnt == 0 && rbdev->attached_rdev != NULL) {
+ if (rbdev->bond_lld_dev == NULL) {
+ ROCE_ERR("Impossible situation! bond lld is NULL.");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ hinic5_detach_service(rbdev->bond_lld_dev, SERVICE_T_ROCE);
+ if (rbdev->attached_rdev != NULL) {
+ ROCE_ERR(
+ "Failed to detach roce service, bond name(%s).",
+ rbdev->name);
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ rbdev->bond_lld_dev = NULL;
+ }
+
+ ret = roce5_bond_del_slave_table(rbdev, slave_temp.er_id,
+ slave_temp.func_id);
+ if (ret != 0) {
+ ROCE_WARN(
+ "Failed to delete table entries of slave(%u), ret(%d).",
+ slave_temp.func_id, ret);
+ ret = 0;
+ }
+
+ ret = hinic5_attach_service(slave_temp.lld_dev, SERVICE_T_ROCE);
+ if (ret != 0) {
+ ROCE_ERR("Failed to attach roce function, func_id(%u).",
+ slave_temp.func_id);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ return ret;
+}
+
+/*
+ * roce5_find_same_slave_and_update - Find and update existing slave
+ * @rbdev: bond device
+ * @tracker: bond tracker from CFM framework
+ * @slave_sync: slave synchronization info
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_find_same_slave_and_update(struct roce5_bond_device *rbdev,
+ struct bond_tracker *tracker,
+ struct roce5_bond_slave_sync *slave_sync)
+{
+ int ret = 0;
+ int i;
+ int roce_slave_index;
+ int tracker_slave_cnt = 0;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ char chip_name[IFNAMSIZ] = { 0 };
+ int err;
+
+ ret = memset_s(slave_sync, sizeof(struct roce5_bond_slave_sync), 0,
+ sizeof(struct roce5_bond_slave_sync));
+ if (ret != 0) {
+ ROCE_ERR("Failed to init slave sync info, ret(%d).", ret);
+ return ret;
+ }
+
+ mutex_lock(&rbdev->slave_lock);
+
+ if (rbdev->bond_lld_dev != NULL) {
+ err = hinic5_get_chip_name(rbdev->bond_lld_dev, chip_name,
+ sizeof(chip_name));
+ if (err != 0) {
+ ROCE_ERR("Bond dev get chip name err %d.", err);
+ mutex_unlock(&rbdev->slave_lock);
+ return err;
+ }
+ }
+
+ for (i = 0; i < BOND_PORT_MAX_NUM && tracker_slave_cnt < tracker->cnt;
+ ++i) {
+ if (tracker->ndev[i] == NULL) {
+ continue;
+ }
+
+ roce_slave_index = roce5_get_bond_slave_index_by_ndev(
+ rbdev, tracker->ndev[i]);
+ if (roce_slave_index == -ENODEV) {
+ lld_dev =
+ hinic5_get_lld_dev_by_netdev(tracker->ndev[i]);
+ err = roce5_bond_slave_check(lld_dev, chip_name,
+ sizeof(chip_name));
+ if (err != 0) {
+ ROCE_ERR("Bond slave check err %d.", err);
+ mutex_unlock(&rbdev->slave_lock);
+ return err;
+ }
+
+ slave_sync->new_ndev[slave_sync->new_ndev_num] =
+ tracker->ndev[i];
+ slave_sync->new_ndev_state[slave_sync->new_ndev_num] =
+ tracker->netdev_state[i];
+ ++slave_sync->new_ndev_num;
+ } else {
+ slave_sync->exist_arr[roce_slave_index] = true;
+
+ /* update state of the slave */
+ rbdev->slaves[roce_slave_index].netdev_state.link_up =
+ tracker->netdev_state[i].link_up;
+ rbdev->slaves[roce_slave_index].netdev_state.tx_enabled =
+ tracker->netdev_state[i].tx_enabled;
+ }
+
+ ++tracker_slave_cnt;
+ }
+
+ mutex_unlock(&rbdev->slave_lock);
+
+ return ret;
+}
+
+/*
+ * roce5_handle_diff_slave - Handle different slaves during bond modify
+ * @rbdev: bond device
+ * @tracker: bond tracker from CFM framework
+ * Return: 0 on success, negative error code on failure
+ */
+int roce5_handle_diff_slave(struct roce5_bond_device *rbdev,
+ struct bond_tracker *tracker)
+{
+ u32 i;
+ int ret = 0;
+ struct roce5_bond_slave_sync slave_sync;
+
+ ret = roce5_find_same_slave_and_update(rbdev, tracker, &slave_sync);
+ if (ret != 0) {
+ ROCE_ERR("Failed to find same netdev.");
+ return ret;
+ }
+
+ /* delete slaves */
+ for (i = rbdev->slave_cnt; i > 0; --i) {
+ if (slave_sync.exist_arr[i - 1] == false) {
+ ret = roce5_bond_del_slave(rbdev, i - 1);
+ if (ret != 0) {
+ ROCE_ERR("Failed to delete slave, ret(%d).",
+ ret);
+ return ret;
+ }
+ }
+ }
+
+ /* add new slaves */
+ for (i = 0; i < slave_sync.new_ndev_num; ++i) {
+ ret = roce5_bond_add_slave(rbdev, slave_sync.new_ndev[i],
+ &slave_sync.new_ndev_state[i], true);
+ if (ret != 0) {
+ ROCE_ERR("Failed to add new slave, ret(%d).", ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* ROCE_BONDING_EN */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_tx.c b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_tx.c
new file mode 100644
index 000000000..dd34d319e
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/bond/roce_bond_tx.c
@@ -0,0 +1,94 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
+
+
+#ifdef ROCE_BONDING_EN
+
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include <net/bonding.h>
+#include <linux/atomic.h>
+
+#include "securec.h"
+
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "roce_bond.h"
+#include "roce_bond_internal.h"
+#include "roce_cmd.h"
+#include "roce_netdev.h"
+#include "roce_infra.h"
+
+/*
+ * roce5_bond_get_netdev - Get bond netdev for TX
+ * @rdev: RoCE device
+ * Return: netdev with increased reference count, NULL if no bond
+ * Refcount: caller must call dev_put() when done
+ */
+struct net_device *roce5_bond_get_netdev(struct roce5_device *rdev)
+{
+ u32 i;
+ struct roce5_bond_device *bond_dev = rdev->bond_dev;
+ struct net_device *ret_dev = NULL;
+ struct slave *slave = NULL;
+
+ mutex_lock(&g_roce5_bond_mutex);
+ if (bond_dev == NULL) {
+ mutex_unlock(&g_roce5_bond_mutex);
+ return ret_dev;
+ }
+
+ mutex_lock(&bond_dev->slave_lock);
+ for (i = 0; i < bond_dev->slave_cnt; i++) {
+ rcu_read_lock();
+ slave = bond_slave_get_rcu(bond_dev->slaves[i].netdev);
+ rcu_read_unlock();
+ if (slave == NULL) {
+ continue;
+ }
+ if (bond_is_active_slave(slave)) {
+ if (netif_running(bond_dev->slaves[i].netdev) &&
+ netif_carrier_ok(bond_dev->slaves[i].netdev)) {
+ ret_dev = bond_dev->slaves[i].netdev;
+ } else if (netif_running(
+ bond_dev->slaves[(i + 1) %
+ bond_dev->slave_cnt]
+ .netdev) &&
+ netif_carrier_ok(
+ bond_dev->slaves[(i + 1) %
+ bond_dev->slave_cnt]
+ .netdev)) {
+ ret_dev = bond_dev->slaves[(i + 1) %
+ bond_dev->slave_cnt]
+ .netdev;
+ } else {
+ ret_dev = bond_dev->slaves[i].netdev;
+ }
+ dev_hold(ret_dev);
+ mutex_unlock(&bond_dev->slave_lock);
+ mutex_unlock(&g_roce5_bond_mutex);
+ return ret_dev;
+ }
+ }
+ mutex_unlock(&bond_dev->slave_lock);
+ mutex_unlock(&g_roce5_bond_mutex);
+ return ret_dev;
+}
+
+/*
+ * roce5_bond_rr_set_flow - Set flow hash for round-robin TX selection
+ * @rdev: RoCE device
+ * @rqp: RoCE QP
+ * @qp_attr: QP attributes
+ */
+void roce5_bond_rr_set_flow(struct roce5_device *rdev, struct roce5_qp *rqp,
+ roce_verbs_qp_attr_s *qp_attr)
+{
+ rqp->tx_hash_value = (u32)atomic_add_return(1, &rdev->next_port);
+ qp_attr->path_info.dw0.bs.bond_tx_hash_value =
+ (rqp->tx_hash_value & 0xf);
+}
+
+#endif /* ROCE_BONDING_EN */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/debug/roce_debug.h b/drivers/infiniband/hw/hiroce5/kernel/util/debug/roce_debug.h
new file mode 100644
index 000000000..6b919d753
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/debug/roce_debug.h
@@ -0,0 +1,25 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_DEBUG_H
+#define ROCE_DEBUG_H
+
+/*
+ * DEBUG_ONLY: statement is only valid in debug mode.
+ *
+ * RELEASE_ONLY: statement is only valid in release mode.
+ *
+ * DEBUG_REPLACE: used in functions of release to indicate the function may be replaced by another function with the
+ * same name defined in the debug mode.
+ */
+#ifdef ENABLE_DEBUG
+#define DEBUG_ONLY(statement) statement
+#define RELEASE_ONLY(statement)
+#define DEBUG_REPLACE __attribute__((weak))
+#else
+#define DEBUG_ONLY(statement)
+#define RELEASE_ONLY(statement) statement
+#define DEBUG_REPLACE
+#endif
+
+#endif /* ROCE_DEBUG_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.c b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.c
new file mode 100644
index 000000000..787a86791
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.c
@@ -0,0 +1,375 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+
+
+#ifdef __ROCE_DFX__
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+
+#include "roce.h"
+#include "hinic5_mt.h"
+#include "roce_cc_format.h"
+#include "roce_cmd.h"
+#include "roce_mpu_cmd.h"
+#include "roce_mpu_cmd_defs.h"
+#include "securec.h"
+#include "roce_dfx.h"
+
+int roce5_get_drv_version(void *buf_out, u32 *out_size)
+{
+ struct drv_version_info *ver_info = buf_out;
+ int rc;
+
+ if (!buf_out || !out_size) {
+ ROCE_ERR("Input params is NULL.");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(*ver_info)) {
+ ROCE_ERR("Unexpect out buf size from user :%u, expect: %lu",
+ *out_size, sizeof(*ver_info));
+ return -EINVAL;
+ }
+
+ rc = snprintf_s(ver_info->ver, sizeof(ver_info->ver),
+ sizeof(ver_info->ver) - 1, "%s %s",
+ HIROCE5_DRV_VERSION, __TIME_STR__);
+ if (rc == -1) {
+ ROCE_ERR("Snprintf roce version err");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+void *
+roce5_adm_generic_find_cmd_func(const roce5_adm_generic_cmd_proc_t *cmd_array,
+ int elem_count, u32 target_cmd)
+{
+ int i;
+
+ if (cmd_array == NULL || elem_count <= 0) {
+ return NULL;
+ }
+
+ for (i = 0; i < elem_count; i++) {
+ if (cmd_array[i].cmd_type == target_cmd &&
+ cmd_array[i].proc_func != NULL) {
+ return cmd_array[i].proc_func;
+ }
+ }
+ return NULL;
+}
+
+static int roce5_dfx_enable_bw_ctrl(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_inbuf *inbuf,
+ struct roce5_bw_ctrl_outbuf *outbuf)
+{
+ if (rdev->hw_info.hca_type == ROCE5_2_100G_HCA) {
+ inbuf->ctrl_param.cir = ROCE5_100G_CIR;
+ inbuf->ctrl_param.pir = ROCE5_100G_PIR;
+ inbuf->ctrl_param.cnp = ROCE5_100G_CNP;
+ } else {
+ inbuf->ctrl_param.cir = ROCE5_25G_CIR;
+ inbuf->ctrl_param.pir = ROCE5_25G_PIR;
+ inbuf->ctrl_param.cnp = ROCE5_25G_CNP;
+ }
+ return roce5_set_bw_ctrl_state(rdev, ROCE_BW_CTRL_EN, inbuf);
+}
+
+static int roce5_dfx_disable_bw_ctrl(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_inbuf *inbuf,
+ struct roce5_bw_ctrl_outbuf *outbuf)
+{
+ inbuf->ctrl_param.cir = 0;
+ inbuf->ctrl_param.pir = 0;
+ inbuf->ctrl_param.cnp = 0;
+ return roce5_set_bw_ctrl_state(rdev, ROCE_BW_CTRL_DIS, inbuf);
+}
+
+static int roce5_dfx_change_bw_ctrl_param(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_inbuf *inbuf,
+ struct roce5_bw_ctrl_outbuf *outbuf)
+{
+ return roce5_set_bw_ctrl_state(rdev, ROCE_BW_CTRL_RESET, inbuf);
+}
+
+static int roce5_dfx_query_bw_ctrl_param(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_inbuf *inbuf,
+ struct roce5_bw_ctrl_outbuf *outbuf)
+{
+ return roce5_query_bw_ctrl_state(rdev, &outbuf->bw_ctrl_param);
+}
+
+static const roce5_adm_dfx_bw_ctrl_cmd_proc_t
+ g_roce5_adm_dfx_bw_ctrl_cmd_proc[] = {
+ { ROCE_CMD_ENABLE_BW_CTRL, roce5_dfx_enable_bw_ctrl },
+ { ROCE_CMD_DISABLE_BW_CTRL, roce5_dfx_disable_bw_ctrl },
+ { ROCE_CMD_CHANGE_BW_CTRL_PARAM,
+ roce5_dfx_change_bw_ctrl_param },
+ { ROCE_CMD_QUERY_BW_CTRL_PARAM, roce5_dfx_query_bw_ctrl_param },
+ };
+
+int roce5_adm_dfx_bw_ctrl(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ int ret;
+ struct roce5_bw_ctrl_inbuf *inbuf =
+ (struct roce5_bw_ctrl_inbuf *)buf_in;
+ struct roce5_bw_ctrl_outbuf *outbuf =
+ (struct roce5_bw_ctrl_outbuf *)buf_out;
+ const roce5_adm_generic_cmd_proc_t *generic_array =
+ (const roce5_adm_generic_cmd_proc_t *)
+ g_roce5_adm_dfx_bw_ctrl_cmd_proc;
+ int elem_count = sizeof(g_roce5_adm_dfx_bw_ctrl_cmd_proc) /
+ sizeof(g_roce5_adm_dfx_bw_ctrl_cmd_proc[0]);
+ roce5_adm_dfx_bw_ctrl_func_t roce5_adm_dfx_bw_ctrl_func = NULL;
+
+ if (in_size < sizeof(struct roce5_bw_ctrl_inbuf)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(struct roce5_bw_ctrl_inbuf));
+ return -ENOMEM;
+ }
+ if (*out_size < sizeof(struct roce5_bw_ctrl_outbuf)) {
+ ROCE_ERR(
+ "Input parameter(out_zise: %dB) is shorter than allocated buffer(allocated: %dB)",
+ (int)*out_size,
+ (int)sizeof(struct roce5_bw_ctrl_outbuf));
+ return -ENOMEM;
+ }
+ ret = memset_s(buf_out, sizeof(struct roce5_bw_ctrl_outbuf), 0,
+ sizeof(struct roce5_bw_ctrl_outbuf));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset buf_out.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ *out_size = sizeof(struct roce5_bw_ctrl_outbuf);
+
+ if (inbuf->cmd_type >= VM_COMPAT_TEST) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ roce5_adm_dfx_bw_ctrl_func =
+ (roce5_adm_dfx_bw_ctrl_func_t)roce5_adm_generic_find_cmd_func(
+ generic_array, elem_count, inbuf->cmd_type);
+ if (roce5_adm_dfx_bw_ctrl_func == NULL) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ return roce5_adm_dfx_bw_ctrl_func(rdev, inbuf, outbuf);
+}
+
+int roce5_adm_dfx_set_ldcp_param(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ int ret;
+ roce_ldcp_param_s ldcp_param;
+ const struct roce5_ldcp_param *inbuf =
+ (struct roce5_ldcp_param *)buf_in;
+
+ if (in_size < sizeof(struct roce5_ldcp_param)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(struct roce5_ldcp_param));
+ return -ENOMEM;
+ }
+ if (inbuf->cmd_type != ROCE_CMD_SET_LDCP_PARAM) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ ldcp_param.dw0.bs.alpha = inbuf->ldcp_param.alpha & 0xf;
+ ldcp_param.dw0.bs.beta = inbuf->ldcp_param.beta & 0xf;
+ ldcp_param.dw0.bs.gamma = inbuf->ldcp_param.gamma & 0xf;
+ ldcp_param.dw0.bs.eta = inbuf->ldcp_param.eta & 0xf;
+ ldcp_param.dw0.bs.set_flag = inbuf->ldcp_param.set_flag & 0x1;
+
+ ret = roce5_set_sysfs_cfg_param(rdev->hwdev, rdev->glb_func_id,
+ (u32 *)(void *)&ldcp_param,
+ sizeof(roce_ldcp_param_s),
+ (u16)ROCE_MPU_CMD_CC_CFG_LDCP_PARAM);
+ if (ret != 0) {
+ ROCE_ERR("Failed to set ldcp param.(ret:%d)", ret);
+ } else {
+ ROCE_WARN("Set ldcp param 0x%x", ldcp_param.dw0.value);
+ }
+ return ret;
+}
+
+int roce5_adm_dfx_port_traffic(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ roce_mpu_port_statics_cmd_inbuf_t inbuf;
+ roce_port_sta_outbuf_t *outbuf = (roce_port_sta_outbuf_t *)buf_out;
+ int ret;
+
+ memset_s(&inbuf, sizeof(inbuf), 0, sizeof(inbuf));
+ inbuf.cmd = *(roce_port_sta_inbuf_t *)buf_in;
+ outbuf->head.status = 0xFF;
+
+ if (in_size < sizeof(roce_port_sta_inbuf_t)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(roce_port_sta_inbuf_t));
+ return -ENOMEM;
+ }
+ if (inbuf.cmd.cmd_type != ROCE_CMD_PORT_TRAFFIC) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d).",
+ inbuf.cmd.cmd_type);
+ return -EINVAL;
+ }
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_DFX_PORT_TRAFFIC,
+ (void *)&inbuf, (u16)sizeof(inbuf),
+ buf_out, (u16 *)(void *)out_size);
+ if ((ret != 0) || (*out_size == 0) || (outbuf->head.status != 0)) {
+ ROCE_ERR(
+ "Failed to query port traffic, err(%d), out size(0x%x) status(0x%x)",
+ ret, *out_size, outbuf->head.status);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#ifdef ROCE_CHIP_TEST
+static const roce5_adm_dfx_vnic_waterline_cmd_proc_t
+ g_roce5_adm_dfx_vnic_wl_cmd_proc[] = {
+ { ROCE_CMD_SET_VNIC_WATERLINE, roce5_set_vnic_waterline_state },
+ { ROCE_CMD_GET_VNIC_WATERLINE, roce5_get_vnic_waterline_state },
+ };
+
+int roce5_adm_dfx_vnic_wl_ctrl(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ int ret;
+ struct roce5_vnic_waterline_ctrl_buf *inbuf =
+ (struct roce5_vnic_waterline_ctrl_buf *)buf_in;
+ struct roce5_vnic_waterline_ctrl_buf *outbuf =
+ (struct roce5_vnic_waterline_ctrl_buf *)buf_out;
+ const roce5_adm_generic_cmd_proc_t *generic_array =
+ (const roce5_adm_generic_cmd_proc_t *)
+ g_roce5_adm_dfx_vnic_wl_cmd_proc;
+ int elem_count = sizeof(g_roce5_adm_dfx_vnic_wl_cmd_proc) /
+ sizeof(g_roce5_adm_dfx_vnic_wl_cmd_proc[0]);
+ roce5_adm_dfx_vnic_waterline_ctrl_func_t roce5_adm_dfx_vnic_wl_ctrl_func;
+
+ if (in_size < sizeof(struct roce5_vnic_waterline_ctrl_buf)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size,
+ (int)sizeof(struct roce5_vnic_waterline_ctrl_buf));
+ return -EINVAL;
+ }
+
+ if (inbuf->cmd_type >= VM_COMPAT_TEST) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ ret = memset_s(buf_out, sizeof(struct roce5_vnic_waterline_ctrl_buf), 0,
+ sizeof(struct roce5_vnic_waterline_ctrl_buf));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset buf_out.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ roce5_adm_dfx_vnic_wl_ctrl_func =
+ (roce5_adm_dfx_vnic_waterline_ctrl_func_t)
+ roce5_adm_generic_find_cmd_func(
+ generic_array, elem_count, inbuf->cmd_type);
+ if (roce5_adm_dfx_vnic_wl_ctrl_func == NULL) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d)",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ return roce5_adm_dfx_vnic_wl_ctrl_func(rdev, inbuf, outbuf);
+}
+
+#endif /* ROCE_CHIP_TEST */
+
+int roce5_adm_dfx_roce_set(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+
+{
+ roce_dfx_set_cmd_s inbuf;
+ roce_dfx_set_outbuf_s *outbuf = (roce_dfx_set_outbuf_s *)buf_out;
+ int ret;
+
+ if (in_size < sizeof(roce_dfx_set_inbuf_s)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(roce_dfx_set_inbuf_s));
+ return -ENOMEM;
+ }
+
+ memset_s(&inbuf, sizeof(inbuf), 0, sizeof(inbuf));
+ inbuf.cmd = *(roce_dfx_set_inbuf_s *)buf_in;
+ inbuf.cmd.func_id = rdev->glb_func_id;
+
+ if (inbuf.cmd.cmd_type != ROCE_CMD_ROCE_SET) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d).",
+ inbuf.cmd.cmd_type);
+ return -EINVAL;
+ }
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev, ROCE_MPU_CMD_DFX_ROCE_SET,
+ (void *)&inbuf, (u16)sizeof(inbuf), outbuf,
+ (u16 *)(void *)out_size);
+ if ((ret != 0) || (*out_size == 0) || (outbuf->head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set roce configs, err(%d), out size(0x%x) status(0x%x)",
+ ret, *out_size, outbuf->head.status);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int roce5_adm_dfx_roce_set_debug(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+
+{
+ roce_dfx_set_debug_cmd_s inbuf;
+ roce_dfx_set_debug_outbuf_s *outbuf =
+ (roce_dfx_set_debug_outbuf_s *)buf_out;
+ int ret;
+
+ if (in_size < sizeof(roce_dfx_set_debug_inbuf_s)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size, (int)sizeof(roce_dfx_set_debug_inbuf_s));
+ return -ENOMEM;
+ }
+
+ memset_s(&inbuf, sizeof(inbuf), 0, sizeof(inbuf));
+ inbuf.cmd = *(roce_dfx_set_debug_inbuf_s *)buf_in;
+ inbuf.cmd.func_id = rdev->glb_func_id;
+
+ if (inbuf.cmd.cmd_type != ROCE_CMD_ROCE_SET_DEBUG) {
+ ROCE_DEV_ERR(rdev, "Not support this type(%d).",
+ inbuf.cmd.cmd_type);
+ return -EINVAL;
+ }
+
+ ret = roce5_msg_to_mgmt_sync(rdev->hwdev,
+ ROCE_MPU_CMD_DFX_ROCE_SET_DEBUG,
+ (void *)&inbuf, (u16)sizeof(inbuf), outbuf,
+ (u16 *)(void *)out_size);
+ if ((ret != 0) || (*out_size == 0) || (outbuf->head.status != 0)) {
+ ROCE_ERR(
+ "Failed to set roce configs, err(%d), out size(0x%x) status(0x%x)",
+ ret, *out_size, outbuf->head.status);
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif /* __ROCE_DFX__ */
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.h b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.h
new file mode 100644
index 000000000..139867581
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx.h
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+
+
+#ifndef ROCE_DFX_H
+#define ROCE_DFX_H
+
+#include <linux/types.h>
+
+#include "hinic5_rdma.h"
+
+#include "roce_sysfs.h"
+#include "roce.h"
+#include "roce_gid.h"
+#include "roce_compat.h"
+#include "roce_pub_cmd.h"
+#include "roce_npu_cmd_dfx_defs.h"
+#include "roce_debug.h"
+
+#include "securec.h"
+
+#define MR_KEY_2_INDEX_SHIFT 8
+
+#define ROCE_IO_DFX_CFG_VADDR_ID 0
+#define ROCE_IO_DFX_CFG_PADDR_ID 1
+#define ROCE_IO_DFX_CFG_ADDR_NUM 2
+
+#define roce5_dfx_print(fmt, args...) \
+ do { \
+ (void)printk("[roce5_dfx] : " fmt "\n", ##args); \
+ } while (0)
+
+typedef struct tag_roce_cmd_mpt_query {
+ roce_verbs_cmd_com_s com;
+} roce_cmd_mpt_query_s;
+
+typedef struct roce5_mpt_query_outbuf {
+ u32 value[16];
+} roce5_mpt_query_outbuf_s;
+
+typedef struct tag_roce_cmd_roce_cq_query {
+ roce_verbs_cmd_com_s com;
+} roce_cmd_cq_query_s;
+
+typedef struct roce5_cq_query_outbuf {
+ u32 value[32];
+} roce5_cq_query_outbuf_s;
+
+typedef struct tag_roce_cmd_qp_query {
+ roce_verbs_cmd_com_s com;
+} roce_cmd_qp_query_s;
+
+typedef struct roce5_qp_query_outbuf {
+ u32 context[128];
+} roce5_qp_query_outbuf_s;
+
+typedef struct roce5_srq_query_outbuf {
+ u32 value[24];
+} roce5_srq_query_outbuf_s;
+
+struct roce5_dfx_query_inbuf {
+ u32 cmd_type;
+ union {
+ u32 qpn;
+ u32 cqn;
+ u32 srqn;
+ u32 mpt_key;
+ u32 gid_index;
+ struct {
+ u32 qpn;
+ u32 cqn;
+ } query_pi_ci;
+ };
+};
+
+#define ROCE_DEV_NAME_LEN_MAX 64
+
+struct roce5_dfx_dbg_inbuf {
+ u32 cmd_type;
+ union {
+ u32 qpn;
+ u32 srqn;
+ };
+ char dev_name[ROCE_DEV_NAME_LEN_MAX];
+};
+
+#define ROCE_CTX_MAX_SIZE 512 // adaptation lock store referencein of structure
+
+union roce5_dfx_dbg_outbuf {
+ roce_verbs_qp_attr_s qp_attr;
+ roce_verbs_srq_attr_dfx_s srq_attr;
+ u32 buf[ROCE_CTX_MAX_SIZE];
+ u32 algo_type;
+ u32 dev_type;
+};
+
+struct roce5_dfx_common_inbuf {
+ u32 cmd_type;
+ char dev_name[ROCE_DEV_NAME_LEN_MAX];
+};
+
+union roce5_dfx_common_outbuf {
+ u32 dev_type;
+};
+
+struct roce5_dfx_pi_ci {
+ u32 qpc_sq_pi_on_chip;
+ u32 qpc_sq_pi;
+ u32 qpc_sq_load_pi;
+ u32 qpc_rq_pi_on_chip;
+ u32 qpc_rq_load_pi;
+ u32 qpc_rq_pi;
+ u32 qpc_rc_pi;
+ u32 qpc_sq_ci;
+ u32 qpc_sq_wqe_prefetch_ci;
+ u32 qpc_sq_mtt_prefetch_wqe_ci;
+ u32 qpc_sqa_ci;
+ u32 qpc_sqa_wqe_prefetch_ci;
+ u32 qpc_rq_ci;
+ u32 qpc_rq_wqe_prefetch_ci;
+ u32 qpc_rq_mtt_prefetch_wqe_ci;
+ u32 qpc_rq_base_ci;
+ u32 qpc_rc_ci;
+ u32 qpc_rc_prefetch_ci;
+ u32 cq_ci_on_chip;
+ u32 cq_ci;
+ u32 cq_load_ci;
+ u64 cq_ci_record_gpa_at_hop_num;
+ u32 cq_last_solicited_pi;
+ u32 cq_pi;
+ u32 cq_last_notified_pi;
+};
+
+struct roce5_dfx_qp_count {
+ u32 qp_alloced;
+ u32 qp_deleted;
+ u32 qp_alive;
+};
+
+#define ROCE_GID_ENTRY_NUM 17 // 1 host fe + 16 shadow fe
+union roce5_dfx_query_outbuf {
+ /* query cache context */
+ roce_verbs_qp_attr_s qp_attr;
+ roce_verbs_cq_attr_s cq_attr;
+ roce_verbs_srq_attr_s srq_attr;
+ roce_verbs_mr_attr_s mr_attr;
+ /* query host context */
+ roce5_qp_query_outbuf_s qp_query;
+ roce5_cq_query_outbuf_s cq_query;
+ roce5_srq_query_outbuf_s srq_query;
+ struct roce_mpt_context mpt;
+ struct rdma_gid_entry gid_entry[ROCE_GID_ENTRY_NUM];
+ struct roce5_dfx_pi_ci pi_ci;
+ struct roce5_dfx_qp_count qp_count;
+ u32 algo_type;
+ struct roce_uni_cmd_latch_data latch_data_outbuf;
+};
+
+enum roce5_bw_ctrl_cmd_e {
+ ROCE_BW_CTRL_DIS,
+ ROCE_BW_CTRL_EN,
+ ROCE_BW_CTRL_RESET
+};
+
+enum roce5_qos_wl_ctrl_cmd_e {
+ ROCE_QOS_WL_CTRL_CMD_SET,
+ ROCE_QOS_WL_CTRL_CMD_GET
+};
+
+struct rdma_gid_query_outbuf {
+ struct rdma_gid_entry gid_entry[ROCE_GID_ENTRY_NUM];
+};
+
+struct roce5_bw_ctrl_inbuf {
+ u32 cmd_type;
+ struct {
+ u32 cir;
+ u32 pir;
+ u32 cnp;
+ } ctrl_param;
+};
+
+struct roce5_bw_set_inbuf {
+ u32 cmd_type;
+ struct {
+ u32 mod;
+ u32 cir;
+ u32 cbs;
+ u32 pir;
+ u32 pbs;
+ } set_param;
+};
+
+struct roce5_bw_ctrl_param {
+ u8 color_type;
+ u16 ptype;
+ u8 hw_wred_mode;
+
+ u32 cir;
+ u32 pir;
+ u32 cbs;
+ u32 xbs;
+ u32 cnp;
+ u32 enable;
+};
+
+struct roce5_bw_set_param {
+ u16 ptype;
+ u8 color_type;
+ u8 hw_wred_mode;
+
+ u32 cir;
+ u32 cbs;
+ u32 pir;
+ u32 pbs;
+ u32 enable;
+};
+
+struct roce5_ldcp_param {
+ u32 cmd_type;
+ struct {
+ u8 alpha;
+ u8 beta;
+ u8 gamma;
+ u8 eta;
+ u8 set_flag;
+ } ldcp_param;
+};
+
+struct roce5_bw_ctrl_outbuf {
+ struct roce5_bw_ctrl_param bw_ctrl_param;
+};
+
+struct roce5_bw_set_outbuf {
+ struct roce5_bw_set_param bw_set_param;
+};
+
+enum roce5_dfx_io_cmd_type { ROCE_IO_CTRL_DIS, ROCE_IO_CTRL_EN };
+
+struct roce5_dfx_io_alarm {
+ enum roce5_dfx_io_cmd_type en_flag;
+ u16 pf_id;
+ u16 rsvd;
+ u16 io_latency_thd;
+ u16 exec_time;
+ u32 exp_qpn;
+ void *rcd_uaddr;
+ struct timespec64 start;
+ struct mutex io_alarm_mutex;
+};
+
+struct roce5_dfx_io_inbuf {
+ u32 cmd_type;
+ struct roce5_dfx_io_alarm io_alarm;
+};
+
+struct roce5_dfx_io_outbuf {
+ struct roce5_dfx_io_alarm io_alarm;
+};
+
+typedef struct roce5_adm_generic_cmd_proc {
+ u32 cmd_type;
+ void *proc_func;
+} roce5_adm_generic_cmd_proc_t;
+
+typedef int (*roce5_adm_func_t)(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+typedef struct roce5_adm_cmd_proc {
+ u32 cmd_type;
+ roce5_adm_func_t proc_func;
+} roce5_adm_cmd_proc_t;
+
+typedef int (*roce5_adm_dfx_dbg_t)(struct roce5_device *rdev,
+ const struct roce5_dfx_dbg_inbuf *inbuf,
+ union roce5_dfx_dbg_outbuf *outbuf);
+
+typedef struct roce5_adm_dfx_dbg_cmd_proc {
+ u32 cmd_type;
+ roce5_adm_dfx_dbg_t proc_func;
+} roce5_adm_dfx_dbg_cmd_proc_t;
+
+typedef int (*roce5_adm_dfx_query_t)(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf);
+
+typedef struct roce5_adm_dfx_query_cmd_proc {
+ u32 cmd_type;
+ roce5_adm_dfx_query_t proc_func;
+} roce5_adm_dfx_query_cmd_proc_t;
+
+typedef int (*roce5_adm_dfx_bw_ctrl_func_t)(struct roce5_device *rdev,
+ struct roce5_bw_ctrl_inbuf *inbuf,
+ struct roce5_bw_ctrl_outbuf *outbuf);
+
+typedef struct roce5_adm_dfx_bw_ctrl_cmd_proc {
+ u32 cmd_type;
+ roce5_adm_dfx_bw_ctrl_func_t proc_func;
+} roce5_adm_dfx_bw_ctrl_cmd_proc_t;
+
+#ifdef ROCE_CHIP_TEST
+typedef struct roce5_vnic_waterline_ctrl_param {
+ u16 red_waterline;
+ u16 yellow_waterline;
+ u32 ip_val;
+} roce5_vnic_waterline_ctrl_param_s;
+
+struct roce5_vnic_waterline_ctrl_buf {
+ u32 cmd_type;
+ roce5_vnic_waterline_ctrl_param_s waterline_param;
+};
+
+typedef int (*roce5_adm_dfx_vnic_waterline_ctrl_func_t)(
+ struct roce5_device *rdev, struct roce5_vnic_waterline_ctrl_buf *inbuf,
+ struct roce5_vnic_waterline_ctrl_buf *outbuf);
+
+typedef struct roce5_adm_dfx_vnic_waterline_cmd_proc {
+ u32 cmd;
+ roce5_adm_dfx_vnic_waterline_ctrl_func_t proc_func;
+} roce5_adm_dfx_vnic_waterline_cmd_proc_t;
+
+int roce5_adm_dfx_vnic_wl_ctrl(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+#endif /* ROCE_CHIP_TEST */
+
+/* and above next is V100 compatible data structure */
+typedef struct tag_roce_qurey_gid {
+ roce_verbs_cmd_com_s com;
+ __be32 port;
+} roce_cmd_query_gid_s;
+
+typedef int (*roce_adm_dfx_attack_func_t)(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf);
+struct roce_dfx_attack_cmd_func {
+ u32 cmd_id;
+ roce_adm_dfx_attack_func_t cmd_func;
+};
+
+DEBUG_REPLACE int roce5_get_drv_version(void *buf_out, u32 *out_size);
+void *
+roce5_adm_generic_find_cmd_func(const roce5_adm_generic_cmd_proc_t *cmd_array,
+ int elem_count, u32 target_cmd);
+int roce5_adm_dfx_query(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int roce5_adm_dfx_bw_ctrl(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int roce5_adm_dfx_set_ldcp_param(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int roce5_adm_dfx_port_traffic(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int roce5_adm_dfx_dbg(struct roce5_device *rdev, const void *buf_in,
+ void *buf_out, u32 *out_size);
+int roce5_adm_dfx_roce_set(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int roce5_adm_dfx_roce_set_debug(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+int roce5_dfx_attack_func(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+void roce5_dfx_clean_up(struct roce5_device *rdev);
+
+void *global_roce5_io_alarm_va_get(void);
+
+void global_roce5_io_alarm_va_set(u64 va);
+
+void global_roce5_io_alarm_pa_set(dma_addr_t pa);
+
+dma_addr_t global_roce5_io_alarm_pa_get(void);
+
+int roce5_dfx_query_cq(struct roce5_device *rdev, u32 cqn, u32 *context,
+ int cqc_size);
+
+int roce5_dfx_cmd_query_srq(struct roce5_device *rdev, u32 srqn,
+ roce_verbs_srq_attr_s *srq_attr);
+
+#endif // __ROCE_DFX_H__
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_attack.c b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_attack.c
new file mode 100644
index 000000000..84cc1455b
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_attack.c
@@ -0,0 +1,828 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include <linux/semaphore.h>
+
+#include "hinic5_hw.h"
+#include "hinic5_hwdev.h"
+#include "hisdk5_hwif.h"
+#include "hinic5_mt.h"
+#include "rdma_comp.h"
+#include "roce.h"
+#include "roce_qp.h"
+#include "roce_infra.h"
+#include "roce_mr.h"
+#include "roce_dfx.h"
+#include "roce_kernel_compat_gen.h"
+
+#define DB_BUFF_SIZE 2048
+#define DWQE_SIZE 256
+#define DWQE_TYPE_NUM 4
+#define ALIGN_UP_8B(length) (((length) + 7) >> 3)
+#define ALIGN_DOWN_8B(offset) ((offset)&0xfffffff8)
+#define IS_OFFSET_8B_ALIGN(offset) (((offset)&7) != 0)
+#define UPPER_HALF_BIT_OFFSET 32
+#define U32S_PER_U64 2
+
+static void roce5_copy_mask_attack_value_to_addr(u32 *addr, u32 attack_value,
+ u32 mask)
+{
+ u32 val;
+
+ val = *addr;
+ val &= ~mask;
+ val |= (attack_value & mask);
+ *addr = val;
+}
+
+static void roce5_copy_mask_attack_value_to_u64_addr(u64 *addr,
+ u32 attack_value, u32 mask,
+ bool is_upper_half)
+{
+ u64 val;
+
+ val = *addr;
+
+ if (is_upper_half) {
+ val &= ~((u64)mask << UPPER_HALF_BIT_OFFSET);
+ val |= ((u64)(attack_value & mask) << UPPER_HALF_BIT_OFFSET);
+ } else {
+ val &= ~mask;
+ val |= (attack_value & mask);
+ }
+
+ *addr = val;
+}
+
+static int roce5_copy_data_to_page(struct roce5_device *rdev, const u32 *val,
+ struct ib_umem *umem, u32 copy_len,
+ u32 offset, u32 attack_len, u32 mask)
+{
+ struct scatterlist *sg = NULL;
+ u32 *inbuf_tmp = NULL;
+ u32 sg_len;
+ u32 page_copy_len = 0;
+ u32 copied_len = 0;
+ u32 sgl_offset = 0;
+ u64 buf_offset = 0;
+ void *va = NULL;
+ u32 i = 0;
+ int ret;
+
+ inbuf_tmp = (u32 *)kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (inbuf_tmp == NULL) {
+ ROCE_ERR("Failed to alloc inbuf temp.");
+ return -ENOMEM;
+ }
+
+ if (mask == 0) {
+ for (i = 0; i < PAGE_SIZE / sizeof(u32); i++) {
+ inbuf_tmp[i] = val[i % attack_len];
+ }
+ }
+
+ ROCE_INFO(
+ "copy_data_to_page va:%lx, length:%lu, offset:%u, copy_len:%u",
+ umem->address, umem->length, offset, copy_len);
+
+#if defined(IB_UMEM_HAVE_SG_APPEND_TABLE)
+ for_each_sg(umem->sgt_append.sgt.sgl, sg, umem->sgt_append.sgt.nents, i)
+#else
+ //scatterlist of traverse use nents, orig_nents >= nents >= nmap
+ for_each_sg(umem->sg_head.sgl, sg, umem->sg_head.nents, i)
+#endif
+ {
+ sg_len = sg->length;
+ if (buf_offset + sg_len <=
+ offset) { //not found offset of scatterlist, accumulate sg_len, continue 往 next find
+ buf_offset += sg_len;
+ } else { //found offset of scatterlist
+ sgl_offset =
+ offset -
+ (u32)buf_offset; //get based on current scatterlist of offset
+ buf_offset =
+ offset; //found current page after, later of page of offset all max at offset
+
+ va = sg_virt(sg);
+ if (va == NULL) {
+ ROCE_ERR("Failed to get va");
+ kfree(inbuf_tmp);
+ return -ENOMEM;
+ }
+
+ va += sgl_offset;
+ page_copy_len = ((copy_len - copied_len) <
+ (sg_len - sgl_offset)) ?
+ (copy_len - copied_len) :
+ (sg_len - sgl_offset);
+
+ if (mask != 0) {
+ roce5_copy_mask_attack_value_to_addr(
+ (u32 *)va, val[0], mask);
+ ROCE_INFO(
+ "copy mask data to buf, buf_offset:%llu, sgl_offset:%u, mask_val:%u\n",
+ buf_offset, sgl_offset,
+ (val[0] & mask));
+ break;
+ }
+
+ ret = memcpy_s(va, page_copy_len, inbuf_tmp,
+ page_copy_len);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to memcpy attack value, ret(%d)",
+ ret);
+ kfree(inbuf_tmp);
+ return -EFAULT;
+ }
+
+ ROCE_INFO(
+ "copy_data_from_page buf_offset:%llu, sgl_offset:%u, copied_len:%u, page_copy_len:%u, i:%u\n",
+ buf_offset, sgl_offset, copied_len,
+ page_copy_len, i);
+
+ copied_len += page_copy_len;
+ if (copied_len >= copy_len) {
+ break;
+ }
+ }
+ }
+
+ kfree(inbuf_tmp);
+ return 0;
+}
+
+static void roce5_copy_attack_value_to_addr(u64 *addr, u64 attack_value,
+ u32 length)
+{
+ int i;
+ int count = ALIGN_UP_8B(length);
+
+ for (i = 0; i < count; i++) {
+ wmb();
+ *((u64 *)addr + i) = attack_value;
+ wmb();
+ }
+}
+
+static int roce5_dfx_attack_sqdb_hard(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_ucontext *ucontext = NULL;
+ u64 db_phy_start;
+ void __iomem *db_virt_start = NULL;
+ void __iomem *db_virt_offset = NULL;
+ void *hwdev = NULL;
+ struct roce5_qp *rqp = NULL;
+ u32 qpn = inbuf->qpn;
+ union roce_sq_db sq_db;
+ u32 db_offset;
+ u32 db_8B_offset;
+ bool is_upper_half;
+ u32 length;
+
+ hwdev = rdev->hwdev;
+ if (hwdev == NULL) {
+ ROCE_ERR("Roce hwdev is NULL");
+ return -ENOMEM;
+ }
+
+ ucontext = rdev->ucontext;
+ if (ucontext == NULL) {
+ ROCE_ERR("Roce device context is null");
+ return -ENOMEM;
+ }
+
+ db_offset = inbuf->offset;
+ if (db_offset >= DB_BUFF_SIZE) {
+ ROCE_ERR(
+ "roce attack sqdb_hard offset is too large, should be less than %u",
+ DB_BUFF_SIZE);
+ return -EINVAL;
+ }
+
+ db_8B_offset = ALIGN_DOWN_8B(db_offset);
+ db_phy_start = ucontext->db_dma_addr;
+ db_virt_start = (db_phy_start -
+ (((struct hinic5_hwdev *)hwdev)->hwif)->db_base_phy) +
+ (((struct hinic5_hwdev *)hwdev)->hwif)->db_base;
+ db_virt_offset = db_virt_start + db_8B_offset;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ if (inbuf->mask != 0) {
+ is_upper_half = IS_OFFSET_8B_ALIGN(db_offset);
+ roce5_copy_mask_attack_value_to_u64_addr((u64 *)db_virt_offset,
+ inbuf->attack_value[0],
+ inbuf->mask,
+ is_upper_half);
+ ROCE_INFO("roce attack sqdb, mask_val:0x%x, offset:%u",
+ (inbuf->attack_value[0] & inbuf->mask), db_offset);
+ } else {
+ sq_db.sq_db_val = 0;
+ sq_db.sq_db_seg.dw0.value =
+ roce5_convert_be32(inbuf->attack_value[0]);
+ sq_db.sq_db_seg.dw1.value =
+ roce5_convert_be32(inbuf->attack_value[1]);
+
+ length = (db_offset + inbuf->length > DB_BUFF_SIZE) ?
+ (DB_BUFF_SIZE - db_offset) :
+ inbuf->length;
+ roce5_copy_attack_value_to_addr((u64 *)db_virt_offset,
+ sq_db.sq_db_val, length);
+
+ ROCE_INFO("roce attack sqdb length:%u, offset:%u", length,
+ db_offset);
+ ROCE_INFO("roce attack sqdb type:%u, cos:%u, qpn:%u\n",
+ sq_db.sq_db_seg.dw0.bs.type,
+ sq_db.sq_db_seg.dw0.bs.cos,
+ sq_db.sq_db_seg.dw0.bs.qpn);
+ ROCE_INFO("roce attack sqdb mtu_shift:%u, pi:%u\n",
+ sq_db.sq_db_seg.dw1.bs.mtu_shift,
+ sq_db.sq_db_seg.dw1.bs.pi);
+ }
+
+ roce5_rqp_put(rqp);
+ return 0;
+}
+
+static int roce5_copy_attack_value_to_dwqe_addr(u64 *addr, const u32 *val,
+ u32 length, u32 attack_len)
+{
+ int i;
+ int count = ALIGN_UP_8B(length);
+ u64 *inbuf_tmp = NULL;
+ u32 step = 2;
+
+ inbuf_tmp = (u64 *)kzalloc(DWQE_SIZE, GFP_KERNEL);
+ if (inbuf_tmp == NULL) {
+ ROCE_ERR("Failed to alloc inbuf temp.");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < count * U32S_PER_U64; i += step) {
+ inbuf_tmp[i / step] = ((u64)val[(i + 1) % attack_len]
+ << UPPER_HALF_BIT_OFFSET) |
+ val[i % attack_len];
+ }
+
+ for (i = 0; i < count; i++) {
+ wmb();
+ *((u64 *)addr + i) = inbuf_tmp[i];
+ wmb();
+ }
+
+ kfree(inbuf_tmp);
+ return 0;
+}
+
+static int roce5_dfx_attack_dwqe(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_ucontext *ucontext = NULL;
+ u64 dwqe_phy_start;
+ void __iomem *dwqe_virt_start = NULL;
+ void __iomem *dwqe_virt_offset = NULL;
+ void *hwdev = NULL;
+ struct roce5_qp *rqp = NULL;
+ u32 qpn = inbuf->qpn;
+ u32 dwqe_offset;
+ u32 length;
+ u32 dwqe_8B_offset;
+ bool is_upper_half;
+ int i;
+ int ret;
+
+ hwdev = rdev->hwdev;
+ if (hwdev == NULL) {
+ ROCE_ERR("Roce hwdev is NULL");
+ return -ENOMEM;
+ }
+
+ ucontext = rdev->ucontext;
+ if (ucontext == NULL) {
+ ROCE_ERR("Roce device context is null");
+ return -ENOMEM;
+ }
+
+ dwqe_offset = inbuf->offset;
+ if (dwqe_offset >= DWQE_SIZE) {
+ ROCE_ERR(
+ "roce attack dwqe offset is too large, should be less than %u",
+ DWQE_SIZE);
+ return -EINVAL;
+ }
+
+ dwqe_phy_start = ucontext->dwqe_dma_addr;
+ //dwqe physical base address and virtual base address all is based on db perform offset of offset, so corresponding when at db of va basebase on to before offset offset
+ dwqe_virt_start =
+ (dwqe_phy_start -
+ (((struct hinic5_hwdev *)hwdev)->hwif)->db_base_phy) +
+ (((struct hinic5_hwdev *)hwdev)->hwif)->db_base;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ length = (dwqe_offset + inbuf->length > DWQE_SIZE) ?
+ (DWQE_SIZE - dwqe_offset) :
+ (inbuf->length);
+ dwqe_8B_offset = ALIGN_DOWN_8B(dwqe_offset);
+ for (i = 0; i < DWQE_TYPE_NUM; i++) {
+ dwqe_virt_offset =
+ dwqe_virt_start + i * DWQE_SIZE + dwqe_8B_offset;
+ if (inbuf->mask != 0) {
+ is_upper_half = IS_OFFSET_8B_ALIGN(dwqe_offset);
+ roce5_copy_mask_attack_value_to_u64_addr(
+ (u64 *)dwqe_virt_offset, inbuf->attack_value[0],
+ inbuf->mask, is_upper_half);
+ } else {
+ ret = roce5_copy_attack_value_to_dwqe_addr(
+ (u64 *)dwqe_virt_offset, inbuf->attack_value,
+ length, inbuf->attack_len);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to copy attack value to dwqe, ret(%d)",
+ ret);
+ return -EFAULT;
+ }
+ }
+ }
+
+ if (inbuf->mask != 0) {
+ ROCE_INFO("roce attack dwqe, mask_val:0x%x, offset:%u",
+ (inbuf->attack_value[0] & inbuf->mask), dwqe_offset);
+ } else {
+ ROCE_INFO("roce attack dwqe, length:%u, offset:%u", length,
+ dwqe_offset);
+ }
+
+ roce5_rqp_put(rqp);
+ return 0;
+}
+
+static int roce5_dfx_attack_sqwqe(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret = 0;
+ u32 qpn = inbuf->qpn;
+ u32 sq_buf_sz;
+ u32 length;
+ u32 sq_wqe_offset;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ sq_buf_sz = (u32)ROCE_ALIGN((u64)rqp->sq.wqebb_cnt
+ << (unsigned)rqp->sq.wqe_shift,
+ PAGE_SIZE);
+ sq_wqe_offset = inbuf->offset;
+ if (sq_wqe_offset >= sq_buf_sz) {
+ ROCE_ERR(
+ "roce attack sq wqe offset is too large, should be less than %u",
+ sq_buf_sz);
+ ret = -EINVAL;
+ goto sq_wqe_err;
+ }
+
+ length = (sq_wqe_offset + inbuf->length > sq_buf_sz) ?
+ (sq_buf_sz - sq_wqe_offset) :
+ inbuf->length;
+ ret = roce5_copy_data_to_page(rdev, inbuf->attack_value, rqp->umem,
+ length, sq_wqe_offset, inbuf->attack_len,
+ inbuf->mask);
+ if (ret != 0) {
+ ROCE_ERR("Failed to copy to sq page, qpn:0x%x", qpn);
+ }
+
+sq_wqe_err:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int roce5_dfx_attack_rqwqe(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret = 0;
+ u32 qpn = inbuf->qpn;
+ u32 rq_buf_sz;
+ u32 length;
+ u32 rq_attack_offset;
+ u32 rq_wqe_offset;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ rq_buf_sz = (u32)ROCE_ALIGN((u64)rqp->rq.wqebb_cnt
+ << (unsigned)rqp->rq.wqe_shift,
+ PAGE_SIZE);
+ rq_attack_offset = inbuf->offset;
+ if (rq_attack_offset >= rq_buf_sz) {
+ ROCE_ERR(
+ "roce attack rq wqe offset is too large, should be less than %u",
+ rq_buf_sz);
+ ret = -EINVAL;
+ goto rq_wqe_err;
+ }
+
+ length = (rq_attack_offset + inbuf->length > rq_buf_sz) ?
+ (rq_buf_sz - rq_attack_offset) :
+ inbuf->length;
+ rq_wqe_offset = rqp->rq.offset + rq_attack_offset;
+ ret = roce5_copy_data_to_page(rdev, inbuf->attack_value, rqp->umem,
+ length, rq_wqe_offset, inbuf->attack_len,
+ inbuf->mask);
+ if (ret != 0) {
+ ROCE_ERR("Failed to copy to rq page, qpn:0x%x", qpn);
+ }
+
+rq_wqe_err:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int roce5_dfx_attack_mtt(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct mtt *roce_mtt)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ u64 *mtts = NULL;
+ u64 *mtts_offset = NULL;
+ u64 page_size;
+ u32 mtt_offset;
+ u32 length;
+ u64 val = ((u64)inbuf->attack_value[1] << 32) |
+ (u64)inbuf->attack_value[0];
+ u32 mtt_8B_offset;
+ bool is_upper_half;
+
+ if (roce_mtt == NULL) {
+ ROCE_ERR("roce qp mtt is null");
+ return -ENOMEM;
+ }
+
+ if (roce_mtt->mtt_vaddr == NULL) {
+ ROCE_ERR("roce mtt vaddr is null, layers:%u",
+ roce_mtt->mtt_layers);
+ return -ENOMEM;
+ }
+
+ comp_priv = get_hmm_comp_priv(rdev->hwdev, SERVICE_T_ROCE);
+ if (comp_priv == NULL) {
+ ROCE_ERR("Comp_priv is null");
+ return -ENOMEM;
+ }
+
+ mtts = (u64 *)hmm_em_table_find(
+ &comp_priv->mtt_em_table,
+ roce_mtt->mtt_seg[roce_mtt->mtt_layers - 1]->offset, NULL);
+ if (mtts == NULL) {
+ ROCE_ERR("Can't find va and pa of mtt entry");
+ return -ENOMEM;
+ }
+
+ page_size = 1L << roce_mtt->mtt_page_shift;
+ mtt_offset = inbuf->offset;
+ if (mtt_offset >= page_size) {
+ ROCE_ERR(
+ "roce attack mtt offset is too large, should be less than %llu",
+ page_size);
+ return -EINVAL;
+ }
+
+ mtt_8B_offset = ALIGN_DOWN_8B(mtt_offset);
+ mtts_offset = mtts + mtt_8B_offset / sizeof(u64);
+ if (inbuf->mask != 0) {
+ is_upper_half = IS_OFFSET_8B_ALIGN(mtt_offset);
+ roce5_copy_mask_attack_value_to_u64_addr(mtts_offset,
+ inbuf->attack_value[0],
+ inbuf->mask,
+ is_upper_half);
+ ROCE_INFO("roce attack mtt, mask_val:0x%x, offset:%u\n",
+ (inbuf->attack_value[0] & inbuf->mask), mtt_offset);
+ } else {
+ length = (inbuf->length + mtt_offset > page_size) ?
+ (page_size - mtt_offset) :
+ inbuf->length;
+ roce5_copy_attack_value_to_addr(mtts_offset, val, length);
+ ROCE_INFO("roce attack mtt, attack_len:%u, offset:%u", length,
+ mtt_offset);
+ }
+
+ return 0;
+}
+
+static int roce5_dfx_attack_cmtt(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret = 0;
+ u32 qpn = inbuf->qpn;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ ret = roce5_dfx_attack_mtt(rdev, inbuf, &(rqp->mtt));
+ if (ret != 0) {
+ ROCE_ERR("Failed to attack cmtt");
+ }
+
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+struct roce5_mr *roce5_mr_find(struct roce5_device *rdev, u32 key_id)
+{
+ struct roce5_mr *mr = NULL;
+
+ mutex_lock(&rdev->device_res->mr_list.node_lock);
+ list_for_each_entry(mr, &rdev->device_res->mr_list.node, node) {
+ if (mr->rdmamr.mpt.mpt_index == key_id) {
+ mutex_unlock(&rdev->device_res->mr_list.node_lock);
+ ROCE_INFO("Find mr, it's mpt index is %u",
+ mr->rdmamr.mpt.mpt_index);
+ return mr;
+ }
+ }
+
+ mutex_unlock(&rdev->device_res->mr_list.node_lock);
+ ROCE_ERR("Don't find correct mr, key_id:%u", key_id);
+
+ return NULL;
+}
+
+static int roce5_dfx_attack_dmtt(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_mr *mr = NULL;
+ int ret = 0;
+
+ mr = roce5_mr_find(rdev, inbuf->mpt_index);
+ if (mr == NULL) {
+ ROCE_ERR(
+ "Failed to attack dmtt, don't find valid mr, mpt_index:%u",
+ inbuf->mpt_index);
+ return -EINVAL;
+ }
+
+ ret = roce5_dfx_attack_mtt(rdev, inbuf, &(mr->rdmamr.mtt));
+ if (ret != 0) {
+ ROCE_ERR("Failed to attack dmtt");
+ }
+
+ return ret;
+}
+
+static void roce5_attack_value_to_rdmarc(u32 *vaddr, u32 length, const u32 *val,
+ u32 attack_len)
+{
+ int cnt = (length + 3) >> 2;
+ int i;
+
+ for (i = 0; i < cnt; i++) {
+ vaddr[i] = val[i % attack_len];
+ }
+}
+
+static int roce5_dfx_attack_rdmarc(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ u32 qpn = inbuf->qpn;
+ struct rdma_rdmarc *rdmarc = NULL;
+ void *rdmarc_vaddr = NULL;
+ u32 *rdmarc_offset_vaddr = NULL;
+ u32 rdmarc_entry_num;
+ u32 rdmarc_offset;
+ u32 rdmarc_size;
+ u32 length;
+ int ret = 0;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ rdmarc = &(rqp->rdmarc);
+ rdmarc_vaddr = rdmarc->vaddr;
+ if (rdmarc_vaddr == NULL) {
+ ROCE_ERR("Rdmarc vaddr is null");
+ ret = -ENOMEM;
+ goto rdmarc_err;
+ }
+
+ rdmarc_entry_num = (1 << rdmarc->order);
+ rdmarc_size = rdmarc_entry_num * ROCE_RDMARC_ENTRY_SZ;
+ rdmarc_offset = inbuf->offset;
+ if (rdmarc_offset >= rdmarc_size) {
+ ROCE_ERR(
+ "roce attack rdmarc offset is too large, should be less than %u",
+ rdmarc_size);
+ ret = -EINVAL;
+ goto rdmarc_err;
+ }
+
+ rdmarc_offset_vaddr = (u32 *)((u8 *)rdmarc_vaddr + rdmarc_offset);
+
+ if (inbuf->mask != 0) {
+ roce5_copy_mask_attack_value_to_addr(rdmarc_offset_vaddr,
+ inbuf->attack_value[0],
+ inbuf->mask);
+ ROCE_INFO("roce attack rdmarc, mask_val:0x%x, offset:%u",
+ (inbuf->attack_value[0] & inbuf->mask),
+ rdmarc_offset);
+ } else {
+ length = (rdmarc_offset + inbuf->length > rdmarc_size) ?
+ (rdmarc_size - rdmarc_offset) :
+ inbuf->length;
+ roce5_attack_value_to_rdmarc(rdmarc_offset_vaddr, length,
+ inbuf->attack_value,
+ inbuf->attack_len);
+ ROCE_INFO("roce attack rdmarc, attack_length:%u, offset:%u",
+ length, rdmarc_offset);
+ }
+
+rdmarc_err:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int roce5_dfx_attack_cq(struct roce5_cq *cq, struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf)
+{
+ u32 ret;
+ u32 cq_attack_offset;
+ u32 cq_buf_sz;
+ u32 length;
+ u32 cq_depth = cq->cqe_mask + 1;
+ u32 cqe_size = rdev->rdma_cap.cqe_size;
+
+ cq_buf_sz = cqe_size * cq_depth;
+ if (inbuf->offset >= cq_buf_sz) {
+ ROCE_ERR(
+ "Roce attack cq cqe offset is too large, should be less than %u",
+ cq_buf_sz);
+ return -EINVAL;
+ }
+
+ cq_attack_offset = inbuf->offset;
+ length = ((cq_attack_offset + inbuf->length) > cq_buf_sz) ?
+ (cq_buf_sz - cq_attack_offset) :
+ inbuf->length;
+ ret = roce5_copy_data_to_page(rdev, inbuf->attack_value, cq->umem,
+ length, cq_attack_offset,
+ inbuf->attack_len, inbuf->mask);
+ if (ret != 0) {
+ ROCE_ERR("Failed to copy to cq page");
+ }
+
+ return ret;
+}
+
+static int roce5_dfx_attack_cqe(struct roce5_device *rdev,
+ const struct roce_attack_inbuf *inbuf,
+ struct roce_attack_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret = 0;
+ u32 qpn = inbuf->qpn;
+ struct roce5_cq *send_cq = NULL;
+ struct roce5_cq *recv_cq = NULL;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ ROCE_ERR("Failed to get roce qp, qpn:0x%x", qpn);
+ return -EINVAL;
+ }
+
+ roce5_get_cqs(rqp, &send_cq, &recv_cq);
+ if (send_cq != NULL) {
+ ret = roce5_dfx_attack_cq(send_cq, rdev, inbuf);
+ if (ret != 0) {
+ ROCE_ERR("Failed to attack send_cq, qpn:0x%x", qpn);
+ goto cq_wqe_err;
+ }
+ }
+
+ if (recv_cq != NULL) {
+ ret = roce5_dfx_attack_cq(recv_cq, rdev, inbuf);
+ if (ret != 0) {
+ ROCE_ERR("Failed to attack recv_cq, qpn:0x%x", qpn);
+ goto cq_wqe_err;
+ }
+ }
+
+cq_wqe_err:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static struct roce_dfx_attack_cmd_func g_roce_attack_cmd_funcs[] = {
+ { ROCE_ATTACK_TYPE_SQDB_HARD, roce5_dfx_attack_sqdb_hard },
+ { ROCE_ATTACK_TYPE_DWQE, roce5_dfx_attack_dwqe },
+ { ROCE_ATTACK_TYPE_SQWQE, roce5_dfx_attack_sqwqe },
+ { ROCE_ATTACK_TYPE_RQWQE, roce5_dfx_attack_rqwqe },
+ { ROCE_ATTACK_TYPE_CMTT, roce5_dfx_attack_cmtt },
+ { ROCE_ATTACK_TYPE_DMTT, roce5_dfx_attack_dmtt },
+ { ROCE_ATTACK_TYPE_RDMARC, roce5_dfx_attack_rdmarc },
+ { ROCE_ATTACK_TYPE_CQE, roce5_dfx_attack_cqe },
+};
+
+void roce5_cpu_to_be32(void *data, u32 len)
+{
+ u32 chunk_sz = sizeof(u32);
+ u32 *mem = (u32 *)data;
+ u32 data_len;
+ u32 i;
+
+ if (data == NULL)
+ return;
+
+ data_len = len / chunk_sz;
+
+ for (i = 0; i < data_len; i++) {
+ *mem = cpu_to_be32(*mem);
+ mem++;
+ }
+}
+
+int roce5_dfx_attack_func(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct roce_attack_inbuf *inbuf = (struct roce_attack_inbuf *)buf_in;
+ struct roce_attack_outbuf *outbuf =
+ (struct roce_attack_outbuf *)buf_out;
+ roce_adm_dfx_attack_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ if ((inbuf == NULL) || (outbuf == NULL)) {
+ ROCE_ERR("Roce dfx attack buf in or buf out is null.");
+ return -EINVAL;
+ }
+
+ /* check in and out buf size */
+ if (in_size < (u32)sizeof(struct roce_attack_inbuf)) {
+ ROCE_ERR("roce dfx attack buffer in size too small");
+ return -EINVAL;
+ }
+ if (*out_size < (u32)sizeof(struct roce_attack_outbuf)) {
+ ROCE_ERR("roce dfx attack buffer out size too small");
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+
+ if (inbuf->convert_endian != 0)
+ roce5_cpu_to_be32(&(inbuf->attack_value),
+ sizeof(inbuf->attack_value));
+
+ for (i = 0; i < sizeof(g_roce_attack_cmd_funcs) /
+ sizeof(g_roce_attack_cmd_funcs[0]);
+ i++) {
+ cmd_type = g_roce_attack_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->attack_type) {
+ func = g_roce_attack_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ ROCE_ERR(
+ "function of attack cmd(0x%x) is not supported.",
+ cmd_type);
+ return -EINVAL;
+ }
+
+ *out_size = sizeof(struct roce_attack_outbuf);
+
+ return func(rdev, inbuf, outbuf);
+ }
+ }
+
+ ROCE_ERR("attack cmd(0x%x) does't exist.", cmd_type);
+
+ return -EINVAL;
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_debug.c b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_debug.c
new file mode 100644
index 000000000..371fa3211
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_debug.c
@@ -0,0 +1,35 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/semaphore.h>
+#include "hinic5_mt.h"
+#include "securec.h"
+#include "roce_infra.h"
+#include "roce.h"
+
+int roce5_get_drv_version(void *buf_out, u32 *out_size)
+{
+ struct drv_version_info *ver_info = buf_out;
+ int rc;
+
+ if (!buf_out) {
+ ROCE_ERR("Buf_out is NULL.");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(*ver_info)) {
+ ROCE_ERR("Unexpect out buf size from user :%u, expect: %lu",
+ *out_size, sizeof(*ver_info));
+ return -EINVAL;
+ }
+
+ rc = snprintf_s(ver_info->ver, sizeof(ver_info->ver),
+ sizeof(ver_info->ver) - 1, "%s %s(debug)",
+ HIROCE5_DRV_VERSION, __TIME_STR__);
+ if (rc == -1) {
+ ROCE_ERR("Snprintf roce version err");
+ return -EFAULT;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_query.c b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_query.c
new file mode 100644
index 000000000..ef4b2da57
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/dfx/roce_dfx_query.c
@@ -0,0 +1,851 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+
+
+#ifdef __ROCE_DFX__
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "hinic5_mt.h"
+
+#include "roce_compat.h"
+#include "roce.h"
+#include "roce_dfx.h"
+#include "roce_srq.h"
+#include "roce_qp.h"
+#include "roce_cq.h"
+#include "roce_cmd.h"
+#include "roce_mix.h"
+#include "roce_infra.h"
+#include "roce_npu_cmd.h"
+#include "roce_cqm_cmd.h"
+#include "roce_restore.h"
+#include "roce_main_extension.h"
+#include "roce_com.h"
+#include "securec.h"
+#include "hmm_common.h"
+#include "roce_npu_cmd_gid_defs.h"
+
+static int roce5_dfx_get_dev_algo(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ u32 cc_algo;
+ struct roce5_ecn_ctx ecn_ctx;
+ u32 *algo_type = &outbuf->algo_type;
+
+ if (rdev == NULL) {
+ ROCE_ERR("Failed to get roce device.");
+ return -EINVAL;
+ }
+ ecn_ctx = rdev->ecn_ctx;
+ cc_algo = ecn_ctx.cc_algo;
+ *algo_type = cc_algo;
+
+ return 0;
+}
+
+static int roce5_dfx_get_qp_count(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ struct roce5_dfx_qp_count *qp_count = &outbuf->qp_count;
+
+ qp_count->qp_alloced = rdev->qp_cnt.alloc_qp_cnt;
+ qp_count->qp_deleted = rdev->qp_cnt.del_qp_cnt;
+ qp_count->qp_alive =
+ rdev->qp_cnt.alloc_qp_cnt - rdev->qp_cnt.del_qp_cnt;
+
+ return 0;
+}
+
+/* QPC is statically allocated, so it is not necessary to judge whether it exists when querying the cache content */
+static int roce5_dfx_query_cache_qpc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ u32 qpn = inbuf->qpn;
+ roce_verbs_qp_attr_s *qp_attr = &outbuf->qp_attr;
+
+ ret = memset_s(qp_attr, sizeof(roce_verbs_qp_attr_s), 0,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset qp_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_qp_query(rdev, qpn, (u32 *)(void *)qp_attr,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to query QPC from cache!");
+ roce5_dfx_print(
+ "******************From Cache: qpn(%#x) ********************",
+ qpn);
+ roce5_dfx_print(
+ ">>>>>>>>>>>>>>>> QUERY QPC FROM CACHE FAILED <<<<<<<<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: qpn(%#x) ********************",
+ qpn);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int roce5_dfx_query_host_qpc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ struct roce5_qp *rqp = NULL;
+ int ret = 0;
+ u32 qpn = inbuf->qpn;
+ roce5_qp_query_outbuf_s *qp_query = &outbuf->qp_query;
+
+ rqp = roce5_get_rqp_by_qpn(rdev, qpn);
+ if (rqp == NULL) {
+ roce5_dfx_print("Failed to get roce qp.");
+ roce5_dfx_print(
+ "******************From Host: qpn(%#x) ********************",
+ qpn);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY QPC FROM HOST FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Host: qpn(%#x) ********************",
+ qpn);
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(qp_query, sizeof(roce5_qp_query_outbuf_s),
+ rqp->qpc_info->vaddr, sizeof(roce5_qp_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy qp_ctx, ret(%d).", ret);
+ goto err_out;
+ }
+
+err_out:
+ roce5_rqp_put(rqp);
+ return ret;
+}
+
+static int roce5_dfx_uni_cmd_query_cq(struct roce5_device *rdev, u32 cqn,
+ u32 *verbs_cq_attr, int cq_attr_size)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_cq_query_s *cq_query_inbuf = NULL;
+ roce_uni_cmd_cq_query_outbuf_s *cq_query_outbuf = NULL;
+ struct roce5_cq *rcq = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_cq_query_s), &cqm_cmd_outbuf,
+ (u16)sizeof(roce_uni_cmd_cq_query_outbuf_s));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to alloc cqm_cmd_inoutbuf, ret=%d",
+ ret);
+ return ret;
+ }
+
+ rcq = roce5_get_rcq_by_cqn(rdev, cqn);
+ if (rcq == NULL) {
+ roce5_dfx_print("Failed to get roce cq.");
+ goto err_rcq;
+ }
+ cq_query_inbuf = (roce_uni_cmd_cq_query_s *)cqm_cmd_inbuf->buf;
+ cq_query_inbuf->com.index = cpu_to_be32(cqn);
+ cq_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_CQ_BITMASK));
+ if (rcq->shadow != 0) {
+ cq_query_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ cq_query_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rcq->shadow_vfid);
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE, ROCE_CMD_QUERY_CQ,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ ROCE_CMD_TIME_CLASS_B, HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ roce5_dfx_print("Failed to send cmd QUERY_CQ, ret=%d", ret);
+ ret = -1;
+ goto out;
+ }
+
+ cq_query_outbuf = (roce_uni_cmd_cq_query_outbuf_s *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)verbs_cq_attr, (size_t)cq_attr_size,
+ (void *)&cq_query_outbuf->cq_info.context[0],
+ (size_t)cq_attr_size);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy verbs_cq_attr.(ret:%d)", ret);
+ ret = -EINVAL;
+ goto out;
+ }
+out:
+ roce5_rcq_put(rcq);
+err_rcq:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int roce5_dfx_query_cq(struct roce5_device *rdev, u32 cqn, u32 *context,
+ int cqc_size)
+{
+ if (ROCE5_SUPPORT_DFX_CMD_QUERY_CQ_MSG_V2(rdev) != 0) {
+ return roce5_dfx_uni_cmd_query_cq(rdev, cqn, context, cqc_size);
+ }
+ return -EINVAL;
+}
+
+/* CQC is dynamic allocation. When querying cache content, you need to determine whether it exists or not. */
+static int roce5_dfx_query_cache_cqc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ cqm_object_s *cqm_obj_cq = NULL;
+ u32 cqn = inbuf->cqn;
+ roce5_cq_query_outbuf_s *cq_query = &outbuf->cq_query;
+
+ cqm_obj_cq =
+ cqm5_object_get(rdev->hwdev, CQM_OBJECT_RDMA_SCQ, cqn, false);
+ if (cqm_obj_cq == NULL) {
+ roce5_dfx_print("Failed to get cqm_obj_cq.");
+ roce5_dfx_print(
+ "******************From Cache: cqn(%#x) ********************",
+ cqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY CQC FROM CACHE FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: cqn(%#x) ********************",
+ cqn);
+
+ return -EINVAL;
+ }
+
+ cqm5_object_put(cqm_obj_cq);
+
+ ret = memset_s(cq_query, sizeof(roce5_cq_query_outbuf_s), 0,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset cq_context.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_dfx_query_cq(rdev, cqn, (u32 *)(void *)cq_query,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to query cq from cache!");
+ roce5_dfx_print(
+ "******************From Cache: cqn(%#x) ********************",
+ cqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>>>>>>> QUERY CQC FROM CACHE FAILED <<<<<<<<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: cqn(%#x) ********************",
+ cqn);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_dfx_query_host_cqc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ struct roce5_cq *rcq = NULL;
+ int ret = 0;
+ u32 cqn = inbuf->cqn;
+ roce5_cq_query_outbuf_s *cq_query = &outbuf->cq_query;
+
+ rcq = roce5_get_rcq_by_cqn(rdev, cqn);
+ if (rcq == NULL) {
+ roce5_dfx_print("Failed to get roce cq.");
+ roce5_dfx_print(
+ "******************From Host: cqn(%#x) ********************",
+ cqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY CQC FROM HOST FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Host: cqn(%#x) ********************",
+ cqn);
+
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(cq_query, sizeof(roce5_cq_query_outbuf_s),
+ rcq->cqm_cq->q_ctx_vaddr,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy cq_ctx.(ret:%d)", ret);
+ goto err_out;
+ }
+
+err_out:
+ roce5_rcq_put(rcq);
+ return ret;
+}
+
+int roce5_dfx_cmd_query_srq(struct roce5_device *rdev, u32 srqn,
+ roce_verbs_srq_attr_s *srq_attr)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_srq_query_s *srq_query_inbuf = NULL;
+ roce_uni_cmd_srq_query_outbuf_s *srq_query_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_srq_query_s), &cqm_cmd_outbuf,
+ (u16)sizeof(roce_uni_cmd_srq_query_outbuf_s));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to alloc cqm_cmd_inoutbuf, ret=%d",
+ ret);
+ return ret;
+ }
+
+ srq_query_inbuf = (roce_uni_cmd_srq_query_s *)cqm_cmd_inbuf->buf;
+ srq_query_inbuf->com.index = cpu_to_be32(srqn);
+ srq_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SRQ_BITMASK));
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_QUERY_SRQ, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, ROCE_CMD_TIME_CLASS_B,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ roce5_dfx_print("Failed to send cmd QUERY_SRQ, ret=%d", ret);
+ ret = -1;
+ goto out;
+ }
+
+ srq_query_outbuf =
+ (roce_uni_cmd_srq_query_outbuf_s *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s(srq_attr, sizeof(roce_verbs_srq_attr_s),
+ &srq_query_outbuf->com.srq_attr,
+ sizeof(roce_verbs_srq_attr_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy srq_attr.(ret:%d)", ret);
+ ret = -EINVAL;
+ goto out;
+ }
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+/* SRQC is dynamic allocation. When querying the cache content, you need to determine whether it exists or not. */
+static int roce5_dfx_query_cache_srqc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ cqm_object_s *cqm_obj_srq = NULL;
+ u32 srqn = inbuf->srqn;
+ roce_verbs_srq_attr_s *srq_attr = &outbuf->srq_attr;
+
+ cqm_obj_srq =
+ cqm5_object_get(rdev->hwdev, CQM_OBJECT_RDMA_SRQ, srqn, false);
+ if (cqm_obj_srq == NULL) {
+ roce5_dfx_print("Failed to get cqm_obj_srq");
+ roce5_dfx_print(
+ "******************From Cache: srqn(%#x) ********************",
+ srqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY SRQC FROM CACHE FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: srqn(%#x) ********************",
+ srqn);
+
+ return -EINVAL;
+ }
+
+ cqm5_object_put(cqm_obj_srq);
+
+ ret = memset_s(srq_attr, sizeof(roce_verbs_srq_attr_s), 0,
+ sizeof(roce_verbs_srq_attr_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset srq_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_dfx_cmd_query_srq(rdev, srqn, srq_attr);
+ if (ret != 0) {
+ roce5_dfx_print("Failed to query srq from cache");
+ roce5_dfx_print(
+ "******************From Cache: srqn(%#x) ********************",
+ srqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>>>>>>> QUERY SRQC FROM CACHE FAILED <<<<<<<<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: srqn(%#x) ********************",
+ srqn);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int roce5_dfx_query_host_srqc(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ struct roce5_srq *rsrq = NULL;
+ int ret = 0;
+ u32 srqn = inbuf->srqn;
+ roce5_srq_query_outbuf_s *srq_query = &outbuf->srq_query;
+
+ rsrq = roce5_get_rsrq_by_srqn(rdev, srqn);
+ if (rsrq == NULL) {
+ roce5_dfx_print("Failed to get roce srq.");
+ roce5_dfx_print(
+ "******************From Host: srqn(%#x) ********************",
+ srqn);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY SRQC FROM HOST FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Host: srqn(%#x) ********************",
+ srqn);
+
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(srq_query, sizeof(roce5_srq_query_outbuf_s),
+ rsrq->cqm_srq->q_ctx_vaddr,
+ sizeof(roce5_srq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy srq_ctx.(ret:%d)", ret);
+ goto err_out;
+ }
+
+err_out:
+ roce5_rsrq_put(rsrq);
+ return ret;
+}
+
+static int roce5_dfx_uni_cmd_query_mpt(struct roce5_device *rdev, u32 key,
+ struct roce_mpt_context *mpt_entry)
+{
+ int ret;
+ u32 mpt_index;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_mpt_query_s *mpt_query_inbuf = NULL;
+ roce_uni_cmd_mpt_query_outbuf_s *mpt_query_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_mpt_query_s), &cqm_cmd_outbuf,
+ (u16)sizeof(roce_uni_cmd_mpt_query_outbuf_s));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to alloc cqm_cmd_inoutbuf, ret=%d",
+ ret);
+ return ret;
+ }
+
+ mpt_query_inbuf = (roce_uni_cmd_mpt_query_s *)cqm_cmd_inbuf->buf;
+ mpt_index = (key >> MR_KEY_2_INDEX_SHIFT) & 0xFFFFFF;
+ mpt_query_inbuf->com.index = cpu_to_be32(mpt_index);
+ mpt_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_MR_BITMASK));
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_QUERY_MPT, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, ROCE_CMD_TIME_CLASS_B,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ roce5_dfx_print("Failed to send cmd QUERY_MPT");
+ ret = -1;
+ goto out;
+ }
+
+ mpt_query_outbuf =
+ (roce_uni_cmd_mpt_query_outbuf_s *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s(mpt_entry, sizeof(struct roce_mpt_context),
+ &mpt_query_outbuf->mpt_info.context[0],
+ sizeof(struct roce_mpt_context));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy mpt_entry.(ret:%d)", ret);
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static int roce5_dfx_query_mpt(struct roce5_device *rdev, u32 key,
+ struct roce_mpt_context *mpt_entry)
+{
+ if (ROCE5_SUPPORT_DFX_CMD_QUERY_MPT_MSG_V2(rdev) != 0) {
+ return roce5_dfx_uni_cmd_query_mpt(rdev, key, mpt_entry);
+ }
+ return -EINVAL;
+}
+
+static int roce5_dfx_uni_cmd_query_gid(struct roce5_device *rdev, u32 port,
+ u32 gid_index,
+ struct rdma_gid_entry *gid_entry)
+{
+ int ret;
+ cqm_cmd_buf_s *cqm_cmd_inbuf = NULL;
+ cqm_cmd_buf_s *cqm_cmd_outbuf = NULL;
+ roce_uni_cmd_query_gid_s *gid_query_inbuf = NULL;
+ struct rdma_gid_query_outbuf *gid_query_outbuf = NULL;
+
+ ret = roce5_cqm_cmd_zalloc_inoutbuf(
+ rdev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(roce_uni_cmd_query_gid_s), &cqm_cmd_outbuf,
+ (u16)sizeof(struct rdma_gid_query_outbuf));
+ if (ret != 0) {
+ roce5_dfx_print("Failed to alloc cqm_cmd_inoutbuf, ret=%d",
+ ret);
+ return ret;
+ }
+
+ gid_query_inbuf = (roce_uni_cmd_query_gid_s *)cqm_cmd_inbuf->buf;
+ gid_query_inbuf->com.index = cpu_to_be32(gid_index);
+ gid_query_inbuf->com.dw0.bs.cmd_bitmask =
+ cpu_to_be16(ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_GID_BITMASK));
+ gid_query_inbuf->com.opt = cpu_to_be32(port);
+
+ if (rdev->shadow != 0) {
+ gid_query_inbuf->com.dw3.bs.shadow_vfid =
+ cpu_to_be16(rdev->shadow_vfid);
+ gid_query_inbuf->com.dw0.bs.cmd_bitmask = cpu_to_be16(
+ ROCE5_ULP_CMD(rdev, VERBS_CMD_TYPE_SHADOW_BITMASK));
+ gid_query_inbuf->gid_query.dw0.shadow.shadow_vf_num =
+ rdev->shadow_vf_num;
+ gid_query_inbuf->gid_query.dw0.value =
+ cpu_to_be32(gid_query_inbuf->gid_query.dw0.value);
+ }
+
+ ret = cqm5_send_cmd_box(rdev->hwdev, HINIC5_MOD_ROCE,
+ ROCE_CMD_QUERY_GID, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, ROCE_CMD_TIME_CLASS_B,
+ HINIC5_CHANNEL_ROCE);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to send cmd QUERY_GID, ret(%d)",
+ ret);
+ ret = -1;
+ goto out;
+ }
+
+ gid_query_outbuf = (struct rdma_gid_query_outbuf *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s(gid_entry,
+ sizeof(struct rdma_gid_entry) * ROCE_GID_ENTRY_NUM,
+ gid_query_outbuf->gid_entry,
+ sizeof(struct rdma_gid_entry) * ROCE_GID_ENTRY_NUM);
+ if (ret != 0) {
+ ROCE_DEV_ERR(rdev, "Failed to memcpy gid_entry.(ret:%d)", ret);
+ }
+out:
+ roce5_cqm5_cmd_free_inoutbuf(rdev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int roce5_dfx_query_gid(struct roce5_device *rdev, u32 port,
+ u32 gid_index, struct rdma_gid_entry *gid_entry)
+{
+ if (ROCE5_SUPPORT_DFX_CMD_QUERY_GID_MSG_V2(rdev) != 0) {
+ return roce5_dfx_uni_cmd_query_gid(rdev, port, gid_index,
+ gid_entry);
+ }
+ return -EINVAL;
+}
+
+/* MPT is statically allocated, so it is not necessary to judge whether it exists when querying the cache content */
+static int roce5_dfx_query_cache_mpt(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ u32 mpt_key = inbuf->mpt_key;
+ struct roce_mpt_context *mpt_entry = &outbuf->mpt;
+
+ ret = memset_s(mpt_entry, sizeof(struct roce_mpt_context), 0,
+ sizeof(struct roce_mpt_context));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset mpt_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_dfx_query_mpt(rdev, mpt_key, mpt_entry);
+ if (ret != 0) {
+ roce5_dfx_print("Failed to query mpt from cache!");
+ roce5_dfx_print(
+ "******************From Cache: mpt_key(%#x) ********************",
+ mpt_key);
+ roce5_dfx_print(
+ ">>>>>>>>>>>>>>>> QUERY MPT FROM CACHE FAILED <<<<<<<<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Cache: mpt_key(%#x) ********************",
+ mpt_key);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int roce5_dfx_query_host_mpt(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ u32 mpt_index = 0;
+ struct mpt *rmpt = NULL;
+ int ret = 0;
+ u32 mpt_key = inbuf->mpt_key;
+ struct roce_mpt_context *mpt_entry = &outbuf->mpt;
+
+ mpt_index = (mpt_key >> MR_KEY_2_INDEX_SHIFT) & 0xFFFFFF;
+ rmpt = roce5_get_mpt_by_index(rdev, mpt_index);
+ if (rmpt == NULL) {
+ roce5_dfx_print("Failed to get roce mpt.");
+ roce5_dfx_print(
+ "******************From Host: mpt_key(%#x) ********************",
+ mpt_key);
+ roce5_dfx_print(
+ ">>>>>>>>>>> QUERY MPT FROM HOST FAILED, NOT EXIST <<<<<<<<<<<");
+ roce5_dfx_print(
+ "******************From Host: mpt_key(%#x) ********************",
+ mpt_key);
+
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(mpt_entry, sizeof(struct roce_mpt_context), rmpt->vaddr,
+ sizeof(struct roce_mpt_context));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memcpy mpt_entry.(ret:%d)", ret);
+ goto err_out;
+ }
+
+err_out:
+ roce5_mpt_put(rmpt);
+ return ret;
+}
+
+static int roce5_dfx_query_cache_gid(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ u32 gid_index = inbuf->gid_index;
+ struct rdma_gid_entry *gid_entry = outbuf->gid_entry;
+
+ ret = memset_s(gid_entry,
+ sizeof(struct rdma_gid_entry) * ROCE_GID_ENTRY_NUM, 0,
+ sizeof(struct rdma_gid_entry) * ROCE_GID_ENTRY_NUM);
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset gid_entry.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_dfx_query_gid(rdev, 0, gid_index, gid_entry);
+ if (ret != 0) {
+ roce5_dfx_print(
+ "***************port(1), gid_index(%d) *****************",
+ gid_index);
+ roce5_dfx_print("Failed to query gid from cache!");
+ roce5_dfx_print(
+ "***************port(1), gid_index(%d) *****************",
+ gid_index);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void roce5_dfx_query_pi_ci_set(const roce_verbs_qp_attr_s *qp_attr,
+ struct roce5_dfx_pi_ci *pi_ci)
+{
+ pi_ci->qpc_sq_pi_on_chip = qp_attr->chip_seg.dw5.bs.sq_pi_on_chip;
+ pi_ci->qpc_sq_pi = qp_attr->ext_seg.dfx_info.dw0.bs.sq_pi;
+ pi_ci->qpc_sq_load_pi = qp_attr->ext_seg.dfx_info.dw1.bs.sq_load_pi;
+ pi_ci->qpc_rq_pi_on_chip = qp_attr->chip_seg.dw8.bs.rq_pi_on_chip;
+ pi_ci->qpc_rq_load_pi = qp_attr->ext_seg.dfx_info.dw1.bs.rq_load_pi;
+ pi_ci->qpc_rq_pi = qp_attr->ext_seg.dfx_info.dw4.bs.rq_pi;
+ pi_ci->qpc_rc_pi = qp_attr->ext_seg.dfx_info.dw5.bs.rc_pi;
+ pi_ci->qpc_sq_ci = qp_attr->ext_seg.dfx_info.dw0.bs.sq_ci;
+ pi_ci->qpc_sq_wqe_prefetch_ci =
+ qp_attr->ext_seg.dfx_info.dw1.bs.sq_wqe_prefetch_ci;
+ pi_ci->qpc_sq_mtt_prefetch_wqe_ci =
+ qp_attr->ext_seg.dfx_info.dw3.bs.sq_mtt_prefetch_wqe_ci;
+ pi_ci->qpc_sqa_ci = qp_attr->ext_seg.dfx_info.dw2.bs.sqa_ci;
+ pi_ci->qpc_sqa_wqe_prefetch_ci =
+ qp_attr->ext_seg.dfx_info.dw2.bs.sqa_wqe_prefetch_ci;
+ pi_ci->qpc_rq_ci = qp_attr->ext_seg.dfx_info.dw4.bs.rq_ci;
+ pi_ci->qpc_rq_wqe_prefetch_ci =
+ qp_attr->ext_seg.dfx_info.dw5.bs.rq_wqe_prefetch_ci;
+ pi_ci->qpc_rq_mtt_prefetch_wqe_ci =
+ qp_attr->ext_seg.dfx_info.dw3.bs.rq_mtt_prefetch_wqe_ci;
+ pi_ci->qpc_rq_base_ci = qp_attr->chip_seg.dw4.bs.rq_base_ci;
+ pi_ci->qpc_rc_ci = qp_attr->ext_seg.dfx_info.dw5.bs.rc_ci;
+ pi_ci->qpc_rc_prefetch_ci =
+ qp_attr->ext_seg.dfx_info.dw1.bs.rc_prefetch_ci;
+}
+
+static int roce5_dfx_query_pi_ci(const struct roce5_dfx_query_inbuf *inbuf,
+ struct roce5_device *rdev,
+ union roce5_dfx_query_outbuf *outbuf)
+{
+ int ret;
+ roce_verbs_qp_attr_s be_attr; /* BE context structure */
+ roce_verbs_qp_attr_s qp_attr; /* LE context structure */
+ roce_verbs_cq_attr_s cq_attr;
+ roce5_cq_query_outbuf_s cq_query;
+ u32 qpn = inbuf->query_pi_ci.qpn;
+ u32 cqn = inbuf->query_pi_ci.cqn;
+ struct roce5_dfx_pi_ci *pi_ci = &outbuf->pi_ci;
+
+ ret = memset_s(pi_ci, sizeof(struct roce5_dfx_pi_ci), 0,
+ sizeof(struct roce5_dfx_pi_ci));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset pi_ci.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+
+ ret = memset_s(&qp_attr, sizeof(qp_attr), 0, sizeof(qp_attr));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset qp_attr.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_qp_query(rdev, qpn, (u32 *)(void *)&be_attr,
+ sizeof(roce_verbs_qp_attr_s));
+ if (ret != 0) {
+ return ret;
+ }
+
+ roce5_be32_2_le32(&be_attr, (u32 *)(void *)&qp_attr,
+ (sizeof(roce_verbs_qp_attr_s) / sizeof(u32)));
+
+ roce5_dfx_query_pi_ci_set(&qp_attr, pi_ci);
+
+ ret = memset_s(&cq_query, sizeof(roce5_cq_query_outbuf_s), 0,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset cq_query.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ ret = roce5_dfx_query_cq(rdev, cqn, (u32 *)(void *)&cq_query,
+ sizeof(roce5_cq_query_outbuf_s));
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (ROCE5_SUPPORT_DFX_CMD_QUERY_PI_CI_MSG_V2(rdev) != 0) {
+ (void)memcpy_s(&cq_attr, sizeof(roce_verbs_cq_attr_s),
+ &cq_query, sizeof(roce_verbs_cq_attr_s));
+ cq_attr.dw0.value = be32_to_cpu(cq_attr.dw0.value);
+ cq_attr.dfx_info.dw0.value =
+ be32_to_cpu(cq_attr.dfx_info.dw0.value);
+ cq_attr.dfx_info.dw1.value =
+ be32_to_cpu(cq_attr.dfx_info.dw1.value);
+ cq_attr.dfx_info.dw2.value =
+ be32_to_cpu(cq_attr.dfx_info.dw2.value);
+ cq_attr.dfx_info.dw3.value =
+ be32_to_cpu(cq_attr.dfx_info.dw3.value);
+ cq_attr.ci_record_gpa_at_hop_num =
+ be64_to_cpu(cq_attr.ci_record_gpa_at_hop_num);
+
+ pi_ci->cq_ci_on_chip = cq_attr.dw0.bs.ci_on_chip;
+ pi_ci->cq_ci = cq_attr.dfx_info.dw0.bs.ci;
+ pi_ci->cq_load_ci = cq_attr.dfx_info.dw2.bs.load_ci;
+ pi_ci->cq_ci_record_gpa_at_hop_num =
+ cq_attr.ci_record_gpa_at_hop_num;
+ pi_ci->cq_last_solicited_pi =
+ cq_attr.dfx_info.dw2.bs.last_solicited_pi;
+ pi_ci->cq_pi = cq_attr.dfx_info.dw1.bs.pi;
+ pi_ci->cq_last_notified_pi =
+ cq_attr.dfx_info.dw3.bs.last_notified_pi;
+ }
+ return 0;
+}
+
+static roce5_adm_dfx_query_cmd_proc_t g_roce5_adm_dfx_query_cmd_proc[] = {
+ { ROCE_CMD_GET_QPC_FROM_CACHE, roce5_dfx_query_cache_qpc },
+ { ROCE_CMD_GET_QPC_FROM_HOST, roce5_dfx_query_host_qpc },
+ { ROCE_CMD_GET_CQC_FROM_CACHE, roce5_dfx_query_cache_cqc },
+ { ROCE_CMD_GET_CQC_FROM_HOST, roce5_dfx_query_host_cqc },
+ { ROCE_CMD_GET_SRQC_FROM_CACHE, roce5_dfx_query_cache_srqc },
+ { ROCE_CMD_GET_SRQC_FROM_HOST, roce5_dfx_query_host_srqc },
+ { ROCE_CMD_GET_MPT_FROM_CACHE, roce5_dfx_query_cache_mpt },
+ { ROCE_CMD_GET_MPT_FROM_HOST, roce5_dfx_query_host_mpt },
+ { ROCE_CMD_GET_GID_FROM_CACHE, roce5_dfx_query_cache_gid },
+ { ROCE_CMD_GET_QPC_CQC_PI_CI, roce5_dfx_query_pi_ci },
+ { ROCE_CMD_GET_QP_COUNT, roce5_dfx_get_qp_count },
+ { ROCE_CMD_GET_DEV_ALGO, roce5_dfx_get_dev_algo },
+};
+
+int roce5_adm_dfx_query(struct roce5_device *rdev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ int ret;
+ const struct roce5_dfx_query_inbuf *inbuf =
+ (struct roce5_dfx_query_inbuf *)buf_in;
+ union roce5_dfx_query_outbuf *outbuf =
+ (union roce5_dfx_query_outbuf *)buf_out;
+ const roce5_adm_generic_cmd_proc_t *generic_array =
+ (const roce5_adm_generic_cmd_proc_t *)
+ g_roce5_adm_dfx_query_cmd_proc;
+ int elem_count = sizeof(g_roce5_adm_dfx_query_cmd_proc) /
+ sizeof(g_roce5_adm_dfx_query_cmd_proc[0]);
+ roce5_adm_dfx_query_t roce5_adm_dfx_query_func = NULL;
+
+ if (in_size < sizeof(struct roce5_dfx_query_inbuf)) {
+ ROCE_ERR(
+ "Input parameter(in_size: %dB) is shorter than input buffer(allocated: %dB)",
+ (int)in_size,
+ (int)sizeof(struct roce5_dfx_query_inbuf));
+ return -ENOMEM;
+ }
+ if (*out_size < sizeof(union roce5_dfx_query_outbuf)) {
+ ROCE_ERR(
+ "Input parameter(out_size: %dB) is shorter than allocated buffer(allocated: %dB)",
+ (int)*out_size,
+ (int)sizeof(union roce5_dfx_query_outbuf));
+ return -ENOMEM;
+ }
+ ret = memset_s(buf_out, sizeof(union roce5_dfx_query_outbuf), 0,
+ sizeof(union roce5_dfx_query_outbuf));
+ if (ret != 0) {
+ ROCE_ERR("Failed to memset buf_out.(ret:%d)", ret);
+ return -ENOMEM;
+ }
+ *out_size = (u32)sizeof(union roce5_dfx_query_outbuf);
+
+ if (inbuf->cmd_type >= VM_COMPAT_TEST) {
+ roce5_dfx_print("Not support this type(%d)", inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ roce5_adm_dfx_query_func =
+ (roce5_adm_dfx_query_t)roce5_adm_generic_find_cmd_func(
+ generic_array, elem_count, inbuf->cmd_type);
+ if (roce5_adm_dfx_query_func == NULL) {
+ roce5_dfx_print("Not support this type(%d)", inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ return roce5_adm_dfx_query_func(inbuf, rdev, outbuf);
+}
+
+#endif
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.c b/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.c
new file mode 100644
index 000000000..7c641f422
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.c
@@ -0,0 +1,83 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/slab.h>
+#include "securec.h"
+#include "roce_infra.h"
+#include "roce_obj_ext.h"
+
+int roce5_obj_ext_init(void *parent, const struct roce5_ext_reg *reg_items,
+ u8 item_num, struct roce5_obj_ext *obj_ext)
+{
+ int i, ret;
+
+ ret = memset_s(obj_ext->bufs, sizeof(void *) * ROCE_EXT_FEATURE_MAX, 0,
+ sizeof(void *) * ROCE_EXT_FEATURE_MAX);
+ if (ret != 0) {
+ ROCE_ERR(
+ "Failed to execute memset to object extension buffer, ret(%d).",
+ ret);
+ return ret;
+ }
+
+ for (i = 0; i < item_num; ++i) {
+ if (reg_items[i].ext_id >= ROCE_EXT_FEATURE_MAX) {
+ ROCE_ERR("Invalid extension id(%u).",
+ reg_items[i].ext_id);
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ if (obj_ext->bufs[reg_items[i].ext_id] != NULL) {
+ ROCE_ERR("Repeated register, extension id(%u).",
+ reg_items[i].ext_id);
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ obj_ext->bufs[reg_items[i].ext_id] =
+ kzalloc(reg_items[i].data_size, GFP_KERNEL);
+ if (obj_ext->bufs[reg_items[i].ext_id] == NULL) {
+ ROCE_ERR("Failed alloc memory for extension.");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ ret = reg_items[i].init_func(
+ parent, obj_ext->bufs[reg_items[i].ext_id]);
+ if (ret != 0) {
+ ROCE_ERR("Failed to init extension, ret(%d).", ret);
+ goto err_out;
+ }
+ }
+
+ return 0;
+
+err_out:
+ if (obj_ext->bufs[reg_items[i].ext_id] != NULL) {
+ kfree(obj_ext->bufs[reg_items[i].ext_id]);
+ }
+
+ for (--i; i >= 0; --i) {
+ reg_items[i].cleanup_func(parent,
+ obj_ext->bufs[reg_items[i].ext_id]);
+ kfree(obj_ext->bufs[reg_items[i].ext_id]);
+ }
+ return ret;
+}
+
+void roce5_obj_ext_deinit(void *parent, const struct roce5_ext_reg *reg_items,
+ u8 item_num, struct roce5_obj_ext *obj_ext)
+{
+ int i;
+ for (i = 0; i < item_num; ++i) {
+ if (reg_items[i].ext_id >= ROCE_EXT_FEATURE_MAX ||
+ obj_ext->bufs[reg_items[i].ext_id] == NULL) {
+ continue;
+ }
+
+ reg_items[i].cleanup_func(parent,
+ obj_ext->bufs[reg_items[i].ext_id]);
+ kfree(obj_ext->bufs[reg_items[i].ext_id]);
+ }
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.h b/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.h
new file mode 100644
index 000000000..3e5f7196c
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/obj_ext/roce_obj_ext.h
@@ -0,0 +1,40 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_OBJ_EXT_H
+#define ROCE_OBJ_EXT_H
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+
+typedef int (*ext_init_func)(void *parent, void *ext_data);
+typedef void (*ext_cleanup_func)(void *parent, void *ext_data);
+
+enum ROCE_EXT_ID { ROCE_EXT_HYPER_ROCE, ROCE_EXT_FEATURE_MAX };
+
+struct roce5_ext_reg {
+ u8 ext_id;
+ size_t data_size;
+ ext_init_func init_func;
+ ext_cleanup_func cleanup_func;
+};
+
+struct roce5_obj_ext {
+ void *bufs[ROCE_EXT_FEATURE_MAX];
+};
+
+static inline void *roce5_obj_ext_get_buf(struct roce5_obj_ext *obj_ext,
+ enum ROCE_EXT_ID ext_id)
+{
+ if (ext_id >= ROCE_EXT_FEATURE_MAX) {
+ return NULL;
+ }
+ return obj_ext->bufs[ext_id];
+}
+
+int roce5_obj_ext_init(void *parent, const struct roce5_ext_reg *reg_items,
+ u8 item_num, struct roce5_obj_ext *obj_ext);
+void roce5_obj_ext_deinit(void *parent, const struct roce5_ext_reg *reg_items,
+ u8 item_num, struct roce5_obj_ext *obj_ext);
+
+#endif /* ROCE_OBJ_EXT_H */
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.c b/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.c
new file mode 100644
index 000000000..6cfed12be
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.c
@@ -0,0 +1,125 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+
+#include "roce_infra.h"
+#include "securec.h"
+#include "roce_option.h"
+
+#define ROCE_WAIT_TIME_SEC 60
+
+struct roce5_option *roce5_some(void *value)
+{
+ int ret;
+
+ struct roce5_option *opt =
+ kmalloc(sizeof(struct roce5_option), GFP_KERNEL);
+ if (opt == NULL) {
+ ROCE_ERR("Failed to alloc memory.");
+ return NULL;
+ }
+
+ ret = strcpy_s(opt->waiting_msg, ROCE_WAITING_MSG_MAX_SIZE,
+ "Waiting for object release...");
+ if (ret != EOK) {
+ ROCE_ERR("Failed to init waiting message.");
+ kfree(opt);
+ return NULL;
+ }
+
+ spin_lock_init(&opt->spin_lock);
+ kref_init(&opt->refcount);
+ opt->value = value;
+
+ return opt;
+}
+
+static void roce5_wait_release(struct kref *refcount)
+{
+ struct roce5_option *opt =
+ container_of(refcount, struct roce5_option, refcount);
+
+ opt->value = NULL;
+ complete(&opt->release_comp);
+}
+
+static void roce5_timer_print_wait_msg(struct timer_list *tl)
+{
+ struct roce5_option *opt = from_timer(opt, tl, msg_timer);
+
+ ROCE_WARN("%s", opt->waiting_msg);
+
+ mod_timer(&opt->msg_timer, jiffies + ROCE_WAIT_TIME_SEC * HZ);
+}
+
+void roce5_option_unset(struct roce5_option *opt, char *waiting_msg,
+ size_t waiting_msg_size)
+{
+ int ret;
+ unsigned long flags; /* type required by kernel API */
+
+ if (opt == NULL) {
+ ROCE_ERR("Invalid parameter, opt is NULL.");
+ return;
+ }
+
+ if (waiting_msg != NULL && waiting_msg_size > 0) {
+ ret = strcpy_s(opt->waiting_msg, ROCE_WAITING_MSG_MAX_SIZE,
+ waiting_msg);
+ if (ret != EOK) {
+ ROCE_WARN("Failed to set waiting message, ret(%d).",
+ ret);
+ }
+ }
+
+ init_completion(&opt->release_comp);
+
+ timer_setup(&opt->msg_timer, roce5_timer_print_wait_msg, 0);
+ mod_timer(&opt->msg_timer, jiffies + ROCE_WAIT_TIME_SEC * HZ);
+
+ spin_lock_irqsave(&opt->spin_lock, flags);
+ kref_put(&opt->refcount, roce5_wait_release);
+ spin_unlock_irqrestore(&opt->spin_lock, flags);
+
+ wait_for_completion(&opt->release_comp);
+
+ del_timer_sync(&opt->msg_timer);
+}
+
+void *roce5_option_get_value(struct roce5_option *opt)
+{
+ void *ans = NULL;
+ unsigned long flags; /* type required by kernel API */
+
+ if (opt == NULL) {
+ ROCE_ERR("Invalid parameter, opt is NULL.");
+ return NULL;
+ }
+
+ spin_lock_irqsave(&opt->spin_lock, flags);
+ if (opt->value != NULL) {
+ kref_get(&opt->refcount);
+ ans = opt->value;
+ }
+ spin_unlock_irqrestore(&opt->spin_lock, flags);
+
+ return ans;
+}
+
+void roce5_option_put_value(struct roce5_option *opt)
+{
+ unsigned long flags; /* type required by kernel API */
+ if (opt == NULL) {
+ ROCE_ERR("Invalid parameter, opt is NULL.");
+ return;
+ }
+
+ spin_lock_irqsave(&opt->spin_lock, flags);
+ if (opt->value != NULL) {
+ kref_put(&opt->refcount, roce5_wait_release);
+ }
+ spin_unlock_irqrestore(&opt->spin_lock, flags);
+}
\ No newline at end of file
diff --git a/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.h b/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.h
new file mode 100644
index 000000000..dba51cd68
--- /dev/null
+++ b/drivers/infiniband/hw/hiroce5/kernel/util/option/roce_option.h
@@ -0,0 +1,30 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef ROCE_OPTION_H
+#define ROCE_OPTION_H
+
+#include <linux/kref.h>
+#include <linux/completion.h>
+#include <linux/timer.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+#define ROCE_WAITING_MSG_MAX_SIZE 100
+
+struct roce5_option {
+ spinlock_t spin_lock;
+ struct kref refcount; /* count for the value ptr. */
+ struct completion release_comp;
+ struct timer_list msg_timer;
+ char waiting_msg[ROCE_WAITING_MSG_MAX_SIZE];
+ void *value;
+};
+
+struct roce5_option *roce5_some(void *value);
+void roce5_option_unset(struct roce5_option *opt, char *waiting_msg,
+ size_t waiting_msg_size);
+void *roce5_option_get_value(struct roce5_option *opt);
+void roce5_option_put_value(struct roce5_option *opt);
+
+#endif /* ROCE_OPTION_H */
--
2.37.7
2
1
From: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
driver inclusion
category: feature
bugzilla: https://atomgit.com/openeuler/kernel/issues/9708
CVE: NA
---------------------------------
Add hiudma5 driver to support ub device of hi1825 chip.
Signed-off-by: maogangpin <maogangpin(a)huawei.com<mailto:maogangpin@huawei.com>>
Reviewed-by: Qiujun <roland.qiu(a)huawei.com<mailto:roland.qiu@huawei.com>>
Reviewed-by: chiqijun <chiqijun(a)huawei.com<mailto:chiqijun@huawei.com>>
---
.../ub/urma/hw/hiudma5/base/third/ubdevshm.h | 177 ++
.../urma/hw/hiudma5/base/udma_base_common.h | 19 +
.../ub/urma/hw/hiudma5/base/udma_base_sq.c | 20 +
.../ub/urma/hw/hiudma5/base/udma_base_sq.h | 17 +
.../ub/urma/hw/hiudma5/kernel/CMakeLists.txt | 36 +
drivers/ub/urma/hw/hiudma5/kernel/Makefile | 239 ++
.../kernel/module/base/cmdq/udma_cmd_com.c | 225 ++
.../kernel/module/base/cmdq/udma_cmd_com.h | 97 +
.../kernel/module/base/cmdq/udma_cmd_eid.c | 596 ++++
.../kernel/module/base/cmdq/udma_cmd_eid.h | 37 +
.../kernel/module/base/cmdq/udma_cmd_event.c | 194 ++
.../kernel/module/base/cmdq/udma_cmd_event.h | 26 +
.../kernel/module/base/cmdq/udma_cmd_jetty.c | 1198 ++++++++
.../kernel/module/base/cmdq/udma_cmd_jetty.h | 69 +
.../kernel/module/base/cmdq/udma_cmd_jfc.c | 334 +++
.../kernel/module/base/cmdq/udma_cmd_jfc.h | 23 +
.../kernel/module/base/cmdq/udma_cmd_jfr.c | 422 +++
.../kernel/module/base/cmdq/udma_cmd_jfr.h | 20 +
.../kernel/module/base/cmdq/udma_cmd_jfrc.c | 480 +++
.../kernel/module/base/cmdq/udma_cmd_jfrc.h | 28 +
.../kernel/module/base/cmdq/udma_cmd_jfs.c | 341 +++
.../kernel/module/base/cmdq/udma_cmd_jfs.h | 23 +
.../kernel/module/base/cmdq/udma_cmd_mig.c | 60 +
.../kernel/module/base/cmdq/udma_cmd_mig.h | 14 +
.../module/base/cmdq/udma_cmd_segment.c | 418 +++
.../module/base/cmdq/udma_cmd_segment.h | 30 +
.../kernel/module/base/cmdq/udma_cmd_sip.c | 183 ++
.../kernel/module/base/cmdq/udma_cmd_sip.h | 20 +
.../kernel/module/base/cmdq/udma_cmd_srq.c | 326 ++
.../kernel/module/base/cmdq/udma_cmd_srq.h | 22 +
.../kernel/module/base/cmdq/udma_cmd_tp.c | 1885 ++++++++++++
.../kernel/module/base/cmdq/udma_cmd_tp.h | 72 +
.../kernel/module/base/cmdq/udma_cmd_tpg.c | 333 +++
.../kernel/module/base/cmdq/udma_cmd_tpg.h | 32 +
.../kernel/module/base/cmdq/udma_cmd_utp.c | 206 ++
.../kernel/module/base/cmdq/udma_cmd_utp.h | 19 +
.../kernel/module/base/cmdq/udma_cmd_vtp.c | 656 ++++
.../kernel/module/base/cmdq/udma_cmd_vtp.h | 57 +
.../kernel/module/base/common/udma_abi.h | 62 +
.../kernel/module/base/common/udma_bitmap.c | 84 +
.../kernel/module/base/common/udma_bitmap.h | 27 +
.../kernel/module/base/common/udma_common.h | 489 +++
.../kernel/module/base/common/udma_cqm.c | 67 +
.../kernel/module/base/common/udma_cqm.h | 19 +
.../kernel/module/base/common/udma_log.c | 20 +
.../kernel/module/base/common/udma_log.h | 179 ++
.../kernel/module/base/common/udma_misc.c | 1386 +++++++++
.../kernel/module/base/common/udma_misc.h | 131 +
.../kernel/module/base/common/udma_mtt.c | 154 +
.../kernel/module/base/common/udma_mtt.h | 19 +
.../hiudma5/kernel/module/base/db/udma_db.c | 81 +
.../hiudma5/kernel/module/base/db/udma_db.h | 40 +
.../hw/hiudma5/kernel/module/bond/udma_bond.h | 10 +
.../kernel/module/bond/udma_bond_common.c | 163 +
.../kernel/module/context/udma_ucontext.c | 325 ++
.../kernel/module/context/udma_ucontext.h | 51 +
.../hiudma5/kernel/module/device/udma_cmd.c | 281 ++
.../hiudma5/kernel/module/device/udma_cmd.h | 78 +
.../hiudma5/kernel/module/device/udma_comp.h | 46 +
.../kernel/module/device/udma_device.c | 242 ++
.../kernel/module/device/udma_device.h | 15 +
.../kernel/module/device/udma_fast_msg.c | 787 +++++
.../kernel/module/device/udma_fast_msg.h | 35 +
.../hiudma5/kernel/module/device/udma_main.c | 1044 +++++++
.../hiudma5/kernel/module/device/udma_query.c | 332 +++
.../hiudma5/kernel/module/device/udma_query.h | 20 +
.../kernel/module/device/udma_ubrc_comp.c | 153 +
.../kernel/module/device/udma_ubrc_comp.h | 15 +
.../kernel/module/device/udma_xid_cfg.c | 72 +
.../kernel/module/device/udma_xid_cfg.h | 16 +
.../hw/hiudma5/kernel/module/dfx/udma_dfx.c | 2625 +++++++++++++++++
.../hw/hiudma5/kernel/module/dfx/udma_dfx.h | 71 +
.../kernel/module/dfx/udma_dfx_attack.c | 831 ++++++
.../kernel/module/dfx/udma_dfx_attack.h | 24 +
.../kernel/module/dfx/udma_dfx_capture.c | 312 ++
.../kernel/module/dfx/udma_dfx_capture.h | 114 +
.../kernel/module/dfx/udma_dfx_cc_inject.c | 40 +
.../kernel/module/dfx/udma_dfx_cc_inject.h | 24 +
.../kernel/module/dfx/udma_dfx_cqm_modify.c | 362 +++
.../kernel/module/dfx/udma_dfx_cqm_modify.h | 28 +
.../hiudma5/kernel/module/dfx/udma_dfx_drop.c | 249 ++
.../hiudma5/kernel/module/dfx/udma_dfx_drop.h | 34 +
.../hiudma5/kernel/module/dfx/udma_dfx_l2d.c | 187 ++
.../hiudma5/kernel/module/dfx/udma_dfx_l2d.h | 28 +
.../kernel/module/dfx/udma_dfx_latch.c | 671 +++++
.../kernel/module/dfx/udma_dfx_latch.h | 34 +
.../kernel/module/dfx/udma_dfx_modify.c | 649 ++++
.../kernel/module/dfx/udma_dfx_modify.h | 15 +
.../kernel/module/dfx/udma_dfx_perf_ctr.c | 108 +
.../kernel/module/dfx/udma_dfx_perf_ctr.h | 24 +
.../kernel/module/dfx/udma_dfx_perf_query.c | 152 +
.../kernel/module/dfx/udma_dfx_perf_query.h | 29 +
.../kernel/module/dfx/udma_dfx_port_sta.c | 182 ++
.../kernel/module/dfx/udma_dfx_port_sta.h | 24 +
.../kernel/module/dfx/udma_dfx_query_tp.c | 861 ++++++
.../kernel/module/dfx/udma_dfx_query_tp.h | 16 +
.../kernel/module/event/udma_resource.c | 1457 +++++++++
.../kernel/module/event/udma_resource.h | 31 +
.../hiudma5/kernel/module/jetty/udma_jetty.c | 2326 +++++++++++++++
.../hiudma5/kernel/module/jetty/udma_jetty.h | 551 ++++
.../hw/hiudma5/kernel/module/jetty/udma_jfc.c | 1358 +++++++++
.../hw/hiudma5/kernel/module/jetty/udma_jfc.h | 77 +
.../hw/hiudma5/kernel/module/jetty/udma_jfr.c | 1042 +++++++
.../hw/hiudma5/kernel/module/jetty/udma_jfs.c | 2107 +++++++++++++
.../hw/hiudma5/kernel/module/jetty/udma_srq.c | 528 ++++
.../hw/hiudma5/kernel/module/jetty/udma_srq.h | 205 ++
.../kernel/module/rc_table/udma_rc_table.c | 1049 +++++++
.../kernel/module/rc_table/udma_rc_table.h | 46 +
.../hiudma5/kernel/module/segment/udma_key.c | 73 +
.../hiudma5/kernel/module/segment/udma_key.h | 29 +
.../kernel/module/segment/udma_segment.c | 788 +++++
.../kernel/module/segment/udma_segment.h | 78 +
.../kernel/module/segment/udma_shm_manage.c | 67 +
.../kernel/module/segment/udma_shm_manage.h | 25 +
.../hiudma5/kernel/module/sysfs/udma_sysfs.c | 476 +++
.../hiudma5/kernel/module/sysfs/udma_sysfs.h | 158 +
.../kernel/module/sysfs/udma_sysfs_api.h | 216 ++
.../kernel/module/sysfs/udma_sysfs_common.c | 715 +++++
.../kernel/module/sysfs/udma_sysfs_common.h | 88 +
.../kernel/module/sysfs/udma_sysfs_config.c | 688 +++++
.../kernel/module/sysfs/udma_sysfs_config.h | 13 +
.../kernel/module/table_manage/udma_net.c | 330 +++
.../kernel/module/table_manage/udma_net.h | 77 +
.../hw/hiudma5/kernel/module/tp/udma_tp.c | 1809 ++++++++++++
.../hw/hiudma5/kernel/module/tp/udma_tp.h | 184 ++
.../hw/hiudma5/kernel/module/tp/udma_tpg.c | 677 +++++
.../hw/hiudma5/kernel/module/tp/udma_tpg.h | 54 +
.../hw/hiudma5/kernel/module/tp/udma_utp.c | 209 ++
.../hw/hiudma5/kernel/module/tp/udma_utp.h | 32 +
.../hw/hiudma5/kernel/module/tp/udma_vtp.c | 1011 +++++++
.../hw/hiudma5/kernel/module/tp/udma_vtp.h | 66 +
.../kernel/module/userctl/udma_userctl.c | 96 +
.../kernel/module/userctl/udma_userctl.h | 51 +
.../kernel/module/userctl/udma_userctl_dfx.c | 243 ++
.../kernel/module/userctl/udma_userctl_dfx.h | 14 +
.../kernel/module/userctl/udma_userctl_uvs.c | 364 +++
.../kernel/module/userctl/udma_userctl_uvs.h | 23 +
.../hw/hiudma5/kernel/module/vram/udma_vram.c | 225 ++
.../hw/hiudma5/kernel/module/vram/udma_vram.h | 95 +
.../kernel/module/vram/udma_vram_base.c | 104 +
.../kernel/module/vram/udma_vram_base.h | 22 +
.../kernel/module/vram/udma_vram_cfg.c | 108 +
.../kernel/module/vram/udma_vram_cfg.h | 20 +
.../kernel/module/vram/udma_vram_common.h | 25 +
.../kernel/module/vram/udma_vram_mem.c | 412 +++
.../kernel/module/vram/udma_vram_mem.h | 44 +
.../kernel/module/vram/udma_vram_type_dev.c | 37 +
.../kernel/module/vram/udma_vram_type_dev.h | 10 +
.../kernel/module/vram/udma_vram_type_tp.c | 89 +
.../kernel/module/vram/udma_vram_type_tp.h | 10 +
.../kernel/module/vram/udma_vram_type_tpg.c | 69 +
.../kernel/module/vram/udma_vram_type_tpg.h | 10 +
.../kernel/module/vram/udma_vram_type_vtp.c | 45 +
.../kernel/module/vram/udma_vram_type_vtp.h | 10 +
154 files changed, 43857 insertions(+)
create mode 100644 drivers/ub/urma/hw/hiudma5/base/third/ubdevshm.h
create mode 100644 drivers/ub/urma/hw/hiudma5/base/udma_base_common.h
create mode 100644 drivers/ub/urma/hw/hiudma5/base/udma_base_sq.c
create mode 100644 drivers/ub/urma/hw/hiudma5/base/udma_base_sq.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/CMakeLists.txt
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/Makefile
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_abi.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_common.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond_common.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_comp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_main.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfr.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfs.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_api.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_common.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.h
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.c
create mode 100644 drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.h
diff --git a/drivers/ub/urma/hw/hiudma5/base/third/ubdevshm.h b/drivers/ub/urma/hw/hiudma5/base/third/ubdevshm.h
new file mode 100644
index 000000000..79da16b5d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/base/third/ubdevshm.h
@@ -0,0 +1,177 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Hisilicon Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef _UBDEVSHM_H
+#define _UBDEVSHM_H
+
+#include <linux/kernel.h>
+
+struct uba_eid {
+ u64 eid : 20; /* bus_instance_eid */
+ u64 reserved0 : 44;
+ u64 reserved1 : 64;
+};
+
+union uba_attr {
+ struct {
+ u64 readable : 1;
+ u64 writeable : 1;
+ u64 executeable : 1;
+ u64 token_value_required : 1;
+ u64 reserved : 60;
+ } bs;
+ u64 value;
+};
+
+union acquire_attr {
+ struct {
+ u64 require_pin : 1;
+ u64 require_invalidate : 1;
+ u64 reserved : 62;
+ } bs;
+ u64 value;
+};
+
+struct mem_uva {
+ u64 va;
+ u64 size;
+ u64 invalidate_tag;
+};
+
+struct mem_uba {
+ u64 uba;
+ u64 size;
+ u32 token_id; /* BIT[0:19] is valid for token_id */
+ struct uba_eid eid;
+ union uba_attr attr;
+
+ void *mem_handle; /* used by ubdevshm inner */
+};
+
+enum identity_type {
+ /*
+ * IDENTIY_TGID constraint:
+ * The shared and user processes must reside within the same PID namespace.
+ */
+ IDENTIY_TGID,
+ IDENTIY_TYPE_MAX,
+};
+
+struct shm_user {
+ enum identity_type type;
+ u32 user_len;
+ void *user;
+};
+
+struct access_ctx {
+ u32 shm_container_id;
+ u32 access_ctx_id;
+};
+
+typedef int (*invalidate)(u64 invalidate_tag);
+
+#define UBDEV_SHM_DRIVER_NAME_LENGTH 128
+
+struct ubdevshm_mem_ops {
+ char name[UBDEV_SHM_DRIVER_NAME_LENGTH];
+ u32 version;
+
+ /* Request access to the virtual address range of the given VA */
+ int (*acquire)(struct mem_uva *va, union acquire_attr *attr,
+ invalidate func, struct mem_uba *uba);
+
+ /* Release the uba address */
+ int (*release)(struct mem_uba *uba);
+};
+
+#ifdef ushm_handle_t
+#error "ushm_handle_t already defined!"
+#else
+typedef unsigned long ushm_handle_t;
+#endif
+
+/**
+ * ubdevshm initialization check interface
+ * @return: true indicates ubdevshm is avaialbe, false indicates not
+ * @note: this interface should be called before any other ubdevshm interfaces
+ */
+bool ubdevshm_is_inited(void);
+
+/*
+ * NOTE:
+ * pid/tgid is implicit in the calling context and not passed explicitly
+ * in the following interfaces.
+ */
+
+/**
+ * Memory provider registration interface
+ * @input: struct ubdevshm_mem_ops *ops, memory provider specific alloc/free callbacks
+ * @output: ushm_handle_t *handle, corresponding memory provider handle
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_register_ops(struct ubdevshm_mem_ops *ops, ushm_handle_t *handle);
+
+/**
+ * Memory provider unregistration interface
+ * @input: ushm_handle_t *handle, corresponding memory provider handle
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_unregister_ops(ushm_handle_t *handle);
+
+/**
+ * Share memory segment registration interface
+ * @input: ushm_handle_t *handle, corresponding memory provider handle
+ * @input: struct mem_uva *va, virtual address range of the given VA
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_register_segment(ushm_handle_t *handle, struct mem_uva *va);
+
+/**
+ * Share memory segment unregistration interface
+ * @input: ushm_handle_t *handle, corresponding memory provider handle
+ * @input: struct mem_uva *va, virtual address range of the given VA
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_unregister_segment(ushm_handle_t *handle, struct mem_uva *va);
+
+/**
+ * Authorize the memory of mem_uva to shm_user
+ * @input: ushm_handle_t *handle, corresponding memory provider handle
+ * @input: struct shm_user *user, corresponding authorized process information
+ * @input: struct mem_uva *va, virtual address range of the given VA
+ * @output: struct access_ctx *ctx, the context of the segment obtained after authorization
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_grant_access(ushm_handle_t *handle, struct shm_user *user,
+ struct mem_uva *va, struct access_ctx *ctx);
+
+/**
+ * De-authorize the shared memory associated with access_ctx
+ * @input: struct access_ctx *ctx, the context of the segment obtained after authorization
+ * @return: 0 indicates success, while any other value indicates failure
+ */
+int ubdevshm_ungrant_access(struct access_ctx *ctx);
+
+/**
+ * Request to acqurie the address corresponding to mem_uva and convert it into
+ * a ub address
+ * @input: struct access_ctx *ctx, the context of the segment
+ * @input: struct mem_uva *va, virtual address range of the given VA
+ * @input: union acquire_attr *attr, request attributes
+ * @input: func, When require_invalidate in acquire_attr is set to 1,
+ * this function must not be NULL, and is used as a callback
+ * for the memory provider to release memory.
+ * @output: struct mem_uba uba, the ub address corresponding to the virtual address va
+ */
+int ubdevshm_acquire_uba(struct access_ctx *ctx, struct mem_uva *va,
+ union acquire_attr *attr, invalidate func,
+ struct mem_uba *uba);
+
+/**
+ * Request to release the address corresponding to mem_uba
+ * @input: struct access_ctx *ctx, the context of the segment
+ * @input: struct mem_uba *uba, the ub address to be released
+ */
+int ubdevshm_release_uba(struct access_ctx *ctx, struct mem_uba *uba);
+#endif /* _UBDEVSHM_H */
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/base/udma_base_common.h b/drivers/ub/urma/hw/hiudma5/base/udma_base_common.h
new file mode 100644
index 000000000..172203737
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/base/udma_base_common.h
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_BASE_COMMON_H
+#define UDMA_BASE_COMMON_H
+
+#ifndef BIT
+#define BIT(n) (1U << (n))
+#endif
+
+enum udma_device_type {
+ UDMA_DEV_TYPE_UNKNOWN = 0U, /**< unknown device type */
+ UDMA_DEV_TYPE_HI1825_V100 = BIT(0), /**< HI1825 V100 device type */
+};
+
+#define UDMA_DEV_TYPE_ALL (UDMA_DEV_TYPE_HI1825_V100)
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.c b/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.c
new file mode 100644
index 000000000..79f9ad1a4
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.c
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "udma_base_sq.h"
+#include <stddef.h>
+
+void udma_base_construct_sq_db(union tag_ub_sq_db_u *send_queue_db, u32 xid,
+ u32 pi, u8 cos)
+{
+ if (send_queue_db == NULL) {
+ return;
+ }
+ send_queue_db->sq_db_value = 0;
+ send_queue_db->sq_db.dw0.bs.xqn = xid;
+ send_queue_db->sq_db.dw0.bs.type = UB_SERVICE_TYPE;
+ send_queue_db->sq_db.dw1.bs.pi = (pi >> UB_SQ_DB_SHIFT) & 0xFF;
+ send_queue_db->sq_db.dw0.bs.cntx_size = UB_CNTX_SIZE;
+ send_queue_db->sq_db.dw0.bs.cos = cos;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.h b/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.h
new file mode 100644
index 000000000..b43a7c092
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/base/udma_base_sq.h
@@ -0,0 +1,17 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_BASE_SQ_H
+#define UDMA_BASE_SQ_H
+
+#include "ub_xqe_format.h"
+
+#define UB_SERVICE_TYPE 2
+#define UB_SQ_DB_SHIFT 8
+#define UB_CNTX_SIZE 2
+
+void udma_base_construct_sq_db(union tag_ub_sq_db_u *send_queue_db, u32 xid,
+ u32 pi, u8 cos);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/CMakeLists.txt b/drivers/ub/urma/hw/hiudma5/kernel/CMakeLists.txt
new file mode 100644
index 000000000..832ac9aa9
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/CMakeLists.txt
@@ -0,0 +1,36 @@
+if("${BUILD_VERSION}" MATCHES "ub_ascend")
+ set(UMMU_CORE_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ummu-core-v1)
+elseif("${PRODUCT}" STREQUAL "ascend910D" OR "${PRODUCT}" STREQUAL "ascend910Desl")
+ set(UBUS_DIR ${TOP_DIR}/drivers/ubus)
+ set(KDIR ${KERNEL_WORK_DIR}/../linux-4.19)
+ set(UMMU_CORE_BUILD_DIR ${UBUS_DIR}/kernel/ummu-core-v1)
+else()
+ set(UMMU_CORE_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ummu-core)
+endif()
+
+set(UBUS_UBC_BUILD_DIR ${UBUS_BUILD_DIR}/kernel/ubus)
+set(HISDK5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/sdk/knldk/lld)
+set(HINIC5_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/ChipSolution/src/dpu_platform_library/host/service/nic/linux)
+set(UBCORE_BUILD_DIR ${BUILD_CACHE_TOP_DIR}/cmake/component/kernel/urma/code/output/kmod/ubcore)
+
+if("${PRODUCT}" STREQUAL "ascend910D" OR "${PRODUCT}" STREQUAL "ascend910Desl")
+ set(udma_depends ubus URMA)
+ add_device_ko(LOCAL_MODULE hiudma5
+ KO_SRC_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}
+ MAKE_ARGS "IS_ASCEND=true" "URMA_SOURCE_DIR=${URMA_SOURCE_DIR}"
+ TARGETE_DPENDS "${udma_depends}")
+else()
+ add_custom_target(hiudma5_ko
+ COMMENT echo "build ${CMAKE_CURRENT_SOURCE_DIR} start."
+ COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/Makefile ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${MAKE} -j64 -C ${KDIR} M=${CMAKE_CURRENT_BINARY_DIR} src=${CMAKE_CURRENT_SOURCE_DIR} UBUS_UBC_BUILD_DIR=${UBUS_UBC_BUILD_DIR} UBCORE_SYMVERS=${UBCORE_BUILD_DIR}/Module.symvers UMMU_CORE_BUILD_DIR=${UMMU_CORE_BUILD_DIR} HI1823_TRUNK_DIR=${TOP_DIR}/ChipSolution HI1823_BUILD_DIR=${TOP_DIR}/ChipSolution/build CONFIG_UBUS_DEVICE=y HI1823_OS_TYPE=openEuler24.03 VERBOSE=1 HISDK5_SYMVERS=${HISDK5_BUILD_DIR}/Module.symvers HINIC5_SYMVERS=${HINIC5_BUILD_DIR}/Module.symvers CHIP_VERSION=hi1825v100
+ COMMAND cp -f *.ko ${CMAKE_INSTALL_PREFIX}/ko
+ DEPENDS kernel
+ )
+
+ add_dependencies(hiudma5_ko URMA)
+ add_dependencies(hiudma5_ko hisdk5_ko)
+ add_dependencies(hiudma5_ko hinic5_ko)
+ add_dependencies(hiudma5_ko ubus_ko)
+ add_dependencies(hiudma5_ko ummu_core_ko)
+endif()
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/Makefile b/drivers/ub/urma/hw/hiudma5/kernel/Makefile
new file mode 100644
index 000000000..7230ad40d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/Makefile
@@ -0,0 +1,239 @@
+#
+# Makefile for the Hisilicon ubep drivers.
+#
+#
+mkfile_dir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+KDIR=/lib/modules/$(shell uname -r)/build
+TOP_DIR := $(src)/../../../../../../
+KUDMA_DIR := $(src)
+
+ifeq ($(CONFIG_UBUS_DEVICE), y)
+TOP_DIR := $(HI1823_TRUNK_DIR)
+UMDK_DIR := $(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/urma/code
+KUDMA_DIR := $(HI1823_TRUNK_DIR)/src/dpu_platform_library/host/service/udma/kernel
+endif
+
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/public \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfg_mgmt \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mpu \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/rdma/hi182x \
+ -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/roce \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/nic \
+ -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/nic \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/mag \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/migrate \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/bond \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/cfm \
+ -I$(TOP_DIR)/src/dpu_platform_library/host/include/cfm/fast_msg \
+ -I$(TOP_DIR)/src/dpu_platform_library/host/include/sdk/knldk \
+ -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/uboe \
+ -I$(TOP_DIR)/src/dpu_develop_interface/fw_msg_intf/ubc_net \
+ -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf \
+ -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/hisdk \
+ -I$(TOP_DIR)/src/dpu_platform_library/include/drv_tool_msg \
+ -I$(TOP_DIR)/src/dpu_platform_library/include\
+ -I$(TOP_DIR)/src/dpu_platform_library/include/drv_fw_msg/uboe \
+ -I$(TOP_DIR)/src/dpu_platform_library/host/service/include \
+ -I$(TOP_DIR)/src/dpu_develop_interface/drv_sdk_intf/ossl \
+ -I$(TOP_DIR)/src/dpu_develop_interface/drv_srvc_intf/udma \
+ -I$(TOP_DIR)/platform/huawei_secure_c/include \
+ -I$(TOP_DIR)/platform/huawei_secure_c/src
+
+ifeq ($(CONFIG_UBUS_DEVICE), y)
+ccflags-y += -I$(TOP_DIR)/src/dpu_develop_interface \
+ -I$(TOP_DIR)/../opensource/openeuler/kernel/olk-6.6/include/linux
+endif
+
+ccflags-y += -I$(UMDK_DIR)/kmod/ubcore \
+ -I$(UMDK_DIR)/kmod/ubcore/include \
+ -I$(UMDK_DIR)/include \
+ -I$(UMDK_DIR)/include/common \
+ -I$(KUDMA_DIR)/module/base/common \
+ -I$(KUDMA_DIR)/module \
+ -I$(KUDMA_DIR)/module/base/cmdq \
+ -I$(KUDMA_DIR)/module/bond \
+ -I$(KUDMA_DIR)/module/vram \
+ -I$(KUDMA_DIR)/module/userctl \
+ -I$(TOP_DIR)/src/dpu_platform_library/host/include/cfm/bond \
+ -I$(KUDMA_DIR)/../../../../../dpu_develop_interface/fw_msg_intf/cfm \
+ -I$(KUDMA_DIR)/../../../../../dpu_develop_interface/drv_cfm_intf/hmm \
+ -I$(TOP_DIR)/src/dpu_platform_library/host/cfm/hmm \
+ -I$(KUDMA_DIR)/module/dfx \
+ -I$(KUDMA_DIR)/../base \
+ -I$(KUDMA_DIR)/../base/third \
+ -I$(KUDMA_DIR)/module/segment \
+ -I$(KUDMA_DIR)/module/base/db \
+ -I$(KUDMA_DIR)/module/context \
+ -I$(KUDMA_DIR)/module/sysfs \
+ -I$(KUDMA_DIR)/module/device \
+ -I$(KUDMA_DIR)/module/tp \
+ -I$(KUDMA_DIR)/module/jetty \
+ -I$(KUDMA_DIR)/module/rc_table \
+ -I$(KUDMA_DIR)/module/event \
+ -I$(KUDMA_DIR)/module/table_manage
+
+ifeq ($(VERSION),UDMA_STANDARD)
+ ccflags-y += -DSIGN_MTT_EN
+endif
+
+ccflags-y += -I$(UMDK_DIR)/src/urma/kmod/include \
+ -I$(UMDK_DIR)/src/urma/kmod/include/ub/urma \
+ -I$(UMDK_DIR)/src/urma/kmod/drivers/ub/urma/ubcore
+
+ccflags-y += -DLINUX_KERNEL -Wno-implicit-fallthrough
+ccflags-y += -DSECUREC_EXPORT_KERNEL_SYMBOL=0
+
+##Safe compilation options
+ccflags-y += -fstack-protector-all -Wl,-z,noexecstack
+ifneq ($(CONFIG_UBUS_DEVICE), y)
+ccflags-y += -Werror -std=gnu11
+endif
+
+KBUILD_EXTRA_SYMBOLS += $(TOP_DIR)/ci/lib/UBCORE_Module.symvers
+ifeq ($(CONFIG_UBUS_DEVICE), y)
+KBUILD_EXTRA_SYMBOLS += $(HISDK5_SYMVERS)
+KBUILD_EXTRA_SYMBOLS += $(HINIC5_SYMVERS)
+else
+KBUILD_EXTRA_SYMBOLS += $(TOP_DIR)/ci/lib/SDK_Module.symvers
+KBUILD_EXTRA_SYMBOLS += $(TOP_DIR)/ci/lib/NIC_Module.symvers
+endif
+
+UDMA_OBJS := module/tp/udma_tp.o \
+ module/tp/udma_tpg.o \
+ module/device/udma_query.o \
+ module/tp/udma_vtp.o \
+ module/tp/udma_utp.o \
+ module/device/udma_fast_msg.o \
+ module/device/udma_xid_cfg.o \
+ module/device/udma_device.o \
+ module/device/udma_cmd.o \
+ module/event/udma_resource.o \
+ module/table_manage/udma_net.o \
+ module/device/udma_ubrc_comp.o \
+ module/segment/udma_segment.o \
+ module/segment/udma_key.o \
+ module/segment/udma_shm_manage.o \
+ module/context/udma_ucontext.o \
+ module/base/db/udma_db.o \
+ module/sysfs/udma_sysfs.o \
+ module/sysfs/udma_sysfs_common.o \
+ module/sysfs/udma_sysfs_config.o \
+ module/jetty/udma_jetty.o \
+ module/jetty/udma_jfs.o \
+ module/jetty/udma_jfr.o \
+ module/jetty/udma_jfc.o \
+ module/jetty/udma_srq.o \
+ module/rc_table/udma_rc_table.o
+
+UDMA_CMDQ_OBJS := module/base/cmdq/udma_cmd_jetty.o \
+ module/base/cmdq/udma_cmd_com.o \
+ module/base/cmdq/udma_cmd_eid.o \
+ module/base/cmdq/udma_cmd_event.o \
+ module/base/cmdq/udma_cmd_jfs.o \
+ module/base/cmdq/udma_cmd_jfc.o \
+ module/base/cmdq/udma_cmd_segment.o \
+ module/base/cmdq/udma_cmd_srq.o \
+ module/base/cmdq/udma_cmd_jfrc.o \
+ module/base/cmdq/udma_cmd_sip.o \
+ module/base/cmdq/udma_cmd_utp.o \
+ module/base/cmdq/udma_cmd_tp.o \
+ module/base/cmdq/udma_cmd_vtp.o \
+ module/base/cmdq/udma_cmd_tpg.o \
+ module/base/cmdq/udma_cmd_jfr.o \
+ module/base/cmdq/udma_cmd_mig.o
+
+COM_OBJS := module/base/common/udma_bitmap.o \
+ module/base/common/udma_cqm.o \
+ module/base/common/udma_mtt.o \
+ module/base/common/udma_misc.o \
+ module/base/common/udma_log.o
+
+
+BOND_OBJS := module/bond/udma_bond_common.o
+
+UDMA_VRAM := module/vram/udma_vram.o \
+ module/vram/udma_vram_base.o \
+ module/vram/udma_vram_cfg.o \
+ module/vram/udma_vram_mem.o \
+ module/vram/udma_vram_type_dev.o \
+ module/vram/udma_vram_type_tp.o \
+ module/vram/udma_vram_type_tpg.o \
+ module/vram/udma_vram_type_vtp.o
+
+
+USERCTL_OBJS := module/userctl/udma_userctl.o \
+ module/userctl/udma_userctl_uvs.o \
+ module/userctl/udma_userctl_dfx.o
+
+BASE_OBJS := ../base/udma_base_sq.o
+
+HMM_OBJS := ../../../cfm/hmm/hmm_buddy.o \
+ ../../../cfm/hmm/hmm_common.o \
+ ../../../cfm/hmm/hmm_mtt.o \
+ ../../../cfm/hmm/hmm_mpt.o \
+ ../../../cfm/hmm/hmm_em.o \
+
+DFX_OBJS := module/dfx/udma_dfx.o \
+ module/dfx/udma_dfx_attack.o \
+ module/dfx/udma_dfx_capture.o \
+ module/dfx/udma_dfx_drop.o \
+ module/dfx/udma_dfx_port_sta.o \
+ module/dfx/udma_dfx_cc_inject.o \
+ module/dfx/udma_dfx_cqm_modify.o \
+ module/dfx/udma_dfx_query_tp.o \
+ module/dfx/udma_dfx_perf_ctr.o \
+ module/dfx/udma_dfx_modify.o \
+ module/dfx/udma_dfx_latch.o \
+ module/dfx/udma_dfx_l2d.o \
+ module/dfx/udma_dfx_perf_query.o
+
+HW_SECUREC_OBJS := ../../../../../../platform/huawei_secure_c/src/securecutil.o \
+ ../../../../../../platform/huawei_secure_c/src/secureinput_a.o \
+ ../../../../../../platform/huawei_secure_c/src/secureprintoutput_a.o \
+ ../../../../../../platform/huawei_secure_c/src/memset_s.o \
+ ../../../../../../platform/huawei_secure_c/src/memcpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strncpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strncat_s.o \
+ ../../../../../../platform/huawei_secure_c/src/sprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsnprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/snprintf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/vsscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/sscanf_s.o \
+ ../../../../../../platform/huawei_secure_c/src/memmove_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strcpy_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strcat_s.o \
+ ../../../../../../platform/huawei_secure_c/src/strtok_s.o
+
+MAIN_OBJS := module/device/udma_main.o
+
+hiudma5-objs := $(MAIN_OBJS) \
+ $(UDMA_OBJS) \
+ $(UDMA_CMDQ_OBJS) \
+ $(COM_OBJS) \
+ $(BOND_OBJS) \
+ $(UDMA_VRAM) \
+ $(HMM_OBJS) \
+ $(DFX_OBJS) \
+ $(HW_SECUREC_OBJS) \
+ $(USERCTL_OBJS) \
+ $(BASE_OBJS)
+
+ifeq ($(CONFIG_UBUS_DEVICE), y)
+KBUILD_EXTRA_SYMBOLS += $(UBUS_UBC_BUILD_DIR)/Module.symvers
+ccflags-y += -D__UBUS_DRIVER__
+endif
+
+obj-m := hiudma5.o
+
+all:build_info default
+
+build_info:
+ mkdir -p build
+ @echo "CURDIR=$(CURDIR)" > build/build_src.txt
+ @for obj in $(hiudma5-objs); do \
+ echo $$(realpath $$obj) >> build/build_src.txt; \
+ done
+
+include $(HI1823_BUILD_DIR)/host/linux/Makefile.ko
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.c
new file mode 100644
index 000000000..c3706ab75
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/sched.h>
+#include <linux/ktime.h>
+#include "comm_defs.h"
+#include "udma_misc.h"
+#include "udma_cmd_com.h"
+
+#define UDMA_CMD_DPATH_CHECK_VAL 0xa5
+
+#define UDMA_CMD_WQEBB_INDEX_BASE 4
+#define UDMA_CMD_WQEBB_INDEX_MIN 2
+#define UDMA_CMD_WQEBB_INDEX_MAX 4
+#define UDMA_CMD_DEFAULT_WQEBB_SIZE 64
+#define UDMA_US_TO_NS(x) ((x)*1000)
+
+struct udma_page_shift {
+ u32 size;
+ u32 shift;
+};
+
+void udma_cpu_to_be32(void *data, u32 len)
+{
+ u32 chunk_sz = sizeof(u32);
+ u32 *mem = (u32 *)data;
+ u32 data_len;
+ u32 i;
+
+ if (data == NULL)
+ return;
+
+ data_len = len / chunk_sz;
+
+ for (i = 0; i < data_len; i++) {
+ *mem = cpu_to_be32(*mem);
+ mem++;
+ }
+}
+
+void udma_be32_to_cpu(void *data, u32 len)
+{
+ u32 i, chunk_sz = sizeof(u32);
+ u32 data_len = len;
+ u32 *mem = (u32 *)data;
+
+ if (!data)
+ return;
+
+ data_len = data_len / chunk_sz;
+
+ for (i = 0; i < data_len; i++) {
+ *mem = be32_to_cpu(*mem);
+ mem++;
+ }
+}
+
+void udma_be64_to_cpu(void *data, u32 len)
+{
+ u32 i, chunk_sz = sizeof(u64);
+ u32 data_len = len;
+ u64 *mem = (u64 *)data;
+
+ if (!data)
+ return;
+
+ data_len = data_len / chunk_sz;
+
+ for (i = 0; i < data_len; i++) {
+ *mem = be64_to_cpu(*mem);
+ mem++;
+ }
+}
+
+void udma_fill_cmd_header(struct ub_cmd_com_header *header, u8 cmd_type,
+ u8 cmd_subtype, u16 cmd_len, u32 id)
+{
+ header->major_version = 1;
+ header->minor_version = 0;
+ header->cmd_type = cmd_type;
+ header->cmd_subtype = cmd_subtype;
+ header->cmd_len = cmd_len;
+ header->idx = id;
+}
+
+static u32 udma_get_timeout_for_dpath(enum ub_env_type env_type)
+{
+ return env_type == UB_ENV_ESL ? UB_CMD_TIME_CLASS_B_FOR_ESL :
+ UB_CMD_TIME_CLASS_B;
+}
+
+int udma_cmd_check_dpath_dma(struct udma_device *udma_dev, u8 *buf, u32 size,
+ u32 step)
+{
+ u32 timeout = udma_get_timeout_for_dpath(udma_dev->env_type);
+ ulong end = jiffies + msecs_to_jiffies(timeout);
+ u32 i;
+
+ step = step == 0 ? 1 : step;
+ size = size * step;
+
+ while (time_before(jiffies, end) != 0) {
+ for (i = 0; i < size; i = i + step) {
+ if (buf[i] != UDMA_CMD_DPATH_CHECK_VAL)
+ break;
+ }
+
+ if (i == size)
+ return 0;
+
+ cond_resched();
+ }
+ udma_err(udma_dev->dev, UDMA_M_COM,
+ "check udma cmd dpath failed, size(%u), timeout(%u)\n", size,
+ timeout);
+ udma_dump_byte_err_dfx(udma_dev, buf, size);
+
+ return -EIO;
+}
+
+int udma_dpath_drain_handle(struct udma_device *udma_dev, u8 *buf,
+ u32 dpath_oq_num)
+{
+ if (dpath_oq_num > UDMA_DPATH_MAX_OQ_NUM) {
+ udma_err(udma_dev->dev, UDMA_M_COM,
+ "dpath oq num(%u) is over max oq num(%u)\n",
+ dpath_oq_num, UDMA_DPATH_MAX_OQ_NUM);
+ return -EINVAL;
+ }
+
+ /* dpath_oq_num return actually pending flush of oq num data, driver check magic number of corresponding count; */
+ return udma_cmd_check_dpath_dma(udma_dev, buf, dpath_oq_num,
+ sizeof(u32));
+}
+
+uint32_t udma_cal_page_shift(uint32_t buf_size)
+{
+ const struct udma_page_shift page_shift_map[] = {
+ { PAGE_SIZE_4K, PAGE_SHIFT_4K },
+ { PAGE_SIZE_64K, PAGE_SHIFT_64K },
+ { PAGE_SIZE_2M, PAGE_SHIFT_2M },
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(page_shift_map); i++) {
+ if (buf_size == page_shift_map[i].size) {
+ return page_shift_map[i].shift;
+ }
+ }
+
+ return PAGE_SHIFT_4K;
+}
+
+/*
+ * Page size of Queue.
+ * 0: 4KB
+ * 4: 64KB
+ * 9: 2MB
+ * others: reserved
+ */
+u32 udma_get_queue_kernel_page_size(u8 mtt_pro_en, u32 queue_size)
+{
+ u32 page_shift = PAGE_SHIFT;
+
+ if (mtt_pro_en == 1) {
+ page_shift = udma_cal_page_shift(queue_size);
+ }
+
+ return ((u32)(page_shift - PAGE_SHIFT_4K)) & UB_PAGE_SIZE_MASK;
+}
+
+static u32 udma_get_timeout_for_cmd(enum ub_env_type env_type)
+{
+ return env_type == UB_ENV_ESL ? UB_CMD_TIME_CLASS_C_FOR_ESL :
+ UB_CMD_TIME_CLASS_C;
+}
+
+int udma_send_cmd_box(struct udma_device *udma_dev, u8 cmd,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_cmd_buf *buf_out,
+ ub_cmdq_cqe_udata_s *out_param, struct cmdq_rtt *rtt)
+{
+ int ret;
+ ktime_t time_start = 0;
+ ktime_t time_cost = 0;
+ ub_cmdq_cqe_udata_s cmdq_cqe = { 0 };
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ time_start = ktime_get();
+ }
+
+ ret = cqm5_send_cmd_box(udma_dev->hwdev, HINIC5_MOD_UB, cmd, buf_in,
+ buf_out, (u64 *)(void *)&cmdq_cqe,
+ udma_get_timeout_for_cmd(udma_dev->env_type),
+ HINIC5_CHANNEL_UB);
+ if (unlikely(ret != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_COM,
+ "cmdq failed! cmd_type: 0x%x, sub_type: 0x%x, err_status: 0x%x, err_value: 0x%x, dw0: %x, dw1: 0x%x",
+ cmdq_cqe.bs.cmd_type, cmdq_cqe.bs.sub_type,
+ cmdq_cqe.bs.err_status, cmdq_cqe.bs.err_value,
+ cmdq_cqe.bs.dw0_value, cmdq_cqe.bs.dw1_value);
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1) &&
+ rtt != NULL) {
+ /* debug when enabled, statistics cmdq latency on success */
+ if (unlikely(ret != 0)) {
+ return ret;
+ }
+ time_cost = ktime_to_ns(ktime_sub(ktime_get(), time_start));
+ atomic64_inc(&rtt->times);
+ atomic64_add(UDMA_US_TO_NS(cmdq_cqe.bs.exec_time),
+ &rtt->cmdq_npu_rtt_sum);
+ atomic64_add(time_cost, &rtt->cmdq_rtt_sum);
+ }
+
+ if (out_param != NULL) {
+ (void)memcpy_s(out_param, sizeof(ub_cmdq_cqe_udata_s),
+ &cmdq_cqe, sizeof(ub_cmdq_cqe_udata_s));
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.h
new file mode 100644
index 000000000..c4f90d742
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_com.h
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_COM_H
+#define UDMA_CMD_COM_H
+
+#include "hinic5_cqm.h"
+#include "udma_common.h"
+#include "ub_npu_base_cmd.h"
+
+#define UB_RC_HI_PADDR_SHIFT 40 // high:24bit, 64-24= 40
+#define UB_RC_HI_PADDR_MASK 0xffffff
+#define UB_RC_LOW_PADDR_SHIFT 8
+#define UB_DPATH_CHECK_FLAG ((u32)(1 << 31))
+#define UB_PAGE_SIZE_MASK 0xf
+#define UDMA_DPATH_MAX_OQ_NUM 32
+
+#define DATALEN_RATIO 2 // user input of data is 4bit, one byte 8bit / 4 = 2
+#define DATA_SHIFT \
+ 4 // user input of data is 4bit, to convert to byte unit, even index need left shift 4 bit
+
+/* cmdq timeout for ASIC, FPGA */
+enum {
+ UB_CMD_TIME_CLASS_A = 3000,
+ UB_CMD_TIME_CLASS_B = 6000,
+ UB_CMD_TIME_CLASS_C = 10000,
+ UB_CMD_TIME_CLASS_D = 15000,
+ UB_CMD_TIME_CLASS_E = 20000
+};
+
+/* cmdq timeout for ESL */
+enum {
+ UB_CMD_TIME_CLASS_A_FOR_ESL = 3000000,
+ UB_CMD_TIME_CLASS_B_FOR_ESL = 6000000,
+ UB_CMD_TIME_CLASS_C_FOR_ESL = 10000000,
+ UB_CMD_TIME_CLASS_D_FOR_ESL = 15000000,
+ UB_CMD_TIME_CLASS_E_FOR_ESL = 20000000,
+};
+
+enum jetty_type {
+ JETTY_RAW_OR_NIC,
+ JETTY_UM,
+ JETTY_RC,
+ JETTY_RM,
+ JETTY_TYPE_RESERVED,
+};
+
+typedef struct udma_cqm_cmd_type_info {
+ u8 cmd_type;
+ u8 cmd_subtype;
+} udma_cqm_cmd_type_info_t;
+
+void udma_cpu_to_be32(void *data, u32 len);
+void udma_be32_to_cpu(void *data, u32 len);
+void udma_be64_to_cpu(void *data, u32 len);
+
+void udma_fill_cmd_header(struct ub_cmd_com_header *header, u8 cmd_type,
+ u8 cmd_subtype, u16 cmd_len, u32 id);
+int udma_cmd_check_dpath_dma(struct udma_device *udma_dev, u8 *buf, u32 size,
+ u32 step);
+u32 udma_get_queue_kernel_page_size(u8 mtt_pro_en, u32 queue_size);
+int udma_send_cmd_box(struct udma_device *udma_dev, u8 cmd,
+ struct tag_cqm_cmd_buf *buf_in,
+ struct tag_cqm_cmd_buf *buf_out,
+ ub_cmdq_cqe_udata_s *out_param, struct cmdq_rtt *rtt);
+int udma_dpath_drain_handle(struct udma_device *udma_dev, u8 *buf,
+ u32 dpath_oq_num);
+
+/**
+ * @brief data convert cmdq buf
+ *
+ * @param[in] in_buf - tool passed in of data
+ * @param[in] in_len - tool passed in of data length
+ * @param[out] out_buf - cmdq inbuf in of buf
+ * @param[out] out_len - cmdq inbuf in of buf length
+ * @param[in] offset - in ctx in offset
+ *
+ * @details user input copy to context corresponding position, Note: user input a character occupy 4bit, and user inputs in big-endian format, no need to convert again
+ * todo pending tool passed in of data in each u8 all in normal use when change is memory cpy
+ *
+ * @return NULL
+ * */
+static inline void udma_cmdq_data_to_context_buf(const u8 *in_buf, u32 in_len,
+ u8 *out_buf, u32 out_len,
+ u32 offset)
+{
+ u32 i = 0;
+
+ for (i = 0; (i < (in_len / DATALEN_RATIO)) && (i + offset < out_len);
+ ++i) {
+ *(out_buf + i + offset) =
+ (in_buf[i * DATALEN_RATIO] << DATA_SHIFT) +
+ in_buf[i * DATALEN_RATIO + 1];
+ }
+}
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.c
new file mode 100644
index 000000000..c5ab7660a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.c
@@ -0,0 +1,596 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+#include <linux/workqueue.h>
+#include "udma_cqm.h"
+#include "udma_cmd_com.h"
+#include "ub_npu_eid_cmd_defs.h"
+#include "ub_npu_eid_cmd.h"
+#include "ub_npu_upi_cmd_defs.h"
+#include "ub_npu_upi_cmd.h"
+#include "udma_cmd_eid.h"
+
+#define EID_ERR_VFID 0xffff
+
+static void udma_fill_ueid_cmd(enum UB_CMD_UPI_TYPE cmd_type, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg,
+ ub_upi_mig_state_e mig_state,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_upi_update);
+ struct ub_cmd_upi_update *ueid_inbuf = NULL;
+
+ ueid_inbuf = (struct ub_cmd_upi_update *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&ueid_inbuf->header, UB_CMD_TYPE_UPI, cmd_type,
+ cmd_len, 0);
+ ueid_inbuf->body.upi = cfg->upi;
+ ueid_inbuf->body.vfid = vf_id;
+ ueid_inbuf->body.mig_state = mig_state;
+
+ udma_cpu_to_be32(ueid_inbuf, cmd_len);
+ (void)memcpy_s(ueid_inbuf->body.id, sizeof(ueid_inbuf->body.id),
+ cfg->eid.raw,
+ sizeof(cfg->eid.raw)); //id not need endian conversion
+}
+
+static int udma_add_ueid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg,
+ ub_upi_mig_state_e mig_state)
+{
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_EID, "%s Invalid parameter: udma_dev(%d).\n",
+ __func__, !!udma_dev);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_upi_update), &cqm_cmd_outbuf,
+ (u16)(sizeof(int)));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for add_ueid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_ueid_cmd(UB_CMD_UPI_UPDATE, vf_id, cfg, mig_state,
+ cqm_cmd_inbuf);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_UPI_UPDATE, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send add_ueid command, ret = %d.\n", ret);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int udma_delete_ueid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_EID, "%s to_udma_dev failed.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_upi_update), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for delete_ueid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_ueid_cmd(UB_CMD_UPI_CLEAR, vf_id, cfg, UB_UPI_NORM,
+ cqm_cmd_inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_UPI_CLEAR, cqm_cmd_inbuf, NULL,
+ NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send delete_ueid command, ret = %d.\n",
+ ret);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_update_upi(struct udma_device *udma_dev, u16 vfid,
+ ub_seid_ctx_info_s *seid_ctx,
+ ub_upi_mig_state_e mig_state)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_upi_update);
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_upi_update *ueid_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_upi_update), &cqm_cmd_outbuf,
+ (u16)(sizeof(int)));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_EID,
+ "Update upi: failed to alloc inbuf for add_ueid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ ueid_inbuf = (struct ub_cmd_upi_update *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&ueid_inbuf->header, UB_CMD_TYPE_UPI,
+ UB_CMD_UPI_UPDATE, cmd_len, 0);
+ ueid_inbuf->body.upi = seid_ctx->upi;
+ ueid_inbuf->body.vfid = vfid;
+ ueid_inbuf->body.mig_state = mig_state;
+ udma_cpu_to_be32(ueid_inbuf, cmd_len);
+ ret = memcpy_s(ueid_inbuf->body.id, sizeof(ueid_inbuf->body.id),
+ seid_ctx->seid,
+ sizeof(seid_ctx->seid)); //id not need endian conversion
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Update upi: memcpy failed, ret:%d.\n", ret);
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_UPI_UPDATE, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_EID,
+ "Update upi: failed to send add_ueid command, ret = %d.\n",
+ ret);
+ ret = -EFAULT;
+ }
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static void udma_fill_add_seid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_seid_add);
+ struct ub_cmd_seid_add *seid_inbuf = NULL;
+
+ seid_inbuf = (struct ub_cmd_seid_add *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&seid_inbuf->header, UB_CMD_TYPE_EID,
+ UB_CMD_SEID_ADD, cmd_len, 0);
+ seid_inbuf->body.idx = cfg->eid_index;
+ seid_inbuf->body.upi = cfg->upi;
+ seid_inbuf->body.vfid = vf_id;
+
+ udma_cpu_to_be32(seid_inbuf, cmd_len);
+ (void)memcpy_s((void *)seid_inbuf->body.eid,
+ sizeof(seid_inbuf->body.eid), (void *)cfg->eid.raw,
+ sizeof(seid_inbuf->body.eid)); //eid not need endian conversion
+}
+
+static int udma_cmd_seid_add(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_EID, "Invalid parameter. dev(%d) cfg(%d).\n",
+ !!dev, !!cfg);
+ return -ENXIO;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_seid_add),
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for add seid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_add_seid_cmd(dev, vf_id, cfg, cqm_cmd_inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SEID_ADD, cqm_cmd_inbuf, NULL,
+ NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send command for add seid, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_ueid_add_npu_cmdq(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ int ret;
+
+ if ((dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_EID,
+ "%s Invalid parameter: dev(%d), cfg(%d).\n",
+ __func__, !!dev, !!cfg);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(dev);
+ ret = udma_add_ueid_cmd(dev, vf_id, cfg, UB_UPI_NORM);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Set ueid failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ ret = udma_cmd_seid_add(dev, vf_id, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Set seid failed, ret = %d\n", ret);
+ udma_delete_ueid_cmd(dev, vf_id, cfg);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_fill_del_seid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_seid_del);
+ struct ub_cmd_seid_del *seid_inbuf = NULL;
+
+ seid_inbuf = (struct ub_cmd_seid_del *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&seid_inbuf->header, UB_CMD_TYPE_EID,
+ UB_CMD_SEID_DEL, cmd_len, 0);
+ seid_inbuf->body.idx = cfg->eid_index;
+ seid_inbuf->body.vfid = vf_id;
+
+ udma_cpu_to_be32(seid_inbuf, cmd_len);
+}
+
+static int udma_cmd_seid_delete(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if ((dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_EID,
+ "%s Invalid parameter: dev(%d), cfg(%d).\n",
+ __func__, !!dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_EID, "%s to_udma_dev failed.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_seid_del),
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for del seid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_del_seid_cmd(dev, vf_id, cfg, cqm_cmd_inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SEID_DEL, cqm_cmd_inbuf, NULL,
+ NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send command for del seid, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int delete_ueid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ int ret;
+
+ if ((dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_EID,
+ "%s Invalid parameter: dev(%d), cfg(%d).\n",
+ __func__, !!dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+
+ ret = udma_delete_ueid_cmd(dev, vf_id, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID, "Delete ueid failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = udma_cmd_seid_delete(dev, vf_id, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID, "Delete seid failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_fill_query_seid_cmd(u16 vf_id, u32 idx,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_seid_query);
+
+ struct ub_cmd_seid_query *seid_inbuf = NULL;
+ seid_inbuf = (struct ub_cmd_seid_query *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&seid_inbuf->header, UB_CMD_TYPE_EID,
+ UB_CMD_SEID_QUERY, cmd_len, idx);
+ seid_inbuf->body.vfid = vf_id;
+ seid_inbuf->body.idx = idx;
+
+ udma_cpu_to_be32(seid_inbuf, cmd_len);
+}
+
+int udma_cmd_seid_query_ctx_from_cache(struct udma_device *udma_dev, u16 vf_id,
+ u32 idx, struct ub_seid_ctx_query *ctx,
+ u32 len)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ int ret;
+
+ if (len < sizeof(*ctx)) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "out len(%u) < ctx size(%u)\n", len,
+ (u32)(sizeof(*ctx)));
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_EID,
+ "Start query seid, vfid: %u, idx: %u\n", vf_id, idx);
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_seid_query), &cqm_cmd_outbuf,
+ sizeof(struct ub_seid_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for del seid, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_query_seid_cmd(vf_id, idx, cqm_cmd_inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SEID_QUERY, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send command for query seid, ret = %d.\n",
+ ret);
+ } else {
+ ret = memcpy_s((u8 *)ctx, sizeof(*ctx),
+ (u8 *)cqm_cmd_outbuf->buf, sizeof(*ctx));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "memcpy_s failed, ret = %d.\n", ret);
+ ret = -EFAULT;
+ }
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_seid_query_ignore_ub_disable_err(struct udma_device *udma_dev,
+ u16 vf_id, u32 idx,
+ ub_seid_ctx_info_s *ctx, u32 len)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_seid_query);
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_seid_query *seid_inbuf = NULL;
+ int ret;
+
+ if (len < sizeof(*ctx)) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "seid query, out len(%u) < ctx size(%u)\n", len,
+ (u32)(sizeof(*ctx)));
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_EID,
+ "Start query seid ignore ub disable, vfid: %u, idx: %u\n",
+ vf_id, idx);
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_seid_query), &cqm_cmd_outbuf,
+ sizeof(ub_seid_ctx_info_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to alloc inbuf for seid query, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ seid_inbuf = (struct ub_cmd_seid_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&seid_inbuf->header, UB_CMD_TYPE_EID,
+ UB_CMD_SEID_QUERY, cmd_len, idx);
+ seid_inbuf->body.vfid = vf_id;
+ seid_inbuf->body.idx = idx;
+ seid_inbuf->body.ignore_ub_disable_err = 1;
+ udma_cpu_to_be32(seid_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SEID_QUERY, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "Failed to send command for seid query, ret = %d.\n",
+ ret);
+ } else {
+ ret = memcpy_s((u8 *)ctx, sizeof(*ctx),
+ (u8 *)cqm_cmd_outbuf->buf, sizeof(*ctx));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_EID,
+ "memcpy_s failed, ret = %d.\n", ret);
+ ret = -EFAULT;
+ }
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+int udma_cmd_upi_query(struct udma_device *udma_dev,
+ ub_cmd_upi_key_attr_s *upi_idx,
+ ub_cmd_upi_value_attr_s *upi_value)
+{
+ struct ub_cmd_upi_query *cmd_upi_inbuf = NULL;
+ ub_cmd_upi_value_attr_s *cmd_upi_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ u16 cmd_len = sizeof(struct ub_cmd_upi_query);
+ int i = 0;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_upi_query), &cqm_cmd_outbuf,
+ (u16)sizeof(ub_cmd_upi_value_attr_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Alloc cmd_buf failed, err(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_upi_outbuf = (ub_cmd_upi_value_attr_s *)cqm_cmd_outbuf->buf;
+ cmd_upi_inbuf = (struct ub_cmd_upi_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&cmd_upi_inbuf->header, UB_CMD_TYPE_UPI,
+ UB_CMD_UPI_QUERY, sizeof(struct ub_cmd_upi_query),
+ 0);
+ cmd_upi_inbuf->body.dw0.value = upi_idx->dw0.value;
+ for (i = 0; i < UB_EID_LEN; i++)
+ cmd_upi_inbuf->body.id_dw[i] = upi_idx->id_dw[i];
+ udma_cpu_to_be32(cmd_upi_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_UPI_QUERY, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = memcpy_s(upi_value, sizeof(ub_cmd_upi_value_attr_s),
+ cmd_upi_outbuf, sizeof(ub_cmd_upi_value_attr_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy_s failed, ret(%d)\n", ret);
+ ret = -EFAULT;
+ goto out;
+ }
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+int udma_config_function_migrate_state(struct ubcore_device *dev, u16 fe_idx,
+ u32 cnt, struct ubcore_ueid_cfg *cfg,
+ enum ubcore_mig_state state)
+{
+ int ret = -EINVAL;
+ int cfg_cnt = 0;
+ uint32_t i;
+ struct udma_device *udma_dev = to_udma_dev(dev);
+
+ if (udma_dev == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_EID,
+ "config function migrate state invalid parameter. udma_dev(%d),cfg(%d) .\n",
+ !!udma_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_info(
+ udma_dev->dev, UDMA_M_EID,
+ "config function migrate state, vfid: %u, cnt: %u, state %u\n",
+ fe_idx, cnt, state);
+ for (i = 0; i < cnt; i++) {
+ switch (state) {
+ case UBCORE_MIG_STATE_START:
+ ret = udma_add_ueid_cmd(dev, fe_idx, cfg, UB_UPI_MIGR);
+ break;
+
+ case UBCORE_MIG_STATE_ROLLBACK:
+ ret = udma_add_ueid_cmd(dev, fe_idx, cfg,
+ UB_UPI_ROLLBACK);
+ break;
+
+ case UBCORE_MIG_STATE_FINISH:
+ ret = udma_add_ueid_cmd(dev, fe_idx, cfg, UB_UPI_NORM);
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_EID,
+ "config function migrate state failed, vfid: %u, cnt: %d, ret %d\n",
+ fe_idx, cfg_cnt, ret);
+ return -1;
+ }
+
+ cfg_cnt++;
+ cfg++;
+ }
+
+ return cfg_cnt;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.h
new file mode 100644
index 000000000..43e4e77e7
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_eid.h
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_EID_H
+#define UDMA_CMD_EID_H
+
+#include <linux/types.h>
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "ub_npu_upi_cmd_defs.h"
+#include "ub_npu_eid_cmd_defs.h"
+
+#define UDMA_SEID_LOOP \
+ 256 // this value need and ub_max_eid_tbl_cnt keep same as, used for traverse SEID
+
+int udma_cmd_seid_query_ctx_from_cache(struct udma_device *udma_dev, u16 vf_id,
+ u32 idx, struct ub_seid_ctx_query *ctx,
+ u32 len);
+int udma_cmd_seid_query_ignore_ub_disable_err(struct udma_device *udma_dev,
+ u16 vf_id, u32 idx,
+ ub_seid_ctx_info_s *ctx, u32 len);
+int udma_cmd_upi_query(struct udma_device *udma_dev,
+ ub_cmd_upi_key_attr_s *upi_idx,
+ ub_cmd_upi_value_attr_s *upi_value);
+int udma_ueid_add_npu_cmdq(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg);
+int delete_ueid_cmd(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg);
+int udma_config_function_migrate_state(struct ubcore_device *dev, u16 fe_idx,
+ u32 cnt, struct ubcore_ueid_cfg *cfg,
+ enum ubcore_mig_state state);
+int udma_cmd_update_upi(struct udma_device *udma_dev, u16 vfid,
+ ub_seid_ctx_info_s *seid_ctx,
+ ub_upi_mig_state_e mig_state);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.c
new file mode 100644
index 000000000..cc38eadbb
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.c
@@ -0,0 +1,194 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/device.h>
+#include "udma_cqm.h"
+#include "udma_cmd_com.h"
+#include "ub_pub_cmd.h"
+#include "ub_npu_event_cmd.h"
+#include "ub_npu_event_cmd_defs.h"
+#include "udma_cmd_event.h"
+
+static void udma_fill_async_event_credit_cmd(
+ u32 credit, struct ub_cmd_async_event_info *async_event_inbuf,
+ enum UB_CMD_ASYNC_EVENT_TYPE type)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_async_event_info);
+
+ udma_fill_cmd_header(&async_event_inbuf->header,
+ UB_CMD_TYPE_ASYNC_EVENT, type, cmd_len, 0);
+ async_event_inbuf->body.credit = credit;
+
+ udma_cpu_to_be32(async_event_inbuf, cmd_len);
+}
+
+int udma_cmd_async_event_credit_init(struct udma_device *udma_dev)
+{
+ struct ub_cmd_async_event_info *async_event_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_async_event_info), NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to alloc inbuf for init_async_event_credit, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ async_event_inbuf =
+ (struct ub_cmd_async_event_info *)cqm_cmd_inbuf->buf;
+ udma_fill_async_event_credit_cmd(UDMA_ASYNC_EVENT_CREDIT_MAX,
+ async_event_inbuf,
+ UB_CMD_ASYNC_EVENT_CREDIT_INIT);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_ASYNC_EVENT_CREDIT_INIT,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to send init_async_event_credit command, ret = %d.\n",
+ ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return 0;
+}
+
+int udma_cmd_async_event_credit_return(struct udma_device *udma_dev,
+ u32 return_credit)
+{
+ struct ub_cmd_async_event_info *async_event_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_async_event_info), NULL, 0);
+ if (ret != 0) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to alloc inbuf for return_async_event_credit, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ async_event_inbuf =
+ (struct ub_cmd_async_event_info *)cqm_cmd_inbuf->buf;
+ udma_fill_async_event_credit_cmd(return_credit, async_event_inbuf,
+ UB_CMD_ASYNC_EVENT_CREDIT_RETURN);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_ASYNC_EVENT_CREDIT_RETURN,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to send return_async_event_credit command, ret = %d.\n",
+ ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return 0;
+}
+
+int udma_cmd_async_event_credit_query(struct udma_device *udma_dev,
+ u32 return_credit)
+{
+ struct ub_cmd_async_event_info *async_event_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_async_event_info), &cqm_cmd_outbuf,
+ (u16)(sizeof(int)));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to alloc inbuf for return_async_event_credit, ret = %d.\n",
+ ret);
+ return -ENOMEM;
+ }
+
+ async_event_inbuf =
+ (struct ub_cmd_async_event_info *)cqm_cmd_inbuf->buf;
+ udma_fill_async_event_credit_cmd(return_credit, async_event_inbuf,
+ UB_CMD_ASYNC_EVENT_CREDIT_QUERY);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_ASYNC_EVENT_CREDIT_QUERY,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "Failed to send return_async_event_credit command, ret = %d.\n",
+ ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return 0;
+}
+
+int udma_cmd_dfx_aeqe_inject(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_async_event_inject_info *aeqe_info_cmd = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_async_event_inject_info);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_async_event_inject_info), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ aeqe_info_cmd =
+ (struct ub_cmd_async_event_inject_info *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&aeqe_info_cmd->header, UB_CMD_TYPE_ASYNC_EVENT,
+ UB_CMD_ASYNC_EVENT_DFX_INJECT, cmd_len, 0);
+
+ aeqe_info_cmd->body.xid = inbuf->xid;
+ aeqe_info_cmd->body.event_type = inbuf->event_type;
+ aeqe_info_cmd->body.queue_type = inbuf->queue_type;
+ aeqe_info_cmd->body.event_sub_type = inbuf->event_sub_type;
+ aeqe_info_cmd->body.vfid = inbuf->vfid;
+
+ udma_cpu_to_be32(aeqe_info_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_ASYNC_EVENT_DFX_INJECT,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Failed to send aeqe inject command, ret = %d.\n",
+ ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ udma_info(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "send aeqe(%u, %u,%u) inject command success\n", inbuf->xid,
+ inbuf->event_type, inbuf->event_sub_type);
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.h
new file mode 100644
index 000000000..e5d5f0746
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_event.h
@@ -0,0 +1,26 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_EVENT_H
+#define UDMA_CMD_EVENT_H
+
+#include "udma_common.h"
+
+/*
+ * The depth of AEQ is 64k, set credit to 63k for the overmeasure.
+ * Because the credit return is faster than aqe consume idx,
+ * it will lead event dropped when aeq is full. So overmeasure set
+ * is needed.
+ */
+#define UDMA_ASYNC_EVENT_CREDIT_MAX 0xFC00
+
+int udma_cmd_async_event_credit_return(struct udma_device *udma_dev,
+ u32 return_credit);
+int udma_cmd_async_event_credit_init(struct udma_device *udma_dev);
+int udma_cmd_async_event_credit_query(struct udma_device *udma_dev,
+ u32 return_credit);
+int udma_cmd_dfx_aeqe_inject(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.c
new file mode 100644
index 000000000..c4bec3a04
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.c
@@ -0,0 +1,1198 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_misc.h"
+#include "udma_srq.h"
+#include "udma_cmd_com.h"
+#include "ub_pub_cmd.h"
+#include "ub_npu_jetty_cmd.h"
+#include "udma_cmd_jetty.h"
+
+#define DATALEN_RATIO 2 // user input of data is 4bit, one byte 8bit / 4 = 2
+#define DATA_SHIFT \
+ 4 // user input of data is 4bit, to convert to byte unit, even index need left shift 4 bit
+#define UB_RNR_TIMER_MASK 0x1f
+#define UB_JETTY_BATCH_MODIFY_MAX_LEN UB_JETTY_CONTEXT_SIZE
+
+void udma_fill_cmd_jetty_chip_attr(struct udma_device *udma_dev,
+ struct ub_chip_attr *chip_attr,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg,
+ u8 pi_on_chip_en, u8 mtt_pro_en)
+{
+ ub_mtt_attr_s *sq_mtt_attr = &chip_attr->sq_mtt_attr;
+ ub_sq_attr_s *sq_attr = &chip_attr->sq_attr;
+ ub_srq_attr_s *srq_attr = &chip_attr->srq_attr;
+ ub_rc_attr_s *rc_attr = &chip_attr->rc_attr;
+ u64 baseblk_cnt = 0;
+
+ sq_mtt_attr->mtt_paddr_h = upper_32_bits(jetty->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_paddr_l = lower_32_bits(jetty->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_layers = jetty->ub_mtt.mtt_layers;
+ sq_mtt_attr->mtt_page_shift = jetty->ub_mtt.mtt_page_shift;
+
+ chip_attr->db_paddr_h = upper_32_bits(jetty->sdb.dma);
+ chip_attr->db_paddr_l = lower_32_bits(jetty->sdb.dma);
+ chip_attr->srq_en = 1;
+
+ if (cfg->jfs_depth != 0) {
+ baseblk_cnt = roundup_pow_of_two(jetty->sq.baseblk_cnt);
+ sq_attr->sq_size = (u32)((u32)UB_ILOG2(baseblk_cnt)) &
+ UB_JETTY_SIZE_MASK;
+ }
+
+ sq_attr->sq_wqebb_size =
+ ((u32)(JETTY_WQE_SHIFT - UB_JETTY_WQEBB_SIZE_SHIFT)) &
+ UB_JETTY_WQEBB_SIZE_MASK;
+ sq_attr->sq_page_size =
+ udma_get_queue_kernel_page_size(mtt_pro_en, jetty->sq_buf_len);
+ if (cfg->send_jfc != NULL)
+ sq_attr->cqn = cfg->send_jfc->id;
+ sq_attr->sq_inline_en = 1;
+ sq_attr->sq_pi_on_chip = pi_on_chip_en;
+
+ srq_attr->container_mode = jetty->ub_jfr->srq.container_mode;
+ srq_attr->srqn = jetty->ub_jfr->srq.srqn;
+ srq_attr->srq_size = (u32)UB_ILOG2(jetty->ub_jfr->srq.max_depth);
+ srq_attr->srq_wqebb_size =
+ jetty->ub_jfr->srq.wqe_shift - SRQ_WQEBB_SIZE_CAL_SECTTOR;
+ srq_attr->srq_page_size = udma_get_queue_kernel_page_size(
+ mtt_pro_en, jetty->ub_jfr->srq.buf_size);
+ if ((cfg->jfr != NULL) && (cfg->jfr->jfr_cfg.jfc != NULL))
+ srq_attr->srq_cqn = cfg->jfr->jfr_cfg.jfc->id;
+ srq_attr->container_en = 1;
+
+ if (jetty->trans_mode == UBCORE_TP_RM ||
+ jetty->trans_mode == UBCORE_TP_RC) {
+ rc_attr->rc_paddr_h =
+ (jetty->ubrc.dma_addr >> UB_RC_HI_PADDR_SHIFT) &
+ UB_RC_HI_PADDR_MASK;
+ rc_attr->rc_paddr_l = (u32)(jetty->ubrc.dma_addr >>
+ UB_RC_LOW_PADDR_SHIFT); // bit[39:8]
+ rc_attr->rc_size = depth_align_power2(
+ udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_depth);
+ rc_attr->ext_order =
+ jetty->ubrc.ext_order - UB_RC_EXT_ORDER_SHIFT;
+ }
+}
+
+void udma_fill_cmd_jetty_sw_attr(struct udma_device *udma_dev,
+ struct ub_jetty_sw_attr *sw_attr,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ ub_jetty_com_attr_s *jetty_com_attr = &sw_attr->jetty_com_attr;
+ ub_jetty_sq_attr_s *jetty_sq_attr = &sw_attr->jetty_sq_attr;
+ ub_jetty_rq_attr_s *jetty_rq_attr = &sw_attr->jetty_rq_attr;
+
+ jetty_com_attr->jetty_state = UBCORE_JETTY_STATE_READY;
+ jetty_com_attr->jetty_type = JETTY;
+ jetty_com_attr->priority = cfg->priority;
+ jetty_com_attr->db_cos = jetty->cos;
+ jetty_com_attr->transport_mode =
+ (cfg->trans_mode == UBCORE_TP_UM) ?
+ UB_TRANSPORT_MODE_UM :
+ ((cfg->trans_mode == UBCORE_TP_RM) ?
+ UB_TRANSPORT_MODE_RM :
+ UB_TRANSPORT_MODE_RSC);
+ jetty_com_attr->jetty_id = jetty->jetty_id;
+ jetty_com_attr->eid_index = cfg->eid_index;
+ jetty_com_attr->slice_size_shift = udma_dev->slice;
+ jetty_com_attr->slice_en = udma_get_jetty_slice_en(udma_dev);
+ if (jetty_com_attr->transport_mode == UB_TRANSPORT_MODE_RSC)
+ jetty_com_attr->hash =
+ (u32)atomic_inc_return(&udma_dev->rs_hash);
+ else
+ jetty_com_attr->hash =
+ (u32)atomic_inc_return(&udma_dev->jfs_hash);
+
+ if (cfg->send_jfc != NULL)
+ jetty_sq_attr->tx_jfcn = cfg->send_jfc->id;
+ else
+ udma_warn(udma_dev->dev, UDMA_M_JETTY,
+ "cfg->send_jfc is null, tx_jfcn default 0.\n");
+ jetty_sq_attr->ta_timeout = cfg->err_timeout;
+ jetty_sq_attr->rnr_max_retry_num = cfg->rnr_retry;
+ jetty_sq_attr->err_mode = UB_ERROR_SUSPEND;
+
+ if ((cfg->jfr != NULL) && (cfg->jfr->jfr_cfg.jfc != NULL)) {
+ jetty_rq_attr->rx_jfcn = cfg->jfr->jfr_cfg.jfc->id;
+ jetty_rq_attr->jfc_inline =
+ udma_get_jfc_inline(udma_dev, cfg->jfr->jfr_cfg.jfc);
+ } else {
+ udma_warn(udma_dev->dev, UDMA_M_JETTY,
+ "recv_jfc is null, rx_jfcn default 0.\n");
+ }
+
+ jetty_rq_attr->rnr_timer =
+ jetty->ub_jfr->ubcore_jfr.jfr_cfg.min_rnr_timer &
+ UB_RNR_TIMER_MASK;
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY, "jetty rnr_timer:%u.\n",
+ jetty_rq_attr->rnr_timer);
+
+ jetty_rq_attr->jfrn = jetty->ub_jfr->jfr_id;
+ jetty_rq_attr->jfr_round = jetty->ub_jfr->round;
+ jetty_rq_attr->token_value =
+ jetty->ub_jfr->ubcore_jfr.jfr_cfg.token_value.token;
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "slice = %u, err_mode: %u, hash: %u\n", udma_dev->slice,
+ jetty_sq_attr->err_mode, jetty_com_attr->hash);
+}
+
+void udma_fill_cmd_jetty_create_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg,
+ struct ub_cmd_jetty_create *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+ u8 sq_pi_on_chip = 0;
+
+ if (udma_dev->ub_cap.dev_cap.feature.bs.pi_on_chip_en != 0)
+ sq_pi_on_chip =
+ (u8)(jetty->jetty_id <
+ udma_dev->ub_cap.dev_cap.max_pi_on_chip_num);
+
+ udma_fill_cmd_jetty_chip_attr(udma_dev, &cmd_buf->body.chip_attr, jetty,
+ cfg, sq_pi_on_chip,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ udma_fill_cmd_jetty_sw_attr(udma_dev, &cmd_buf->body.sw_attr, jetty,
+ cfg);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CREATE_CTX, cmd_len, jetty->jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_create_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_create *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_create), &cqm_cmd_outbuf,
+ sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_create_ctx(udma_dev, jetty, cfg, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_CREATE_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ &jetty->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ jetty->round = (u32)ntohl(*(u32 *)cqm_cmd_outbuf->buf);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "cmdq create jetty(%u) success and get round(0x%08x)\n",
+ jetty->jetty_id, jetty->round);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_modify_ctx(struct udma_jetty *jetty,
+ enum ubcore_jetty_state state,
+ struct ub_cmd_jetty_modify *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.jetty_type = JETTY;
+ cmd_buf->body.mask.state = UDMA_MASK_VALID;
+ cmd_buf->body.old_state = jetty->state;
+ cmd_buf->body.new_state = state;
+ cmd_buf->body.sq_pi = jetty->sq.pi;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_MODIFY_CTX, cmd_len, jetty->jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_modify_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ enum ubcore_jetty_state state,
+ struct ubcore_udata *udata)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_modify *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_modify_ctx(jetty, state, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, &jetty->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_modify_dfx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct udma_jetty_modify_dfx *jetty_dfx,
+ struct ub_cmd_jetty_modify *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.jetty_type = JETTY;
+ cmd_buf->body.mask.next_send_tassn_flg =
+ jetty_dfx->mask.next_send_tassn;
+ cmd_buf->body.next_send_tassn = jetty_dfx->attr.next_send_tassn;
+ cmd_buf->body.mask.next_ack_tassn_flg = jetty_dfx->mask.next_ack_tassn;
+ cmd_buf->body.next_ack_tassn = jetty_dfx->attr.next_ack_tassn;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "%s: next_send_tassn: mask(0x%x), value(0x%x)\n", __func__,
+ jetty_dfx->mask.next_send_tassn,
+ jetty_dfx->attr.next_send_tassn);
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "%s: next_ack_tassn: mask(0x%x), value(0x%x)\n", __func__,
+ jetty_dfx->mask.next_ack_tassn,
+ jetty_dfx->attr.next_ack_tassn);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_MODIFY_CTX, cmd_len, jetty->jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_modify_dfx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct udma_jetty_modify_dfx *jetty_dfx)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_modify *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_modify_dfx(udma_dev, jetty, jetty_dfx, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, &jetty->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_delete_ctx(u32 jetty_id,
+ struct ub_cmd_jetty_delete *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_DELETE_CTX, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_delete_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_delete *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_delete), &cqm_cmd_outbuf,
+ sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_delete_ctx(jetty->jetty_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_DELETE_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ &jetty->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ else
+ ret = udma_cmd_check_dpath_dma(udma_dev,
+ (u8 *)cqm_cmd_outbuf->buf,
+ sizeof(u8), sizeof(u8));
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_fill_cmd_body(struct udma_device *udma_dev,
+ struct ub_cmd_jetty_cache_invld *cmd_buf, u32 buf_len,
+ u64 wb_dma)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_COM,
+ "Failed to get hmm comp priv.\n");
+ return -EINVAL;
+ }
+
+ cmd_buf->body.sq_buf_len = ALIGN(buf_len, PAGE_SIZE);
+ cmd_buf->body.rq_buf_len = ALIGN(buf_len, PAGE_SIZE);
+ cmd_buf->body.syn_gpa_hi32 = upper_32_bits(wb_dma);
+ cmd_buf->body.syn_gpa_lo32 = lower_32_bits(wb_dma);
+ cmd_buf->body.mtt_cache_line_start = comp_priv->ub_cap.cmtt_cl_start;
+ cmd_buf->body.mtt_cache_line_end = comp_priv->ub_cap.cmtt_cl_end;
+ cmd_buf->body.mtt_cache_line_size = comp_priv->ub_cap.cmtt_cl_sz;
+ cmd_buf->body.mtt_flags = 0;
+ cmd_buf->body.mtt_num = 0;
+ cmd_buf->body.wqe_cache_line_start = comp_priv->ub_cap.wqe_cl_start;
+ cmd_buf->body.wqe_cache_line_end = comp_priv->ub_cap.wqe_cl_end;
+ cmd_buf->body.wqe_cache_line_size = comp_priv->ub_cap.wqe_cl_sz;
+ cmd_buf->body.wqe_flags = 0;
+ cmd_buf->body.wqe_num = 0;
+
+ return 0;
+}
+
+static int
+udma_fill_cmd_jetty_cache_invld_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u64 wb_dma,
+ struct ub_cmd_jetty_cache_invld *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+ int ret;
+
+ ret = udma_fill_cmd_body(udma_dev, cmd_buf, jetty->sq_buf_len, wb_dma);
+ if (ret != 0) {
+ return ret;
+ }
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CACHE_INVLD_CTX, cmd_len,
+ jetty->jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ return 0;
+}
+
+int udma_send_cache_invld_ctx(struct udma_device *udma_dev,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf, u32 *times,
+ u8 cmd_subtype, struct cmdq_rtt *cmdq_rtt)
+{
+ u64 jiffies_now;
+ int ret = 0;
+ u64 end;
+
+ jiffies_now = get_jiffies_64();
+ end = jiffies_now + (UB_DESTROY_FLOW_TIMEOUT * HZ);
+ while (time_before64(jiffies_now, end)) {
+ (*times)++;
+ ret = udma_send_cmd_box(udma_dev, cmd_subtype, cqm_cmd_inbuf,
+ NULL, NULL, cmdq_rtt);
+ if (ret <= 0)
+ break;
+
+ cond_resched();
+ jiffies_now = get_jiffies_64();
+ }
+
+ return ret;
+}
+
+int udma_cmd_jetty_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u64 wb_dma)
+{
+ struct ub_cmd_jetty_cache_invld *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u32 times = 0;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_cache_invld), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_cache_invld *)cqm_cmd_inbuf->buf;
+ ret = udma_fill_cmd_jetty_cache_invld_ctx(udma_dev, jetty, wb_dma,
+ cmd_buf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed fill jetty cacheout inbuf, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return ret;
+ }
+
+ ret = udma_send_cache_invld_ctx(udma_dev, cqm_cmd_inbuf, ×,
+ UB_CMD_JETTY_CACHE_INVLD_CTX,
+ &jetty->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box after try times(%u), jetty(%u), ret(%d)\n",
+ times, jetty->jetty_id, ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_query_ctx(u32 jetty_id,
+ struct ub_cmd_jetty_query *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_QUERY_CTX, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_query_ctx(struct udma_device *udma_dev, u32 jetty_id,
+ struct cmdq_rtt *rtt,
+ struct ub_ta_context_query *outbuf)
+{
+ struct ub_cmd_jetty_query *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_query), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_ta_context_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret=%d", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_query_ctx(jetty_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cmd QUERY_JETTY, ret=%d", ret);
+ ret = -EIO;
+ goto out;
+ }
+
+ (void)memcpy_s(outbuf, sizeof(struct ub_ta_context_query),
+ cqm_cmd_outbuf->buf, sizeof(struct ub_ta_context_query));
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_query_rdma_rc(u32 jetty_id, u32 entry_index,
+ struct ub_cmd_jetty_query_rdma_rc *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.entry_index = entry_index;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_QUERY_RDMA_RC, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_query_rdma_rc(struct udma_device *udma_dev, u32 jetty_id,
+ u32 entry_index,
+ struct ub_ta_rdma_rc_outbuf *outbuf)
+{
+ struct ub_cmd_jetty_query_rdma_rc *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+ u32 entry_size = udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_entry_size;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_query_rdma_rc), &cqm_cmd_outbuf,
+ sizeof(struct ub_ta_rdma_rc_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_query_rdma_rc *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_query_rdma_rc(jetty_id, entry_index, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_QUERY_RDMA_RC,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to send cqm cmd, jetty_id:%u, ret = %d.\n",
+ jetty_id, ret);
+ goto err_send_cmd;
+ }
+
+ (void)memcpy_s((void *)outbuf->rdmarc, entry_size,
+ (void *)cqm_cmd_outbuf->buf, entry_size);
+ outbuf->rc_table_size = entry_size;
+
+err_send_cmd:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_query_ta_msn_entry(u32 xid, u32 entry_index, u8 msn_type,
+ struct ub_cmd_jetty_query_tamsn *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.index = entry_index;
+ cmd_buf->body.type = msn_type;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_QUERY_TAMSN_ENTRY, cmd_len, xid);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_query_ta_msn_entry(struct udma_device *udma_dev, u32 xid,
+ u32 entry_index, u8 msn_type,
+ struct ub_msn_entry_outbuf *outbuf)
+{
+ struct ub_cmd_jetty_query_tamsn *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_query_tamsn), &cqm_cmd_outbuf,
+ sizeof(struct ub_msn_entry_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_query_tamsn *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_query_ta_msn_entry(xid, entry_index, msn_type,
+ cmd_buf);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_QUERY_TAMSN_ENTRY,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to send cqm cmd, xid:%u, ret = %d.\n", xid,
+ ret);
+ goto err_send_cmd;
+ }
+
+ (void)memcpy_s((void *)outbuf->msn_entry, UB_MSN_ENTRY_SIZE,
+ (void *)cqm_cmd_outbuf->buf, UB_MSN_ENTRY_SIZE);
+ outbuf->msn_entry_size = UB_MSN_ENTRY_SIZE;
+
+err_send_cmd:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_clear_dfx_lock_ctx(
+ u32 jetty_id, struct ub_cmd_jetty_clear_dfx_lock *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CLEAR_DFX_LOCK_CTX, cmd_len,
+ jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_clear_dfx_lock_ctx(struct udma_device *udma_dev,
+ u32 jetty_id)
+{
+ struct ub_cmd_jetty_clear_dfx_lock *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_clear_dfx_lock), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_clear_dfx_lock *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_clear_dfx_lock_ctx(jetty_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_CLEAR_DFX_LOCK_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "failed to send jetty clear dfx lock ctx command, ret = %d.\n",
+ ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_batch_modify_ctx(u32 jetty_id, u32 offset, u32 len,
+ const u8 *data,
+ struct ub_cmd_jetty_batch_modify *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+ u32 i;
+
+ cmd_buf->body.offset = offset;
+ cmd_buf->body.length = len;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_BATCH_MODIFY, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ for (i = 0; i < len; ++i)
+ cmd_buf->body.ctx[i + offset] =
+ (data[i * DATALEN_RATIO] << DATA_SHIFT) +
+ data[i * DATALEN_RATIO + 1];
+}
+
+int udma_cmd_jetty_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ struct ub_cmd_jetty_batch_modify *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (inbuf->length > UB_JETTY_BATCH_MODIFY_MAX_LEN ||
+ inbuf->offset > UB_JETTY_BATCH_MODIFY_MAX_LEN - inbuf->length) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "offset(%u) + length(%u) exceed max len(%u)\n",
+ inbuf->offset, inbuf->length,
+ UB_JETTY_BATCH_MODIFY_MAX_LEN);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_batch_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to alloc buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_batch_modify_ctx(
+ inbuf->xid, inbuf->offset, inbuf->length, inbuf->data, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_BATCH_MODIFY,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_warn(udma_dev->dev, UDMA_M_JETTY,
+ "can't send jetty batch modify command, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_grp_create_ctx(enum ubcore_jetty_grp_policy policy,
+ struct udma_jetty_grp *jetty_grp,
+ struct ub_cmd_jetty_grp_create *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.policy = policy;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_GRP_CREATE_CTX, cmd_len,
+ jetty_grp->jetty_grp_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_grp_create_ctx(struct udma_device *udma_dev,
+ struct udma_jetty_grp *jetty_grp,
+ struct ubcore_jetty_grp_cfg *cfg)
+{
+ struct ub_cmd_jetty_grp_create *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_grp_create), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to alloc buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_grp_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_grp_create_ctx(cfg->policy, jetty_grp, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_GRP_CREATE_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to send jetty grp create command, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_grp_update_ctx(enum UB_JETTY_GRP_UPDATE_TYPE_E type,
+ u32 jetty_id, u32 jetty_grp_id,
+ struct ub_cmd_jetty_grp_update *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.update_type = type;
+ cmd_buf->body.jetty_id = jetty_id;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_GRP_UPDATE_CTX, cmd_len,
+ jetty_grp_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_grp_update_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u32 jetty_grp_id,
+ enum UB_JETTY_GRP_UPDATE_TYPE_E type)
+{
+ struct ub_cmd_jetty_grp_update *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_grp_update), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate mtt, ret:%d\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_grp_update *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_grp_update_ctx(type, jetty->jetty_id, jetty_grp_id,
+ cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_GRP_UPDATE_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_grp_delete_ctx(u32 jetty_grp_id,
+ struct ub_cmd_jetty_grp_delete *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_GRP_DELETE_CTX, cmd_len,
+ jetty_grp_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_grp_delete_ctx(struct udma_device *udma_dev,
+ struct udma_jetty_grp *jetty_grp)
+{
+ struct ub_cmd_jetty_grp_delete *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_grp_delete), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to alloc buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_grp_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_grp_delete_ctx(jetty_grp->jetty_grp_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_GRP_DELETE_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to send jetty grp delete command, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static void
+udma_fill_cmd_jetty_grp_query_ctx(u32 jetty_group_id,
+ struct ub_cmd_jetty_grp_query *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_GRP_QUERY_CTX, cmd_len,
+ jetty_group_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_grp_query_ctx(struct udma_device *udma_dev,
+ u32 jetty_group_id,
+ struct ub_jetty_grp_ctx_query *outbuf)
+{
+ struct ub_cmd_jetty_grp_query *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_grp_query), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_jetty_grp_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to alloc cqm_cmd_inoutbuf, ret=%d", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_grp_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_grp_query_ctx(jetty_group_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_GRP_QUERY_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Failed to send cmd QUERY_JETTY_GROUP_CONTEXT, ret = %d.\n",
+ ret);
+ ret = -EIO;
+ goto out;
+ }
+
+ (void)memcpy_s(outbuf, sizeof(struct ub_jetty_grp_ctx_query),
+ cqm_cmd_outbuf->buf,
+ sizeof(struct ub_jetty_grp_ctx_query));
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_query_rdma_rc_ext(
+ u32 jetty_id, u32 idx, struct ub_cmd_jetty_query_rdma_rc *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.idx = idx;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_QUERY_RDMA_RC_EXT, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_query_rdma_rc_ext(struct udma_device *udma_dev, u32 jetty_id,
+ u32 idx,
+ struct ub_ta_rdma_rc_ext_outbuf *outbuf)
+{
+ struct ub_cmd_jetty_query_rdma_rc *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u32 rc_ext_table_size;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_query_rdma_rc), &cqm_cmd_outbuf,
+ sizeof(struct ub_ta_rdma_rc_ext_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_query_rdma_rc *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_query_rdma_rc_ext(jetty_id, idx, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_QUERY_RDMA_RC_EXT,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "failed to send cqm cmd, jetty_id:%u, idx:%u, ret = %d.\n",
+ jetty_id, idx, ret);
+ goto err_send_cmd;
+ }
+
+ rc_ext_table_size = udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100 ?
+ UB_TA_RDMARC_EXT_TABLE_SIZE_HI1825 :
+ UB_TA_RDMARC_EXT_TABLE_SIZE_HI1823;
+ (void)memcpy_s((void *)outbuf->rdmarc_ext, rc_ext_table_size,
+ (void *)cqm_cmd_outbuf->buf, rc_ext_table_size);
+ outbuf->rc_ext_table_size = rc_ext_table_size;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "query ta rdma rc ext success, jetty_id:%u, idx:%u\n",
+ jetty_id, idx);
+
+err_send_cmd:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_jetty_query_driver_ctr(struct udma_device *udma_dev, u32 jetty_id,
+ ub_driver_comm_ctr_t *outbuf)
+{
+ struct udma_jetty *ub_jetty = NULL;
+ struct mutex *lock = &udma_dev->device_res->jetty_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(ub_jetty, &udma_dev->device_res->jetty_list.node,
+ node) {
+ if (ub_jetty->jetty_id == jetty_id) {
+ mutex_unlock(lock);
+ outbuf->post_send_wr_num = (u64)atomic64_read(
+ &ub_jetty->sq.udma_driver_sq_ctr
+ .post_send_wr_num);
+ outbuf->post_recv_wr_num = (u64)atomic64_read(
+ &ub_jetty->ub_jfr->srq.udma_driver_rq_ctr
+ .post_recv_wr_num);
+ return 0;
+ }
+ }
+ mutex_unlock(lock);
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "query driver ctr fail, jetty_id:%u\n", jetty_id);
+ return -EINVAL;
+}
+
+static void udma_fill_cmd_jetty_bind_ctx(u32 jetty_id, u32 tjetty_id,
+ struct ub_cmd_jetty_bind *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.peer_jetty_id = tjetty_id;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_BIND_CTX, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_bind_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u32 tjetty_id)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_bind *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_bind), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_bind *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_bind_ctx(jetty->ubcore_jetty.jetty_id.id, tjetty_id,
+ cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_BIND_CTX, cqm_cmd_inbuf,
+ NULL, NULL, &jetty->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ ret = -EFAULT;
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_unbind_ctx(u32 jetty_id,
+ struct ub_cmd_jetty_unbind *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_UNBIND_CTX, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_unbind_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_unbind *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_unbind), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_unbind *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_unbind_ctx(jetty->ubcore_jetty.jetty_id.id,
+ cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_UNBIND_CTX,
+ cqm_cmd_inbuf, NULL, NULL, &jetty->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ ret = -EFAULT;
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jetty_query_ta_oor_info(
+ u32 jetty_id, u32 idx, struct ub_cmd_jetty_query_rdma_rc *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+
+ cmd_buf->body.idx = idx;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_QUERY_TA_OOR_INFO, cmd_len, jetty_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jetty_query_ta_oor_info(struct udma_device *udma_dev, u32 jetty_id,
+ u32 idx, struct ub_oor_ta_info *outbuf)
+{
+ struct ub_cmd_jetty_query_rdma_rc *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_query_rdma_rc), &cqm_cmd_outbuf,
+ sizeof(struct ub_oor_ta_info));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_query_rdma_rc *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jetty_query_ta_oor_info(jetty_id, idx, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_QUERY_TA_OOR_INFO,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "failed to send cqm cmd, jetty_id:%u, idx:%u, ret = %d.\n",
+ jetty_id, idx, ret);
+ goto err_send_cmd;
+ }
+
+ (void)memcpy_s((void *)outbuf, sizeof(struct ub_oor_ta_info),
+ (void *)cqm_cmd_outbuf->buf,
+ sizeof(struct ub_oor_ta_info));
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "query ta oor info success, jetty_id:%u, idx:%u\n", jetty_id,
+ idx);
+
+err_send_cmd:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.h
new file mode 100644
index 000000000..517fecd0b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jetty.h
@@ -0,0 +1,69 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_JETTY_H
+#define UDMA_CMD_JETTY_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_jetty.h"
+#include "ub_pub_cmd.h"
+
+int udma_cmd_jetty_create_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg);
+int udma_cmd_jetty_modify_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ enum ubcore_jetty_state state,
+ struct ubcore_udata *udata);
+int udma_cmd_jetty_delete_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty);
+int udma_cmd_jetty_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u64 wb_dma);
+int udma_cmd_jetty_bind_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u32 tjetty_id);
+int udma_cmd_jetty_unbind_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty);
+int udma_cmd_jetty_query_ctx(struct udma_device *udma_dev, u32 jetty_id,
+ struct cmdq_rtt *rtt,
+ struct ub_ta_context_query *outbuf);
+int udma_cmd_jetty_query_rdma_rc(struct udma_device *udma_dev, u32 jetty_id,
+ u32 entry_index,
+ struct ub_ta_rdma_rc_outbuf *outbuf);
+int udma_cmd_jetty_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+int udma_cmd_jetty_clear_dfx_lock_ctx(struct udma_device *udma_dev,
+ u32 jetty_id);
+int udma_cmd_jetty_query_ta_oor_info(struct udma_device *udma_dev, u32 jetty_id,
+ u32 idx, struct ub_oor_ta_info *outbuf);
+
+int udma_cmd_jetty_grp_create_ctx(struct udma_device *udma_dev,
+ struct udma_jetty_grp *jetty_grp,
+ struct ubcore_jetty_grp_cfg *cfg);
+int udma_cmd_jetty_grp_update_ctx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u32 jetty_grp_id,
+ enum UB_JETTY_GRP_UPDATE_TYPE_E type);
+int udma_cmd_jetty_grp_delete_ctx(struct udma_device *udma_dev,
+ struct udma_jetty_grp *jetty_grp);
+int udma_cmd_jetty_grp_query_ctx(struct udma_device *udma_dev,
+ u32 jetty_group_id,
+ struct ub_jetty_grp_ctx_query *outbuf);
+int udma_cmd_jetty_query_rdma_rc_ext(struct udma_device *udma_dev, u32 jetty_id,
+ u32 idx,
+ struct ub_ta_rdma_rc_ext_outbuf *outbuf);
+int udma_send_cache_invld_ctx(struct udma_device *udma_dev,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf, u32 *times,
+ u8 cmd_subtype, struct cmdq_rtt *cmdq_rtt);
+int udma_fill_cmd_body(struct udma_device *udma_dev,
+ struct ub_cmd_jetty_cache_invld *cmd_buf, u32 buf_len,
+ u64 wb_dma);
+int udma_cmd_jetty_query_driver_ctr(struct udma_device *udma_dev, u32 jetty_id,
+ ub_driver_comm_ctr_t *outbuf);
+int udma_cmd_jetty_query_ta_msn_entry(struct udma_device *udma_dev, u32 xid,
+ u32 entry_index, u8 msn_type,
+ struct ub_msn_entry_outbuf *outbuf);
+int udma_cmd_jetty_modify_dfx(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct udma_jetty_modify_dfx *jetty_dfx);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.c
new file mode 100644
index 000000000..0cfc27af9
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.c
@@ -0,0 +1,334 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_jetty.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jfc.h"
+
+#define DATALEN_RATIO 2 //user input of data is 4bit, one byte 8bit / 4 = 2
+#define DATA_SHIFT \
+ 4 //user input of data is 4bit, to convert to byte unit, even index need left shift 4 bit
+
+static u16 get_cmdq_len[] = {
+ [UB_CMD_JFC_CREATE_CTX] = (u16)sizeof(struct ub_cmd_jfc_create),
+ [UB_CMD_JFC_MODIFY_CTX] = (u16)sizeof(struct ub_cmd_jfc_modify),
+ [UB_CMD_JFC_DELETE_CTX] = (u16)sizeof(struct ub_cmd_jfc_delete),
+ [UB_CMD_JFC_CACHE_INVLD_CTX] = (u16)sizeof(struct ub_cmd_jfc_invld),
+
+ [UB_CMD_JFC_MAX] = 0,
+};
+
+static void udma_fill_cmd_jfc_chip_attr(struct ub_jfc_chip_attr *chip_attr,
+ struct udma_jfc *jfc, u8 mtt_pro_en)
+{
+ ub_mtt_attr_s *cq_mtt_attr = &chip_attr->cq_mtt_attr;
+
+ cq_mtt_attr->mtt_paddr_h = upper_32_bits(jfc->ub_mtt.mtt_paddr);
+ cq_mtt_attr->mtt_paddr_l = lower_32_bits(jfc->ub_mtt.mtt_paddr);
+ cq_mtt_attr->mtt_layers = jfc->ub_mtt.mtt_layers;
+ cq_mtt_attr->mtt_page_shift = jfc->ub_mtt.mtt_page_shift;
+
+ chip_attr->db_paddr_h = upper_32_bits(jfc->db.dma);
+ chip_attr->db_paddr_l = lower_32_bits(jfc->db.dma);
+
+ chip_attr->cq_size = (u32)ilog2(jfc->base.jfc_cfg.depth);
+ chip_attr->cqe_size = UB_JFC_CQE_SIZE;
+ chip_attr->cq_page_size =
+ udma_get_queue_kernel_page_size(mtt_pro_en, jfc->cq_buf_size);
+
+ chip_attr->ceqn = jfc->base.jfc_cfg.ceqn;
+
+ chip_attr->cnt_adjust_en = 1;
+ chip_attr->cnt_clear_en = 1;
+ chip_attr->ceqe_en = 1;
+}
+
+static void udma_fill_cmd_jfc_sw_attr(struct ub_jfc_sw_attr *sw_attr,
+ struct udma_jfc *jfc)
+{
+ sw_attr->jfc_inline_en = jfc->base.jfc_cfg.flag.bs.jfc_inline;
+}
+
+static void udma_fill_cmd_jfc_create_ctx(struct udma_jfc *jfc,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf,
+ u8 mtt_pro_en)
+{
+ struct ub_cmd_jfc_create *cmd_buf =
+ (struct ub_cmd_jfc_create *)cqm_cmd_inbuf->buf;
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_create);
+
+ udma_fill_cmd_jfc_chip_attr(&cmd_buf->body.chip_attr, jfc, mtt_pro_en);
+
+ udma_fill_cmd_jfc_sw_attr(&cmd_buf->body.sw_attr, jfc);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_CREATE_CTX, cmd_len, jfc->base.id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_jfc_modify_ctx(u32 jfc_id,
+ const struct ubcore_jfc_attr *attr,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ struct ub_cmd_jfc_modify *cmd_buf =
+ (struct ub_cmd_jfc_modify *)cqm_cmd_inbuf->buf;
+ struct ub_cmd_body_jfc_modify *body = &cmd_buf->body;
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_modify);
+
+ body->mask = attr->mask;
+ body->max_cnt = attr->moderate_count;
+ body->timeout = attr->moderate_period;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_MODIFY_CTX, cmd_len, jfc_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_jfc_delete_ctx(u32 jfc_id,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ struct ub_cmd_jfc_delete *cmd_buf =
+ (struct ub_cmd_jfc_delete *)cqm_cmd_inbuf->buf;
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_delete);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_DELETE_CTX, cmd_len, jfc_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_jfc_invld_ctx(u32 jfc_id,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ struct ub_cmd_jfc_invld *cmd_buf =
+ (struct ub_cmd_jfc_invld *)cqm_cmd_inbuf->buf;
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_invld);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_CACHE_INVLD_CTX, cmd_len, jfc_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_jfc_query_ctx(u32 jfc_id,
+ struct ub_cmd_jfc_query *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_query);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_QUERY_CTX, cmd_len, jfc_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfc_ctx(struct udma_device *udma_dev, struct udma_jfc *jfc,
+ const struct ubcore_jfc_attr *attr,
+ enum UB_CMD_JFC_TYPE type)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ ub_cmdq_cqe_udata_s cmdq_cqe = { 0 };
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ get_cmdq_len[type], &cqm_cmd_outbuf,
+ sizeof(u32) * UDMA_DPATH_MAX_OQ_NUM);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ goto err_cqm_alloc;
+ }
+
+ switch (type) {
+ case UB_CMD_JFC_CREATE_CTX:
+ udma_fill_cmd_jfc_create_ctx(
+ jfc, cqm_cmd_inbuf,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+ break;
+
+ case UB_CMD_JFC_MODIFY_CTX:
+ udma_fill_cmd_jfc_modify_ctx(jfc->base.id, attr, cqm_cmd_inbuf);
+ break;
+
+ case UB_CMD_JFC_DELETE_CTX:
+ udma_fill_cmd_jfc_delete_ctx(jfc->base.id, cqm_cmd_inbuf);
+ break;
+
+ case UB_CMD_JFC_CACHE_INVLD_CTX:
+ udma_fill_cmd_jfc_invld_ctx(jfc->base.id, cqm_cmd_inbuf);
+ break;
+
+ default:
+ ret = -EINVAL;
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "invalid jfc cmd type(%u)\n", type);
+ goto err_cqm_send;
+ }
+
+ ret = udma_send_cmd_box(udma_dev, type, cqm_cmd_inbuf, cqm_cmd_outbuf,
+ &cmdq_cqe, &jfc->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ ret = -EIO;
+ goto err_cqm_send;
+ }
+
+ /* 删 JFC when need according to actual return of oq num flush data generalpath */
+ if (type == UB_CMD_JFC_DELETE_CTX &&
+ udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ ret = udma_dpath_drain_handle(udma_dev,
+ (u8 *)cqm_cmd_outbuf->buf,
+ cmdq_cqe.bs.dpath_oq_num);
+ }
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFC,
+ "sub_type(%u), cmdq_cqe.bs.dpath_oq_num(%u), cmdq_cqe.value(0x%llx), ret:%d\n",
+ type, cmdq_cqe.bs.dpath_oq_num, cmdq_cqe.value, ret);
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+err_cqm_alloc:
+ return ret;
+}
+
+int udma_cmd_jfc_query_ctx(struct udma_device *udma_dev, u32 jfc_id,
+ struct ub_jfc_ctx_query *jfc_ctx)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jfc_query *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jfc_query), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_jfc_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ goto err_cqm_alloc;
+ }
+
+ cmd_buf = (struct ub_cmd_jfc_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfc_query_ctx(jfc_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFC_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ (void)memcpy_s(jfc_ctx, sizeof(struct ub_jfc_ctx_query),
+ cqm_cmd_outbuf->buf, sizeof(struct ub_jfc_ctx_query));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+err_cqm_alloc:
+ return ret;
+}
+
+static void
+udma_fill_cmd_jfc_batch_modify_ctx(struct ub_cmd_jfc_batch_modify *modify_cmd,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jfc_batch_modify);
+ u32 i;
+
+ modify_cmd->body.offset = cpu_to_be32(inbuf->offset);
+ modify_cmd->body.length = cpu_to_be32(inbuf->length);
+ /* user input copy to context corresponding position, Note: user input a character occupy 4bit, and user inputs in big-endian format, no need to convert again */
+ for (i = inbuf->offset; i < inbuf->offset + inbuf->length &&
+ i < UB_CQM_MODIFY_DATA_LEN_JFC / DATALEN_RATIO;
+ ++i) {
+ *(((u8 *)&modify_cmd->body.ctx) + i) =
+ (inbuf->data[(i - inbuf->offset) * DATALEN_RATIO]
+ << DATA_SHIFT) +
+ inbuf->data[(i - inbuf->offset) * DATALEN_RATIO + 1];
+ }
+
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_JFC,
+ UB_CMD_JFC_BATCH_MODIFY_CTX, cmd_len, inbuf->xid);
+ /* here only convert header endian */
+ udma_cpu_to_be32(modify_cmd, sizeof(ub_cmd_com_header_s));
+}
+
+int udma_cmd_jfc_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ struct ub_cmd_jfc_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jfc_batch_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "cqm inbuf allocation failed\n");
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct ub_cmd_jfc_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfc_batch_modify_ctx(modify_cmd, inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFC_BATCH_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "send cmd failed, ret(%d)\n", ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "send cmd success, jfc_id(%u)\n", inbuf->xid);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfc_query_driver_ctr(struct udma_device *udma_dev, u32 jfc_id,
+ ub_driver_comm_ctr_t *outbuf)
+{
+ struct udma_jfc *ub_jfc = NULL;
+ struct mutex *lock = &udma_dev->device_res->jfc_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(ub_jfc, &udma_dev->device_res->jfc_list.node,
+ node) {
+ if (ub_jfc->base.id == jfc_id) {
+ udma_jfc_get(ub_jfc);
+ mutex_unlock(lock);
+ outbuf->poll_total_num = (u64)atomic64_read(
+ &ub_jfc->udma_driver_jfc_ctr.poll_total_num);
+ outbuf->poll_sq_num = (u64)atomic64_read(
+ &ub_jfc->udma_driver_jfc_ctr.poll_sq_num);
+ outbuf->poll_rq_num = (u64)atomic64_read(
+ &ub_jfc->udma_driver_jfc_ctr.poll_rq_num);
+ udma_jfc_put(ub_jfc);
+ return 0;
+ }
+ }
+ mutex_unlock(lock);
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "query driver ctr fail, jfc_id:%u\n", jfc_id);
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.h
new file mode 100644
index 000000000..b45bcb046
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfc.h
@@ -0,0 +1,23 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_JFC_H
+#define UDMA_CMD_JFC_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_jfc.h"
+#include "ub_pub_cmd.h"
+#include "ub_npu_jfc_cmd.h"
+
+int udma_cmd_jfc_ctx(struct udma_device *udma_dev, struct udma_jfc *jfc,
+ const struct ubcore_jfc_attr *attr,
+ enum UB_CMD_JFC_TYPE type);
+int udma_cmd_jfc_query_ctx(struct udma_device *udma_dev, u32 jfc_id,
+ struct ub_jfc_ctx_query *jfc_ctx);
+int udma_cmd_jfc_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+int udma_cmd_jfc_query_driver_ctr(struct udma_device *udma_dev, u32 jfc_id,
+ ub_driver_comm_ctr_t *outbuf);
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.c
new file mode 100644
index 000000000..de492b427
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.c
@@ -0,0 +1,422 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_misc.h"
+#include "udma_srq.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jetty.h"
+#include "ub_npu_jfr_cmd.h"
+#include "udma_cmd_jfr.h"
+
+static inline u32 to_jetty_misc_state(enum ubcore_jfr_state state)
+{
+ switch (state) {
+ case UBCORE_JFR_STATE_RESET:
+ return UB_JETTY_STATE_RESET;
+ case UBCORE_JFR_STATE_READY:
+ return UB_JETTY_STATE_READY;
+ case UBCORE_JFR_STATE_ERROR:
+ return UB_JETTY_STATE_ERROR;
+ default:
+ return UB_JETTY_STATE_RESERVED;
+ }
+}
+
+static void udma_fill_cmd_jfr_chip_attr(struct udma_device *udma_dev,
+ struct ub_chip_attr *chip_attr,
+ struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg)
+{
+ ub_mtt_attr_s *sq_mtt_attr = &chip_attr->sq_mtt_attr;
+ ub_srq_attr_s *srq_attr = &chip_attr->srq_attr;
+
+ sq_mtt_attr->mtt_paddr_h = upper_32_bits(jfr->srq.ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_paddr_l = lower_32_bits(jfr->srq.ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_layers = jfr->srq.ub_mtt.mtt_layers;
+ sq_mtt_attr->mtt_page_shift = jfr->srq.ub_mtt.mtt_page_shift;
+
+ chip_attr->db_paddr_h = upper_32_bits(jfr->sdb.dma);
+ chip_attr->db_paddr_l = lower_32_bits(jfr->sdb.dma);
+ chip_attr->srq_en = 1;
+
+ srq_attr->container_mode = jfr->srq.container_mode;
+ srq_attr->srqn = jfr->srq.srqn;
+ srq_attr->srq_size = (u32)ilog2(jfr->srq.max_depth);
+ srq_attr->srq_wqebb_size =
+ jfr->srq.wqe_shift - SRQ_WQEBB_SIZE_CAL_SECTTOR;
+ srq_attr->srq_page_size = udma_get_queue_kernel_page_size(
+ udma_dev->ub_cap.dev_cap.mtt_pro_en, jfr->srq.buf_size);
+ if (cfg->jfc != NULL)
+ srq_attr->srq_cqn = cfg->jfc->id;
+ else
+ udma_warn(udma_dev->dev, UDMA_M_JFR,
+ "cfg->recv_jfc is null, srq_cqn default 0.\n");
+ srq_attr->container_en = 1;
+}
+
+static void udma_fill_cmd_jfr_sw_attr(struct udma_device *udma_dev,
+ struct ub_jetty_sw_attr *sw_attr,
+ struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg)
+{
+ ub_jetty_com_attr_s *jetty_com_attr = &sw_attr->jetty_com_attr;
+ ub_jetty_rq_attr_s *jetty_rq_attr = &sw_attr->jetty_rq_attr;
+
+ jetty_com_attr->jetty_state = UBCORE_JETTY_STATE_READY;
+ jetty_com_attr->jetty_type = JFR;
+ jetty_com_attr->transport_mode =
+ (cfg->trans_mode == UBCORE_TP_UM) ?
+ UB_TRANSPORT_MODE_UM :
+ ((cfg->trans_mode == UBCORE_TP_RM) ?
+ UB_TRANSPORT_MODE_RM :
+ UB_TRANSPORT_MODE_RSC);
+ jetty_com_attr->jetty_id = jfr->jfr_id;
+ jetty_com_attr->eid_index = cfg->eid_index;
+ jetty_com_attr->hash = (u32)atomic_inc_return(&udma_dev->jfr_hash);
+
+ if (cfg->jfc != NULL) {
+ jetty_rq_attr->rx_jfcn = cfg->jfc->id;
+ jetty_rq_attr->jfc_inline =
+ udma_get_jfc_inline(udma_dev, cfg->jfc);
+ } else {
+ udma_warn(udma_dev->dev, UDMA_M_JFR,
+ "cfg->recv_jfc is null, rx_jfcn default 0.\n");
+ }
+ jetty_rq_attr->rnr_timer = cfg->min_rnr_timer &
+ 0x1f; //rnr_timer: 5bits
+ jetty_rq_attr->jfrn = jfr->jfr_id;
+ jetty_rq_attr->token_value = cfg->token_value.token;
+ jetty_rq_attr->jfr_round = jfr->round;
+}
+
+static void udma_fill_cmd_jfr_index_queue_attr(struct udma_device *udma_dev,
+ struct ub_chip_attr *chip_attr,
+ struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg)
+{
+ ub_mtt_attr_s *sq_mtt_attr = &chip_attr->sq_mtt_attr;
+ ub_index_q_attr_s *index_q_attr = &chip_attr->index_q_attr;
+ __be64 first_page_addr;
+
+ sq_mtt_attr->mtt_paddr_ext_h =
+ upper_32_bits(jfr->index_queue.ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_paddr_ext_l =
+ lower_32_bits(jfr->index_queue.ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_layers_ext = jfr->index_queue.ub_mtt.mtt_layers;
+ sq_mtt_attr->mtt_page_shift_ext =
+ jfr->index_queue.ub_mtt.mtt_page_shift;
+
+ index_q_attr->idx_queue_size = (u32)ilog2(jfr->index_queue.max_depth);
+ index_q_attr->idx_queue_pi_on_chip = 0;
+ index_q_attr->idx_queue_lth_pre_en = 1;
+ index_q_attr->idx_queue_lth_gap =
+ 1; /* PI - CI <= idx_queue_lth_gap + idx_queue_lth when update PI */
+ index_q_attr->user_data0 =
+ 0; /* todo index_q_attr->user_data0 = cfg->user_data0 */
+ index_q_attr->user_data1 =
+ 0; /* todo index_q_attr->user_data1 = cfg->user_data1 */
+ if (sq_mtt_attr->mtt_layers_ext == 0) {
+ index_q_attr->first_page_addr_h = sq_mtt_attr->mtt_paddr_ext_h;
+ index_q_attr->first_page_addr_l = sq_mtt_attr->mtt_paddr_ext_l;
+ } else {
+ first_page_addr = *(jfr->index_queue.ub_mtt.mtt_vaddr);
+ index_q_attr->first_page_addr_h =
+ cpu_to_be32(lower_32_bits(first_page_addr));
+ index_q_attr->first_page_addr_l =
+ cpu_to_be32(upper_32_bits(first_page_addr));
+ }
+}
+
+static void udma_fill_cmd_jfr_create_ctx(struct udma_device *udma_dev,
+ struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg,
+ struct ub_cmd_jetty_create *cmd_buf,
+ udma_cqm_cmd_type_info_t cmd_info)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_create);
+
+ udma_fill_cmd_jfr_chip_attr(udma_dev, &cmd_buf->body.chip_attr, jfr,
+ cfg);
+
+ udma_fill_cmd_jfr_sw_attr(udma_dev, &cmd_buf->body.sw_attr, jfr, cfg);
+
+ if (jfr->srq.index_queue_en) {
+ udma_fill_cmd_jfr_index_queue_attr(
+ udma_dev, &cmd_buf->body.chip_attr, jfr, cfg);
+ }
+
+ udma_fill_cmd_header(&cmd_buf->header, cmd_info.cmd_type,
+ cmd_info.cmd_subtype, cmd_len, jfr->jfr_id);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfr_create_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_create *cmd_buf = NULL;
+ udma_cqm_cmd_type_info_t cmd_info;
+ int ret;
+
+ cmd_info.cmd_type = UB_CMD_TYPE_JFR;
+ cmd_info.cmd_subtype = UB_CMD_JFR_CREATE_CTX;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_create), &cqm_cmd_outbuf,
+ sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfr_create_ctx(udma_dev, jfr, cfg, cmd_buf, cmd_info);
+
+ ret = udma_send_cmd_box(udma_dev, cmd_info.cmd_subtype, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, &jfr->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ ret = -EIO;
+ goto err_cqm_send;
+ }
+
+ jfr->round = (u32)ntohl(*(u32 *)cqm_cmd_outbuf->buf);
+ udma_debug(udma_dev->dev, UDMA_M_JFR,
+ "cmdq create jfr(%d) success and get round(0x%08x)\n",
+ jfr->jfr_id, jfr->round);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jfr_modify_ctx(struct udma_device *udma_dev,
+ struct udma_jfr *jfr,
+ struct udma_jfr_modify_cfg *cfg,
+ struct ub_cmd_jetty_modify *cmd_buf,
+ udma_cqm_cmd_type_info_t cmd_info)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_modify);
+
+ if (cfg->mask.state > 0) {
+ cmd_buf->body.jetty_type = JFR;
+ cmd_buf->body.old_state = to_jetty_misc_state(jfr->state);
+ cmd_buf->body.new_state = to_jetty_misc_state(cfg->state);
+ cmd_buf->body.mask.state = 1;
+ }
+ /* 1825 newly added jfr modify idx_wqe_cnt_lth function */
+ if (cfg->mask.idx_queue_lth > 0) {
+ cmd_buf->body.idx_queue_lth = cfg->idx_queue_lth;
+ cmd_buf->body.idx_queue_lth_pre_en = 1;
+ cmd_buf->body.mask.idx_queue_lth = 1;
+ }
+ udma_fill_cmd_header(&cmd_buf->header, cmd_info.cmd_type,
+ cmd_info.cmd_subtype, cmd_len, jfr->jfr_id);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfr_modify_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ struct udma_jfr_modify_cfg *cfg)
+{
+ struct ub_cmd_jetty_modify *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ udma_cqm_cmd_type_info_t cmd_info;
+ int ret;
+
+ cmd_info.cmd_type = UB_CMD_TYPE_JFR;
+ cmd_info.cmd_subtype = UB_CMD_JFR_MODIFY_CTX;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfr_modify_ctx(udma_dev, jfr, cfg, cmd_buf, cmd_info);
+
+ ret = udma_send_cmd_box(udma_dev, cmd_info.cmd_subtype, cqm_cmd_inbuf,
+ NULL, NULL, &jfr->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfr_delete_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_delete);
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_delete *cmd_buf = NULL;
+ udma_cqm_cmd_type_info_t cmd_info;
+ ub_cmdq_cqe_udata_s cmdq_cqe = { 0 };
+ int ret;
+
+ cmd_info.cmd_type = UB_CMD_TYPE_JFR;
+ cmd_info.cmd_subtype = UB_CMD_JFR_DELETE_CTX;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_delete), &cqm_cmd_outbuf,
+ sizeof(u32) * UDMA_DPATH_MAX_OQ_NUM);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&cmd_buf->header, cmd_info.cmd_type,
+ cmd_info.cmd_subtype, cmd_len, jfr->jfr_id);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, cmd_info.cmd_subtype, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, &cmdq_cqe, &jfr->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ else
+ ret = udma_dpath_drain_handle(udma_dev,
+ (u8 *)cqm_cmd_outbuf->buf,
+ cmdq_cqe.bs.dpath_oq_num);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFR,
+ "cmdq_cqe.bs.dpath_oq_num(%u), cmdq_cqe.value(0x%llx), ret:%d\n",
+ cmdq_cqe.bs.dpath_oq_num, cmdq_cqe.value, ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int
+udma_fill_cmd_jfr_cache_invld_ctx(struct udma_device *udma_dev,
+ struct udma_jfr *jfr, u64 wb_dma,
+ struct ub_cmd_jetty_cache_invld *cmd_buf,
+ udma_cqm_cmd_type_info_t cmd_info)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_cache_invld);
+ struct udma_comp_priv *comp_priv = NULL;
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to get hmm comp priv.\n");
+ return -EINVAL;
+ }
+
+ cmd_buf->body.rq_buf_len = ALIGN(jfr->srq.buf_size, PAGE_SIZE);
+ cmd_buf->body.mtt_flags = 0;
+ cmd_buf->body.mtt_num = 0;
+ cmd_buf->body.mtt_cache_line_start = comp_priv->ub_cap.cmtt_cl_start;
+ cmd_buf->body.mtt_cache_line_end = comp_priv->ub_cap.cmtt_cl_end;
+ cmd_buf->body.mtt_cache_line_size = comp_priv->ub_cap.cmtt_cl_sz;
+ cmd_buf->body.syn_gpa_hi32 = upper_32_bits(wb_dma);
+ cmd_buf->body.syn_gpa_lo32 = lower_32_bits(wb_dma);
+ cmd_buf->body.wqe_flags = 0;
+ cmd_buf->body.wqe_num = 0;
+ cmd_buf->body.wqe_cache_line_start = comp_priv->ub_cap.wqe_cl_start;
+ cmd_buf->body.wqe_cache_line_end = comp_priv->ub_cap.wqe_cl_end;
+ cmd_buf->body.wqe_cache_line_size = comp_priv->ub_cap.wqe_cl_sz;
+
+ udma_fill_cmd_header(&cmd_buf->header, cmd_info.cmd_type,
+ cmd_info.cmd_subtype, cmd_len, jfr->jfr_id);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ return 0;
+}
+
+int udma_cmd_jfr_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jfr *jfr, u64 wb_dma)
+{
+ struct ub_cmd_jetty_cache_invld *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u32 times = 0;
+ udma_cqm_cmd_type_info_t cmd_info;
+ int ret;
+
+ cmd_info.cmd_type = UB_CMD_TYPE_JFR;
+ cmd_info.cmd_subtype = UB_CMD_JFR_CACHE_INVLD_CTX;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_cache_invld), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_cache_invld *)cqm_cmd_inbuf->buf;
+ ret = udma_fill_cmd_jfr_cache_invld_ctx(udma_dev, jfr, wb_dma, cmd_buf,
+ cmd_info);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed fill jfr cacheout inbuf, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return ret;
+ }
+
+ ret = udma_send_cache_invld_ctx(udma_dev, cqm_cmd_inbuf, ×,
+ cmd_info.cmd_subtype, &jfr->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "Failed to send cqm_cmd_box after try times(%u), jfr(%u), ret(%d)\n",
+ times, jfr->jfr_id, ret);
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfr_query_driver_ctr(struct udma_device *udma_dev, u32 jfr_id,
+ ub_driver_comm_ctr_t *outbuf)
+{
+ struct mutex *lock = NULL;
+ struct udma_jfr *ub_jfr = NULL;
+ lock = &udma_dev->device_res->jfr_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(ub_jfr, &udma_dev->device_res->jfr_list.node,
+ node) {
+ if (ub_jfr->jfr_id == jfr_id) {
+ mutex_unlock(lock);
+ outbuf->post_recv_wr_num = (u64)atomic64_read(
+ &ub_jfr->srq.udma_driver_rq_ctr
+ .post_recv_wr_num);
+ return 0;
+ }
+ }
+ mutex_unlock(lock);
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "query driver ctr fail, jfr_id:%u\n", jfr_id);
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.h
new file mode 100644
index 000000000..3876dafe0
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfr.h
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_JFR_H
+#define UDMA_CMD_JFR_H
+
+#include "udma_common.h"
+#include "udma_jetty.h"
+
+int udma_cmd_jfr_create_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg);
+int udma_cmd_jfr_modify_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ struct udma_jfr_modify_cfg *cfg);
+int udma_cmd_jfr_delete_ctx(struct udma_device *udma_dev, struct udma_jfr *jfr);
+int udma_cmd_jfr_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jfr *jfr, u64 wb_dma);
+int udma_cmd_jfr_query_driver_ctr(struct udma_device *udma_dev, u32 jfr_id,
+ ub_driver_comm_ctr_t *outbuf);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.c
new file mode 100644
index 000000000..4d37b0594
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "ub_npu_jetty_cmd_defs.h"
+#include "ub_npu_jetty_cmd.h"
+#include "ub_npu_jfrc_cmd.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_misc.h"
+#include "udma_jetty.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_jfrc.h"
+
+static void udma_fill_cmd_jfrc_sw_attr(struct udma_rc_queue *udma_rcq,
+ struct ub_jetty_sw_attr *sw_attr)
+{
+ sw_attr->jetty_com_attr.transport_mode = UB_TRANSPORT_MODE_RCQ;
+ sw_attr->jetty_com_attr.jetty_type = JFRC;
+}
+
+static void udma_fill_cmd_jfrc_chip_attr(struct udma_rc_queue *udma_rcq,
+ struct ub_chip_attr *chip_attr)
+{
+#define UDMA_MTT_PRO_EN 1
+
+ ub_mtt_attr_s *sq_mtt_attr = &chip_attr->sq_mtt_attr;
+ ub_sq_attr_s *sq_attr = &chip_attr->sq_attr;
+ ub_rc_attr_s *rc_attr = &chip_attr->rc_attr;
+ u64 tmp = 0;
+ u64 rcq_depth = 0;
+
+ sq_mtt_attr->mtt_paddr_h = upper_32_bits(udma_rcq->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_paddr_l = lower_32_bits(udma_rcq->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_layers = udma_rcq->ub_mtt.mtt_layers;
+ sq_mtt_attr->mtt_page_shift = udma_rcq->ub_mtt.mtt_page_shift;
+
+ chip_attr->db_paddr_h =
+ upper_32_bits(udma_rcq->rc_queue->q_header_paddr);
+ chip_attr->db_paddr_l =
+ lower_32_bits(udma_rcq->rc_queue->q_header_paddr);
+
+ if (udma_rcq->total_depth != 0) {
+ /* driver to rcq allocate of 2MB memory page, but agreed chip uses of 1MB(i.e. depth is 8k), so conversion is done here */
+ rcq_depth = udma_rcq->total_depth >> 1;
+
+ /* microcode sq_wqebb_size is 64B, so depth sent to chip needs * UB_PER_RCQE_WQEBB_NUM */
+ tmp = roundup_pow_of_two(rcq_depth * UB_PER_RCQE_WQEBB_NUM);
+ sq_attr->sq_size = (u32)((u32)ilog2((u32)tmp)) &
+ UB_RC_QUEUE_DEPTH_MASK;
+ }
+ sq_attr->sq_wqebb_size = /* value is 2, wqebb_size equal to 2^sq_wqebb_size * 16 = 64 byte */
+ ((u32)(UB_RC_QUEUE_WQE_SHIFT - UB_RC_QUEUE_WQEBB_SIZE_SHIFT)) &
+ UB_JETTY_WQEBB_SIZE_MASK;
+ sq_attr->sq_page_size = udma_get_queue_kernel_page_size(
+ UDMA_MTT_PRO_EN, udma_rcq->total_size);
+ sq_attr->sq_inline_en = 0;
+ sq_attr->sq_pi_on_chip = 0;
+
+ rc_attr->rc_paddr_h =
+ (udma_rcq->ubrc.dma_addr >> UB_RC_HI_PADDR_SHIFT) &
+ UB_RC_HI_PADDR_MASK;
+ rc_attr->rc_paddr_l = (u32)(udma_rcq->ubrc.dma_addr >>
+ UB_RC_LOW_PADDR_SHIFT); // bit[39:8]
+ rc_attr->rc_size = UB_RC_TABLE_SIZE_128B;
+ rc_attr->ext_order = udma_rcq->ubrc.ext_order - UB_RC_EXT_ORDER_SHIFT;
+}
+
+static void
+udma_fill_cmd_jfrc_create_body(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq,
+ struct ub_cmd_body_jetty_create *body)
+{
+ udma_fill_cmd_jfrc_chip_attr(udma_rcq, &body->chip_attr);
+ udma_fill_cmd_jfrc_sw_attr(udma_rcq, &body->sw_attr);
+}
+
+int udma_cmd_jfrc_create_ctx(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_create *rc_cmd = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_create);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jetty_create),
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ rc_cmd = (struct ub_cmd_jetty_create *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_CREATE_CTX, cmd_len,
+ udma_rcq->rc_ctx->xid);
+
+ udma_fill_cmd_jfrc_create_body(udma_dev, udma_rcq, &rc_cmd->body);
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_CREATE_CTX, cqm_cmd_inbuf,
+ NULL, NULL, &udma_rcq->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm send cmd failed, ret(%d), xid(%u)\n",
+ __func__, ret, udma_rcq->rc_ctx->xid);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfrc_delete_ctx(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq)
+{
+ struct ub_cmd_jfrc_delete *rc_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_jfrc_delete);
+ u32 *cmd_out_num = NULL;
+ u32 cmd_out_val = 0;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jfrc_delete),
+ &cqm_cmd_outbuf,
+ sizeof(u64) + sizeof(u64));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return ret;
+ }
+
+ rc_cmd = (struct ub_cmd_jfrc_delete *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_DESTROY_CTX, cmd_len,
+ udma_rcq->rc_ctx->xid);
+
+ rc_cmd->body.bs.dpath_flag = 1;
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+ cmd_out_num = (u32 *)cqm_cmd_outbuf->buf;
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_DESTROY_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ &udma_rcq->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: send cmd failed, ret = %d.\n", __func__, ret);
+ else
+ cmd_out_val = be32_to_cpu(*cmd_out_num);
+ if ((cmd_out_val & UB_DPATH_CHECK_FLAG) != 0) {
+ ret = udma_cmd_check_dpath_dma(
+ udma_dev, ((u8 *)cqm_cmd_outbuf->buf) + sizeof(u64),
+ sizeof(u8), sizeof(u8));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: check_dpath_dma failed\n", __func__);
+ }
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void
+udma_fill_cmd_jfrc_modify_pcqc(u32 jfrc_id, u32 offset, u32 len, const u8 *data,
+ u32 data_len,
+ struct ub_cmd_jfrc_modify_pcqc *cmd_buf)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+ u32 i;
+
+ cmd_buf->body.offset = offset;
+ cmd_buf->body.length = len;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_MODIFY_PCQC, cmd_len, jfrc_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ for (i = 0; i < len; ++i) {
+ if (i + offset < UB_PCQ_CTX_SIZE &&
+ (i * DATALEN_RATIO + 1) < data_len) {
+ cmd_buf->body.ctx[i + offset] =
+ (data[i * DATALEN_RATIO] << DATA_SHIFT) +
+ data[i * DATALEN_RATIO + 1];
+ }
+ }
+}
+
+int udma_cmd_jfrc_modify_pcqc(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ struct ub_cmd_jfrc_modify_pcqc *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jfrc_modify_pcqc), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "failed to alloc buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jfrc_modify_pcqc *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_jfrc_modify_pcqc(inbuf->xid, inbuf->offset, inbuf->length,
+ inbuf->data, inbuf->data_len, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_MODIFY_PCQC,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_warn(udma_dev->dev, UDMA_M_RC_TABLE,
+ "can't send jfrc modify pcqc command, ret = %d.\n",
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static int
+udma_cmd_jfrc_cache_invalidate_fill(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq, u64 wb_dma,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ struct ub_cmd_jetty_cache_invld *rc_cmd =
+ (struct ub_cmd_jetty_cache_invld *)cqm_cmd_inbuf->buf;
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_cache_invld);
+ int ret;
+
+ ret = udma_fill_cmd_body(udma_dev, rc_cmd, udma_rcq->total_size,
+ wb_dma);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* reuse Jetty cache invalidate microcode */
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CACHE_INVLD_CTX, cmd_len,
+ udma_rcq->rc_ctx->xid);
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+
+ return 0;
+}
+
+static int
+udma_rc_queue_send_cache_invalidate_cmd(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq,
+ u64 wb_dma)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ /* reuse jetty command */
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_cache_invld), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: alloc cqm_cmd_inoutbuf failed, ret(%d)\n",
+ __func__, ret);
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_jfrc_cache_invalidate_fill(udma_dev, udma_rcq, wb_dma,
+ cqm_cmd_inbuf);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: fill rc queue cache invalidate inbuf failed, ret(%d)\n",
+ __func__, ret);
+ goto fill_inbuf_failed;
+ }
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_CACHE_INVLD_CTX,
+ cqm_cmd_inbuf, NULL, NULL, &udma_rcq->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: send cqm_cmd_box failed, ret(%d)\n", __func__,
+ ret);
+
+fill_inbuf_failed:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfrc_cache_invalidate(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq)
+{
+ void *wb_va = NULL;
+ u64 wb_dma = 0;
+ int ret;
+
+ wb_va = dma_alloc_coherent(udma_dev->dev, (size_t)4UL, &wb_dma,
+ GFP_KERNEL);
+ if (wb_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: alloc wb_va failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = udma_rc_queue_send_cache_invalidate_cmd(udma_dev, udma_rcq,
+ wb_dma);
+
+ dma_free_coherent(udma_dev->dev, sizeof(u32), wb_va, wb_dma);
+
+ return ret;
+}
+
+int udma_cmd_jfrc_query_qpc_ctx(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf)
+{
+ struct ub_ta_context_query *query_outbuf = NULL;
+ struct ub_cmd_jfrc_query *rc_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_jfrc_query);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jfrc_query),
+ &cqm_cmd_outbuf,
+ sizeof(struct ub_ta_context_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ rc_cmd = (struct ub_cmd_jfrc_query *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_QUERY_QPC_CTX, cmd_len, rc_id);
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_QUERY_QPC_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (struct ub_ta_context_query *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)outbuf, sizeof(struct ub_ta_context_query),
+ (void *)query_outbuf,
+ sizeof(struct ub_ta_context_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: memcpy_s failed, ret(%d)\n", __func__, ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE, "%s success, rc_id(%u)\n",
+ __func__, rc_id);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_jfrc_query_pcqc_ctx(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf)
+{
+ ub_pcqc_query_rsp_s *query_outbuf = NULL;
+ struct ub_cmd_jfrc_query *rc_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_jfrc_query);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jfrc_query),
+ &cqm_cmd_outbuf,
+ sizeof(ub_pcqc_query_rsp_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ rc_cmd = (struct ub_cmd_jfrc_query *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_QUERY_PCQC_CTX, cmd_len, rc_id);
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_QUERY_PCQC_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (ub_pcqc_query_rsp_s *)cqm_cmd_outbuf->buf;
+ (void)memcpy_s((void *)outbuf, sizeof(ub_pcqc_query_rsp_s),
+ (void *)query_outbuf, sizeof(ub_pcqc_query_rsp_s));
+
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE, "%s success, rc_id(%u)\n",
+ __func__, rc_id);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_jfrc_query_wqe(struct udma_device *udma_dev, u32 rc_id, u32 ci,
+ struct ub_rc_queue_wqe *outbuf)
+{
+ struct ub_rc_queue_wqe *query_outbuf = NULL;
+ struct ub_cmd_jfrc_query *rc_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_jfrc_query);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_jfrc_query),
+ &cqm_cmd_outbuf,
+ sizeof(struct ub_rc_queue_wqe));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ rc_cmd = (struct ub_cmd_jfrc_query *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&rc_cmd->header, UB_CMD_TYPE_JFRC,
+ UB_CMD_JFRC_QUERY_WQE, cmd_len, rc_id);
+
+ rc_cmd->body.ci = ci;
+
+ udma_cpu_to_be32(rc_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JFRC_QUERY_WQE, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s: send cmd failed, rc_buf_id(%u) ci(%u) ret(%d)\n",
+ __func__, rc_id, ci, ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (struct ub_rc_queue_wqe *)cqm_cmd_outbuf->buf;
+ (void)memcpy_s((void *)outbuf, sizeof(struct ub_rc_queue_wqe),
+ (void *)query_outbuf, sizeof(struct ub_rc_queue_wqe));
+
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE,
+ "%s success, rc_id(%u) ci(%u)\n", __func__, rc_id, ci);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.h
new file mode 100644
index 000000000..d59e80050
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfrc.h
@@ -0,0 +1,28 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_JFRC_H
+#define UDMA_CMD_JFRC_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "ub_npu_jfrc_cmd_defs.h"
+#include "ub_pub_cmd.h"
+
+int udma_cmd_jfrc_create_ctx(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq);
+int udma_cmd_jfrc_delete_ctx(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq);
+int udma_cmd_jfrc_cache_invalidate(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq);
+int udma_cmd_jfrc_query_qpc_ctx(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf);
+int udma_cmd_jfrc_query_pcqc_ctx(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf);
+int udma_cmd_jfrc_query_wqe(struct udma_device *udma_dev, u32 rc_id, u32 ci,
+ struct ub_rc_queue_wqe *outbuf);
+int udma_cmd_jfrc_modify_pcqc(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.c
new file mode 100644
index 000000000..64116330c
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.c
@@ -0,0 +1,341 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "udma_cqm.h"
+#include "udma_misc.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jetty.h"
+#include "ub_npu_jetty_cmd.h"
+#include "udma_cmd_jfs.h"
+
+static void udma_fill_cmd_jfs_chip_attr(struct udma_device *udma_dev,
+ struct ub_chip_attr *chip_attr,
+ struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg,
+ u8 pi_on_chip_en, u8 mtt_pro_en)
+{
+ ub_mtt_attr_s *sq_mtt_attr = &chip_attr->sq_mtt_attr;
+ ub_sq_attr_s *sq_attr = &chip_attr->sq_attr;
+ ub_rc_attr_s *rc_attr = &chip_attr->rc_attr;
+
+ sq_mtt_attr->mtt_paddr_h = upper_32_bits(jfs->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_paddr_l = lower_32_bits(jfs->ub_mtt.mtt_paddr);
+ sq_mtt_attr->mtt_layers = jfs->ub_mtt.mtt_layers;
+ sq_mtt_attr->mtt_page_shift = jfs->ub_mtt.mtt_page_shift;
+
+ chip_attr->db_paddr_h = upper_32_bits(jfs->sdb.dma);
+ chip_attr->db_paddr_l = lower_32_bits(jfs->sdb.dma);
+
+ if (cfg->depth != 0) {
+ u64 tmp = (u64)roundup_pow_of_two(jfs->sq.baseblk_cnt);
+ sq_attr->sq_size =
+ (u32)((UB_ILOG2((u32)tmp)) & UB_JETTY_SIZE_MASK);
+ }
+
+ sq_attr->sq_wqebb_size =
+ ((u32)(JETTY_WQE_SHIFT - UB_JETTY_WQEBB_SIZE_SHIFT)) &
+ UB_JETTY_WQEBB_SIZE_MASK;
+ sq_attr->sq_page_size =
+ udma_get_queue_kernel_page_size(mtt_pro_en, jfs->sq_buf_len);
+ sq_attr->cqn = cfg->jfc->id;
+ sq_attr->sq_inline_en = 1;
+ sq_attr->sq_pi_on_chip = pi_on_chip_en;
+
+ if (jfs->trans_mode == UBCORE_TP_RM) {
+ rc_attr->rc_paddr_h = (jfs->ubrc.dma_addr >> 40) &
+ 0xffffff; //high:24bit, 64-24= 40
+ rc_attr->rc_paddr_l =
+ (u32)(jfs->ubrc.dma_addr >> 8); //bit[39:8]
+ rc_attr->rc_size = depth_align_power2(
+ udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_depth);
+ rc_attr->ext_order =
+ jfs->ubrc.ext_order - UB_RC_EXT_ORDER_SHIFT;
+ }
+}
+
+static void udma_fill_cmd_jfs_sw_attr(struct udma_device *udma_dev,
+ struct ub_jetty_sw_attr *sw_attr,
+ struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ ub_jetty_com_attr_s *com_attr = &sw_attr->jetty_com_attr;
+ ub_jetty_sq_attr_s *sq_attr = &sw_attr->jetty_sq_attr;
+
+ com_attr->jetty_state = UBCORE_JETTY_STATE_READY;
+ com_attr->jetty_type = JFS;
+ com_attr->priority = cfg->priority;
+ com_attr->db_cos = jfs->cos;
+ com_attr->transport_mode = (cfg->trans_mode == UBCORE_TP_UM) ?
+ UB_TRANSPORT_MODE_UM :
+ UB_TRANSPORT_MODE_RM;
+ com_attr->jetty_id = jfs->jfs_id;
+ com_attr->eid_index = cfg->eid_index;
+ com_attr->slice_size_shift = udma_dev->slice;
+ com_attr->slice_en = udma_get_jetty_slice_en(udma_dev);
+ com_attr->hash = (u32)atomic_inc_return(&udma_dev->jfs_hash);
+
+ sq_attr->tx_jfcn = cfg->jfc->id;
+ sq_attr->ta_timeout = cfg->err_timeout;
+ sq_attr->rnr_max_retry_num = cfg->rnr_retry;
+ sq_attr->err_mode = UB_ERROR_SUSPEND;
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "slice = %u, err_mode: %u, hash: %u\n", udma_dev->slice,
+ sq_attr->err_mode, com_attr->hash);
+}
+
+static void udma_fill_cmd_jfs_create_ctx(struct udma_device *udma_dev,
+ struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg,
+ struct ub_cmd_jetty_create *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_create);
+ u8 sq_pi_on_chip = 0;
+ if (udma_dev->ub_cap.dev_cap.feature.bs.pi_on_chip_en != 0)
+ sq_pi_on_chip =
+ (u8)(jfs->jfs_id <
+ udma_dev->ub_cap.dev_cap.max_pi_on_chip_num);
+
+ udma_fill_cmd_jfs_chip_attr(udma_dev, &cmd_buf->body.chip_attr, jfs,
+ cfg, sq_pi_on_chip,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ udma_fill_cmd_jfs_sw_attr(udma_dev, &cmd_buf->body.sw_attr, jfs, cfg);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CREATE_CTX, cmd_len, jfs->jfs_id);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfs_create_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_create *cmd_buf = NULL;
+
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_create), &cqm_cmd_outbuf,
+ sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfs_create_ctx(udma_dev, jfs, cfg, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_CREATE_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ &jfs->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ jfs->round = (u32)ntohl(*(u32 *)cqm_cmd_outbuf->buf);
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "cmdq create jfs(%d) success and get round(0x%08x)\n",
+ jfs->jfs_id, jfs->round);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jfs_modify_ctx(struct udma_jfs *jfs,
+ enum ubcore_jetty_state state,
+ struct ub_cmd_jetty_modify *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_modify);
+
+ cmd_buf->body.jetty_type = JFS;
+ cmd_buf->body.mask.state = UDMA_MASK_VALID;
+ cmd_buf->body.old_state = jfs->state;
+ cmd_buf->body.new_state = state;
+ cmd_buf->body.sq_pi = jfs->sq.pi;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_MODIFY_CTX, cmd_len, jfs->jfs_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfs_modify_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ enum ubcore_jetty_state state,
+ struct ubcore_udata *udata)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_modify *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfs_modify_ctx(jfs, state, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, &jfs->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_fill_cmd_jfs_delete_ctx(u32 idx,
+ struct ub_cmd_jetty_delete *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_delete);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_DELETE_CTX, cmd_len, idx);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_jfs_delete_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_jetty_delete *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_delete), &cqm_cmd_outbuf,
+ sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_jfs_delete_ctx(jfs->jfs_id, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_JETTY_DELETE_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL,
+ &jfs->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ else
+ ret = udma_cmd_check_dpath_dma(udma_dev,
+ (u8 *)cqm_cmd_outbuf->buf,
+ sizeof(u8), sizeof(u8));
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int
+udma_fill_cmd_jfs_cache_invld_ctx(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, u64 wb_dma,
+ struct ub_cmd_jetty_cache_invld *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_jetty_cache_invld);
+ int ret;
+
+ ret = udma_fill_cmd_body(udma_dev, cmd_buf, jfs->sq_buf_len, wb_dma);
+ if (ret != 0) {
+ return ret;
+ }
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_JETTY,
+ UB_CMD_JETTY_CACHE_INVLD_CTX, cmd_len,
+ jfs->jfs_id);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ return 0;
+}
+
+int udma_cmd_jfs_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, u64 wb_dma)
+{
+ struct ub_cmd_jetty_cache_invld *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u32 times = 0;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_jetty_cache_invld), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to alloc cqm_cmd_inoutbuf, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_jetty_cache_invld *)cqm_cmd_inbuf->buf;
+ ret = udma_fill_cmd_jfs_cache_invld_ctx(udma_dev, jfs, wb_dma, cmd_buf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed fill jetty cacheout inbuf, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return ret;
+ }
+
+ ret = udma_send_cache_invld_ctx(udma_dev, cqm_cmd_inbuf, ×,
+ UB_CMD_JETTY_CACHE_INVLD_CTX,
+ &jfs->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Failed to send cqm_cmd_box after try times(%u), jfs(%u), ret(%d)\n",
+ times, jfs->jfs_id, ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_jfs_query_driver_ctr(struct udma_device *udma_dev, u32 jfs_id,
+ ub_driver_comm_ctr_t *outbuf)
+{
+ struct udma_jfs *ub_jfs = NULL;
+ struct mutex *lock = &udma_dev->device_res->jfs_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(ub_jfs, &udma_dev->device_res->jfs_list.node,
+ node) {
+ if (ub_jfs->jfs_id == jfs_id) {
+ udma_jfs_get(ub_jfs);
+ mutex_unlock(lock);
+ outbuf->post_send_wr_num = (u64)atomic64_read(
+ &ub_jfs->sq.udma_driver_sq_ctr.post_send_wr_num);
+ udma_jfs_put(ub_jfs);
+ return 0;
+ }
+ }
+ mutex_unlock(lock);
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "query driver ctr fail, jfs_id:%u\n", jfs_id);
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.h
new file mode 100644
index 000000000..e271672a8
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_jfs.h
@@ -0,0 +1,23 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_JFS_H
+#define UDMA_CMD_JFS_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_jetty.h"
+
+int udma_cmd_jfs_create_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg);
+int udma_cmd_jfs_modify_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ enum ubcore_jetty_state state,
+ struct ubcore_udata *udata);
+int udma_cmd_jfs_delete_ctx(struct udma_device *udma_dev, struct udma_jfs *jfs);
+int udma_cmd_jfs_cache_out_ctx(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, u64 wb_dma);
+int udma_cmd_jfs_query_driver_ctr(struct udma_device *udma_dev, u32 jfs_id,
+ ub_driver_comm_ctr_t *outbuf);
+
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.c
new file mode 100644
index 000000000..8ea1f9aea
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.c
@@ -0,0 +1,60 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+
+#include "ub_npu_mig_cmd.h"
+#include "udma_cqm.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_mig.h"
+
+int udma_cmd_mig_query_counter(struct udma_device *udma_dev, u32 func_id,
+ struct ub_cmd_mig_drain_status_outbuf *out)
+{
+ struct ub_cmd_mig_query_drain_status *cmd_in = NULL;
+ struct ub_cmd_mig_drain_status_outbuf *cmd_out = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_mig_query_drain_status),
+ &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_cmd_mig_drain_status_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "Alloc cmd_buf failed. ret: %d\n", ret);
+ return ret;
+ }
+
+ cmd_in = (struct ub_cmd_mig_query_drain_status *)cqm_cmd_inbuf->buf;
+ cmd_len = sizeof(struct ub_cmd_mig_query_drain_status);
+ cmd_in->body.func_id = func_id;
+ udma_fill_cmd_header(&cmd_in->header, UB_CMD_TYPE_MIGRATE,
+ UB_CMD_MIG_QUERY_DRAIN_STATUS, cmd_len, 0);
+ udma_cpu_to_be32(cmd_in, cmd_len);
+ cmd_out = (struct ub_cmd_mig_drain_status_outbuf *)cqm_cmd_outbuf->buf;
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MIG_QUERY_DRAIN_STATUS,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return -EBUSY;
+ }
+
+ udma_be32_to_cpu(cmd_out,
+ sizeof(struct ub_cmd_mig_drain_status_outbuf));
+ (void)memcpy_s((void *)out,
+ sizeof(struct ub_cmd_mig_drain_status_outbuf),
+ (void *)cmd_out,
+ sizeof(struct ub_cmd_mig_drain_status_outbuf));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.h
new file mode 100644
index 000000000..5c68d81de
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_mig.h
@@ -0,0 +1,14 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_MIG_H
+#define UDMA_CMD_MIG_H
+
+#include "udma_common.h"
+#include "ub_npu_mig_cmd_defs.h"
+
+int udma_cmd_mig_query_counter(struct udma_device *udma_dev, u32 func_id,
+ struct ub_cmd_mig_drain_status_outbuf *out);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.c
new file mode 100644
index 000000000..8be510539
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.c
@@ -0,0 +1,418 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_cmd_com.h"
+#include "ub_npu_mapt_cmd.h"
+#include "udma_cmd_segment.h"
+
+#define MAPT_MAX_RETRY 200
+#define HMM_MS_DELAY 5
+#define DATALEN_RATIO 2 //user input of data is 4bit, one byte 8bit / 4 = 2
+#define DATA_SHIFT \
+ 4 //user input of data is 4bit, to convert to byte unit, even index need left shift 4 bit
+
+static void udma_set_seg_access(struct ub_mapt_chip_attr *chip_attr,
+ const struct udma_segment *udma_seg)
+{
+ chip_attr->local_write = 1;
+ if ((UBCORE_ACCESS_LOCAL_ONLY & udma_seg->access) != 0)
+ return;
+
+ chip_attr->remote_invld = 1;
+ if ((UBCORE_ACCESS_READ & udma_seg->access) != 0)
+ chip_attr->remote_read = 1;
+
+ if ((UBCORE_ACCESS_WRITE & udma_seg->access) != 0)
+ chip_attr->remote_write = 1;
+
+ if ((UBCORE_ACCESS_ATOMIC & udma_seg->access) != 0)
+ chip_attr->remote_atomic = 1;
+}
+
+static void udma_fill_cmd_seg_chip_attr(struct ub_mapt_chip_attr *chip_attr,
+ struct udma_segment *udma_seg)
+{
+ struct ub_mtt_attr *mtt_attr = &chip_attr->mtt_attr;
+
+ if (!udma_seg->david_hbm_en) {
+ mtt_attr->mtt_paddr_h = upper_32_bits(udma_seg->mtt.mtt_paddr);
+ mtt_attr->mtt_paddr_l = lower_32_bits(udma_seg->mtt.mtt_paddr);
+ mtt_attr->mtt_layers = udma_seg->mtt.mtt_layers;
+ mtt_attr->mtt_page_shift = udma_seg->mtt.mtt_page_shift;
+ chip_attr->buf_page_size = udma_seg->mtt.buf_page_shift;
+ }
+
+ chip_attr->iova_hi = upper_32_bits(udma_seg->va);
+ chip_attr->iova_lo = lower_32_bits(udma_seg->va);
+ chip_attr->length_hi = upper_32_bits(udma_seg->size);
+ chip_attr->length_lo = lower_32_bits(udma_seg->size);
+
+ chip_attr->block_size = udma_seg->block_size;
+ chip_attr->so_ro = 0;
+ chip_attr->mkey = udma_seg->key;
+
+ udma_set_seg_access(chip_attr, udma_seg);
+}
+
+static void udma_fill_cmd_seg_user_attr(struct ub_mapt_sw_attr *attr,
+ struct udma_segment *udma_seg)
+{
+ attr->token_value = udma_seg->token_value;
+ attr->key_type = udma_seg->key_type;
+ if (udma_seg->david_hbm_en) {
+ attr->eid_d = udma_seg->uba.eid.eid;
+ attr->tid_d = udma_seg->uba.token_id;
+ }
+}
+
+static void udma_fill_cmd_seg_create_ctx(struct udma_segment *udma_seg,
+ struct udma_keyid *udma_key,
+ struct ub_cmd_mapt_create *cmd_buf,
+ u8 cmd)
+{
+ struct ub_cmd_body_mapt_create *body = &cmd_buf->body;
+ u16 cmd_len = sizeof(struct ub_cmd_mapt_create);
+
+ udma_fill_cmd_seg_chip_attr(&body->chip_attr, udma_seg);
+
+ udma_fill_cmd_seg_user_attr(&body->sw_attr, udma_seg);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SEGMENT, cmd,
+ cmd_len, udma_key->mpt.mpt_index);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_seg_query_ctx(u32 tokenid,
+ struct ub_cmd_mapt_query *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_mapt_query);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SEGMENT,
+ UB_CMD_MAPT_QUERY_CTX, cmd_len, tokenid);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_seg_delete_ctx(u32 tokenid,
+ struct ub_cmd_mapt_delete *cmd_buf,
+ u8 cmd)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_body_mapt_delete);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SEGMENT, cmd,
+ cmd_len, tokenid);
+
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+static void udma_fill_cmd_seg_query_safe_dmtt_bitmap(
+ const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_bitmap *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_safe_dmtt_bitmap);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SEGMENT,
+ UB_CMD_MAPT_QUERY_SAFE_DMTT_BITMAP, cmd_len,
+ inbuf->xid);
+ cmd_buf->func_id = inbuf->vfid;
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_seg_query_safe_dmtt_bitmap(
+ struct udma_device *udma_dev, const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_bitmap_outbuf *outbuf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_safe_dmtt_bitmap *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_safe_dmtt_bitmap), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_cmd_safe_dmtt_bitmap_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_safe_dmtt_bitmap *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_seg_query_safe_dmtt_bitmap(inbuf, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MAPT_QUERY_SAFE_DMTT_BITMAP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ (void)memcpy_s(outbuf, sizeof(struct ub_cmd_safe_dmtt_bitmap_outbuf),
+ cqm_cmd_outbuf->buf,
+ sizeof(struct ub_cmd_safe_dmtt_bitmap_outbuf));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static void
+udma_fill_cmd_seg_query_safe_dmtt_ctx(const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_ctx *cmd_buf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_safe_dmtt_ctx);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SEGMENT,
+ UB_CMD_MAPT_QUERY_SAFE_DMTT_CTX, cmd_len,
+ inbuf->xid);
+ cmd_buf->func_id = inbuf->vfid;
+ cmd_buf->gpa_hi = upper_32_bits(inbuf->gpa);
+ cmd_buf->gpa_lo = lower_32_bits(inbuf->gpa);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_seg_query_safe_dmtt_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_ctx_outbuf *outbuf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_safe_dmtt_ctx *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_safe_dmtt_ctx), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_cmd_safe_dmtt_ctx_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_safe_dmtt_ctx *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_seg_query_safe_dmtt_ctx(inbuf, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MAPT_QUERY_SAFE_DMTT_CTX,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ (void)memcpy_s(outbuf, sizeof(struct ub_cmd_safe_dmtt_ctx_outbuf),
+ cqm_cmd_outbuf->buf,
+ sizeof(struct ub_cmd_safe_dmtt_ctx_outbuf));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+int udma_cmd_seg_create_ctx(struct udma_device *udma_dev,
+ struct udma_segment *udma_seg,
+ struct udma_keyid *udma_key)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_mapt_create *cmd_buf = NULL;
+ u8 cmd = udma_seg->david_hbm_en ? UB_CMD_MAPT_CREATE_DAVID_CTX :
+ UB_CMD_MAPT_CREATE_CTX;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_mapt_create), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_mapt_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_seg_create_ctx(udma_seg, udma_key, cmd_buf, cmd);
+
+ ret = udma_send_cmd_box(udma_dev, cmd, cqm_cmd_inbuf, NULL, NULL,
+ &udma_seg->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_seg_query_ctx(struct udma_device *udma_dev, u32 tokenid,
+ struct ub_mapt_ctx_query *ctx)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_mapt_query *cmd_buf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_mapt_query), &cqm_cmd_outbuf,
+ (u16)sizeof(struct ub_mapt_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_mapt_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_seg_query_ctx(tokenid, cmd_buf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MAPT_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ }
+
+ (void)memcpy_s(ctx, sizeof(struct ub_mapt_ctx_query),
+ cqm_cmd_outbuf->buf, sizeof(struct ub_mapt_ctx_query));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+int udma_cmd_seg_delete_ctx(struct udma_device *udma_dev,
+ struct udma_keyid *udma_key,
+ struct udma_segment *udma_seg)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_mapt_delete *cmd_buf = NULL;
+ ub_cmdq_cqe_udata_s cmdq_cqe = { 0 };
+ u8 cmd = udma_seg->david_hbm_en ? UB_CMD_MAPT_DELETE_DAVID_CTX :
+ UB_CMD_MAPT_DELETE_CTX;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_mapt_delete), &cqm_cmd_outbuf,
+ sizeof(u32) * UDMA_DPATH_MAX_OQ_NUM);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_mapt_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_seg_delete_ctx(udma_key->mpt.mpt_index, cmd_buf, cmd);
+
+ ret = udma_send_cmd_box(udma_dev, cmd, cqm_cmd_inbuf, cqm_cmd_outbuf,
+ &cmdq_cqe, &udma_seg->cmdq_rtt);
+ if (ret != 0) {
+ ret = -EIO;
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_cqm_send;
+ } else {
+ ret = udma_dpath_drain_handle(udma_dev,
+ (u8 *)cqm_cmd_outbuf->buf,
+ cmdq_cqe.bs.dpath_oq_num);
+ if (ret != 0) {
+ goto err_cqm_send;
+ }
+ }
+ udma_debug(
+ udma_dev->dev, UDMA_M_SEG,
+ "cmdq_cqe.bs.dpath_oq_num(%u), cmdq_cqe.value(0x%llx), ret:%d\n",
+ cmdq_cqe.bs.dpath_oq_num, cmdq_cqe.value, ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return 0;
+
+err_cqm_send:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static void
+udma_fill_cmd_mapt_batch_modify_ctx(struct ub_cmd_mapt_batch_modify *modify_cmd,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_mapt_batch_modify);
+ u32 i;
+
+ modify_cmd->body.offset = cpu_to_be32(inbuf->offset);
+ modify_cmd->body.length = cpu_to_be32(inbuf->length);
+ /* user input copy to context corresponding position, Note: user input a character occupy 4bit, and user inputs in big-endian format, no need to convert again */
+ for (i = inbuf->offset; i < inbuf->offset + inbuf->length &&
+ i < UB_CQM_MODIFY_DATA_LEN_MAPT / DATALEN_RATIO;
+ ++i) {
+ *(((u8 *)&modify_cmd->body.ctx) + i) =
+ (inbuf->data[(i - inbuf->offset) * DATALEN_RATIO]
+ << DATA_SHIFT) +
+ inbuf->data[(i - inbuf->offset) * DATALEN_RATIO + 1];
+ }
+
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_SEGMENT,
+ UB_CMD_MAPT_BATCH_MODIFY_CTX, cmd_len, inbuf->xid);
+ /* here only convert header endian */
+ udma_cpu_to_be32(modify_cmd, sizeof(ub_cmd_com_header_s));
+}
+
+int udma_cmd_seg_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ struct ub_cmd_mapt_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_mapt_batch_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "cqm inbuf allocation failed\n");
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct ub_cmd_mapt_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_mapt_batch_modify_ctx(modify_cmd, inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MAPT_BATCH_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "send cmd failed, ret(%d)\n", ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "seg batch modify success, mapt_id(%u)\n", inbuf->xid);
+
+err_send_cmd:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.h
new file mode 100644
index 000000000..0810ff720
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_segment.h
@@ -0,0 +1,30 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_SEGMENT_H
+#define UDMA_CMD_SEGMENT_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_key.h"
+#include "udma_segment.h"
+#include "ub_pub_cmd.h"
+
+int udma_cmd_seg_create_ctx(struct udma_device *udma_dev,
+ struct udma_segment *udma_seg,
+ struct udma_keyid *udma_key);
+int udma_cmd_seg_query_ctx(struct udma_device *udma_dev, u32 tokenid,
+ struct ub_mapt_ctx_query *ctx);
+int udma_cmd_seg_delete_ctx(struct udma_device *udma_dev,
+ struct udma_keyid *udma_key,
+ struct udma_segment *udma_seg);
+int udma_cmd_seg_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+int udma_cmd_seg_query_safe_dmtt_bitmap(
+ struct udma_device *udma_dev, const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_bitmap_outbuf *outbuf);
+int udma_cmd_seg_query_safe_dmtt_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ struct ub_cmd_safe_dmtt_ctx_outbuf *outbuf);
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.c
new file mode 100644
index 000000000..acbdaba88
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "ub_npu_sip_cmd.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_misc.h"
+#include "udma_net.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_sip.h"
+
+static int udma_sip_cmd(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr, u8 cmd)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_sip_info);
+ struct ub_cmd_sip_info *cmd_buf = NULL;
+ int ret;
+
+ if (sip_idx >= UDMA_SIP_NUM_MAX) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "sip_idx:%u >= %u err\n",
+ sip_idx, UDMA_SIP_NUM_MAX);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "%s: Alloc cmd_buf failed, err(%d)\n", __func__, ret);
+ return ret;
+ }
+
+ // construct cmd data
+ cmd_buf = (struct ub_cmd_sip_info *)cqm_cmd_inbuf->buf;
+ if (sip_attr != NULL) {
+ (void)memcpy_s(&cmd_buf->body.sip_attr,
+ sizeof(struct ub_sip_attr), sip_attr,
+ sizeof(struct ub_sip_attr));
+ } else {
+ ret = -EINVAL;
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "sip attr is null, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return ret;
+ }
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SIP, cmd, cmd_len,
+ sip_idx);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, cmd, cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "%s:Failed to send cqm_cmd_box, ret(%d)\n", __func__,
+ ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_sip_add(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr)
+{
+ return udma_sip_cmd(udma_dev, sip_idx, sip_attr, UB_CMD_ADD_SIP);
+}
+
+int udma_cmd_sip_del(struct udma_device *udma_dev, u32 sip_idx)
+{
+ struct ub_sip_attr sip_attr = { 0 };
+
+ return udma_sip_cmd(udma_dev, sip_idx, &sip_attr, UB_CMD_DEL_SIP);
+}
+
+int udma_cmd_sip_modify(struct udma_device *udma_dev, u32 sip_idx,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_sip_info);
+ struct ub_cmd_sip_info *cmd_buf = NULL;
+ int ret;
+ u32 i;
+
+ if (sip_idx >= UDMA_SIP_NUM_MAX) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "sip_idx:%u >= %u err\n",
+ sip_idx, UDMA_SIP_NUM_MAX);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "%s: Alloc cmd_buf failed, err(%d)\n", __func__, ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_sip_info *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SIP,
+ UB_CMD_MODIFY_SIP, cmd_len, inbuf->xid);
+ cmd_buf->body.offset = inbuf->offset;
+ cmd_buf->body.length = inbuf->length;
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ /* user input copy to context corresponding position, Note: user input a character occupy 4bit, and user inputs in big-endian format, no need to convert again */
+ for (i = inbuf->offset;
+ i < inbuf->offset + inbuf->length && i < sizeof(ub_sip_attr_s);
+ ++i) {
+ *(((u8 *)&cmd_buf->body.sip_attr) + i) =
+ (inbuf->data[(i - inbuf->offset) * DATALEN_RATIO]
+ << DATA_SHIFT) +
+ inbuf->data[(i - inbuf->offset) * DATALEN_RATIO + 1];
+ }
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_MODIFY_SIP, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "[ERR] %s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "[INFO] %s: success, tpn(%u)\n", __func__, inbuf->xid);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_sip_query(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr)
+{
+ struct ub_cmd_sip_info *cmd_buf = NULL;
+ struct ub_sip_attr *cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_sip_info);
+ u16 out_len = sizeof(struct ub_sip_attr);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, &cqm_cmd_outbuf, out_len);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Alloc cmd_buf failed, err(%d)\n", ret);
+ return ret;
+ }
+
+ // construct cmd data
+ cmd_buf = (struct ub_cmd_sip_info *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SIP,
+ UB_CMD_QUERY_SIP, cmd_len, sip_idx);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_QUERY_SIP, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to send cqm_cmd_box, ret(%d)\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return -EBUSY;
+ }
+
+ cmd_outbuf = (struct ub_sip_attr *)cqm_cmd_outbuf->buf;
+ (void)memcpy_s(sip_attr, sizeof(struct ub_sip_attr), cmd_outbuf,
+ sizeof(struct ub_sip_attr));
+ sip_attr->dw4.dw4_value = be32_to_cpu(sip_attr->dw4.dw4_value);
+ sip_attr->dw5.dw5_value = be32_to_cpu(sip_attr->dw5.dw5_value);
+ sip_attr->dw6.dw6_value = be32_to_cpu(sip_attr->dw6.dw6_value);
+ sip_attr->smac_l32 = be32_to_cpu(sip_attr->smac_l32);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.h
new file mode 100644
index 000000000..5682aaa96
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_sip.h
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_SIP_H
+#define UDMA_CMD_SIP_H
+
+#include "udma_common.h"
+#include "ub_npu_sip_cmd_defs.h"
+#include "ub_pub_cmd.h"
+
+int udma_cmd_sip_add(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr);
+int udma_cmd_sip_del(struct udma_device *udma_dev, u32 sip_idx);
+int udma_cmd_sip_query(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr);
+int udma_cmd_sip_modify(struct udma_device *udma_dev, u32 sip_idx,
+ const struct ub_cqm_modify_inbuf *inbuf);
+
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.c
new file mode 100644
index 000000000..e6ea67377
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.c
@@ -0,0 +1,326 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ub_npu_srq_cmd.h"
+#include "ub_npu_srq_cmd_defs.h"
+#include "udma_srq.h"
+#include "udma_comp.h"
+#include "udma_cqm.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_srq.h"
+
+static void udma_fill_cmd_srq_sw_attr(struct ub_srq_sw_attr *attr,
+ struct udma_srq *srq,
+ const struct udma_db *sdb, u8 mtt_pro_en)
+{
+ attr->dw0.bs.size = (u32)ilog2(srq->max_depth);
+ attr->dw0.bs.page_size =
+ udma_get_queue_kernel_page_size(mtt_pro_en, srq->buf_size);
+ attr->dw0.bs.wqebb_size = srq->wqe_shift - SRQ_WQEBB_SIZE_CAL_SECTTOR;
+ attr->dw0.bs.mtt_page_size = srq->ub_mtt.mtt_page_shift - PAGE_SHIFT_4K;
+
+ attr->dw1.bs.dma_attr_idx = 0;
+ attr->dw1.bs.so_ro = 1;
+ attr->dw1.bs.state = UB_SRQ_STATE_VALID;
+ attr->dw1.bs.container = 1; //ub use container mode
+ attr->dw1.bs.lth_pre_en = 0; //rdma engine prefetch
+ attr->dw1.bs.pcnt_on_chip = 0;
+ attr->dw1.bs.rkey_en = 1;
+
+ attr->srqn = srq->srqn;
+
+ attr->cont.dw0.bs.head_idx = 0;
+ attr->cont.dw0.bs.warn_th = 0; //Do NOT init warn_th until user arm srq
+ attr->cont.dw0.bs.cont_size = (srq->container_mode - 1) & 0x3;
+
+ attr->mtt_paddr_h = upper_32_bits(srq->ub_mtt.mtt_paddr);
+ attr->mtt_paddr_l = lower_32_bits(srq->ub_mtt.mtt_paddr);
+
+ attr->db_paddr_h = upper_32_bits(sdb->dma);
+ attr->db_paddr_l_at_hop_num = lower_32_bits(sdb->dma) & (~0x3ULL);
+ attr->db_paddr_l_at_hop_num |= srq->ub_mtt.mtt_layers & 0x3;
+ return;
+}
+
+void udma_fill_cmd_srq_create_ctx(struct ub_cmd_srq_create *cmd_buf,
+ struct udma_srq *srq, struct udma_db *sdb,
+ u8 mtt_pro_en)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_srq_create);
+ udma_fill_cmd_srq_sw_attr(&cmd_buf->body.sw_attr, srq, sdb, mtt_pro_en);
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SRQ,
+ UB_CMD_SRQ_CREATE_CTX, cmd_len, srq->srqn);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_srq_create_ctx(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct udma_db *sdb)
+{
+ struct ub_cmd_srq_create *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret = 0;
+
+ udma_debug(udma_dev->dev, UDMA_M_SRQ,
+ "srq cmdq refactor start, srqn(%u)\n", srq->srqn);
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_srq_create), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Alloc cqm_cmd_inoutbuf failed, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_srq_create *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_srq_create_ctx(cmd_buf, srq, sdb,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SRQ_CREATE_CTX, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Send CREATE_SRQ command failed, ret(%d)\n", ret);
+ ret = -EIO;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+void udma_fill_cmd_srq_delete_ctx(struct ub_cmd_srq_delete *cmd_buf,
+ struct udma_srq *srq,
+ struct udma_comp_priv *comp_priv)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_srq_delete);
+
+ cmd_buf->body.srq_buf_len = srq->buf_size;
+ cmd_buf->body.mtt_flags = 0;
+ cmd_buf->body.mtt_num = 0;
+ cmd_buf->body.mtt_cache_line_start = comp_priv->ub_cap.cmtt_cl_start;
+ cmd_buf->body.mtt_cache_line_end = comp_priv->ub_cap.cmtt_cl_end;
+ cmd_buf->body.mtt_cache_line_size = comp_priv->ub_cap.cmtt_cl_sz;
+
+ cmd_buf->body.wqe_cache_line_start = comp_priv->ub_cap.wqe_cl_start;
+ cmd_buf->body.wqe_cache_line_end = comp_priv->ub_cap.wqe_cl_end;
+ cmd_buf->body.wqe_cache_line_size = comp_priv->ub_cap.wqe_cl_sz;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SRQ,
+ UB_CMD_SRQ_DELETE_CTX, cmd_len, srq->srqn);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_srq_delete_ctx(struct udma_device *udma_dev, struct udma_srq *srq)
+{
+ struct ub_cmd_srq_delete *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct udma_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Get hmm comp priv failed. srqn(%u)\n", srq->srqn);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_srq_delete), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "(%u)Alloc cqm_cmd_inoutbuf failed, ret(%d)\n",
+ srq->srqn, ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_srq_delete *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_srq_delete_ctx(cmd_buf, srq, comp_priv);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SRQ_DELETE_CTX, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "(%u)Send DELETE_SRQ command failed, ret(%d)\n",
+ srq->srqn, ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static u8 udma_cal_srq_container_num(u32 avail_wr, struct udma_srq *srq)
+{
+ u32 container_num = 0;
+ u32 srqe_num = 0;
+
+ /* cal container_num by avail_wr from user */
+ srqe_num = srq->container_size - 1;
+
+ /* explain the formula: round up by srqe_num */
+ container_num =
+ (srqe_num == 0) ? 0 : ((avail_wr + srqe_num - 1) / srqe_num);
+ if (container_num == 0)
+ return 0;
+
+ container_num = (u32)roundup_pow_of_two(container_num);
+ return (u8)ilog2(container_num);
+}
+
+void udma_fill_cmd_srq_modify_ctx(struct ub_cmd_srq_modify *cmd_buf,
+ struct udma_srq *srq, u8 container_warn_th)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_srq_modify);
+ u8 warh = 0;
+
+ cmd_buf->body.jfr_id = srq->jfr_id;
+ cmd_buf->body.dw0.bs.cont_en = srq->container_flag;
+ cmd_buf->body.dw0.bs.th_up_en =
+ 1; //Valid for setting up container warn_threshold
+ warh = udma_cal_srq_container_num(container_warn_th, srq);
+ cmd_buf->body.dw0.bs.warth = warh & UB_SRQ_CONTAINER_WARTH_MASK;
+
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SRQ,
+ UB_CMD_SRQ_MODIFY_CTX, cmd_len, srq->srqn);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+}
+
+int udma_cmd_srq_modify_ctx(struct udma_device *udma_dev, struct udma_srq *srq,
+ u8 container_warn_th)
+{
+ struct ub_cmd_srq_modify *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret = 0;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_srq_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "(%u)Alloc cqm_cmd_inoutbuf failed, ret(%d)\n",
+ srq->srqn, ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_srq_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_srq_modify_ctx(cmd_buf, srq, container_warn_th);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SRQ_MODIFY_CTX, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "(%u)Send MODIFY_SRQ command failed, ret(%d)\n",
+ srq->srqn, ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_srq_query_ctx(struct udma_device *udma_dev, u32 srqn,
+ ub_cmd_srq_query_rsp_s *srq_entry)
+{
+ struct ub_cmd_srq_query *cmd_buf = NULL;
+ ub_cmd_srq_query_rsp_s *srq_query_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_srq_query);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_srq_query),
+ &cqm_cmd_outbuf,
+ (u16)sizeof(ub_cmd_srq_query_rsp_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "(%u)Alloc cqm_cmd_inoutbuf failed, ret(%d)\n", srqn,
+ ret);
+ return -ENOMEM;
+ }
+
+ cmd_buf = (struct ub_cmd_srq_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&cmd_buf->header, UB_CMD_TYPE_SRQ,
+ UB_CMD_SRQ_QUERY_CTX, cmd_len, srqn);
+ udma_cpu_to_be32(cmd_buf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SRQ_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Failed to send cmd QUERY_SRQ, ret=%d", ret);
+ ret = -EIO;
+ goto out;
+ }
+
+ srq_query_outbuf = (ub_cmd_srq_query_rsp_s *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s(srq_entry, sizeof(ub_cmd_srq_query_rsp_s),
+ srq_query_outbuf, sizeof(ub_cmd_srq_query_rsp_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ, "memcpy_s failed, ret=%d\n",
+ ret);
+ ret = -EFAULT;
+ goto out;
+ }
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+ return ret;
+}
+
+static void
+udma_fill_cmd_srq_batch_modify_ctx(struct ub_cmd_body_srq_batch_modify *body,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ body->offset = inbuf->offset;
+ body->length = inbuf->length;
+
+ udma_cpu_to_be32(body, sizeof(struct ub_cmd_body_srq_batch_modify));
+
+ udma_cmdq_data_to_context_buf(inbuf->data, inbuf->data_len,
+ (u8 *)&body->srq_ctx,
+ sizeof(body->srq_ctx) / sizeof(u8),
+ inbuf->offset);
+}
+
+int udma_cmd_srq_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_srq_batch_modify);
+ struct ub_cmd_srq_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Alloc cqm_cmd_inoutbuf failed, ret(%d)\n", ret);
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct ub_cmd_srq_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_SRQ,
+ UB_CMD_SRQ_BATCH_MODIFY_CTX, cmd_len, inbuf->xid);
+ udma_cpu_to_be32(modify_cmd, sizeof(modify_cmd->header));
+
+ udma_fill_cmd_srq_batch_modify_ctx(&modify_cmd->body, inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_SRQ_BATCH_MODIFY_CTX,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Failed to send cmd SRQ_BATCH_MODIFY_CTX, ret=%d",
+ ret);
+ goto err_send_cmd;
+ }
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.h
new file mode 100644
index 000000000..981843091
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_srq.h
@@ -0,0 +1,22 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_SRQ_H
+#define UDMA_CMD_SRQ_H
+
+#include "ub_npu_srq_cmd_defs.h"
+#include "udma_common.h"
+#include "udma_srq.h"
+#include "ub_pub_cmd.h"
+
+int udma_cmd_srq_create_ctx(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct udma_db *sdb);
+int udma_cmd_srq_delete_ctx(struct udma_device *udma_dev, struct udma_srq *srq);
+int udma_cmd_srq_modify_ctx(struct udma_device *udma_dev, struct udma_srq *srq,
+ u8 container_warn_th);
+int udma_cmd_srq_query_ctx(struct udma_device *udma_dev, u32 srqn,
+ ub_cmd_srq_query_rsp_s *srq_entry);
+int udma_cmd_srq_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.c
new file mode 100644
index 000000000..06f268570
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.c
@@ -0,0 +1,1885 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include "ubcore_types.h"
+#include "ub_npu_tp_cmd.h"
+#include "ub_npu_tp_cmd_defs.h"
+#include "udma_cqm.h"
+#include "udma_db.h"
+#include "udma_net.h"
+#include "udma_tpg.h"
+#include "udma_cmd_com.h"
+#include "udma_tp.h"
+#include "udma_cmd_tp.h"
+
+#define TP_DIP_MASK 0xffffffff //32 bit
+
+#define TP_DEFAULT_OOR_BS 4
+#define TP_RC_NUM 0x2
+
+bool g_must_check_token_en = 0;
+
+module_param(g_must_check_token_en, bool,
+ (S_IRUSR | S_IRGRP | S_IROTH)); //0444
+
+static int udma_tp_get_oor_bs(struct udma_device *udma_dev, u32 oor_cnt)
+{
+ u32 udma_tp_bitmap_level[] = { UDMA_TP_OOR_64, UDMA_TP_OOR_128,
+ UDMA_TP_OOR_256, UDMA_TP_OOR_512,
+ UDMA_TP_OOR_1024 };
+ int i;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter. udma_dev(%d) .\n",
+ !!udma_dev);
+ return -EINVAL;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: tp oor_cnt:%u\n", __func__,
+ oor_cnt);
+
+ for (i = 0;
+ i < sizeof(udma_tp_bitmap_level) / sizeof(udma_tp_bitmap_level[0]);
+ i++) {
+ if (oor_cnt == udma_tp_bitmap_level[i])
+ return i;
+ }
+
+ return TP_DEFAULT_OOR_BS; //default:4 contrast:1024
+}
+
+static void udma_cmd_tp_create_chip_seg_fill(struct tag_ub_tp_chip *chip_seg,
+ struct udma_tp *ub_tp)
+{
+ u64 tmp = 0;
+
+ /* QPCC */
+ if (ub_tp->kdb != NULL) {
+ chip_seg->dw2.bs.sq_rq_pi_record_gpa_hi =
+ upper_32_bits(ub_tp->kdb->dma);
+ chip_seg->dw2.bs.sq_rq_pi_record_gpa_lo_at_hop_num =
+ lower_32_bits(ub_tp->kdb->dma) & (~0x3ULL); //bits:31-2
+ }
+
+ chip_seg->dw0.bs.sq_rq_l0mtt_gpa_hi =
+ upper_32_bits(ub_tp->ub_mtt.mtt_paddr);
+ chip_seg->dw0.bs.sq_rq_l0mtt_gpa_lo =
+ lower_32_bits(ub_tp->ub_mtt.mtt_paddr);
+ chip_seg->dw2.bs.sq_rq_pi_record_gpa_lo_at_hop_num |=
+ ub_tp->ub_mtt.mtt_layers & 0x3; //bits:1-0
+ chip_seg->dw4.bs.sq_rq_mtt_page_size =
+ ub_tp->ub_mtt.mtt_page_shift - PAGE_SHIFT_4K;
+
+ if (ub_tp->entry_cnt != 0) {
+ tmp = roundup_pow_of_two(ub_tp->entry_cnt);
+ chip_seg->dw4.bs.rq_base_ci = ((u32)ilog2((u32)tmp)) &
+ TP_SQ_SIZE_MASK;
+ }
+ chip_seg->dw4.bs.rrw_mtt_prefetch_maxlen = 0;
+ chip_seg->dw4.bs.sq_wqe_prefetch_mode = 0;
+ chip_seg->dw4.bs.sq_mtt_prefetch_maxlen = 0;
+ chip_seg->dw4.bs.sqa_mtt_prefetch_maxlen = 0;
+ chip_seg->dw4.bs.rc_entry_prefetch_maxnum = 0;
+ chip_seg->dw4.bs.rc_mtt_prefetch_maxlen = TP_QP_MAX_PFETCH_MTT_LAYER;
+ chip_seg->dw4.bs.qp_rkey_en = 1;
+ chip_seg->dw4.bs.sq_wqebb_size =
+ ((u32)(TP_WQE_SHIFT - TP_WQEBB_SIZE_SHIFT)) &
+ TP_WQEBB_SIZE_MASK;
+ chip_seg->dw4.bs.sq_rkey_en = 1;
+
+ if (ub_tp->entry_cnt != 0) {
+ tmp = roundup_pow_of_two(ub_tp->entry_cnt);
+ chip_seg->dw5.bs.sq_size = ((u32)ilog2((u32)tmp)) &
+ TP_SQ_SIZE_MASK;
+ }
+ chip_seg->dw5.bs.sq_pi_on_chip = 0;
+
+ chip_seg->dw5.bs.sq_wqecnt_lth = TP_SQ_WQECNT_LTH;
+ chip_seg->dw5.bs.sq_wqecnt_rctl_en = 0;
+ chip_seg->dw5.bs.sq_wqecnt_rctl = 0;
+ chip_seg->dw5.bs.sq_wqe_prefetch_minnum = TP_SQ_PREFETCH_MINNUM;
+ chip_seg->dw5.bs.sq_wqe_prefetch_maxnum = TP_SQ_PREFETCH_MAXNUM;
+ chip_seg->dw5.bs.sq_wqe_cache_thd_sel = 0;
+ chip_seg->dw5.bs.sqa_wqe_prefetch_minnum = TP_SQ_PREFETCH_MINNUM;
+ chip_seg->dw5.bs.sqa_wqe_prefetch_maxnum = TP_WQE_PREFETCH_MAXNUM;
+ chip_seg->dw5.bs.sqa_wqe_cache_thd_sel = 0;
+ chip_seg->dw5.bs.sq_inline_en = 1;
+}
+
+static void udma_cmd_tp_create_sw_fill(struct ubcore_device *ub_dev,
+ struct tag_tp_sw_ctx *tp_sw,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct udma_tpg *ub_tpg = NULL;
+ u32 i;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return;
+ }
+
+ /* dw0 */
+ if (ub_tp->tp_info != NULL) {
+ tp_sw->srctpn = ub_tp->tp_info->xid;
+ }
+ tp_sw->retry_factor = cfg->retry_factor;
+ tp_sw->state = UB_TPC_STATE_RST;
+ tp_sw->transport_mode = (cfg->trans_mode == UBCORE_TP_UM) ?
+ UB_TRANSPORT_MODE_UM :
+ ((cfg->trans_mode == UBCORE_TP_RM) ?
+ UB_TRANSPORT_MODE_RM :
+ UB_TRANSPORT_MODE_RC);
+ /* dw1 */
+ tp_sw->tp_retry_num = cfg->retry_num;
+ tp_sw->tp_timeout = cfg->ack_timeout;
+ tp_sw->oor_bitmap_size =
+ (u32)udma_tp_get_oor_bs(udma_dev, cfg->oor_cnt);
+ /* dw3 */
+ tp_sw->loopback = cfg->flag.bs.loopback;
+ tp_sw->ep_id = udma_dev->hw_info.ep_id;
+ tp_sw->must_check_token_en = g_must_check_token_en;
+ tp_sw->jetty_id = cfg->local_jetty.id;
+
+ if (cfg->flag.bs.ack_resp == 0 && cfg->tpg != NULL) {
+ for (i = 0; i < TP_RC_NUM; i++) {
+ ub_tpg = container_of(cfg->tpg, struct udma_tpg, tpg);
+ if (ub_tpg->tpinfo_list[i]->xid != ub_tp->tp.tpn) {
+ tp_sw->rsp_tpgn = ub_tpg->tpinfo_list[i]->xid;
+ break;
+ }
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "rsp_tpgn: %u\n",
+ tp_sw->rsp_tpgn);
+ }
+ /* dw5 */
+ tp_sw->suspend_cnt = udma_dev->suspend_cnt;
+ /* dw6 */
+ tp_sw->suspend_period = udma_dev->suspend_period;
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw0_value(0x%08x)\n",
+ __func__, tp_sw->dw0_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw1_value(0x%08x)\n",
+ __func__, tp_sw->dw1_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw2_value(0x%08x)\n",
+ __func__, tp_sw->dw2_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw3_value(0x%08x)\n",
+ __func__, tp_sw->dw3_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw4_value(0x%08x)\n",
+ __func__, tp_sw->dw4_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: suspend_cnt(0x%08x)\n",
+ __func__, tp_sw->suspend_cnt);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: suspend_period(0x%08x)\n",
+ __func__, tp_sw->suspend_period);
+}
+
+static void udma_cmd_tp_create_body_fill(struct ubcore_device *ub_dev, u32 cnt,
+ struct ub_cmd_tp_create_body *body,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp[])
+{
+ u32 i;
+
+ body->num = cnt;
+
+ for (i = 0; i < cnt; i++) {
+ udma_cmd_tp_create_chip_seg_fill(&body->tp_attr[i].chip_seg,
+ ub_tp[i]);
+ udma_cmd_tp_create_sw_fill(ub_dev, &body->tp_attr[i].tpc_com,
+ cfg + i, ub_tp[i]);
+ }
+}
+
+/* return value: cmd tp create success of count */
+u32 udma_cmd_tp_create_ctx(struct ubcore_device *ub_dev, u32 cnt,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp[])
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ u16 cmd_len = sizeof(struct ub_cmd_tp_create);
+ struct ub_cmd_tp_create *tp_cmd_in = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ struct cmdq_rtt *cmdq_rtt = NULL;
+ u32 *cmd_out_num = NULL;
+ u32 ret_num;
+ int ret;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return 0;
+ }
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "%s to_udma_dev failed.\n", __func__);
+ return 0;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_create),
+ &buf_out, sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: allocate cqm inbuf failed\n", __func__);
+ return 0;
+ }
+
+ tp_cmd_in = (struct ub_cmd_tp_create *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd_in->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_CREATE_CTX, cmd_len,
+ 0); //xid fill 0 not affect, actual xid in body in passed in
+
+ udma_cmd_tp_create_body_fill(ub_dev, cnt, &tp_cmd_in->body, cfg, ub_tp);
+
+ udma_cpu_to_be32(tp_cmd_in, cmd_len);
+
+ cmd_out_num = (u32 *)buf_out->buf;
+
+ cmdq_rtt = (cfg->tpg == NULL) ? &ub_tp[0]->cmdq_rtt :
+ &to_udma_tpg(cfg->tpg)->cmdq_rtt;
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_CREATE_CTX, buf_in, buf_out,
+ NULL, cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: send cqm cmd failed, ret(%d)\n", __func__, ret);
+ }
+
+ ret_num = be32_to_cpu(*cmd_out_num);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret_num;
+}
+
+static void
+udma_fill_update_attr_mask(const union ubcore_tp_attr_mask *mask,
+ struct tag_ub_tp_modify_attr *modify_attr)
+{
+ modify_attr->attr_mask.bs.flag = mask->bs.flag;
+ modify_attr->attr_mask.bs.peer_tpn = mask->bs.peer_tpn;
+ modify_attr->attr_mask.bs.state = mask->bs.state;
+ modify_attr->attr_mask.bs.tx_psn = mask->bs.tx_psn;
+ modify_attr->attr_mask.bs.rx_psn = mask->bs.rx_psn;
+ modify_attr->attr_mask.bs.mtu = mask->bs.mtu;
+ modify_attr->attr_mask.bs.cc_pattern_idx = mask->bs.cc_pattern_idx;
+ modify_attr->attr_mask.bs.oos_cnt = mask->bs.oos_cnt;
+ modify_attr->attr_mask.bs.local_net_addr_idx =
+ mask->bs.local_net_addr_idx;
+ modify_attr->attr_mask.bs.peer_net_addr = mask->bs.peer_net_addr;
+ modify_attr->attr_mask.bs.data_udp_start = mask->bs.data_udp_start;
+ modify_attr->attr_mask.bs.ack_udp_start = mask->bs.ack_udp_start;
+ modify_attr->attr_mask.bs.udp_range = mask->bs.udp_range;
+ modify_attr->attr_mask.bs.hop_limit = mask->bs.hop_limit;
+ modify_attr->attr_mask.bs.flow_label = mask->bs.flow_label;
+ modify_attr->attr_mask.bs.port = mask->bs.port_id;
+ modify_attr->attr_mask.bs.mn = mask->bs.mn;
+}
+
+static ub_cc_algo_e udma_get_ub_cc_alg(struct udma_device *udma_dev,
+ enum ubcore_tp_cc_alg cc_alg)
+{
+ switch (cc_alg) {
+ case UBCORE_TP_CC_DCQCN:
+ return UB_CC_ALGO_DCQCN;
+ case UBCORE_TP_CC_LDCP:
+ return UB_CC_ALGO_LDCP;
+ case UBCORE_TP_CC_CAQM:
+ return UB_CC_ALGO_CAQM;
+ case UBCORE_TP_CC_LDCP_L2_HEADER:
+ return UB_CC_ALGO_LDCP_L2H;
+ case UBCORE_TP_CC_LDCP_TP_HEADER:
+ return UB_CC_ALGO_LDCP_TPH;
+ case UBCORE_TP_CC_CUSTOM_1:
+ return UB_CC_ALGO_USER_1;
+ case UBCORE_TP_CC_CUSTOM_2:
+ return UB_CC_ALGO_USER_2;
+ default:
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "the configured cc_alg is currently not supported\n");
+ return UB_CC_ALGO_MAX;
+ }
+}
+
+static void udma_fill_droute_attr(struct udma_device *udma_dev,
+ const struct udma_tp *ub_tp,
+ const union ubcore_tp_attr_mask *mask,
+ const struct ubcore_tp_attr *attr,
+ struct tag_ub_tp_modify_attr *modify_attr)
+{
+ vlan_u vlan_value = { 0 };
+
+ if (mask->bs.peer_net_addr == 1) {
+ /* Note: cmd send before will uniformly perform cpu_to_be32 convert, here dip original this then is big-endian sequence, no need convert to big-endian;
+ * 因 this here 先 be32_to_cpu, 这 样 after cpu_to_be32 就 keep 最 初 of value (done) */
+ if (attr->peer_net_addr.type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: peer is call ipv4\n", __func__);
+ modify_attr->droute.dip3 = be32_to_cpu(
+ attr->peer_net_addr.net_addr.in4.addr);
+ } else {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: peer is call ipv6\n", __func__);
+ /* dip0 - dip3 */
+ modify_attr->droute.dip0 = be32_to_cpu(
+ attr->peer_net_addr.net_addr.in6.subnet_prefix &
+ TP_DIP_MASK);
+ modify_attr->droute.dip1 =
+ be32_to_cpu((attr->peer_net_addr.net_addr.in6
+ .subnet_prefix >>
+ 32) &
+ TP_DIP_MASK); //take upper 32 bit
+ modify_attr->droute.dip2 = be32_to_cpu(
+ attr->peer_net_addr.net_addr.in6.interface_id &
+ TP_DIP_MASK);
+ modify_attr->droute.dip3 = be32_to_cpu(
+ (attr->peer_net_addr.net_addr.in6.interface_id >>
+ 32) &
+ TP_DIP_MASK); //take upper 32 bit
+ }
+
+ /* dw0 */
+ modify_attr->droute.ack_udp_srcport =
+ (mask->bs.ack_udp_start == 1) ?
+ attr->ack_udp_start :
+ modify_attr->droute.ack_udp_srcport;
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: modify ack_udp_start:0x%x\n", __func__,
+ attr->ack_udp_start);
+ modify_attr->droute.dmac_h16 =
+ UDMA_GET_MAC_HI(attr->peer_net_addr.mac[0x0],
+ attr->peer_net_addr.mac[0x1]);
+ /* dmac */
+ modify_attr->droute.dmac_l32 =
+ UDMA_GET_MAC_LO(attr->peer_net_addr.mac[0x2],
+ attr->peer_net_addr.mac[0x3],
+ attr->peer_net_addr.mac[0x4],
+ attr->peer_net_addr.mac[0x5]);
+ /* dw6 */
+ modify_attr->droute.tclass =
+ (ub_tp->pri & 0x3f) << 0x2 |
+ 0x2; //ub and roce return one, high 6 bit store dscp, low 2 bit is ecn
+ modify_attr->droute.flow_label =
+ (mask->bs.flow_label == 1) ?
+ attr->flow_label :
+ modify_attr->droute.flow_label;
+ /* dw7 */
+ vlan_value.value = (u16)attr->peer_net_addr.vlan;
+ modify_attr->droute.sl = ub_tp->pri & 0x7;
+ modify_attr->droute.vlan_id = vlan_value.bs.vlan;
+ modify_attr->droute.hoplmt = (mask->bs.hop_limit == 1) ?
+ attr->hop_limit :
+ modify_attr->droute.hoplmt;
+ /* enable vlan */
+ if (modify_attr->droute.vlan_id != 0) {
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: vlan en\n",
+ __func__);
+ modify_attr->attr_mask.bs.vlan_en = 1;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: peer vlan:%llu\n",
+ __func__, attr->peer_net_addr.vlan);
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw0:0x%x\n", __func__,
+ modify_attr->droute.dw0_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dmac_l32:0x%x\n",
+ __func__, modify_attr->droute.dmac_l32);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dsip0:0x%x\n",
+ __func__, modify_attr->droute.dip0);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dsip1:0x%x\n",
+ __func__, modify_attr->droute.dip1);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dsip2:0x%x\n",
+ __func__, modify_attr->droute.dip2);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dsip3:0x%x\n",
+ __func__, modify_attr->droute.dip3);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw6:0x%x\n", __func__,
+ modify_attr->droute.dw6_value);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: dw7:0x%x\n", __func__,
+ modify_attr->droute.dw7_value);
+ }
+}
+
+static void udma_fill_update_attr(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp,
+ const union ubcore_tp_attr_mask *mask,
+ const struct ubcore_tp_attr *attr,
+ struct tag_ub_tp_modify_attr *modify_attr)
+{
+ modify_attr->tpn = ub_tp->tp.tpn;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter. udma_dev(%d) .\n",
+ !!udma_dev);
+ return;
+ }
+
+ /* determine no need cmdq microcode handle, other attr then no need continue assignment */
+ if (mask->bs.state == 1 && ub_tp->tp.state == UBCORE_TP_STATE_ERR &&
+ attr->state == UBCORE_TP_STATE_ERR) {
+ modify_attr->attr_mask.bs.cmd_ignore = 1;
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "%s: tp state is already ERR\n", __func__);
+ return;
+ }
+
+ if (mask->bs.flag == 1) {
+ modify_attr->oor_en = attr->flag.bs.oor_en;
+ modify_attr->sr_en = attr->flag.bs.sr_en;
+ modify_attr->cc_en = attr->flag.bs.cc_en;
+ modify_attr->cc_alg =
+ udma_get_ub_cc_alg(udma_dev, attr->flag.bs.cc_alg);
+ modify_attr->spray_en = attr->flag.bs.spray_en;
+ }
+
+ if (mask->bs.state == 1) {
+ modify_attr->state = attr->state;
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "tpn:%u, change state:%u\n", ub_tp->tp.tpn,
+ attr->state);
+ }
+
+ if (mask->bs.local_net_addr_idx == 1) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: local index(%d), cos(%d)\n", __func__,
+ attr->local_net_addr_idx, ub_tp->cos);
+ modify_attr->local_net_addr_idx = attr->local_net_addr_idx;
+ modify_attr->cos = ub_tp->cos;
+ }
+
+ modify_attr->tpgn = ((ub_tp->tp.tpg != NULL) &&
+ (ub_tp->tp.trans_mode == UBCORE_TP_RM)) ?
+ ub_tp->tp.tpg->tpgn :
+ UB_INVALID_TPGN;
+ modify_attr->peer_tpn = (mask->bs.peer_tpn == 1) ?
+ attr->peer_tpn :
+ modify_attr->peer_tpn;
+ modify_attr->tx_psn = (mask->bs.tx_psn == 1) ? attr->tx_psn :
+ modify_attr->tx_psn;
+ modify_attr->rx_psn = (mask->bs.rx_psn == 1) ? attr->rx_psn :
+ modify_attr->rx_psn;
+ modify_attr->mtu = (mask->bs.mtu == 1) ? attr->mtu : modify_attr->mtu;
+ modify_attr->cc_pattern_idx = (mask->bs.cc_pattern_idx == 1) ?
+ attr->cc_pattern_idx :
+ modify_attr->cc_pattern_idx;
+ modify_attr->oos_cnt = (mask->bs.oos_cnt == 1) ? attr->oos_cnt :
+ modify_attr->oos_cnt;
+ modify_attr->data_udp_start = (mask->bs.data_udp_start == 1) ?
+ attr->data_udp_start :
+ modify_attr->data_udp_start;
+ modify_attr->udp_range = (mask->bs.udp_range == 1) ?
+ attr->udp_range :
+ modify_attr->udp_range;
+ modify_attr->port = (mask->bs.port_id == 1) ? attr->port_id :
+ modify_attr->port;
+ modify_attr->mn = (mask->bs.mn == 1) ? attr->mn : modify_attr->mn;
+
+ udma_fill_update_attr_mask(mask, modify_attr);
+
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: peer_tpn(0x%x), mask->peer_tpn(0x%x), srctpn(0x%x)\n",
+ __func__, modify_attr->peer_tpn, mask->bs.peer_tpn,
+ ub_tp->tp.tpn);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: port(%u)\n", __func__,
+ modify_attr->port);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: modify attr 0x%x\n", __func__,
+ modify_attr->dw3_value);
+}
+
+static void udma_fill_cmd_tp_modify(u32 cnt, struct ubcore_tp **tp,
+ const struct ubcore_tp_attr *attr,
+ const union ubcore_tp_attr_mask *mask,
+ struct ub_cmd_tp_modify *tp_cmd)
+{
+ struct tag_ub_tp_modify_attr *modify_attr = tp_cmd->body.attr;
+ struct udma_device *udma_dev = to_udma_dev(tp[0]->ub_dev);
+ struct udma_tp *ub_tp = NULL;
+ u32 i;
+ if (tp[0]->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter: ub_dev(%d).\n",
+ !!tp[0]->ub_dev);
+ return;
+ }
+
+ tp_cmd->body.num = cnt;
+
+ for (i = 0; i < cnt; ++i) {
+ ub_tp = container_of(tp[i], struct udma_tp, tp);
+ udma_fill_update_attr(udma_dev, ub_tp, &mask[i], &attr[i],
+ &modify_attr[i]);
+ if (modify_attr[i].attr_mask.bs.cmd_ignore ==
+ 0) //need cmdq microcode handle, then continue assignment droute
+ udma_fill_droute_attr(udma_dev, ub_tp, &mask[i],
+ &attr[i], &modify_attr[i]);
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s:dw0:0x%x\n", __func__,
+ modify_attr[i].droute.dw0_value);
+ }
+}
+
+static void udma_fill_local_en(struct udma_device *udma_dev, u32 cnt,
+ struct ub_cmd_tp_modify *tp_cmd)
+{
+ u32 i;
+
+ for (i = 0; i < cnt; ++i)
+ tp_cmd->body.attr[i].attr_mask.bs.local_en = udma_dev->local_en;
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: TP fill local en:%u\n",
+ __func__, udma_dev->local_en);
+}
+
+static u32 udma_cmd_tp_cmd_ignore_num_cal(const struct ub_cmd_tp_modify *tp_cmd,
+ u32 cnt)
+{
+ u32 cmd_ignore_num = 0;
+ u32 i;
+
+ for (i = 0; i < cnt; i++) {
+ if (tp_cmd->body.attr[i].attr_mask.bs.cmd_ignore == 1)
+ ++cmd_ignore_num;
+ }
+
+ return cmd_ignore_num;
+}
+
+/* input @cnt: send down modify cmd of tp count
+ * return: send down cmd success of tp count
+ * note: input parameter tp, attr, mask may is alreadypast offset of address, non- ubcore passed in of start address, specific see function be call of code
+ */
+u32 udma_cmd_tp_modify_ctx(u32 cnt, struct ubcore_tp **tp,
+ const struct ubcore_tp_attr *attr,
+ const union ubcore_tp_attr_mask *mask)
+{
+ struct udma_device *udma_dev = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_modify);
+ struct ub_cmd_tp_modify *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ struct cmdq_rtt *cmdq_rtt = NULL;
+ u32 *cmd_out_num = NULL;
+ u32 modify_num = 0;
+ int ret;
+
+ if (tp[0]->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "%s Invalid parameter: ub_dev(%d).\n",
+ __func__, !!tp[0]->ub_dev);
+ return 0;
+ }
+
+ udma_dev = to_udma_dev(tp[0]->ub_dev);
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "%s to_udma_dev failed.\n", __func__);
+ return 0;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_modify),
+ &buf_out, sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: modify tp: failed to allocate cqm inbuf\n",
+ __func__);
+ return 0;
+ }
+
+ cmd_out_num = (u32 *)buf_out->buf;
+ tp_cmd = (struct ub_cmd_tp_modify *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_MODIFY_CTX, cmd_len,
+ 0); // actual xid in body in, here only is default fill 0
+
+ udma_fill_local_en(udma_dev, cnt, tp_cmd);
+ udma_fill_cmd_tp_modify(cnt, tp, attr, mask, tp_cmd);
+
+ /* if all tp all no need cmdq microcode handle, then directly return */
+ if (udma_cmd_tp_cmd_ignore_num_cal(tp_cmd, cnt) == cnt) {
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: all tp don't need send cmd, cnt(%u)\n", __func__,
+ cnt);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+ return cnt;
+ }
+
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+ cmdq_rtt = (tp[0]->tpg == NULL) ? &to_udma_tp(tp[0])->cmdq_rtt :
+ &to_udma_tpg(tp[0]->tpg)->cmdq_rtt;
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_MODIFY_CTX, buf_in, buf_out,
+ NULL, cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: modify tp ctx failed, ret(%d)\n", __func__, ret);
+ }
+
+ modify_num = be32_to_cpu(*cmd_out_num);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "%s: modify_num(%u), cnt(%u)\n",
+ __func__, modify_num, cnt);
+
+ return modify_num;
+}
+
+static void
+udma_cmd_tp_modify_dfx_print(struct udma_device *udma_dev,
+ const struct tag_ub_tp_modify_attr *modify_attr)
+{
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: state: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.state, modify_attr->state);
+ udma_info(
+ udma_dev->dev, UDMA_M_TP,
+ "%s: flag: mask(0x%x), oor_en(0x%x), sr_en(0x%x), spray_en(0x%x)\n",
+ __func__, modify_attr->attr_mask.bs.flag, modify_attr->oor_en,
+ modify_attr->sr_en, modify_attr->spray_en);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: flag: mask(0x%x), cc_en(0x%x), cc_alg(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.flag, modify_attr->cc_en,
+ modify_attr->cc_alg);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: cc_pattern_idx: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.cc_pattern_idx,
+ modify_attr->cc_pattern_idx);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: mtu: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.mtu, modify_attr->mtu);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: rx_psn: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.rx_psn, modify_attr->rx_psn);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: tx_psn: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.tx_psn, modify_attr->tx_psn);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: peer_tpn: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.peer_tpn, modify_attr->peer_tpn);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: sq_err_state: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.sq_err_state,
+ modify_attr->sq_err_state);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: sqa_err_state: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.sqa_err_state,
+ modify_attr->sqa_err_state);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: rq_err_state: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.rq_err_state,
+ modify_attr->rq_err_state);
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: rqa_err_state: mask(0x%x), value(0x%x)\n", __func__,
+ modify_attr->attr_mask.bs.rqa_err_state,
+ modify_attr->rqa_err_state);
+}
+
+static void
+udma_fill_cmd_tp_modify_dfx(struct udma_device *udma_dev, struct udma_tp *ub_tp,
+ const struct udma_tp_modify_dfx *tp_dfx,
+ struct tag_ub_tp_modify_attr *modify_attr)
+{
+ modify_attr->tpn = ub_tp->tp.tpn;
+
+ /* status modify will cause other field of modify, is ensure modify of 准correct validity, constraint: modify status when cannot modify other field */
+ if (tp_dfx->mask.state == 1) {
+ modify_attr->attr_mask.bs.state = tp_dfx->mask.state;
+ modify_attr->state = tp_dfx->attr.state;
+ modify_attr->tpgn = ((ub_tp->tp.tpg != NULL) &&
+ (ub_tp->tp.trans_mode == UBCORE_TP_RM)) ?
+ ub_tp->tp.tpg->tpgn :
+ UB_INVALID_TPGN;
+ udma_cmd_tp_modify_dfx_print(udma_dev, modify_attr);
+ return;
+ }
+
+ modify_attr->attr_mask.bs.flag = tp_dfx->mask.flag;
+ modify_attr->oor_en = tp_dfx->attr.oor_en;
+ modify_attr->sr_en = tp_dfx->attr.sr_en;
+ modify_attr->cc_en = tp_dfx->attr.cc_en;
+ modify_attr->cc_alg = udma_get_ub_cc_alg(udma_dev, tp_dfx->attr.cc_alg);
+ modify_attr->spray_en = tp_dfx->attr.spray_en;
+
+ modify_attr->attr_mask.bs.cc_pattern_idx = tp_dfx->mask.cc_pattern_idx;
+ modify_attr->cc_pattern_idx = tp_dfx->attr.cc_pattern_idx;
+ modify_attr->attr_mask.bs.mtu = tp_dfx->mask.mtu;
+ modify_attr->mtu = tp_dfx->attr.mtu;
+ modify_attr->attr_mask.bs.rx_psn = tp_dfx->mask.rx_psn;
+ modify_attr->rx_psn = tp_dfx->attr.rx_psn;
+ modify_attr->attr_mask.bs.tx_psn = tp_dfx->mask.tx_psn;
+ modify_attr->tx_psn = tp_dfx->attr.tx_psn;
+ modify_attr->attr_mask.bs.peer_tpn = tp_dfx->mask.peer_tpn;
+ modify_attr->peer_tpn = tp_dfx->attr.peer_tpn;
+ modify_attr->attr_mask.bs.sq_err_state = tp_dfx->mask.sq_err_state;
+ modify_attr->sq_err_state = tp_dfx->attr.sq_err_state;
+ modify_attr->attr_mask.bs.sqa_err_state = tp_dfx->mask.sqa_err_state;
+ modify_attr->sqa_err_state = tp_dfx->attr.sqa_err_state;
+ modify_attr->attr_mask.bs.rq_err_state = tp_dfx->mask.rq_err_state;
+ modify_attr->rq_err_state = tp_dfx->attr.rq_err_state;
+ modify_attr->attr_mask.bs.rqa_err_state = tp_dfx->mask.rqa_err_state;
+ modify_attr->rqa_err_state = tp_dfx->attr.rqa_err_state;
+ udma_cmd_tp_modify_dfx_print(udma_dev, modify_attr);
+}
+
+/* dfx path, used for tool modify tp ctx in specifies field */
+int udma_cmd_tp_modify_dfx(struct udma_device *udma_dev, struct udma_tp *ub_tp,
+ const struct udma_tp_modify_dfx *tp_dfx)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tp_modify);
+ struct ub_cmd_tp_modify *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_out =
+ NULL; /* microcode will return modify success count of need out buf */
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ u32 *cmd_out_num = NULL;
+ int ret = 0;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_modify),
+ &buf_out, sizeof(u32));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: modify tp: failed to allocate cqm inbuf\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ cmd_out_num = (u32 *)buf_out->buf;
+ tp_cmd = (struct ub_cmd_tp_modify *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_MODIFY_CTX, cmd_len,
+ 0); //actual xid in body in, here only is default fill 0
+ tp_cmd->body.num = 1;
+ udma_fill_cmd_tp_modify_dfx(udma_dev, ub_tp, tp_dfx,
+ &tp_cmd->body.attr[0]);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_MODIFY_CTX, buf_in, buf_out,
+ NULL, NULL);
+ if (ret != 0 || *cmd_out_num == 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: modify tp ctx failed, ret(%d) modify_num(%d)\n",
+ __func__, ret, *cmd_out_num);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
+
+static void udma_fill_cmd_tp_cc_modify(struct tag_ub_cmd_tp_cc_modify *tp_cmd,
+ const struct tag_ub_cc_attr *cc_attr)
+{
+ tp_cmd->body.attr.inject_mode = cc_attr->cc_inject_mode;
+ tp_cmd->body.attr.percent = cc_attr->cc_percent;
+ tp_cmd->body.attr.prm_limit_l = cc_attr->cc_limit_low;
+ tp_cmd->body.attr.prm_limit_h = cc_attr->cc_limit_high;
+}
+
+int udma_cmd_tp_cc_modify(struct udma_device *udma_dev,
+ const struct tag_ub_cc_attr *cc_attr)
+{
+ u16 cmd_len = sizeof(struct tag_ub_cmd_tp_cc_modify);
+ struct tag_ub_cmd_tp_cc_modify *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct tag_ub_cmd_tp_cc_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct tag_ub_cmd_tp_cc_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_MODIFY_TP_CC, cmd_len, cc_attr->tpn);
+ udma_fill_cmd_tp_cc_modify(tp_cmd, cc_attr);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_MODIFY_TP_CC, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, tpn(0x%x), ret = %d.\n",
+ cc_attr->tpn, ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "%s: success, tpn(0x%x), inject mode: %u\n", __func__,
+ cc_attr->tpn, cc_attr->cc_inject_mode);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tp_modify_tp_srp_bitmap(struct udma_device *udma_dev,
+ u32 tp_srp_index, u32 bitmap_index,
+ u32 bitmap_mode)
+{
+ u16 cmd_len = sizeof(struct tag_ub_cmd_tp_srp_modify);
+ struct tag_ub_cmd_tp_srp_modify *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct tag_ub_cmd_tp_srp_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "udma_cmd_tp_modify_tp_srp_bitmap failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct tag_ub_cmd_tp_srp_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_MODIFY_SRP_BITMAP, cmd_len, 0);
+ tp_cmd->body.attr.bitmap_index = bitmap_index;
+ tp_cmd->body.attr.tp_srp_index = tp_srp_index;
+ tp_cmd->body.attr.bitmap_mode = bitmap_mode;
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_MODIFY_SRP_BITMAP,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, ret = %d.\n", ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "modify tp srp bitmap success\n");
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tp_modify_srp_ctr_bitmap(struct udma_device *udma_dev,
+ u32 ctr_bitmap_index, u32 bitmap_mode)
+{
+ u16 cmd_len = sizeof(struct tag_ub_cmd_tp_srp_modify);
+ struct tag_ub_cmd_tp_srp_modify *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct tag_ub_cmd_tp_srp_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "udma_cmd_tp_modify_srp_ctr_bitmap failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct tag_ub_cmd_tp_srp_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_MODIFY_SRP_CTR_BITMAP, cmd_len, 0);
+ tp_cmd->body.attr.ctr_bitmap_index = ctr_bitmap_index;
+ tp_cmd->body.attr.bitmap_mode = bitmap_mode;
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_MODIFY_SRP_CTR_BITMAP,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, ret = %d.\n", ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "modify tp srp ctr bitmap success\n");
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_cc_info(struct udma_device *udma_dev, u32 tpn,
+ ub_cc_dfx_info_s *cc_attr)
+{
+ u16 cmd_len = sizeof(struct tag_ub_cmd_tp_cc_query);
+ ub_cc_dfx_info_s *query_outbuf = NULL;
+ struct tag_ub_cmd_tp_cc_query *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &buf_in, sizeof(struct tag_ub_cmd_tp_cc_query),
+ &buf_out, sizeof(ub_cc_dfx_info_s));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp cc info res: failed to allocate cqm inoutbuf, tpn:0x%x, ret:%u\n",
+ tpn, ret);
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct tag_ub_cmd_tp_cc_query *)buf_in->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_CC_INFO, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_CC_INFO, buf_in,
+ buf_out, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp cc info res: failed to query tp cc info res, tpn:0x%x, ret:%u\n",
+ tpn, ret);
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in,
+ buf_out);
+ return -EBUSY;
+ }
+
+ query_outbuf = (ub_cc_dfx_info_s *)buf_out->buf;
+ query_outbuf->timestamp = be32_to_cpu(query_outbuf->timestamp);
+ query_outbuf->cwnd = be32_to_cpu(query_outbuf->cwnd);
+ query_outbuf->send_out = be32_to_cpu(query_outbuf->send_out);
+ query_outbuf->lost_out = be32_to_cpu(query_outbuf->lost_out);
+ query_outbuf->send_credit = be32_to_cpu(query_outbuf->send_credit);
+ query_outbuf->send_credit_rate =
+ be32_to_cpu(query_outbuf->send_credit_rate);
+ query_outbuf->srtt = be32_to_cpu(query_outbuf->srtt);
+ query_outbuf->ldcp.acked_seq =
+ be32_to_cpu(query_outbuf->ldcp.acked_seq);
+ query_outbuf->ldcp.acked_ce_seq =
+ be32_to_cpu(query_outbuf->ldcp.acked_ce_seq);
+
+ ret = memcpy_s(cc_attr, sizeof(ub_cc_dfx_info_s), query_outbuf,
+ sizeof(ub_cc_dfx_info_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%lu",
+ sizeof(ub_cc_dfx_info_s));
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+ return ret;
+ }
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "query tp cc info success\n");
+
+ return 0;
+}
+
+int udma_cmd_tp_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct tag_ub_cmd_tp_batch_modify);
+ struct tag_ub_cmd_tp_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+ u32 i;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct tag_ub_cmd_tp_batch_modify), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct tag_ub_cmd_tp_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_BATCH_MODIFY_CONTEXT, cmd_len,
+ inbuf->xid);
+ udma_cpu_to_be32(modify_cmd, sizeof(struct ub_cmd_com_header));
+ modify_cmd->body.attr.offset = cpu_to_be32(inbuf->offset);
+ modify_cmd->body.attr.length = cpu_to_be32(inbuf->length);
+ /* user input copy to context corresponding position, Note: user input a character occupy 4bit, and user inputs in big-endian format, no need to convert again */
+ for (i = inbuf->offset; i < inbuf->offset + inbuf->length &&
+ i < UB_CQM_MODIFY_DATA_LEN_TP / DATALEN_RATIO;
+ ++i) {
+ *(((u8 *)&modify_cmd->body.attr.tp_ctx) + i) =
+ (inbuf->data[(i - inbuf->offset) * DATALEN_RATIO]
+ << DATA_SHIFT) +
+ inbuf->data[(i - inbuf->offset) * DATALEN_RATIO + 1];
+ }
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_BATCH_MODIFY_CONTEXT,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX, "%s: success, tpn(%u)\n",
+ __func__, inbuf->xid);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+void udma_fill_cmd_tp_create_ubrc(struct ub_cmd_tp_create_ubrc *create_cmd,
+ struct udma_tp *ub_tp)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tp_create_ubrc);
+
+ create_cmd->body.rc_page_gpa_h = (ub_tp->rc_table.dma_addr >> 40) &
+ 0xffffff; //high:24bit, 64-24= 40
+ create_cmd->body.rc_page_gpa_l =
+ (u32)(ub_tp->rc_table.dma_addr >> 8); //low address right shift 8 bit
+
+ /* dw0 */
+ create_cmd->body.rc_max_size =
+ ub_tp->rc_table.ext_order - ub_tp->rc_log_ubrc_seg;
+
+ /* dw1 */
+ create_cmd->body.rc_entry_size = 1; //32B
+ create_cmd->body.rc_size = ub_tp->rc_table.order; //size as 128 corresponding is 7
+
+ if (ub_tp->tp_info != NULL) {
+ udma_fill_cmd_header(&create_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_CREATE_UBRC, cmd_len,
+ ub_tp->tp_info->xid);
+ }
+
+ udma_cpu_to_be32(create_cmd, cmd_len);
+}
+
+int udma_cmd_tp_create_ubrc(struct udma_device *udma_dev, struct udma_tp *ub_tp)
+{
+ struct ub_cmd_tp_create_ubrc *create_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct cmdq_rtt *cmdq_rtt = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_tp_create_ubrc),
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp: failed to allocate cqm inbuf\n");
+ return ret;
+ }
+
+ create_cmd = (struct ub_cmd_tp_create_ubrc *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_tp_create_ubrc(create_cmd, ub_tp);
+ cmdq_rtt = (ub_tp->cfg.tpg == NULL) ?
+ &ub_tp->cmdq_rtt :
+ &to_udma_tpg(ub_tp->cfg.tpg)->cmdq_rtt;
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_CREATE_UBRC, cqm_cmd_inbuf,
+ NULL, NULL, cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp ubrc: failed to send cqm cmd, ret = %d.\n",
+ ret);
+ }
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+int udma_cmd_tp_query_srp_bitmap(
+ struct udma_device *udma_dev, u32 tpn,
+ struct ub_cmd_tp_query_srp_bitmap_outbuf *outbuf, u16 outbuf_size)
+{
+ struct ub_cmd_tp_query_srp_bitmap_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_srp_bitmap);
+ struct ub_cmd_tp_query_srp_bitmap *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_tp_query_srp_bitmap), &cqm_cmd_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_query_srp_bitmap *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_SRP_BITMAP, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_SRP_BITMAP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, tpn:%u, ret:%d\n", tpn, ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf =
+ (struct ub_cmd_tp_query_srp_bitmap_outbuf *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)outbuf, outbuf_size, (void *)query_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%u",
+ outbuf_size);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query srp bitmap from cache success, tpn:%u\n", tpn);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_srp_ctr_bitmap(
+ struct udma_device *udma_dev, u32 tpn,
+ struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf *outbuf, u16 outbuf_size)
+{
+ struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_srp_ctr_bitmap);
+ struct ub_cmd_tp_query_srp_ctr_bitmap *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_tp_query_srp_ctr_bitmap), &cqm_cmd_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_query_srp_ctr_bitmap *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_SRP_CTR_BITMAP, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_SRP_CTR_BITMAP,
+ cqm_cmd_inbuf, cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, ret:%d\n", ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf *)
+ cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)outbuf, outbuf_size, (void *)query_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%u",
+ outbuf_size);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query srp ctr bitmap from cache success\n");
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_oor_info(struct udma_device *udma_dev, u32 tpn, u32 msn,
+ struct ub_oor_tp_info *oor_tp_info,
+ u32 outbuf_size)
+{
+ struct ub_cmd_tp_query_oor_info_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_oor_info);
+ struct ub_cmd_tp_query_oor_info *query_inbuf = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_query_oor_info), &buf_out,
+ sizeof(struct ub_cmd_tp_query_oor_info_outbuf));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to allocate cqm inoutbuf, tpn:0x%x\n",
+ tpn);
+ return -ENOMEM;
+ }
+
+ query_outbuf = (struct ub_cmd_tp_query_oor_info_outbuf *)buf_out->buf;
+ query_inbuf = (struct ub_cmd_tp_query_oor_info *)buf_in->buf;
+
+ query_inbuf->body.attr.msn = msn;
+ udma_fill_cmd_header(&query_inbuf->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_OOR_INFO, cmd_len, tpn);
+ udma_cpu_to_be32(query_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_OOR_INFO, buf_in,
+ buf_out, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to query tp res, tpn:0x%x, ret = %d.\n",
+ tpn, ret);
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in,
+ buf_out);
+ return -EBUSY;
+ }
+
+ ret = memcpy_s(oor_tp_info, sizeof(struct ub_oor_tp_info),
+ &query_outbuf->oor_tp_info,
+ sizeof(struct ub_oor_tp_info));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%lu",
+ sizeof(struct ub_oor_tp_info));
+ }
+
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_msn_entry(struct udma_device *udma_dev, u32 tpn,
+ u32 entry_index,
+ struct ub_msn_entry_outbuf *tp_msn_entry,
+ u32 outbuf_size)
+{
+ struct ub_msn_entry_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_msn_entry_info);
+ struct ub_cmd_tp_query_msn_entry_info *query_inbuf = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_query_msn_entry_info), &buf_out,
+ sizeof(struct ub_msn_entry_outbuf));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to allocate cqm inoutbuf, tpn:0x%x\n",
+ tpn);
+ return -ENOMEM;
+ }
+
+ query_outbuf = (struct ub_msn_entry_outbuf *)buf_out->buf;
+ query_inbuf = (struct ub_cmd_tp_query_msn_entry_info *)buf_in->buf;
+
+ query_inbuf->body.entry_index = entry_index;
+ udma_fill_cmd_header(&query_inbuf->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_TPMSN_TABLE, cmd_len, tpn);
+ udma_cpu_to_be32(query_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_TPMSN_TABLE, buf_in,
+ buf_out, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to query tp res, tpn:0x%x, ret = %d.\n",
+ tpn, ret);
+ goto err_send_cmd;
+ }
+
+ ret = memcpy_s(tp_msn_entry->msn_entry, UB_CMD_TP_MSN_ENTRY_SIZE,
+ query_outbuf, UB_CMD_TP_MSN_ENTRY_SIZE);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "memcpy failed, size:%u, ret:%d", outbuf_size, ret);
+ goto err_send_cmd;
+ }
+ tp_msn_entry->msn_entry_size = UB_CMD_TP_MSN_ENTRY_SIZE;
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_wqe(struct udma_device *udma_dev, u32 tpn, u32 ci,
+ struct ub_tp_wqe *outbuf, u32 outbuf_size)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query);
+ struct ub_cmd_tp_query *tp_cmd = NULL;
+ struct ub_tp_wqe *query_outbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, &cqm_cmd_outbuf,
+ sizeof(struct ub_tp_wqe));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_query *)cqm_cmd_inbuf->buf;
+ tp_cmd->body.ci = ci;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_WQE, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_WQE, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, tpn:%u, ci:%u, ret:%d\n", tpn,
+ ci, ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (struct ub_tp_wqe *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)outbuf, outbuf_size, (void *)query_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%u",
+ outbuf_size);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp wqe from cache success, tpn:%u, ci:%u\n", tpn, ci);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_pcqc(struct udma_device *udma_dev, u32 tpn,
+ ub_pcqc_query_rsp_s *outbuf, u32 outbuf_size)
+{
+ ub_pcqc_query_rsp_s *query_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query);
+ struct ub_cmd_tp_query *tp_cmd = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, &cqm_cmd_outbuf,
+ (u16)outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_PCQC, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_PCQC, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, tpn:%u, ret = %d.\n", tpn,
+ ret);
+ goto err_send_cmd;
+ }
+
+ query_outbuf = (ub_pcqc_query_rsp_s *)cqm_cmd_outbuf->buf;
+ ret = memcpy_s((void *)outbuf, outbuf_size, (void *)query_outbuf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%u",
+ outbuf_size);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp pcqc form cache success, tpn:%u\n", tpn);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+static int udma_tp_fill_cacheout_inbuf(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp, u64 wb_dma,
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf)
+{
+ struct udma_tp *ub_tp = container_of(tp[0], struct udma_tp, tp);
+ struct ub_cmd_tp_cache_invalid *tp_cacheout_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_cache_invalid);
+ struct udma_comp_priv *comp_priv = NULL;
+ u32 i;
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to get hmm comp priv info\n");
+ return -EINVAL;
+ }
+
+ tp_cacheout_inbuf =
+ (struct ub_cmd_tp_cache_invalid *)cqm_cmd_inbuf->buf;
+ tp_cacheout_inbuf->body.tp_cache.sq_buf_len =
+ ALIGN(ub_tp->buf_size, PAGE_SIZE);
+ tp_cacheout_inbuf->body.tp_cache.rq_buf_len =
+ ALIGN(ub_tp->buf_size, PAGE_SIZE);
+ tp_cacheout_inbuf->body.tp_cache.mtt_flags = 0;
+ tp_cacheout_inbuf->body.tp_cache.mtt_num = 0;
+ tp_cacheout_inbuf->body.tp_cache.mtt_cache_line_start =
+ comp_priv->ub_cap.cmtt_cl_start;
+ tp_cacheout_inbuf->body.tp_cache.mtt_cache_line_end =
+ comp_priv->ub_cap.cmtt_cl_end;
+ tp_cacheout_inbuf->body.tp_cache.mtt_cache_line_size =
+ comp_priv->ub_cap.cmtt_cl_sz;
+ tp_cacheout_inbuf->body.tp_cache.gpa_dw.syn_gpa_hi32 =
+ upper_32_bits(wb_dma);
+ tp_cacheout_inbuf->body.tp_cache.gpa_dw.syn_gpa_lo32 =
+ lower_32_bits(wb_dma);
+ tp_cacheout_inbuf->body.tp_cache.wqe_flags = 0;
+ tp_cacheout_inbuf->body.tp_cache.wqe_num = 0;
+ tp_cacheout_inbuf->body.tp_cache.wqe_cache_line_start =
+ comp_priv->ub_cap.wqe_cl_start;
+ tp_cacheout_inbuf->body.tp_cache.wqe_cache_line_end =
+ comp_priv->ub_cap.wqe_cl_end;
+ tp_cacheout_inbuf->body.tp_cache.wqe_cache_line_size =
+ comp_priv->ub_cap.wqe_cl_sz;
+ tp_cacheout_inbuf->body.tp_cnt = cnt;
+ for (i = 0; i < cnt; i++)
+ tp_cacheout_inbuf->body.ub_tpn[i] = tp[i]->tpn;
+
+ udma_fill_cmd_header(&tp_cacheout_inbuf->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_CACHE_INVLD, cmd_len, ub_tp->tp.tpn);
+ udma_cpu_to_be32(tp_cacheout_inbuf, cmd_len);
+
+ return 0;
+}
+
+static u32 udma_get_timeout_for_cache_out(enum ub_env_type env_type)
+{
+#define UB_DESTROY_FLOW_TIMEOUT 10
+#define UB_DESTROY_FLOW_TIMEOUT_FOR_ESL 1000
+
+ return env_type == UB_ENV_ESL ? UB_DESTROY_FLOW_TIMEOUT_FOR_ESL :
+ UB_DESTROY_FLOW_TIMEOUT;
+}
+
+int udma_cmd_tp_send_cache_out(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp, u64 wb_dma)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct cmdq_rtt *cmdq_rtt = NULL;
+ u64 jiffies_now;
+ u32 times = 0;
+ u64 end;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_tp_cache_invalid), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm cmd inoutbuf, ret:%d\n", ret);
+ return -ENOMEM;
+ }
+
+ ret = udma_tp_fill_cacheout_inbuf(udma_dev, cnt, tp, wb_dma,
+ cqm_cmd_inbuf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed fill tp cacheout inbuf, ret:%d\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ NULL);
+ return ret;
+ }
+
+ jiffies_now = get_jiffies_64();
+ end = jiffies_now +
+ (udma_get_timeout_for_cache_out(udma_dev->env_type) * HZ);
+ while (time_before64(jiffies_now, end)) {
+ times++;
+ cmdq_rtt = (tp[0]->tpg == NULL) ?
+ &to_udma_tp(tp[0])->cmdq_rtt :
+ &to_udma_tpg(tp[0]->tpg)->cmdq_rtt;
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_CACHE_INVLD,
+ cqm_cmd_inbuf, NULL, NULL, cmdq_rtt);
+ if (ret <= 0)
+ break;
+
+ cond_resched();
+ jiffies_now = get_jiffies_64();
+ }
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "Failed to send cqm_cmd_box after try times(%u), tpn(%u), ret(%d)\n",
+ times, tp[0]->tpn, ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_cnt(struct udma_device *udma_dev, u32 *tp_state_num,
+ u32 outbuf_size)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query);
+ struct ub_cmd_tp_query *tp_cmd = NULL;
+ int ret;
+ u32 i;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, &cqm_cmd_outbuf,
+ (u16)outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_CNT, cmd_len, 0);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_CNT, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, ret = %d.\n", ret);
+ goto err_send_cmd;
+ }
+
+ ret = memcpy_s((void *)tp_state_num, outbuf_size, cqm_cmd_outbuf->buf,
+ outbuf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%u",
+ outbuf_size);
+ goto err_send_cmd;
+ }
+
+ for (i = UB_TPC_STATE_RST; i < UB_TPC_STATE_MAX; i++) {
+ tp_state_num[i] = be32_to_cpu(tp_state_num[i]);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp cnt from cache success\n");
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_tp_set_drop_level(struct udma_device *udma_dev, const u32 tpn,
+ const u32 drop_level)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tp_dfx_drop);
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_tp_dfx_drop *tp_cmd = NULL;
+ struct tag_cqm_object *cqm_obj = NULL;
+ int ret;
+
+ /* ensure has tpn corresponding to tp context exist */
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX, tpn,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "get cqm object failed, tpn(0x%x)\n", tpn);
+ return -EINVAL;
+ }
+ cqm5_object_put(cqm_obj);
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tp_dfx_drop *)cqm_cmd_inbuf->buf;
+ tp_cmd->body.drop_level = drop_level;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_SET_DROP_LEVEL, cmd_len, tpn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_SET_DROP_LEVEL,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "failed to send cqm cmd, tpn(0x%x), ret = %d.\n", tpn,
+ ret);
+ goto err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DROP_DFX,
+ "%s: success, tpn(0x%x), drop_level(%u)\n", __func__, tpn,
+ drop_level);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+static void udma_cmd_tp_destroy_body_fill(u32 cnt,
+ struct ub_cmd_tp_destroy_body *body,
+ struct ubcore_tp **tp)
+{
+ u32 i;
+
+ body->num = cnt;
+ body->bs.dpath_flag = 1;
+
+ for (i = 0; i < cnt; i++)
+ body->tp_attr[i].tpn = tp[i]->tpn;
+}
+
+#define UB_DPATH_FLAG_NUM (1 << 2)
+#define UB_DESTROY_OUT_NUM \
+ (1 + UB_DPATH_FLAG_NUM) //destroy_num(1) + dpath_flag(4)
+
+/* return value: delete cmd destroy of tp count */
+u32 udma_cmd_tp_destroy_ctx(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tp_destroy);
+ struct ub_cmd_tp_destroy *tp_cmd_in = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ struct cmdq_rtt *cmdq_rtt = NULL;
+ u32 *cmd_out_num = NULL;
+ u32 destroy_num = 0;
+ int ret;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "%s Invalid parameter: udma_dev(%d).\n",
+ __func__, !!udma_dev);
+ return 0;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in,
+ sizeof(struct ub_cmd_tp_destroy),
+ &buf_out,
+ sizeof(u64) * UB_DESTROY_OUT_NUM);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: failed to allocate cqm inbuf\n", __func__);
+ return 0;
+ }
+
+ tp_cmd_in = (struct ub_cmd_tp_destroy *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd_in->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_DESTROY_CTX, cmd_len,
+ 0); //xid fill 0 not affect, actual xid in body in passed in
+
+ udma_cmd_tp_destroy_body_fill(cnt, &tp_cmd_in->body, tp);
+
+ udma_cpu_to_be32(tp_cmd_in, cmd_len);
+
+ cmd_out_num = (u32 *)buf_out->buf;
+
+ cmdq_rtt = (tp[0]->tpg == NULL) ? &to_udma_tp(tp[0])->cmdq_rtt :
+ &to_udma_tpg(tp[0]->tpg)->cmdq_rtt;
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_DESTROY_CTX, buf_in,
+ buf_out, NULL, cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: send cqm cmd failed, ret(%d)\n", __func__, ret);
+ }
+
+ destroy_num = be32_to_cpu(*cmd_out_num);
+ if ((destroy_num & UB_DPATH_CHECK_FLAG) != 0) {
+ ret = udma_cmd_check_dpath_dma(
+ udma_dev, ((u8 *)buf_out->buf) + sizeof(u64),
+ UB_DPATH_FLAG_NUM, sizeof(u64));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: check_dpath_dma failed\n", __func__);
+ }
+ }
+ destroy_num = destroy_num & (UB_DPATH_CHECK_FLAG - 1);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "%s: destroy_num(%u)\n", __func__,
+ destroy_num);
+
+ return destroy_num;
+}
+
+int udma_cmd_tp_query_ctx(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct ub_dfx_tp_ctx_query *outbuf)
+{
+ struct tag_ub_tpc_query_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_ctx);
+ struct ub_cmd_tp_query_ctx *tp_cmd_in = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &buf_in, sizeof(struct ub_cmd_tp_query_ctx),
+ &buf_out, sizeof(struct tag_ub_tpc_query_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: failed to allocate cqm inoutbuf, key(0x%x)\n",
+ __func__, key->key);
+ return -ENOMEM;
+ }
+
+ query_outbuf = (struct tag_ub_tpc_query_outbuf *)buf_out->buf;
+ tp_cmd_in = (struct ub_cmd_tp_query_ctx *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd_in->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_CTX, cmd_len, key->key);
+
+ udma_cpu_to_be32(tp_cmd_in, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_CTX, buf_in, buf_out,
+ NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: query tp ctx failed, key(0x%x), ret(%d)\n",
+ __func__, key->key, ret);
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in,
+ buf_out);
+ return -EBUSY;
+ }
+
+ ret = memcpy_s(outbuf, sizeof(struct ub_dfx_tp_ctx_query),
+ &query_outbuf->res_val, sizeof(ub_tpc_query_rsp_s));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%lu",
+ sizeof(struct ub_dfx_tp_ctx_query));
+ }
+
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_ctx_ext(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct ub_tp_ctx_ext_query *outbuf)
+{
+ cqm_cmd_buf_s *buf_out = NULL;
+ cqm_cmd_buf_s *buf_in = NULL;
+ ub_cmd_tp_query_ctx_ext_s *tp_cmd_in = NULL;
+ ub_tpc_query_ext_outbuf_s *data_out = NULL;
+ int ret = 0;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in,
+ sizeof(ub_cmd_tp_query_ctx_ext_s),
+ &buf_out,
+ sizeof(ub_tpc_query_ext_outbuf_s));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "[%s] Failed to allocate cqm buffer for command, key(0x%x)\n",
+ __func__, key->key);
+ return ret;
+ }
+
+ tp_cmd_in = (ub_cmd_tp_query_ctx_ext_s *)(buf_in->buf);
+ data_out = (ub_tpc_query_ext_outbuf_s *)(buf_out->buf);
+
+ udma_fill_cmd_header(&tp_cmd_in->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_CTX_EXT,
+ sizeof(ub_cmd_tp_query_ctx_ext_s), key->key);
+ udma_cpu_to_be32(tp_cmd_in, sizeof(ub_cmd_tp_query_ctx_ext_s));
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_CTX_EXT, buf_in,
+ buf_out, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "[%s] Failed to query extern TP context, key(0x%x), ret(%d).\n",
+ __func__, key->key, ret);
+ goto err_out;
+ }
+
+ ret = memcpy_s(outbuf, sizeof(struct ub_mapt_ctx_query),
+ &data_out->ret_val, sizeof(struct ub_mapt_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "[%s] Failed to copy memory, size(%zu), ret(%d).\n",
+ __func__, sizeof(struct ub_mapt_ctx_query), ret);
+ goto err_out;
+ }
+
+err_out:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
+
+int udma_cmd_tp_query_ctx_info(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct tag_ub_tp_query_info_outbuf *outbuf)
+{
+ struct tag_ub_tp_query_info_outbuf *query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_tp_query_ctx);
+ struct ub_cmd_tp_query_ctx *tp_cmd_in = NULL;
+ struct tag_cqm_cmd_buf *buf_out = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &buf_in, sizeof(struct ub_cmd_tp_query_ctx),
+ &buf_out, sizeof(struct tag_ub_tp_query_info_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: failed to allocate cqm inoutbuf, key(0x%x)\n",
+ __func__, key->key);
+ return -ENOMEM;
+ }
+
+ query_outbuf = (struct tag_ub_tp_query_info_outbuf *)buf_out->buf;
+ tp_cmd_in = (struct ub_cmd_tp_query_ctx *)buf_in->buf;
+
+ udma_fill_cmd_header(&tp_cmd_in->header, UB_CMD_TYPE_TP,
+ UB_CMD_TP_QUERY_CTX_FOR_UDMA, cmd_len, key->key);
+
+ udma_cpu_to_be32(tp_cmd_in, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TP_QUERY_CTX_FOR_UDMA, buf_in,
+ buf_out, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: query tp ctx info failed, key(0x%x), ret(%d)\n",
+ __func__, key->key, ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+ return -EBUSY;
+ }
+ udma_be32_to_cpu(query_outbuf,
+ sizeof(struct tag_ub_tp_query_info_outbuf));
+
+ ret = memcpy_s(outbuf, sizeof(struct tag_ub_tp_query_info_outbuf),
+ query_outbuf,
+ sizeof(struct tag_ub_tp_query_info_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "memcpy failed, size:%lu",
+ sizeof(struct tag_ub_tp_query_info_outbuf));
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, buf_out);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.h
new file mode 100644
index 000000000..9615d3085
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tp.h
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_TP_H
+#define UDMA_CMD_TP_H
+
+#include "udma_common.h"
+#include "udma_tp.h"
+#include "udma_dfx_cc_inject.h"
+#include "ub_pub_cmd.h"
+
+#define DATALEN_RATIO 2 // user input of data is 4bit, one byte 8bit / 4 = 2
+#define DATA_SHIFT \
+ 4 // user input of data is 4bit, to convert to byte unit, even index need left shift 4 bit
+
+u32 udma_cmd_tp_create_ctx(struct ubcore_device *ub_dev, u32 cnt,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp[]);
+u32 udma_cmd_tp_modify_ctx(u32 cnt, struct ubcore_tp **tp,
+ const struct ubcore_tp_attr *attr,
+ const union ubcore_tp_attr_mask *mask);
+u32 udma_cmd_tp_destroy_ctx(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp);
+int udma_cmd_tp_query_ctx(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct ub_dfx_tp_ctx_query *outbuf);
+int udma_cmd_tp_cc_modify(struct udma_device *udma_dev,
+ const struct tag_ub_cc_attr *cc_attr);
+int udma_cmd_tp_modify_tp_srp_bitmap(struct udma_device *udma_dev,
+ u32 tp_srp_index, u32 bitmap_index,
+ u32 bitmap_mode);
+int udma_cmd_tp_modify_srp_ctr_bitmap(struct udma_device *udma_dev,
+ u32 ctr_bitmap_index, u32 bitmap_mode);
+int udma_cmd_tp_query_cc_info(struct udma_device *udma_dev, u32 tpn,
+ ub_cc_dfx_info_s *cc_attr);
+int udma_cmd_tp_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+int udma_cmd_tp_query_srp_bitmap(
+ struct udma_device *udma_dev, u32 tpn,
+ struct ub_cmd_tp_query_srp_bitmap_outbuf *outbuf, u16 outbuf_size);
+int udma_cmd_tp_query_srp_ctr_bitmap(
+ struct udma_device *udma_dev, u32 tpn,
+ struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf *outbuf, u16 outbuf_size);
+int udma_cmd_tp_query_oor_info(struct udma_device *udma_dev, u32 tpn, u32 msn,
+ struct ub_oor_tp_info *oor_tp_info,
+ u32 outbuf_size);
+int udma_cmd_tp_create_ubrc(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp);
+int udma_cmd_tp_query_wqe(struct udma_device *udma_dev, u32 tpn, u32 ci,
+ struct ub_tp_wqe *outbuf, u32 outbuf_size);
+int udma_cmd_tp_query_pcqc(struct udma_device *udma_dev, u32 tpn,
+ ub_pcqc_query_rsp_s *outbuf, u32 outbuf_size);
+int udma_cmd_tp_send_cache_out(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp, u64 wb_dma);
+int udma_cmd_tp_query_cnt(struct udma_device *udma_dev, u32 *tp_state_num,
+ u32 outbuf_size);
+int udma_cmd_tp_set_drop_level(struct udma_device *udma_dev, const u32 tpn,
+ const u32 drop_level);
+int udma_cmd_tp_query_ctx_ext(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct ub_tp_ctx_ext_query *outbuf);
+int udma_cmd_tp_query_ctx_info(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct tag_ub_tp_query_info_outbuf *outbuf);
+int udma_cmd_tp_query_msn_entry(struct udma_device *udma_dev, u32 tpn,
+ u32 entry_index,
+ struct ub_msn_entry_outbuf *tp_msn_entry,
+ u32 outbuf_size);
+int udma_cmd_tp_modify_dfx(struct udma_device *udma_dev, struct udma_tp *ub_tp,
+ const struct udma_tp_modify_dfx *tp_dfx);
+#endif // UDMA_CMD_TP_H
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.c
new file mode 100644
index 000000000..1db269711
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.c
@@ -0,0 +1,333 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "ubcore_uapi.h"
+#include "ub_npu_tpg_cmd.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_misc.h"
+#include "udma_cmd_com.h"
+#include "ub_pub_cmd.h"
+#include "udma_cmd_tpg.h"
+
+u32 g_udma_multi_fast_tp_enable = UDMA_MULTI_FAST_TP_DISABLE;
+module_param(g_udma_multi_fast_tp_enable, uint, 0664);
+MODULE_PARM_DESC(g_udma_multi_fast_tp_enable,
+ "0 for disable multi fast tp, 1 enable multi fast tp");
+
+#define RSV_TP_WQE_CNT 2
+#define WQEBB_IN_TP_WQE_NUM 2
+#define CALC_TP_PCQ_DEPTH(tp_q_depth) \
+ ((tp_q_depth) / WQEBB_IN_TP_WQE_NUM - RSV_TP_WQE_CNT)
+
+int udma_cmd_tpg_query_ctx_from_cache(struct udma_device *udma_dev, u32 tpg_id,
+ struct ub_tpg_ctx_query *outbuf,
+ u32 outbuf_size)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_query_inbuf);
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_tpg_query_inbuf *tp_cmd = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, &cqm_cmd_outbuf,
+ sizeof(struct ub_tpg_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tpg_query_inbuf *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_QUERY_CTX, cmd_len, tpg_id);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "failed to send cqm cmd, tpg_id:%u, ret = %d.\n",
+ tpg_id, ret);
+ goto err_send_cmd;
+ }
+
+ (void)memcpy_s((void *)outbuf, outbuf_size, (void *)cqm_cmd_outbuf->buf,
+ outbuf_size);
+
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "query tpg ctx form cache success, tpg_id:%u\n", tpg_id);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_tp_latch_tpg_create(struct udma_device *udma_dev, u32 tpgn)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_create);
+ struct ub_cmd_tpg_create *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in, cmd_len,
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Cqm inbuf allocation failed, ret=%d.\n", ret);
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tpg_create *)buf_in->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_CREATE, cmd_len, tpgn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_CREATE, buf_in, NULL, NULL,
+ NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Send tpg cmd failed, ret = %d.\n", ret);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, NULL);
+
+ return ret;
+}
+
+int udma_cmd_clear_tp_latch_lock(struct udma_device *udma_dev, u32 xid)
+{
+ struct ub_cmd_com_header *cmd_buf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_com_header),
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "failed to allocate cqm inbuf, ret = %d\n", ret);
+ return ret;
+ }
+
+ cmd_buf = (struct ub_cmd_com_header *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(cmd_buf, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_CLEAR_TP_LATCH_LOCK,
+ sizeof(struct ub_cmd_com_header), xid);
+ udma_cpu_to_be32(cmd_buf, sizeof(struct ub_cmd_com_header));
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_CLEAR_TP_LATCH_LOCK,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "failed to send clear tp latch lock command, ret = %d.\n",
+ ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+int udma_cmd_tpg_create(struct udma_device *udma_dev,
+ const struct ubcore_tpg_cfg *cfg,
+ struct udma_tpg *ub_tpg)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_create);
+ struct ub_cmd_tpg_create *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+ u32 i;
+ u32 tp_pcq_depth;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in, cmd_len,
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "cqm inbuf allocation failed.\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tpg_create *)buf_in->buf;
+ tp_cmd->body.attr.sl = cfg->dscp;
+ tp_cmd->body.attr.all_tp_num = cfg->tp_cnt;
+ tp_cmd->body.attr.ep_id = udma_dev->hw_info.ep_id;
+
+ ub_tpg->tp_q_depth = udma_sysfs_get_tp_depth(&udma_dev->sysfs_res);
+ tp_pcq_depth = CALC_TP_PCQ_DEPTH(ub_tpg->tp_q_depth);
+
+ for (i = 0; i < cfg->tp_cnt; i++) {
+ tp_cmd->body.attr.tpn[i].bs.tpn = ub_tpg->tpinfo_list[i]->xid;
+ tp_cmd->body.attr.tpn[i].bs.depth =
+ tp_pcq_depth; //indicates current depth
+ }
+
+ if (g_udma_multi_fast_tp_enable == UDMA_MULTI_FAST_TP_ENABLE) {
+ tp_cmd->body.attr.multi_fast_tp_en = UDMA_MULTI_FAST_TP_ENABLE;
+ }
+
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_CREATE, cmd_len, ub_tpg->tpg.tpgn);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_CREATE, buf_in, NULL, NULL,
+ &ub_tpg->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Send tpg cmd failed, ret = %d.\n", ret);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tpg_delete(struct udma_device *udma_dev, u32 idx,
+ struct cmdq_rtt *rtt)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_destroy);
+ struct ub_cmd_tpg_destroy *tp_cmd = NULL;
+ struct tag_cqm_cmd_buf *buf_in = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &buf_in, cmd_len,
+ NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "cqm inbuf allocation failed.\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tpg_destroy *)buf_in->buf;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_DESTROY, cmd_len, idx);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_DESTROY, buf_in, NULL,
+ NULL, rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Destroy tpg cmd failed, id: %u, ret = %d.\n", idx,
+ ret);
+ ret = -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf_in, NULL);
+
+ return ret;
+}
+
+int udma_cmd_tpg_modify_multipath(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_modify);
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_tpg_modify *tp_cmd = NULL;
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ tp_cmd = (struct ub_cmd_tpg_modify *)cqm_cmd_inbuf->buf;
+ tp_cmd->body.attr.multi_tp_en = inbuf->multi_tp_en;
+ tp_cmd->body.attr.default_tpn = inbuf->default_tpn;
+ tp_cmd->body.attr.dw0_value = 0;
+ udma_fill_cmd_header(&tp_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_CTX_SELECT_TP, cmd_len, inbuf->tpg_id);
+ udma_cpu_to_be32(tp_cmd, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_CTX_SELECT_TP,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "failed to send cqm cmd, ret = %d.\n", ret);
+ goto out;
+ }
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "query tp cnt from cache success\n");
+
+out:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+static void
+udma_fill_cmd_tpg_batch_modify_ctx(struct ub_cmd_tpg_batch_modify_body *body,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ body->attr.offset = inbuf->offset;
+ body->attr.length = inbuf->length;
+
+ udma_cpu_to_be32(body, sizeof(struct ub_cmd_tpg_batch_modify_body));
+
+ udma_cmdq_data_to_context_buf(inbuf->data, inbuf->data_len,
+ (u8 *)&body->attr.tpg_ctx,
+ sizeof(body->attr.tpg_ctx) / sizeof(u8),
+ inbuf->offset);
+}
+
+int udma_cmd_tpg_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_tpg_batch_modify);
+ struct ub_cmd_tpg_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (udma_dev->device_type < UDMA_DEV_TYPE_HI1825_V100) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TPG,
+ "%s: device_type(%d) not support tpg batch modify ctx\n",
+ __func__, udma_dev->device_type);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct ub_cmd_tpg_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_TP_GROUP,
+ UB_CMD_TPG_BATCH_MODIFY_CONTEXT, cmd_len,
+ inbuf->xid);
+ udma_cpu_to_be32(modify_cmd, sizeof(modify_cmd->header));
+
+ udma_fill_cmd_tpg_batch_modify_ctx(&modify_cmd->body, inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_TPG_BATCH_MODIFY_CONTEXT,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "%s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto batch_err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TPG, "%s: success, tpn(%u)\n", __func__,
+ inbuf->xid);
+
+batch_err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.h
new file mode 100644
index 000000000..df822ba2f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_tpg.h
@@ -0,0 +1,32 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_TPG_H
+#define UDMA_CMD_TPG_H
+
+#include "ubcore_types.h"
+#include "udma_tpg.h"
+#include "ub_npu_tpg_cmd_defs.h"
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+#define UB_TP_PCQ_INIT_DEPTH 62u
+enum { UDMA_MULTI_FAST_TP_DISABLE = 0, UDMA_MULTI_FAST_TP_ENABLE };
+
+int udma_cmd_tpg_query_ctx_from_cache(struct udma_device *udma_dev, u32 tpg_id,
+ struct ub_tpg_ctx_query *outbuf,
+ u32 outbuf_size);
+int udma_cmd_tpg_create(struct udma_device *udma_dev,
+ const struct ubcore_tpg_cfg *cfg,
+ struct udma_tpg *ub_tpg);
+int udma_cmd_tpg_delete(struct udma_device *udma_dev, u32 idx,
+ struct cmdq_rtt *rtt);
+int udma_cmd_tpg_modify_multipath(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
+int udma_cmd_tpg_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+int udma_cmd_tp_latch_tpg_create(struct udma_device *udma_dev, u32 tpgn);
+int udma_cmd_clear_tp_latch_lock(struct udma_device *udma_dev, u32 xid);
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.c
new file mode 100644
index 000000000..2043cf66b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include "ubcore_uapi.h"
+#include "ub_npu_utp_cmd.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_misc.h"
+#include "udma_net.h"
+#include "udma_utp.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_utp.h"
+
+#define UB_CMD_UTP_DIP_MASK 0xffffffff
+#define UB_CMD_UTP_DIP_OFFSET 0x20
+#define UB_CMD_UTP_TCLASS_DSCP 0x3f
+#define UB_CMD_UTP_TCLASS_ECN 0x2
+
+static void udma_fill_create_utp_cmd(struct udma_device *udma_dev,
+ struct tag_ub_create_utp_attr *utp_attr,
+ const struct ubcore_utp_cfg *cfg)
+{
+ vlan_u vlan_value = { 0 };
+ struct ub_sip_attr sip = { 0 };
+ u8 cos = 0;
+
+ /* dw0 */
+ utp_attr->dmac_l32 = UDMA_GET_MAC_LO(cfg->peer_net_addr.mac[0x2],
+ cfg->peer_net_addr.mac[0x3],
+ cfg->peer_net_addr.mac[0x4],
+ cfg->peer_net_addr.mac[0x5]);
+ /* dw1 */
+ utp_attr->dmac_h16 = UDMA_GET_MAC_HI(cfg->peer_net_addr.mac[0],
+ cfg->peer_net_addr.mac[1]);
+ utp_attr->port_id = cfg->port_id;
+ utp_attr->mtu = cfg->mtu;
+
+ /* dw2 - dw5 */
+ if (cfg->peer_net_addr.type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ utp_attr->dip3 = cfg->peer_net_addr.net_addr.in4.addr;
+ } else {
+ utp_attr->dip0 = cfg->peer_net_addr.net_addr.in6.subnet_prefix &
+ UB_CMD_UTP_DIP_MASK;
+ utp_attr->dip1 =
+ (cfg->peer_net_addr.net_addr.in6.subnet_prefix >>
+ UB_CMD_UTP_DIP_OFFSET) &
+ UB_CMD_UTP_DIP_MASK;
+ utp_attr->dip2 = cfg->peer_net_addr.net_addr.in6.interface_id &
+ UB_CMD_UTP_DIP_MASK;
+ utp_attr->dip3 =
+ (cfg->peer_net_addr.net_addr.in6.interface_id >>
+ UB_CMD_UTP_DIP_OFFSET) &
+ UB_CMD_UTP_DIP_MASK;
+ }
+ utp_attr->dip0 = be32_to_cpu(utp_attr->dip0);
+ utp_attr->dip1 = be32_to_cpu(utp_attr->dip1);
+ utp_attr->dip2 = be32_to_cpu(utp_attr->dip2);
+ utp_attr->dip3 = be32_to_cpu(utp_attr->dip3);
+
+ /* dw6 */
+ utp_attr->dip_type =
+ (cfg->peer_net_addr.type == UBCORE_NET_ADDR_TYPE_IPV4) ? 0 : 1;
+ utp_attr->loop_back = cfg->flag.bs.loopback;
+
+ /* dw7 */
+ vlan_value.value = (u16)cfg->peer_net_addr.vlan;
+ utp_attr->vlan_pri =
+ cfg->dscp; // pcp scenario next, user passed in dscp field treated as pri
+ utp_attr->vlan_cfi = vlan_value.bs.cfi;
+ utp_attr->vlan_id = vlan_value.bs.vlan;
+ utp_attr->hoplmt = cfg->hop_limit;
+
+ /* dw8 */
+ utp_attr->flow_label = cfg->flow_label;
+ utp_attr->tclass = (cfg->dscp & UB_CMD_UTP_TCLASS_DSCP)
+ << UB_CMD_UTP_TCLASS_ECN |
+ UB_CMD_UTP_TCLASS_ECN;
+ /* get fails then use priority 0, stub sip field */
+ sip.dw6.tag = VLAN_VALID;
+ sip.dw6.dw6_value = le32_to_cpu(sip.dw6.dw6_value);
+ if (udma_get_dcb_cfg_cos(udma_dev, &sip, cfg->dscp, &cos, 0) == 0) {
+ utp_attr->cos = cos;
+ }
+
+ /* dw9 */
+ utp_attr->sip_idx = cfg->local_net_addr_idx;
+}
+
+int udma_cmd_query_utp(struct udma_device *udma_dev, u32 utpn,
+ struct ub_dip_ctx_query *utp_ctx)
+{
+ struct tag_ub_cmd_query_utp *utp_query_inbuf = NULL;
+ struct ub_dip_ctx_query *utpc = NULL;
+ struct tag_cqm_cmd_buf *cmd_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cmd_outbuf = NULL;
+ u16 cmd_len = sizeof(struct tag_ub_cmd_query_utp);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cmd_inbuf,
+ (u16)sizeof(struct tag_ub_cmd_query_utp), &cmd_outbuf,
+ (u16)sizeof(struct ub_dip_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Failed to alloc in_buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ utp_query_inbuf = (struct tag_ub_cmd_query_utp *)cmd_inbuf->buf;
+ udma_fill_cmd_header(&utp_query_inbuf->header, UB_CMD_TYPE_UTP,
+ UB_CMD_QUERY_DIP, cmd_len, utpn);
+ udma_cpu_to_be32(utp_query_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_QUERY_DIP, cmd_inbuf,
+ cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Send query utp cmd msg failed: %d\n", ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cmd_inbuf,
+ cmd_outbuf);
+ return ret;
+ }
+
+ utpc = (struct ub_dip_ctx_query *)cmd_outbuf->buf;
+ ret = memcpy_s(utp_ctx, sizeof(struct ub_dip_ctx_query), utpc,
+ sizeof(struct ub_dip_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP, "memcpy_s failed, ret:%d\n",
+ ret);
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cmd_inbuf,
+ cmd_outbuf);
+ return -EFAULT;
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cmd_inbuf, cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_create_utp(struct udma_device *udma_dev,
+ const struct ubcore_utp_cfg *cfg, struct udma_utp *utp)
+{
+ struct tag_ub_cmd_create_utp *utp_create_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct tag_ub_cmd_create_utp);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cmd_inbuf,
+ (u16)sizeof(struct tag_ub_cmd_create_utp), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Failed to alloc in_buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ utp_create_inbuf = (struct tag_ub_cmd_create_utp *)cmd_inbuf->buf;
+ udma_fill_create_utp_cmd(udma_dev, &utp_create_inbuf->body.utp_attr,
+ cfg);
+ udma_fill_cmd_header(&utp_create_inbuf->header, UB_CMD_TYPE_UTP,
+ UB_CMD_ADD_DIP, cmd_len, utp->cqm_utpn->index);
+ udma_cpu_to_be32(utp_create_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_ADD_DIP, cmd_inbuf, NULL, NULL,
+ NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Send create utp cmd msg failed: %d\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_destroy_utp(struct udma_device *udma_dev, struct udma_utp *utp)
+{
+ struct tag_ub_cmd_destroy_utp *utp_destroy_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct tag_ub_cmd_destroy_utp);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cmd_inbuf,
+ (u16)sizeof(struct tag_ub_cmd_destroy_utp), NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Failed to alloc in_buffer, ret = %d.\n", ret);
+ return ret;
+ }
+
+ utp_destroy_inbuf = (struct tag_ub_cmd_destroy_utp *)cmd_inbuf->buf;
+ udma_fill_cmd_header(&utp_destroy_inbuf->header, UB_CMD_TYPE_UTP,
+ UB_CMD_DEL_DIP, cmd_len, utp->cqm_utpn->index);
+ udma_cpu_to_be32(utp_destroy_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_DEL_DIP, cmd_inbuf, NULL, NULL,
+ NULL);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Send destroy dip cmd msg failed: %d\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cmd_inbuf, NULL);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.h
new file mode 100644
index 000000000..35fc73f98
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_utp.h
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_CMD_UTP_H
+#define UDMA_CMD_UTP_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_net.h"
+#include "udma_utp.h"
+
+int udma_cmd_query_utp(struct udma_device *udma_dev, u32 utpn,
+ struct ub_dip_ctx_query *utp_ctx);
+int udma_cmd_create_utp(struct udma_device *udma_dev,
+ const struct ubcore_utp_cfg *cfg, struct udma_utp *utp);
+int udma_cmd_destroy_utp(struct udma_device *udma_dev, struct udma_utp *utp);
+
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.c
new file mode 100644
index 000000000..47608237b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+#include "ubcore_uapi.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_vtp.h"
+#include "udma_comp.h"
+#include "ub_npu_vtp_cmd.h"
+#include "udma_misc.h"
+#include "udma_cmd_com.h"
+#include "udma_cqm.h"
+#include "udma_cmd_vtp.h"
+
+int udma_get_rc_tpn(struct udma_device *udma_dev, struct ubcore_tpg *tpg)
+{
+ u32 i;
+
+ if (tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP, "tpg is null\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < tpg->tpg_cfg.tp_cnt) && (i < UBCORE_MAX_TP_CNT_IN_GRP);
+ i++) {
+ if (tpg->tp_list[i] == NULL) {
+ udma_warn(udma_dev->dev, UDMA_M_VTP,
+ "tp_list(%u) in tpg(%u) is null\n", i,
+ tpg->tpgn);
+ continue;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "tp_list(%u) ack_resp: %u\n", i,
+ tpg->tp_list[i]->flag.bs.ack_resp);
+ if (tpg->tp_list[i]->flag.bs.ack_resp == 0) {
+ return (int)tpg->tp_list[i]->tpn;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int udma_fill_cmd_vtp_create_body(struct udma_device *udma_dev,
+ struct ub_cmd_body_vtp_create *body,
+ const struct ubcore_vtp_cfg *cfg)
+{
+ int tpn;
+ u32 i;
+
+ body->func_id = adapted_ue_idx(cfg);
+ (void)memcpy_s((void *)body->seid, UBCORE_EID_SIZE, cfg->local_eid.raw,
+ UBCORE_EID_SIZE);
+ for (i = 0; i < UB_EID_SW_DW_LEN; i++)
+ body->seid[i] = be32_to_cpu(body->seid[i]);
+ (void)memcpy_s((void *)body->deid, UBCORE_EID_SIZE, cfg->peer_eid.raw,
+ UBCORE_EID_SIZE);
+ for (i = 0; i < UB_EID_SW_DW_LEN; i++)
+ body->deid[i] = be32_to_cpu(body->deid[i]);
+ body->upi = cfg->upi;
+
+ switch (cfg->trans_mode) {
+ case UBCORE_TP_RM:
+ body->type = UB_VTP_TYPE_TPG;
+ body->id = cfg->tpg->tpgn;
+ break;
+ case UBCORE_TP_RC:
+ tpn = udma_get_rc_tpn(udma_dev, cfg->tpg);
+ if (tpn < 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Get rc tpn failed\n");
+ return -EINVAL;
+ }
+ body->type = UB_VTP_TYPE_TP;
+ body->id = (u32)tpn;
+ break;
+ case UBCORE_TP_UM:
+ body->type = UB_VTP_TYPE_DIP;
+ body->id = cfg->utp->utpn;
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP, "Unknown trans_mode: %d\n",
+ cfg->trans_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_cmd_create_vtp(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg, struct cmdq_rtt *rtt)
+{
+ struct ub_cmd_vtp_create *vtp_create_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_body_vtp_create *body = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_create);
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP, "Recv create vtp: vtpn:%u vf:%u\n",
+ cfg->vtpn, adapted_ue_idx(cfg));
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_vtp_create), NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to alloc in_buffer for vtp_create_inbuf, ret = %d, vtpn: %u, vfid: %u\n",
+ ret, cfg->vtpn, adapted_ue_idx(cfg));
+ return ret;
+ }
+
+ vtp_create_inbuf = (struct ub_cmd_vtp_create *)cqm_cmd_inbuf->buf;
+
+ udma_fill_cmd_header(&vtp_create_inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_CREATE_CTX, cmd_len, cfg->vtpn);
+
+ body = &vtp_create_inbuf->body;
+ ret = udma_fill_cmd_vtp_create_body(udma_dev, body, cfg);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to create vtp body cmdq msg, vtpn: %u, vfid: %u\n",
+ cfg->vtpn, adapted_ue_idx(cfg));
+ goto out;
+ }
+
+ udma_cpu_to_be32(vtp_create_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_CREATE_CTX, cqm_cmd_inbuf,
+ NULL, NULL, rtt);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Send create vtp cmd msg failed: %d, vtpn: %u, vfid: %u\n",
+ ret, cfg->vtpn, adapted_ue_idx(cfg));
+ goto out;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "create vtpn cmd success, vtpn: %u, vfid: %u, id: %u\n",
+ cfg->vtpn, adapted_ue_idx(cfg), be32_to_cpu(body->id));
+
+out:
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+void udma_fill_cmd_vtp_restore_body_node(
+ struct udma_device *udma_dev, struct udma_vtp_buf *buf,
+ struct ub_cmd_restore_vtp_node *body_node)
+{
+ u32 idx;
+ u64 node_size = sizeof(struct ub_cmd_restore_vtp_node);
+ struct ub_cmd_restore_vtp_node *src_node = NULL;
+
+ src_node = (struct ub_cmd_restore_vtp_node *)((u8 *)buf->addr +
+ buf->cur_idx * node_size);
+ for (idx = buf->cur_idx; idx < UB_MAX_VTP_NUM; idx++) {
+ if (src_node->vld == UDMA_MIG_BUF_USED) {
+ src_node->vld = UDMA_MIG_BUF_IDLE;
+ (void)memcpy_s((void *)body_node, node_size, src_node,
+ node_size);
+ buf->cur_idx = idx;
+ buf->total--;
+ return;
+ }
+ src_node++;
+ }
+}
+
+int udma_fill_vtp_node(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct ub_cmd_restore_vtp_node *node)
+{
+ int tpn, i;
+
+ switch (cfg->trans_mode) {
+ case UBCORE_TP_RM:
+ node->type = UB_VTP_TYPE_TPG;
+ node->id = cfg->tpg->tpgn;
+ break;
+ case UBCORE_TP_RC:
+ tpn = udma_get_rc_tpn(udma_dev, cfg->tpg);
+ if (tpn < 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "get rc tpn failed, ret:%d\n", tpn);
+ return -EINVAL;
+ }
+ node->type = UB_VTP_TYPE_TP;
+ node->id = (u32)tpn;
+ break;
+ case UBCORE_TP_UM:
+ node->type = UB_VTP_TYPE_DIP;
+ node->id = cfg->utp->utpn;
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Unknown trans_mode:%d, vf:%u vtpn:%u\n",
+ cfg->trans_mode, adapted_ue_idx(cfg), cfg->vtpn);
+ return -EINVAL;
+ }
+ node->vtpn = cfg->vtpn;
+ node->destroy = UDMA_RESTORE_VTPN_CREATE;
+
+ (void)memcpy_s((void *)node->seid, UBCORE_EID_SIZE, cfg->local_eid.raw,
+ UBCORE_EID_SIZE);
+ for (i = 0; i < UB_EID_SW_DW_LEN; i++)
+ node->seid[i] = be32_to_cpu(node->seid[i]);
+ (void)memcpy_s((void *)node->deid, UBCORE_EID_SIZE, cfg->peer_eid.raw,
+ UBCORE_EID_SIZE);
+ for (i = 0; i < UB_EID_SW_DW_LEN; i++)
+ node->deid[i] = be32_to_cpu(node->deid[i]);
+ return 0;
+}
+
+static inline void udma_cmd_init_inoutbuf(struct ub_cmd_vtp_restore *inbuf,
+ u32 vfid)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_restore);
+
+ udma_fill_cmd_header(&inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_RESTORE_CTX, cmd_len, 0);
+ inbuf->body.vfid = vfid;
+ inbuf->body.num = 0;
+}
+
+static int udma_cmd_send_restore_ctx(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf,
+ struct ub_cmd_vtp_restore *inbuf)
+{
+ int ret;
+
+ udma_cpu_to_be32(inbuf, sizeof(struct ub_cmd_vtp_restore));
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_RESTORE_CTX,
+ buf->cqm_cmd_buf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "send restore vtp cmd msg failed: %d\n", ret);
+ }
+ udma_cmd_init_inoutbuf(inbuf, buf->func_id);
+ return ret;
+}
+
+static inline int
+udma_cmd_check_body_full_proc(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf,
+ struct ub_cmd_vtp_restore *inbuf)
+{
+ if (inbuf->body.num >= UB_VTP_RESTORE_NUM_MAX) {
+ return udma_cmd_send_restore_ctx(udma_dev, buf, inbuf);
+ }
+ return 0;
+}
+
+int udma_cmd_modify_get_new_tpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct ubcore_vtp_attr *attr, u32 *new_tpn)
+{
+ int ret;
+
+ switch (cfg->trans_mode) {
+ case UBCORE_TP_RM:
+ *new_tpn = attr->tp.tpg->tpgn;
+ break;
+ case UBCORE_TP_RC:
+ ret = udma_get_rc_tpn(udma_dev, attr->tp.tpg);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Get rc tpn failed, vf:%u vtpn:%u\n",
+ adapted_ue_idx(cfg), cfg->vtpn);
+ return -EINVAL;
+ }
+ *new_tpn = (u32)ret;
+ break;
+ case UBCORE_TP_UM:
+ *new_tpn = attr->tp.utp->utpn;
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Modify: invalid transmode:0x%x, vf:%u vtpn:%u\n",
+ cfg->trans_mode, adapted_ue_idx(cfg), cfg->vtpn);
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_VTP, "New tpn:0x%x. vtpn:%u vfid:%u\n",
+ *new_tpn, cfg->vtpn, adapted_ue_idx(cfg));
+ return 0;
+}
+
+// full VTP flush down complete, received incremental create VTP request
+int udma_cmd_restore_vtp_create_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct udma_vtp_buf *buf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_buf =
+ (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ struct ub_cmd_vtp_restore *inbuf =
+ (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+
+ // create vtp, entry checks cfg in of parameters whether valid
+ if (udma_fill_vtp_node(udma_dev, cfg,
+ &inbuf->body.nodes[inbuf->body.num]) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP, "fill vtp node failed\n");
+ return -EINVAL;
+ }
+ inbuf->body
+ .num++; // reaching 32 then will flush down, this count convenient will return 0; nodes to be flushed to microcode stored in order
+
+ return udma_cmd_check_body_full_proc(udma_dev, buf, inbuf);
+}
+
+// full VTP flush down complete, received incremental destroy VTP request, convert to create operation
+int udma_cmd_restore_vtp_modify_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct udma_vtp_buf *buf,
+ struct ubcore_vtp_attr *attr)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_buf =
+ (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ struct ub_cmd_vtp_restore *inbuf =
+ (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+ u32 new_tpn;
+ int ret;
+
+ ret = udma_cmd_modify_get_new_tpn(udma_dev, cfg, attr, &new_tpn);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Modify vtpn: get new tpn failed, ret:%d.\n", ret);
+ return ret;
+ }
+ if (udma_fill_vtp_node(udma_dev, cfg,
+ &inbuf->body.nodes[inbuf->body.num]) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP, "fill vtp node failed\n");
+ return -EINVAL;
+ }
+ inbuf->body.nodes[inbuf->body.num].id = new_tpn;
+ inbuf->body.num++;
+
+ return udma_cmd_check_body_full_proc(udma_dev, buf, inbuf);
+}
+
+// full VTP flush down complete, received incremental destroy VTP request
+int udma_cmd_restore_vtp_destroy_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp *vtp,
+ struct udma_vtp_buf *buf)
+{
+ int ret;
+ struct tag_cqm_cmd_buf *cqm_cmd_buf =
+ (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ struct ub_cmd_vtp_restore *inbuf =
+ (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+
+ ret = udma_cmd_check_body_full_proc(udma_dev, buf, inbuf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "destroy vtpn: send restore vtp cmd msg failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ inbuf->body.nodes[inbuf->body.num].vtpn =
+ vtp->cfg.vtpn; // only care about vtpn and destroy i.e. can, no need to care about other parameters
+ inbuf->body.nodes[inbuf->body.num].destroy =
+ UDMA_RESTORE_VTPN_DESTROY; // matching microcode processing
+ inbuf->body
+ .num++; // nodes to be flushed to microcode stored in order, 32(count word) elements may contain both chain-delete and chain-create requests
+
+ return udma_cmd_check_body_full_proc(udma_dev, buf, inbuf);
+}
+
+int udma_cmd_restore_vtp_create_multi_vld(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf, u32 num)
+{
+ int ret;
+ u32 i;
+
+ struct tag_cqm_cmd_buf *cqm_cmd_buf =
+ (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ struct ub_cmd_vtp_restore *inbuf =
+ (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+
+ inbuf->body.num = num;
+ for (i = 0; i < num; i++) {
+ udma_fill_cmd_vtp_restore_body_node(udma_dev, buf,
+ &inbuf->body.nodes[i]);
+ }
+ udma_cpu_to_be32(inbuf, sizeof(struct ub_cmd_vtp_restore));
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_RESTORE_CTX, cqm_cmd_buf,
+ NULL, NULL, NULL);
+ if (ret != 0)
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "create all vld: send restore vtp cmd msg failed: %d\n",
+ ret);
+ udma_cmd_init_inoutbuf(inbuf, buf->func_id);
+
+ return ret;
+}
+
+int udma_cmd_restore_vtp_remain_vtpn(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_buf =
+ (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ struct ub_cmd_vtp_restore *inbuf =
+ (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+
+ if (inbuf->body.num != 0) {
+ return udma_cmd_send_restore_ctx(udma_dev, buf, inbuf);
+ }
+ return 0;
+}
+
+void *udma_cmd_restore_vtp_get_cqm_cmd_buf(struct udma_device *udma_dev,
+ u32 vfid)
+{
+ int ret;
+ struct tag_cqm_cmd_buf *cqm_cmd_buf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_restore);
+ struct ub_cmd_vtp_restore *vtp_restore_inbuf = NULL;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_buf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to alloc in_buffer for vtp_restore_inbuf, ret = %d.\n",
+ ret);
+ return NULL;
+ }
+
+ vtp_restore_inbuf = (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+ udma_fill_cmd_header(&vtp_restore_inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_RESTORE_CTX, cmd_len, 0);
+ vtp_restore_inbuf->body.vfid = vfid;
+
+ return cqm_cmd_buf;
+}
+
+int udma_cmd_query_vtp(struct udma_device *udma_dev, u32 vfid, u32 vtp_id,
+ struct ub_vtp_ctx_query *outbuf)
+{
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ struct ub_cmd_vtp_query *vtp_query_inbuf = NULL;
+ struct ub_vtp_ctx_query *vtp_query_outbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_query);
+ int ret;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ sizeof(struct ub_cmd_vtp_query),
+ &cqm_cmd_outbuf,
+ sizeof(struct ub_vtp_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "failed to allocate cqm inbuf\n");
+ return -ENOMEM;
+ }
+
+ vtp_query_inbuf = (struct ub_cmd_vtp_query *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&vtp_query_inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_QUERY_CTX, cmd_len, vtp_id);
+
+ vtp_query_inbuf->body.func_id = vfid;
+
+ udma_cpu_to_be32(vtp_query_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_QUERY_CTX, cqm_cmd_inbuf,
+ cqm_cmd_outbuf, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "failed to send cqm cmd, vtp_id:%u, ret = %d.\n",
+ vtp_id, ret);
+ goto err_send_cmd;
+ }
+
+ vtp_query_outbuf = (struct ub_vtp_ctx_query *)cqm_cmd_outbuf->buf;
+ (void)memcpy_s((void *)outbuf, sizeof(struct ub_vtp_ctx_query),
+ (void *)vtp_query_outbuf,
+ sizeof(struct ub_vtp_ctx_query));
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "query vtp ctx form cache success, vtp_id:%u, func_id:%u\n",
+ vtp_id, vtp_query_inbuf->body.func_id);
+
+err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf,
+ cqm_cmd_outbuf);
+
+ return ret;
+}
+
+int udma_cmd_destroy_vtp(struct udma_device *udma_dev, struct ubcore_vtp *vtp)
+{
+ struct ub_cmd_vtp_destory *vtp_destroy_inbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_destory);
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Recv destroy vtp, vtpn: %u, vfid: %u\n", vtp->cfg.vtpn,
+ adapted_ue_idx(&vtp->cfg));
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udma_dev->hwdev, &cqm_cmd_inbuf,
+ (u16)sizeof(struct ub_cmd_vtp_destory), NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to alloc in_buffer for destroy vtp, ret = %d.\n",
+ ret);
+ return ret;
+ }
+
+ vtp_destroy_inbuf = (struct ub_cmd_vtp_destory *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&vtp_destroy_inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_DESTORY_CTX, cmd_len, vtp->cfg.vtpn);
+
+ vtp_destroy_inbuf->body.func_id = adapted_ue_idx(&vtp->cfg);
+
+ udma_cpu_to_be32(vtp_destroy_inbuf, cmd_len);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_DESTORY_CTX, cqm_cmd_inbuf,
+ NULL, NULL, &to_udma_vtp(vtp)->cmdq_rtt);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Send destroy vtp cmd msg failed: %d\n", ret);
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
+
+int udma_cmd_send_modify(struct udma_device *udma_dev, u32 vfid, u32 vtpn,
+ u32 new_tpn)
+{
+ int ret;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_modify);
+ struct ub_cmd_vtp_modify *vtp_modify_inbuf = NULL;
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to alloc in_buffer for vtp_modify_inbuf, ret=%d.\n",
+ ret);
+ return ret;
+ }
+ vtp_modify_inbuf = (struct ub_cmd_vtp_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&vtp_modify_inbuf->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_MODIFY_CTX, cmd_len, vtpn);
+ vtp_modify_inbuf->body.func_id = vfid;
+ vtp_modify_inbuf->body.index = new_tpn;
+
+ udma_cpu_to_be32(vtp_modify_inbuf, cmd_len);
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_MODIFY_CTX, cqm_cmd_inbuf,
+ NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Send modify vtp cmd msg failed, ret=%d\n", ret);
+ }
+
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+ return ret;
+}
+
+int udma_cmd_modify_vtp(struct udma_device *udma_dev, struct ubcore_vtp *vtp,
+ struct ubcore_vtp_attr *attr)
+{
+ u32 new_tpn;
+ int ret;
+
+ ret = udma_cmd_modify_get_new_tpn(udma_dev, &vtp->cfg, attr, &new_tpn);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Modify vtp: get new tpn failed, ret:%d vf:%u.\n", ret,
+ adapted_ue_idx(&vtp->cfg));
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Modify vtp: vf:%u vtpn:%u tpn:%u\n",
+ adapted_ue_idx(&vtp->cfg), vtp->cfg.vtpn, new_tpn);
+
+ return udma_cmd_send_modify(udma_dev, adapted_ue_idx(&vtp->cfg),
+ vtp->cfg.vtpn, new_tpn);
+}
+
+static void
+udma_fill_cmd_vtp_batch_modify_ctx(struct ub_cmd_vtp_batch_modify_body *body,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ body->attr.offset = inbuf->offset;
+ body->attr.length = inbuf->length;
+ body->func_id = inbuf->vf_id;
+
+ udma_cpu_to_be32(body, sizeof(struct ub_cmd_vtp_batch_modify_body));
+
+ udma_cmdq_data_to_context_buf(inbuf->data, inbuf->data_len,
+ (u8 *)&body->attr.vtp_ctx,
+ sizeof(body->attr.vtp_ctx) / sizeof(u8),
+ inbuf->offset);
+}
+
+int udma_cmd_vtp_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ u16 cmd_len = sizeof(struct ub_cmd_vtp_batch_modify);
+ struct ub_cmd_vtp_batch_modify *modify_cmd = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ int ret;
+
+ if (udma_dev->device_type < UDMA_DEV_TYPE_HI1825_V100) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "%s: device_type(%d) not support vtp batch modify ctx\n",
+ __func__, udma_dev->device_type);
+ return -EINVAL;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(udma_dev->hwdev, &cqm_cmd_inbuf,
+ cmd_len, NULL, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "%s: cqm inbuf allocation failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ modify_cmd = (struct ub_cmd_vtp_batch_modify *)cqm_cmd_inbuf->buf;
+ udma_fill_cmd_header(&modify_cmd->header, UB_CMD_TYPE_VTP,
+ UB_CMD_VTP_BATCH_MODIFY_CONTEXT, cmd_len,
+ inbuf->xid);
+ udma_cpu_to_be32(modify_cmd, sizeof(modify_cmd->header));
+
+ udma_fill_cmd_vtp_batch_modify_ctx(&modify_cmd->body, inbuf);
+
+ ret = udma_send_cmd_box(udma_dev, UB_CMD_VTP_BATCH_MODIFY_CONTEXT,
+ cqm_cmd_inbuf, NULL, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "%s: send cmd failed, ret(%d)\n", __func__, ret);
+ goto batch_err_send_cmd;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_VTP, "%s: success, tpn(%u)\n", __func__,
+ inbuf->xid);
+
+batch_err_send_cmd:
+ (void)udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, cqm_cmd_inbuf, NULL);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.h
new file mode 100644
index 000000000..7889b7717
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/cmdq/udma_cmd_vtp.h
@@ -0,0 +1,57 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_CMD_VTP_H
+#define UDMA_CMD_VTP_H
+
+#include <linux/types.h>
+
+#include "ubcore_api.h"
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+
+#define UB_MAX_VTP_NUM (128 * 1024)
+
+typedef void (*udma_cmd_restore_vtp_handler)(struct udma_device *udma_dev,
+ struct ub_cmd_vtp_restore *inbuf,
+ struct udma_vtp_buf *buf,
+ void *para);
+
+int udma_fill_vtp_node(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct ub_cmd_restore_vtp_node *node);
+int udma_cmd_restore_vtp_create_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct udma_vtp_buf *buf);
+int udma_cmd_restore_vtp_modify_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct udma_vtp_buf *buf,
+ struct ubcore_vtp_attr *attr);
+int udma_cmd_restore_vtp_destroy_vtpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp *vtp,
+ struct udma_vtp_buf *buf);
+int udma_cmd_restore_vtp_create_multi_vld(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf, u32 num);
+int udma_cmd_restore_vtp_remain_vtpn(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf);
+void *udma_cmd_restore_vtp_get_cqm_cmd_buf(struct udma_device *udma_dev,
+ u32 vfid);
+int udma_cmd_create_vtp(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg, struct cmdq_rtt *rtt);
+int udma_cmd_query_vtp(struct udma_device *udma_dev, u32 vfid, u32 vtp_id,
+ struct ub_vtp_ctx_query *outbuf);
+int udma_cmd_destroy_vtp(struct udma_device *udma_dev, struct ubcore_vtp *vtp);
+int udma_get_rc_tpn(struct udma_device *udma_dev, struct ubcore_tpg *tpg);
+int udma_cmd_modify_get_new_tpn(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct ubcore_vtp_attr *attr, u32 *new_tpn);
+int udma_cmd_send_modify(struct udma_device *udma_dev, u32 vfid, u32 vtpn,
+ u32 new_tpn);
+int udma_cmd_modify_vtp(struct udma_device *udma_dev, struct ubcore_vtp *vtp,
+ struct ubcore_vtp_attr *attr);
+int udma_cmd_vtp_batch_modify_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_abi.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_abi.h
new file mode 100644
index 000000000..9764af30f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_abi.h
@@ -0,0 +1,62 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#ifndef UDMA_ABI_H
+#define UDMA_ABI_H
+
+#include <linux/types.h>
+#include "udma_common.h"
+
+typedef struct ub_create_ctx_resp {
+ u32 async_fd;
+ u32 num_comp_vectors;
+ u32 cap_flags;
+ u64 db_addr;
+ u32 max_jfc;
+ u32 max_jfs;
+ u32 max_jfr;
+ u32 max_jetty;
+ u32 max_jfs_inline_size;
+ u32 max_jfs_sge;
+ u32 max_jfs_rsge;
+ u32 max_jfr_sge;
+ u32 dwqe_size;
+ u16 db_offset;
+ u16 dwqe_offset;
+ u32 dwqe_dis : 1;
+ u32 mtt_pro_en : 1;
+ u32 debug_en : 1;
+ u32 dcs_en : 1;
+ u32 index_queue_en : 1;
+ u32 fis_en : 1;
+ u32 rsv : 26;
+ enum udma_device_type device_type;
+ enum ub_env_type env_type;
+} ub_create_ctx_resp_t;
+
+struct ub_create_jetty_ucmd {
+ u64 buf_addr;
+ u64 db_addr;
+ u64 sdb_addr;
+ u32 buf_size;
+ u32 jfr_id;
+ u64 index_q_buf_addr;
+ u64 srq_sdb_addr;
+ u32 index_q_buf_size;
+ u32 sq_wqebb_cnt;
+ u32 rsvd[32];
+};
+
+struct ub_modify_jetty_uinfo {
+ u32 id;
+ u32 sq_pi;
+};
+
+struct ub_create_jetty_resp {
+ u32 cos;
+ u32 slice;
+ u32 jetty_round;
+ u8 pattern;
+};
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.c
new file mode 100644
index 000000000..1d102eb15
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.c
@@ -0,0 +1,84 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#include "udma_log.h"
+#include "udma_bitmap.h"
+
+struct udma_bitmap *udma_bitmap_alloc(u32 bitmap_size)
+{
+ struct udma_bitmap *bitmap = NULL;
+
+ bitmap = (struct udma_bitmap *)kzalloc(sizeof(struct udma_bitmap),
+ GFP_KERNEL);
+ if (bitmap == NULL) {
+ udma_pr_err(UDMA_M_BITMAP, "%s: unable to alloc bitmap",
+ __func__);
+ return NULL;
+ }
+
+ spin_lock_init(&bitmap->lock);
+ bitmap->bits = (unsigned long *)kzalloc(
+ BITS_TO_LONGS(bitmap_size) * sizeof(unsigned long), GFP_KERNEL);
+ if (bitmap->bits == NULL) {
+ udma_pr_err(UDMA_M_BITMAP, "%s: unable to alloc bitmap->bits",
+ __func__);
+ kfree(bitmap);
+ return NULL;
+ }
+
+ bitmap->size = bitmap_size;
+ return bitmap;
+}
+
+void udma_bitmap_free(struct udma_bitmap *bitmap)
+{
+ if (bitmap != NULL) {
+ kfree(bitmap->bits);
+ bitmap->bits = NULL;
+ kfree(bitmap);
+ }
+}
+
+u32 udma_bitmap_alloc_id(struct udma_bitmap *bitmap)
+{
+ u32 index = 0;
+ u32 max_num = bitmap->size;
+ u32 offset = bitmap->last;
+ unsigned long *table = bitmap->bits;
+
+ spin_lock(&bitmap->lock);
+
+ /* Search for an idle bit from the offset position. */
+ index = (u32)find_next_zero_bit(table, max_num, offset);
+ /* The preceding search fails. Search for an idle bit
+ * from the beginning.
+ */
+ if (index >= max_num) {
+ offset = 0;
+ index = (u32)find_next_zero_bit(table, max_num, offset);
+ }
+
+ /* Set the found bit to 1 and reset offset. */
+ if (index < max_num) {
+ set_bit(index, table);
+
+ bitmap->last = index + 1;
+ }
+
+ spin_unlock(&bitmap->lock);
+ return index;
+}
+
+void udma_bitmap_free_id(struct udma_bitmap *bitmap, u32 id)
+{
+ spin_lock(&bitmap->lock);
+
+ if (id >= bitmap->size) {
+ spin_unlock(&bitmap->lock);
+ return;
+ }
+
+ clear_bit(id, bitmap->bits);
+
+ spin_unlock(&bitmap->lock);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.h
new file mode 100644
index 000000000..704c472e1
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_bitmap.h
@@ -0,0 +1,27 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef CPU_UDMA_BITMAP_H
+#define CPU_UDMA_BITMAP_H
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#define UDMA_NUM_BIT_BYTE 8
+#define UDMA_BYTE_BIT_SHIFT 3
+
+typedef struct udma_bitmap {
+ unsigned long *bits;
+ u32 size;
+ u32 last;
+ spinlock_t lock;
+} udma_bitmap_t;
+
+udma_bitmap_t *udma_bitmap_alloc(u32 bitmap_size);
+void udma_bitmap_free(udma_bitmap_t *bitmap);
+u32 udma_bitmap_alloc_id(udma_bitmap_t *bitmap);
+void udma_bitmap_free_id(udma_bitmap_t *bitmap, u32 id);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_common.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_common.h
new file mode 100644
index 000000000..91e2d2747
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_common.h
@@ -0,0 +1,489 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_COMMON_H
+#define UDMA_COMMON_H
+
+#include <asm/byteorder.h>
+#include <linux/fwnode.h>
+#include <linux/irqdomain.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+#include <linux/uaccess.h>
+
+#include "securec.h"
+#include "hinic5_crm.h"
+#include "hinic5_cqm.h"
+#include "vram_common.h"
+#include "hinic5_common.h"
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+#include "hinic5_lld.h"
+#include "ubcore_api.h"
+#include "udma_base_common.h"
+#include "udma_bitmap.h"
+#include "udma_comp.h"
+#include "udma_log.h"
+#include "udma_sysfs_api.h"
+#include "ub_mpu_cmd_defs.h"
+
+extern u32 g_mtt_page_size;
+
+#define UDMA_DRV_DESC "UBus UDMA Driver"
+#define UDMA_DRV_VERSION GLOBAL_VERSION_STR
+
+#define MAX_CEQ_NEED 256
+#define TP_POOL_QUEUE_NUM 8192
+
+#define UB_DEFAULT_SLICE_SIZE (0x10000) /* 64K */
+
+#define UB_DEFAULT_PORT_NUM 1
+
+#define UB_BDF_BUS_BIT 8
+#define UB_BDF_DEVICE_ID_BIT 3
+#define UB_BDF_DEVICE_ID_MASK 0x1F
+#define UB_BDF_FUNC_ID_MASK 0x7
+#define UB_FUNCTION_MAX_NUM 2048
+#define UB_DEVID_BUS_U8_OFF 2
+#define UB_DEVID_DEVICE_U8_OFF 1
+#define UB_SPU_HOST_ID 0x4
+
+#define UDMA_DSCP_NUM 64
+#define UDMA_DSCP_MAX 63
+#define UDMA_COS_MAX 7
+
+#define SCQC_VTP_START(udma_dev) \
+ ((udma_dev)->ub_cap.dev_cap_res.udma_res.max_jfrc_num)
+#define SCQC_JETTY_GRP_START(udma_dev) \
+ ((udma_dev)->ub_cap.dev_cap_res.sdk_res.max_vtp)
+#define SCQC_JFC_START(udma_dev) \
+ (SCQC_JETTY_GRP_START(udma_dev) + \
+ (udma_dev)->ub_cap.dev_cap_res.sdk_res.max_jetty_grp)
+#define SCQC_UTP_START(udma_dev) \
+ ((udma_dev)->ub_cap.dev_cap.max_tp + (udma_dev)->ub_cap.dev_cap.max_tpg)
+
+#define UDMA_MAX_MIG_VF_NUM 2
+#define UDMA_MAX_MIG_VF_ID_NUM 64 //live migration of vfid range in [64, 127], total 64(count word)
+#define UDMA_MIG_VFID_MIN 64
+#define UDMA_MIG_VFID_MAX 127
+#define UDMA_IS_MIG_VFID(vfid) \
+ (((vfid) >= UDMA_MIG_VFID_MIN) && ((vfid) <= UDMA_MIG_VFID_MAX))
+#define UDMA_GET_MIG_VF_IDX(vfid) \
+ ((vfid)-UDMA_MIG_VFID_MIN) //used for get live migration manage buffer array of index
+
+#define EID_ERR_VFID 0xffff
+
+#define UDMA_JETTY_CTX_DW4 4
+#define UDMA_JETTY_CTX_STATE_OFFSET 80
+
+#define UDMA_STATE_IN_DW_OFFSET 27
+#define UDMA_STATE_IN_DW_MASK 0x7
+
+#define UDMA_IDX_QUEUE_LTH_IN_DW_OFFSET 16
+
+#define UDMA_MASK_VALID 1
+#define UDMA_MASK_INVALID 0
+
+#define CLOCK_SIZE_OF_INT 32
+
+enum udma_restore_vtpn_type {
+ UDMA_RESTORE_VTPN_CREATE = 0,
+ UDMA_RESTORE_VTPN_DESTROY,
+};
+
+enum udma_vtpn_vld {
+ UDMA_MIG_BUF_IDLE = 0,
+ UDMA_MIG_BUF_USED,
+};
+
+enum udma_vtpn_restore_type {
+ UDMA_MIG_VTPN_STORE_CMDQ = 0,
+ UDMA_MIG_VTPN_STORE_BUF,
+};
+
+enum udma_mig_status {
+ UDMA_MIG_IDLE = 0, //idle status, not start live migration
+ //1 - full cache: start same step VTP ~ VTP full flush down complete before (pre_activate stage segment complete flush down)
+ UDMA_MIG_FULL_VOLUME,
+ //2 - incremental cache: full VTP flush down complete after ~ incremental VTP flush down complete before (restore stage segment complete flush down)
+ UDMA_MIG_INCREMENTAL,
+ //3 - incremental modify cache: incremental VTP flush down complete after ~ incremental modify_vtp flush down complete before (restore stage segment complete flush down)
+ UDMA_MIG_INCREMENTAL_MODIFY,
+ //4 - normal flush down: incremental modify_vtp flush down complete after ~ live migration buf free before (resource free by UVS via config_device control)
+ UDMA_MIG_NORMAL,
+};
+
+enum ub_transport_mode {
+ UB_TRANSPORT_MODE_RC = 0,
+ UB_TRANSPORT_MODE_RM,
+ UB_TRANSPORT_MODE_UM,
+ UB_TRANSPORT_MODE_RCQ,
+ UB_TRANSPORT_MODE_RSC,
+};
+
+enum udma_cqmobj_priv_type {
+ UDMA_JETTY_TYPE_INVALID = 0,
+ UDMA_JETTY_TYPE_JETTY,
+ UDMA_JETTY_TYPE_JFS,
+ UDMA_JETTY_TYPE_JFR,
+ UDMA_JETTY_TYPE_RC,
+ UDMA_CQM_PRIV_TYPE_TP,
+ UDMA_CQM_PRIV_TYPE_JFC,
+ UDMA_CQM_PRIV_TYPE_JETTY_GRP,
+ UDMA_CQM_PRIV_TYPE_UTP,
+ UDMA_CQM_PRIV_TYPE_VTPN,
+ UDMA_CQM_PRIV_TYPE_SRQ,
+};
+
+enum udma_vf_mig_status_e {
+ UDMA_VF_MIG_END = 0,
+ UDMA_VF_MIG_START,
+};
+
+enum ub_env_type {
+ UB_ENV_ASIC = 0, /* asic */
+ UB_ENV_ESL = 1, /* esl */
+ UB_ENV_FPGA = 2, /* fpga */
+ UB_ENV_EMU = 3, /* emu */
+};
+
+struct udma_vf_mig_status_in { //user ctrl opcode 0x3: and UVS agreement of data structure, used for live migration when notify current VF whether start migration
+ u16 vfid;
+ u16 sts; //0: non- live migration status; 1: migration state
+};
+
+struct udma_vf_mig_status_out { //user ctrl opcode 0x3: command result
+ s32 result; //0 : success ; other : fail
+};
+
+struct udma_mig_vf_status_in { //user ctrl opcode 0x4: and UVS agreement of data structure, used for live migration when query VF whether passthrough into VM
+ u16 vfid;
+};
+
+struct udma_mig_vf_status_out { //user ctrl opcode 0x4: query result
+ s32 result; //0: MIG_VF_IN_VM; 1: MIG_VF_NOT_IN_VM; 2: other error
+};
+
+struct udma_dev_cfg_info {
+ u8 scenes_id; /* cfg data scenes ID */
+ u8 lb_en; /* load balance enable */
+ u8 lb_mode; /* load balance mode */
+ u8 rsvd;
+
+ u8 fake_en; /* whether enable fake_vf */
+ u8 page_bit; /* db page address offset */
+ u8 pf_start_bit; /* fake vf in pf start bit bit */
+ u8 pf_end_bit; /* fake vf in pf end bit bit */
+};
+
+struct udma_dev_hw_info {
+ u32 config_num_ports; /* Number of ports from configuration file */
+ u32 hca_type; /* HCA version: 4x25G or 2x100G */
+ u8 phy_port; /* from pci_priv_dev in mention take out roce device corresponding to physical port */
+ u8 ep_id; /* EP ID */
+ u8 cpu_endian; /* 0: little-endian,1: big-endian */
+ u8 rsvd;
+ bool is_vf; /* PF/VF of indicate, from pci_priv_dev get to */
+};
+
+struct udma_tp_sq {
+ struct tag_cqm_queue *sq_info;
+ struct mtt ub_mtt;
+};
+
+struct udma_tp_rq {
+ struct ubrc rc_table;
+};
+
+struct udma_tp_pool {
+ struct udma_tp_sq *sq_list[TP_POOL_QUEUE_NUM];
+ struct udma_tp_rq *rq_list[TP_POOL_QUEUE_NUM];
+ bool is_created_tx;
+ bool is_created_rx;
+};
+
+struct ub_dev_cap_res {
+ struct ub_dev_cap_sdk_res sdk_res; /* definition in sdk */
+ struct ub_dev_cap_udma_res udma_res;
+};
+
+struct udma_device_cap {
+ struct ub_dev_cap_res dev_cap_res;
+ struct ub_dev_cap dev_cap;
+ struct ub_net_dev_cap net_dev_cap;
+};
+
+struct udma_vtp_buf {
+ struct mutex vf_mutex;
+ void *addr; //cache VTPN of buffer(capacity amount 128K), used for " full cache " and " incremental modify cache " stage segment, refer to enum udma_mig_status
+ void *cqm_cmd_buf; //used for " incremental cache " stage segment, via DMA way to microcode send request, single time maximum carry 32 node, struct tag_cqm_cmd_buf
+ u32 total; //current 128K buffer in status is " occupy " of VTP node total data, each VF maximum 128K - 64(count word)
+ u32 cur_idx; //full flush down VTP table, used to indicate each one 轮 flush down (each time at most flush down 32) after already traverse to of VTP table entry bit position, used for mention high traverse valid率
+ u8 mig_sts; //flag: current VF migration state enum udma_mig_status
+ u8 rsvd;
+ u16 func_id; //current VF of ID
+};
+
+struct udma_mig_vf_mgt {
+ struct mutex
+ mig_vf_mgt_mutex; //global lock, newly added live migration VM or VM migration end when need add lock
+ struct udma_vtp_buf
+ buf_array[UDMA_MAX_MIG_VF_ID_NUM]; //via index index corresponding VF
+ u8 migrating_num; //current currently at at live migration process in of VM count
+ u8 rsv[3];
+};
+
+typedef struct udma_dev_bdf_info {
+ u8 bus_id;
+ u8 device_id;
+ u8 func_id;
+ u8 bdf_info_vld;
+ u8 host_id;
+} udma_dev_bdf_info_s;
+
+/* current increasedevice queue(such as wqe/cqe buffer etc.) of one kind new allocate way, via dma interface allocate continuous physical memory,
+ * newly added this data structure store continuous physical memory base this information.
+ */
+struct queue_addr_info {
+ void *va; /* queue va */
+ dma_addr_t pa; /* queue pa */
+ u32 size; /* queue size */
+ struct hinic5_dma_addr_align mem_align;
+};
+
+/* statistics cmdq latency */
+struct cmdq_rtt {
+ atomic64_t cmdq_rtt_sum; /* cmdq send start to cmdq complete return driver of total time */
+ atomic64_t times; /* driver send down cmdq return success count */
+ atomic64_t cmdq_npu_rtt_sum; /* microcode from wake cmdq to complete handle generate CQE of total time */
+};
+
+/* remote command queue */
+struct udma_rc_queue {
+ u32 cqm_priv_type;
+ struct tag_cqm_qpc_mpt *rc_ctx;
+ struct mtt ub_mtt;
+ struct tag_cqm_queue *rc_queue;
+ struct tag_cqm_queue *pcqc; /* producer consumer queue context */
+ struct queue_addr_info queue_addr;
+ void *rcq_va; /* rcq actual virtual addr */
+ u32 total_depth; /* rc queue total number of wqes */
+ u32 total_size; /* queue total size = UB_RCQE_SIZE * total_depth */
+ struct list_head node;
+ struct ubrc ubrc;
+ u32 rsp_depth;
+ struct cmdq_rtt cmdq_rtt;
+};
+
+struct udma_object_n_record {
+ struct mutex mutex;
+ u32 num;
+};
+
+struct udma_default_cos {
+ u8 cfg_cos_en; /* supports user configuration cos value, enable: 1(supports user configuration) disable: 0(not support user configuration, use default cos value) default: 0(same disable) */
+ u8 func_cos;
+ u16 vf_default_cos; /* default value: 5 */
+ u16 pf_default_cos; /* default value: 4 */
+ u16 jfrc_cos; /* default value: 2 */
+};
+
+typedef struct udma_driver_device_ctr {
+ atomic64_t post_send_wr_num;
+ atomic64_t post_recv_wr_num;
+ atomic64_t poll_total_num;
+ atomic64_t poll_sq_num;
+ atomic64_t poll_rq_num;
+} udma_driver_device_ctr_t;
+
+typedef struct udma_device {
+ struct ubcore_device ub_dev;
+ struct device *dev;
+ struct net_device *ndev;
+ void *hwdev;
+ union ubcore_eid eid;
+ u32 tp_num;
+ atomic_t task_jfs_num;
+ struct mutex dev_mutex;
+ struct mutex tp_mutex;
+ struct udma_device_cap ub_cap;
+ u64 feat_bitmap[UB_FEAT_BITMAP_U64_MAX];
+ int numa_original_node_id;
+ bool numa_original_node_id_valid;
+
+ int ceq_num;
+ int ceqn[MAX_CEQ_NEED];
+
+ void __iomem *kernel_db_map;
+ void __iomem *kernel_dwqe_map;
+
+ struct udma_dev_cfg_info cfg_info;
+ struct udma_dev_hw_info hw_info;
+
+ struct udma_rc_queue rsvd_qpc; /* reserved xid 0 of qpc */
+ struct udma_rc_queue *rc_queue;
+ u32 rc_queue_cnt; /* already configured RC queue of count */
+ u32 is_rc_queue_configured; /* whether already configuration RC flag, avoid repeat configuration */
+
+ u32 jfs_current_cnt;
+ atomic_t jfs_hash;
+ atomic_t jfr_hash;
+ atomic_t rs_hash;
+ udma_driver_device_ctr_t udma_driver_device_ctr;
+
+ char dev_name[UBCORE_MAX_DEV_NAME];
+
+ u32 local_en;
+ u8 capture_en; /* 1: capture packet enable 0: capture packet disable */
+ u8 host_id;
+
+ struct udma_device_res *device_res;
+ struct udma_bitmap *bitmap; /* tpg bitmap */
+ struct udma_sysfs_res sysfs_res;
+
+ u8 slice_cfg_en; /* 1: slice can configure 0: slice cannot configure */
+ u8 latch_tpg_configured; /* whether already configuration TP Latch flag, avoid repeat configuration */
+ u32 slice;
+ u32 suspend_period;
+ u32 suspend_cnt;
+
+ u8 mtu_1k_en; /* 1: supports DFX configuration 1K mtu of value 0: default udma only supports configuration 4K, 8K MTU */
+ bool index_queue_en; /* todo pending ub mpu adaptation feat_bitmap after delete, use feat_bitmap to get enable */
+
+ unsigned long status;
+
+ struct udma_tp_pool tp_pool;
+
+ struct udma_mig_vf_mgt mig_vf_mgt;
+ u32 fastmsg_connect;
+
+ struct notifier_block netdev_nb;
+
+ enum mag_cmd_port_speed speed;
+ struct udma_dev_bdf_info *bdf_info;
+ struct mutex bdf_mutex;
+ u32 bdf_cnt;
+ u64 dscp_bitmap;
+ u8 dscp2cos[UDMA_DSCP_NUM];
+ struct udma_default_cos default_cos;
+
+ struct udma_object_n_record jettyn_record;
+ struct udma_object_n_record tpn_record;
+ struct udma_object_n_record jfcn_record;
+ struct udma_object_n_record vtpn_record;
+ struct udma_object_n_record utpn_record;
+ struct udma_object_n_record tpgn_record;
+ struct udma_object_n_record jetty_grpn_record;
+ struct udma_object_n_record srqn_record;
+
+ spinlock_t dwqe_lock;
+
+ enum udma_device_type device_type; /* device type */
+ enum ub_env_type env_type; /* environment type */
+ enum hinic5_dev_type dev_bus_type;
+ u64 card_id;
+ struct {
+ u64 pa;
+ void *va;
+ } fake_dma_addr;
+} udma_device_t;
+
+struct udma_bus_addr {
+ uint32_t domain; /* Device domain */
+ uint8_t bus; /* Device bus */
+ uint8_t devid; /* Device ID */
+ uint8_t function; /* Device function */
+ uint8_t rsvd; /* Rsvd field for align */
+};
+
+#define UDMA_IS_VF_MIGRATING(status) ((status) != UDMA_MIG_IDLE)
+
+#define UDMA_PCI_DEV_DBDF(pdev) \
+ (((u32)pci_domain_nr((pdev)->bus) << 16) | \
+ ((pdev)->bus->number << 8) | ((pdev)->devfn))
+
+//PF and VF of domain id all is 0000
+#define UDMA_QUERY_DBDF_BY_BDF_INFO(bus_addr) \
+ (((bus_addr)->domain << 16) | ((bus_addr)->bus << 8) | \
+ ((bus_addr)->devid << 3) | ((bus_addr)->function))
+
+#define UDMA_PCI_DBDF_DOM(dbdf) (((dbdf) >> 16) & 0xFFFF)
+#define UDMA_PCI_DBDF_BUS(dbdf) (((dbdf) >> 8) & 0xFF)
+#define UDMA_PCI_DBDF_DEVID(dbdf) (((dbdf) >> 3) & 0x1F)
+#define UDMA_PCI_DBDF_FUNCTION(dbdf) ((dbdf)&0x7)
+#define UDMA_PCI_DBDF_DEVFN(dbdf) ((dbdf)&0xFF)
+
+#define udma_container_of(ptr, type, member) \
+ (((ptr) == NULL) ? NULL : container_of(ptr, type, member))
+
+static inline struct udma_vtp_buf *
+udma_mig_get_vf_buf(struct udma_device *udma_dev, u32 vfid)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ return &mig_mgt->buf_array[UDMA_GET_MIG_VF_IDX(vfid)];
+}
+
+static inline struct udma_device *
+to_udma_dev(const struct ubcore_device *ub_dev)
+{
+ return (struct udma_device *)udma_container_of(
+ ub_dev, struct udma_device, ub_dev);
+}
+
+static inline u32 udma_dev_is_tpf(struct udma_device *udma_dev)
+{
+ return udma_dev->ub_cap.net_dev_cap.is_tpf;
+}
+
+static inline void
+udma_fill_kernel_queue_addr_info(u32 queue_len,
+ struct queue_addr_info *queue_addr)
+{
+ queue_addr->va = queue_addr->mem_align.align_vaddr;
+ queue_addr->pa = queue_addr->mem_align.align_paddr;
+ queue_addr->size = queue_len;
+}
+
+void udma_get_dev_name(struct udma_device *udma_dev);
+
+static inline bool udma_get_index_queue_en(struct udma_device *udma_dev)
+{
+ return udma_dev->index_queue_en;
+}
+
+#define adapted_ue_idx(cfg) (cfg)->ue_idx
+#define adapted_type_ue_idx(cfg, type) (cfg)->type##_ue_idx
+typedef struct ubcore_ue_stats adapted_ubcore_ue_stats;
+
+#if defined(__x86_64__)
+static inline uint64_t udma_get_cycles_dfx(void)
+{
+ uint32_t low, high;
+ uint64_t val;
+ asm volatile("rdtsc" : "=a"(low), "=d"(high));
+ val = high;
+ val = (val << CLOCK_SIZE_OF_INT) | low;
+ return val;
+}
+#elif defined(__aarch64__)
+static inline uint64_t udma_get_cycles_dfx(void)
+{
+ uint64_t freq;
+ asm volatile("isb" : : : "memory");
+ asm volatile("mrs %0, cntvct_el0" : "=r"(freq));
+ return freq;
+}
+#else
+#warning get_cycles not implemented
+#endif
+
+#define UDMA_MAX_DEV_NAME 64
+#define UDMA_MAX_CHIP_NAME 64
+
+#endif /* UDMA_H */
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.c
new file mode 100644
index 000000000..b208421dd
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.c
@@ -0,0 +1,67 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Hisilicon Technologies Co., Ltd. 2021. All rights reserved.
+
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 90))
+#include <linux/types.h>
+#else
+#include <linux/auxiliary_bus.h>
+#endif
+
+#include "securec.h"
+#include "hinic5_hw.h"
+#include "udma_cqm.h"
+
+void udma_cqm5_cmd_free_inoutbuf(void *ex_handle, cqm_cmd_buf_s *cqm_cmd_inbuf,
+ cqm_cmd_buf_s *cqm_cmd_outbuf)
+{
+ if (cqm_cmd_outbuf != NULL) {
+ cqm5_cmd_free(ex_handle, cqm_cmd_outbuf);
+ }
+
+ if (cqm_cmd_inbuf != NULL) {
+ cqm5_cmd_free(ex_handle, cqm_cmd_inbuf);
+ }
+}
+
+int udma_cqm_cmd_zalloc_inoutbuf(void *ex_handle, cqm_cmd_buf_s **cqm_cmd_inbuf,
+ u16 inbuf_size, cqm_cmd_buf_s **cqm_cmd_outbuf,
+ u16 outbuf_size)
+{
+ int ret;
+
+ if (cqm_cmd_inbuf != NULL) {
+ *cqm_cmd_inbuf = cqm5_cmd_alloc(ex_handle);
+
+ if (*cqm_cmd_inbuf == NULL) {
+ return -ENOMEM;
+ }
+ (*cqm_cmd_inbuf)->size = inbuf_size;
+
+ (void)memset_s((*cqm_cmd_inbuf)->buf, inbuf_size, 0,
+ inbuf_size);
+ }
+
+ if (cqm_cmd_outbuf != NULL) {
+ *cqm_cmd_outbuf = cqm5_cmd_alloc(ex_handle);
+
+ if (*cqm_cmd_outbuf == NULL) {
+ ret = -ENOMEM;
+ goto err_alloc_outbuf;
+ }
+ (*cqm_cmd_outbuf)->size = outbuf_size;
+
+ (void)memset_s((*cqm_cmd_outbuf)->buf, outbuf_size, 0,
+ outbuf_size);
+ }
+
+ return 0;
+
+err_alloc_outbuf:
+ if (cqm_cmd_inbuf != NULL && *cqm_cmd_inbuf != NULL) {
+ cqm5_cmd_free(ex_handle, *cqm_cmd_inbuf);
+ *cqm_cmd_inbuf = NULL;
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.h
new file mode 100644
index 000000000..f06c352bf
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_cqm.h
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Hisilicon Technologies Co., Ltd. 2021. All rights reserved.
+
+#ifndef _UDMA_CQM_H
+#define _UDMA_CQM_H
+
+#include <linux/types.h>
+#include "hinic5_hw.h"
+#include "hinic5_cqm.h"
+#include "hmm_common.h"
+#include "hmm_em_inner.h"
+
+int udma_cqm_cmd_zalloc_inoutbuf(void *ex_handle, cqm_cmd_buf_s **cqm_cmd_inbuf,
+ u16 inbuf_size, cqm_cmd_buf_s **cqm_cmd_outbuf,
+ u16 outbuf_size);
+void udma_cqm5_cmd_free_inoutbuf(void *ex_handle, cqm_cmd_buf_s *cqm_cmd_inbuf,
+ cqm_cmd_buf_s *cqm_cmd_outbuf);
+
+#endif /* _UDMA_CQM_H */
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.c
new file mode 100644
index 000000000..f7a8ccdc1
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.c
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include "udma_log.h"
+
+u32 g_udma_log_level = UDMA_LOG_LEVEL_INFO;
+
+module_param(g_udma_log_level, uint, 0664);
+MODULE_PARM_DESC(g_udma_log_level,
+ "0 for debug, 1 for info, 2 for warn, 3 for error");
+
+bool udma_kernel_log_level_prior(int level)
+{
+ return (((u32)level < g_udma_log_level) ? true : false);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.h
new file mode 100644
index 000000000..893bb4056
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_log.h
@@ -0,0 +1,179 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_LOG_H
+#define UDMA_LOG_H
+
+#include <linux/device.h>
+#include <linux/sched.h>
+
+enum {
+ UDMA_LOG_LEVEL_DEBUG = 0,
+ UDMA_LOG_LEVEL_INFO,
+ UDMA_LOG_LEVEL_WARN,
+ UDMA_LOG_LEVEL_ERR
+};
+
+extern u32 g_udma_log_level;
+
+#define UDMA_M_COM "COM"
+#define UDMA_M_JETTY "Jetty"
+#define UDMA_M_JFC "JFC"
+#define UDMA_M_JFCE "JFCE"
+#define UDMA_M_JFR "JFR"
+#define UDMA_M_SRQ "SRQ"
+#define UDMA_M_JFS "JFS"
+#define UDMA_M_KEY "Key"
+#define UDMA_M_QUERY "Query"
+#define UDMA_M_SEG "Segment"
+#define UDMA_M_TP "TP"
+#define UDMA_M_TPG "TPG"
+#define UDMA_M_VTP "VTP"
+#define UDMA_M_UTP "UTP"
+#define UDMA_M_FMSG "FMSG"
+#define UDMA_M_JFRC "JFRC"
+#define UDMA_M_TPG "TPG"
+#define UDMA_M_MAIN "Main"
+#define UDMA_M_EID "EID"
+#define UDMA_M_MISC "Misc"
+#define UDMA_M_DFX "DFX"
+#define UDMA_M_DEV "DEV"
+#define UDMA_M_SRQ "SRQ"
+#define UDMA_M_SYSFS "SYSFS"
+#define UDMA_M_RX_RATE_LIMITE "RX_RATE_LIMITE"
+#define UDMA_M_CAPTURE_DFX "Capture_DFX"
+#define UDMA_M_CC_INJECT_DFX "CC_INJECT_DFX"
+#define UDMA_M_PORT_STA_DFX "PORT_STA_DFX"
+#define UDMA_M_DROP_DFX "Drop_DFX"
+#define UDMA_M_CQM_MOD_DFX "CQM_MODIFY_DFX"
+#define UDMA_M_GLB_XID_CFG "GLB_XID_CFG"
+#define UDMA_M_DB "DB"
+#define UDMA_M_ASYNC_EVENT "ASYNC_EVENT"
+#define UDMA_M_DCA "DCA"
+#define UDMA_M_RC_TABLE "RC_TABLE"
+#define UDMA_M_RESOURCE "RESOURCE"
+#define UDMA_M_UBRC_COMP "UBRC_COMP"
+#define UDMA_M_USER_CTL "USER_CTL"
+#define UDMA_M_CMD "CMD"
+#define UDMA_M_BOND "BOND"
+#define UDMA_M_SHM "SHM"
+#define UDMA_M_VRAM "VRAM"
+#define UDMA_M_BITMAP "BITMAP"
+
+#define G_TGID task_tgid_nr(current)
+#define G_PID task_pid_nr(current)
+
+#define udma_debug(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_DEBUG) \
+ dev_info(dev, \
+ "[tgid:%u,pid:%u][UDMA5][DEBUG][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_info(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_INFO) \
+ dev_info(dev, \
+ "[tgid:%u,pid:%u][UDMA5][INFO][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_warn(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_WARN) \
+ dev_warn(dev, \
+ "[tgid:%u,pid:%u][UDMA5][WARN][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_err(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_ERR) \
+ dev_err(dev, \
+ "[tgid:%u,pid:%u][UDMA5][ERR][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_info_limit(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_INFO) \
+ dev_info_ratelimited( \
+ dev, \
+ "[tgid:%u,pid:%u][UDMA5][INFO][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_warn_limit(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_WARN) \
+ dev_warn_ratelimited( \
+ dev, \
+ "[tgid:%u,pid:%u][UDMA5][WARN][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_err_limit(dev, module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_ERR) \
+ dev_err_ratelimited( \
+ dev, \
+ "[tgid:%u,pid:%u][UDMA5][ERR][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_pr_info(module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_INFO) \
+ pr_info("[tgid:%u,pid:%u][UDMA5][INFO][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_pr_warn(module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_WARN) \
+ pr_warn("[tgid:%u,pid:%u][UDMA5][WARN][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_pr_err(module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_ERR) \
+ pr_err("[tgid:%u,pid:%u][UDMA5][ERR][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define udma_pr_err_limit(module, fmt, ...) \
+ do { \
+ if (g_udma_log_level <= UDMA_LOG_LEVEL_ERR) \
+ pr_err_ratelimited( \
+ "[tgid:%u,pid:%u][UDMA5][ERR][" module \
+ "][%s:%u]: " fmt, \
+ G_TGID, G_PID, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+bool udma_kernel_log_level_prior(int level);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.c
new file mode 100644
index 000000000..0a04a680a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.c
@@ -0,0 +1,1386 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <net/ipv6.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/iommu.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include "ubcore_api.h"
+/*
+ * Generally, a driver should not include ubcore_uapi.h for kernel users,
+ * the udma_pci driver for simluation calls ubcore_find_jfs/jfrin the ubcore_uapi.h to reduce complexity
+ */
+#include "comm_defs.h"
+#include "ubcore_uapi.h"
+#include "ubcore_types.h"
+#include "hinic5_crm.h"
+#include "hinic5_profile.h"
+#include "ub_mpu_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "ub_pub_cmd.h"
+#include "ub_dw_index.h"
+#include "udma_cqm.h"
+#include "udma_cmd.h"
+#include "udma_net.h"
+#include "udma_segment.h"
+#include "udma_tp.h"
+#include "udma_tpg.h"
+#include "udma_jetty.h"
+#include "udma_jfc.h"
+#include "udma_utp.h"
+#include "udma_vtp.h"
+#include "udma_rc_table.h"
+#include "udma_cmd_com.h"
+#include "udma_misc.h"
+
+#define MAX_DATA_LEN_UB_DFX 8192
+#define DUMP_LINE_BYTE_NUM 16
+#define DUMP_LINE_BYTE_HALF_NUM (DUMP_LINE_BYTE_NUM / 4)
+#define CHAR_BUF_LEN 64
+#define CHAR_WORD_LEN 9
+#define WORD_SIZE 16
+#define FORMAT_SIZE 8
+#define WORD_LEN 4
+#define COS_TA_MASK 0x7
+#define COS_TP_MASK 0x7
+#define COS_TP_DSCP_MASK 0x3f
+
+/* temporary use global change amount configuration cfg_cos_en, iterate fifth modify is udma_dev->default_cos.cfg_cos_en */
+enum { CFG_COS_DISABLE = 0, CFG_COS_ENABLE };
+
+u32 g_udma_cfg_cos_en = CFG_COS_DISABLE;
+module_param(g_udma_cfg_cos_en, uint, 0664);
+MODULE_PARM_DESC(g_udma_cfg_cos_en,
+ "0 for can't config jetty_cos, 1 for can config jetty_cos");
+
+void udma_store_list(struct udma_device *udma_dev, struct list_head *node,
+ struct udma_list *udma_list)
+{
+ if (udma_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "store list node fail, head node is null\n");
+ return;
+ }
+ mutex_lock(&udma_list->node_lock);
+ list_add(node, &udma_list->node);
+ udma_list->cnt++;
+ mutex_unlock(&udma_list->node_lock);
+}
+
+void udma_delete_list(struct udma_device *udma_dev, struct list_head *node,
+ struct udma_list *udma_list)
+{
+ if (udma_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "delete list node fail, head node is null\n");
+ return;
+ }
+ mutex_lock(&udma_list->node_lock);
+ if (node->prev != NULL) {
+ list_del(node);
+ node->prev = NULL;
+ udma_list->cnt--;
+ }
+ mutex_unlock(&udma_list->node_lock);
+}
+
+static void list_lock_init(struct udma_device_res *device_res)
+{
+ mutex_init(&device_res->tpn_list.node_lock);
+ INIT_LIST_HEAD(&device_res->tpn_list.node);
+ mutex_init(&device_res->jfs_list.node_lock);
+ INIT_LIST_HEAD(&device_res->jfs_list.node);
+ mutex_init(&device_res->jfr_list.node_lock);
+ INIT_LIST_HEAD(&device_res->jfr_list.node);
+ mutex_init(&device_res->jetty_list.node_lock);
+ INIT_LIST_HEAD(&device_res->jetty_list.node);
+ mutex_init(&device_res->jfc_list.node_lock);
+ INIT_LIST_HEAD(&device_res->jfc_list.node);
+ mutex_init(&device_res->seg_list.node_lock);
+ INIT_LIST_HEAD(&device_res->seg_list.node);
+ mutex_init(&device_res->jetty_group_list.node_lock);
+ INIT_LIST_HEAD(&device_res->jetty_group_list.node);
+ mutex_init(&device_res->tpg_list.node_lock);
+ INIT_LIST_HEAD(&device_res->tpg_list.node);
+ mutex_init(&device_res->rc_list.node_lock);
+ INIT_LIST_HEAD(&device_res->rc_list.node);
+ mutex_init(&device_res->vtp_list.node_lock);
+ INIT_LIST_HEAD(&device_res->vtp_list.node);
+ mutex_init(&device_res->utp_list.node_lock);
+ INIT_LIST_HEAD(&device_res->utp_list.node);
+ device_res->tpn_list.cnt = 0;
+ device_res->jfs_list.cnt = 0;
+ device_res->jfr_list.cnt = 0;
+ device_res->jetty_list.cnt = 0;
+ device_res->jfc_list.cnt = 0;
+ device_res->seg_list.cnt = 0;
+ device_res->jetty_group_list.cnt = 0;
+ device_res->tpg_list.cnt = 0;
+ device_res->rc_list.cnt = 0;
+ device_res->vtp_list.cnt = 0;
+ device_res->utp_list.cnt = 0;
+}
+
+int udma_dfx_device_init(struct udma_device *udma_dev)
+{
+ udma_dev->device_res = devm_kzalloc(
+ udma_dev->dev, sizeof(struct udma_device_res), GFP_KERNEL);
+ if (udma_dev->device_res == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "alloc device_res failed.\n");
+ return -ENOMEM;
+ }
+
+ list_lock_init(udma_dev->device_res);
+
+ udma_info(udma_dev->dev, UDMA_M_MISC, "init device_res successful\n");
+
+ return 0;
+}
+
+void udma_dfx_device_deinit(struct udma_device *udma_dev)
+{
+ struct udma_device_res *dfx = udma_dev->device_res;
+
+ if (list_empty(&dfx->jetty_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jetty list is not empty\n");
+
+ if (list_empty(&dfx->jetty_group_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jetty group list is not empty\n");
+
+ if (list_empty(&dfx->jfs_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "jfs list is not empty\n");
+
+ if (list_empty(&dfx->jfr_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "jfr list is not empty\n");
+
+ if (list_empty(&dfx->jfc_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "jfc list is not empty\n");
+
+ if (list_empty(&dfx->seg_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "seg list is not empty\n");
+
+ if (list_empty(&dfx->rc_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "rc list is not empty\n");
+
+ if (list_empty(&dfx->tpn_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "tpn list is not empty\n");
+
+ if (list_empty(&dfx->tpg_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "tpg list is not empty\n");
+
+ if (list_empty(&dfx->vtp_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "vtp list is not empty\n");
+
+ if (list_empty(&dfx->utp_list.node) == 0)
+ udma_err(udma_dev->dev, UDMA_M_MISC, "utp list is not empty\n");
+
+ devm_kfree(udma_dev->dev, udma_dev->device_res);
+
+ udma_info(udma_dev->dev, UDMA_M_MISC,
+ "udma_dfx_device_deinit successful\n");
+}
+
+int udma_query_res_dev_tp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_tp *tpn_now = NULL;
+ u32 *tp_list = NULL;
+ u32 cnt;
+ size_t size;
+
+ mutex_lock(&udma_dev->device_res->tpn_list.node_lock);
+ cnt = udma_dev->device_res->tpn_list.cnt;
+ if (cnt > 0) {
+ size = (size_t)cnt * sizeof(u32);
+ tp_list = (u32 *)vmalloc(size);
+ if (tp_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->tpn_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "tp_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = tp_list;
+ list_for_each_entry(
+ tpn_now, &udma_dev->device_res->tpn_list.node, node) {
+ *tp_list = tpn_now->tp_info->xid;
+ tp_list++;
+ }
+ }
+ mutex_unlock(&udma_dev->device_res->tpn_list.node_lock);
+
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_jfs_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_jfs *jfs_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->jfs_list.node_lock);
+ cnt = udma_dev->device_res->jfs_list.cnt;
+ if (cnt > 0) {
+ u32 *jfs_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (jfs_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->jfs_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jfs_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = jfs_list;
+ list_for_each_entry(
+ jfs_now, &udma_dev->device_res->jfs_list.node, node) {
+ *jfs_list = jfs_now->jfs_id;
+ jfs_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->jfs_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_jfr_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_jfr *jfr_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->jfr_list.node_lock);
+ cnt = udma_dev->device_res->jfr_list.cnt;
+ if (cnt > 0) {
+ u32 *jfr_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (jfr_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->jfr_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jfr_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = jfr_list;
+ list_for_each_entry(
+ jfr_now, &udma_dev->device_res->jfr_list.node, node) {
+ *jfr_list = jfr_now->jfr_id;
+ jfr_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->jfr_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_jetty_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_jetty *jetty_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->jetty_list.node_lock);
+ cnt = udma_dev->device_res->jetty_list.cnt;
+ if (cnt > 0) {
+ u32 *jetty_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (jetty_list == NULL) {
+ mutex_unlock(
+ &udma_dev->device_res->jetty_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jetty_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = jetty_list;
+ list_for_each_entry(jetty_now,
+ &udma_dev->device_res->jetty_list.node,
+ node) {
+ *jetty_list = jetty_now->jettyc_info->xid;
+ jetty_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->jetty_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_jfc_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_jfc *jfc_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->jfc_list.node_lock);
+ cnt = udma_dev->device_res->jfc_list.cnt;
+ if (cnt > 0) {
+ u32 *jfc_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (jfc_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->jfc_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "jfc_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = jfc_list;
+ list_for_each_entry(
+ jfc_now, &udma_dev->device_res->jfc_list.node, node) {
+ *jfc_list = jfc_now->base.id;
+ jfc_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->jfc_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_seg_list(struct udma_device *udma_dev,
+ struct ubcore_res_seg_val *ret_val)
+{
+ struct udma_segment *udma_seg = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->seg_list.node_lock);
+ cnt = udma_dev->device_res->seg_list.cnt;
+ if (cnt > 0) {
+ struct ubcore_seg_info *seg_list =
+ (struct ubcore_seg_info *)vmalloc(
+ sizeof(struct ubcore_seg_info) * cnt);
+ if (seg_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->seg_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "seg_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->seg_list = seg_list;
+ list_for_each_entry(
+ udma_seg, &udma_dev->device_res->seg_list.node, node) {
+ seg_list->ubva.eid = udma_dev->eid;
+ seg_list->ubva.va = udma_seg->va;
+ seg_list->len = udma_seg->size;
+ seg_list->token_id = udma_seg->mpt->mpt_index;
+ seg_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->seg_list.node_lock);
+ ret_val->seg_cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_tpg_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_tpg *tpg_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->tpg_list.node_lock);
+ cnt = udma_dev->device_res->tpg_list.cnt;
+ if (cnt > 0) {
+ u32 *val_tpg_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (val_tpg_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->tpg_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "tpg_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = val_tpg_list;
+ list_for_each_entry(
+ tpg_now, &udma_dev->device_res->tpg_list.node, node) {
+ *val_tpg_list = tpg_now->tpg.tpgn;
+ val_tpg_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->tpg_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_rc_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_rc_queue *rc_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->rc_list.node_lock);
+ cnt = udma_dev->device_res->rc_list.cnt;
+ if (cnt > 0) {
+ u32 *val_rc_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (val_rc_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->rc_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "val_rc_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = val_rc_list;
+ list_for_each_entry(rc_now, &udma_dev->device_res->rc_list.node,
+ node) {
+ *val_rc_list = rc_now->rc_ctx->xid;
+ val_rc_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->rc_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_vtp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_vtp *vtp_now = NULL;
+ struct udma_vtpn *vtpn_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->vtp_list.node_lock);
+ cnt = udma_dev->device_res->vtp_list.cnt;
+ if (cnt > 0) {
+ u32 *val_vtp_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (val_vtp_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->vtp_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "val_vtp_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = val_vtp_list;
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ list_for_each_entry(
+ vtp_now, &udma_dev->device_res->vtp_list.node,
+ node) {
+ *val_vtp_list = vtp_now->base.cfg.vtpn;
+ val_vtp_list++;
+ }
+ } else {
+ list_for_each_entry(
+ vtpn_now, &udma_dev->device_res->vtp_list.node,
+ node) {
+ *val_vtp_list = vtpn_now->base.vtpn;
+ val_vtp_list++;
+ }
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->vtp_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_utp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_utp *utp_now = NULL;
+ u32 cnt;
+
+ mutex_lock(&udma_dev->device_res->utp_list.node_lock);
+ cnt = udma_dev->device_res->utp_list.cnt;
+ if (cnt > 0) {
+ u32 *val_utp_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (val_utp_list == NULL) {
+ mutex_unlock(&udma_dev->device_res->utp_list.node_lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "val_utp_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = val_utp_list;
+ list_for_each_entry(
+ utp_now, &udma_dev->device_res->utp_list.node, node) {
+ *val_utp_list = utp_now->base.utpn;
+ val_utp_list++;
+ }
+ }
+
+ mutex_unlock(&udma_dev->device_res->utp_list.node_lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+int udma_query_res_dev_jetty_group_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val)
+{
+ struct udma_jetty_grp *grp_now = NULL;
+ struct mutex *lock = NULL;
+ u32 cnt;
+
+ lock = &udma_dev->device_res->jetty_group_list.node_lock;
+ mutex_lock(lock);
+ cnt = udma_dev->device_res->jetty_group_list.cnt;
+ if (cnt > 0) {
+ u32 *val_grp_list = (u32 *)vmalloc(sizeof(u32) * cnt);
+ if (val_grp_list == NULL) {
+ mutex_unlock(lock);
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "val_grp_list vmalloc fail\n");
+ return -ENOMEM;
+ }
+
+ ret_val->list = val_grp_list;
+ list_for_each_entry(
+ grp_now, &udma_dev->device_res->jetty_group_list.node,
+ node) {
+ *val_grp_list = grp_now->jetty_grp_id;
+ val_grp_list++;
+ }
+ }
+
+ mutex_unlock(lock);
+ ret_val->cnt = cnt;
+
+ return 0;
+}
+
+static void udma_free_res_list(struct ubcore_res_list_val *res_list)
+{
+ if (res_list == NULL || res_list->list == NULL) {
+ return;
+ }
+
+ vfree(res_list->list);
+ res_list->list = NULL;
+ res_list->cnt = 0;
+}
+
+static void udma_free_res_seg(struct ubcore_res_seg_val *res_seg)
+{
+ if (res_seg == NULL || res_seg->seg_list == NULL) {
+ return;
+ }
+
+ vfree(res_seg->seg_list);
+ res_seg->seg_list = NULL;
+ res_seg->seg_cnt = 0;
+}
+
+void udma_free_dev_ctx_res(struct udma_device_ctx_res *dev_ctx_res)
+{
+ udma_free_res_list(&dev_ctx_res->tp_list);
+ udma_free_res_list(&dev_ctx_res->jfs_list);
+ udma_free_res_list(&dev_ctx_res->jfr_list);
+ udma_free_res_list(&dev_ctx_res->jetty_list);
+ udma_free_res_list(&dev_ctx_res->jfc_list);
+ udma_free_res_seg(&dev_ctx_res->seg_list);
+ udma_free_res_list(&dev_ctx_res->tpg_list);
+ udma_free_res_list(&dev_ctx_res->rc_list);
+ udma_free_res_list(&dev_ctx_res->vtp_list);
+ udma_free_res_list(&dev_ctx_res->utp_list);
+ udma_free_res_list(&dev_ctx_res->jetty_group_list);
+}
+
+int udma_query_res_dev(struct udma_device *udma_dev,
+ struct udma_device_ctx_res *dev_ctx_res)
+{
+ int ret = 0;
+
+ udma_info(udma_dev->dev, UDMA_M_MISC, "start to query device res.\n");
+
+ ret |= udma_query_res_dev_tp_list(udma_dev, &dev_ctx_res->tp_list);
+ ret |= udma_query_res_dev_jfs_list(udma_dev, &dev_ctx_res->jfs_list);
+ ret |= udma_query_res_dev_jfr_list(udma_dev, &dev_ctx_res->jfr_list);
+ ret |= udma_query_res_dev_jetty_list(udma_dev,
+ &dev_ctx_res->jetty_list);
+ ret |= udma_query_res_dev_jfc_list(udma_dev, &dev_ctx_res->jfc_list);
+ ret |= udma_query_res_dev_seg_list(udma_dev, &dev_ctx_res->seg_list);
+ ret |= udma_query_res_dev_tpg_list(udma_dev, &dev_ctx_res->tpg_list);
+ ret |= udma_query_res_dev_rc_list(udma_dev, &dev_ctx_res->rc_list);
+ ret |= udma_query_res_dev_vtp_list(udma_dev, &dev_ctx_res->vtp_list);
+ ret |= udma_query_res_dev_utp_list(udma_dev, &dev_ctx_res->utp_list);
+ ret |= udma_query_res_dev_jetty_group_list(
+ udma_dev, &dev_ctx_res->jetty_group_list);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "Failed to query device resources.\n");
+ udma_free_dev_ctx_res(dev_ctx_res);
+ return -ENOMEM;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_MISC, "query device res successful!\n");
+ return 0;
+}
+
+void udma_dump_dfx(struct udma_device *udma_dev, u64 istart, u32 ilen,
+ u64 buf_addr, u32 buf_size)
+{
+ u8 printf_buf[CHAR_BUF_LEN];
+ u32 *line_start = NULL;
+ u32 *dw_current = NULL;
+ int ret = 0;
+ u64 i = 0;
+ u32 row;
+
+ if (istart == 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "The start addr is null.\n");
+ return;
+ }
+
+ if ((ilen == 0) || (ilen > MAX_DATA_LEN_UB_DFX)) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "The dump mem len is error.\n");
+ return;
+ }
+
+ line_start = (u32 *)(uintptr_t)istart;
+ row = ilen / WORD_SIZE;
+ while (row != 0) {
+ row--;
+ if ((uintptr_t)(void *)line_start >= buf_addr + buf_size)
+ line_start = (u32 *)(uintptr_t)buf_addr;
+ dw_current = line_start;
+ (void)memset_s(printf_buf, CHAR_BUF_LEN, 0x0, CHAR_BUF_LEN);
+ for (i = 0; i < WORD_LEN; i++) {
+ ret = sprintf_s(
+ (char *)(printf_buf + CHAR_WORD_LEN * i),
+ CHAR_BUF_LEN - CHAR_WORD_LEN * i, "%08X ",
+ be32_to_cpu(*dw_current));
+ if (ret < 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "format dump dfx string failed, ret:%d .\n",
+ ret);
+ return;
+ }
+ dw_current++;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_MISC, "%s\n", printf_buf);
+ line_start += WORD_LEN;
+ }
+}
+
+void udma_dump_byte_err_dfx(struct udma_device *udma_dev, const u8 *buf,
+ u32 ilen)
+{
+ char line[CHAR_BUF_LEN] = { 0 };
+ size_t line_len = 0;
+ int ret = 0;
+ u32 i;
+
+ if (buf == NULL) {
+ udma_err_limit(udma_dev->dev, UDMA_M_MISC,
+ "The buf addr is NULL\n");
+ return;
+ }
+
+ if ((ilen == 0) || (ilen > MAX_DATA_LEN_UB_DFX)) {
+ udma_err_limit(udma_dev->dev, UDMA_M_MISC,
+ "The dump mem len is error.\n");
+ return;
+ }
+
+ for (i = 0; i < ilen; i++) {
+ if ((i != 0) && (i % DUMP_LINE_BYTE_NUM == 0)) {
+ udma_err_limit(udma_dev->dev, UDMA_M_MISC, "%08x:%s\n",
+ i - DUMP_LINE_BYTE_NUM, line);
+ line[0] = '\0';
+ } else if (i % DUMP_LINE_BYTE_HALF_NUM == 0) {
+ line_len = strlen(line);
+ ret = sprintf_s(line + line_len,
+ CHAR_BUF_LEN - line_len, " ");
+ if (ret < 0) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_MISC,
+ "format dump byte string separator failed, ret:%d .\n",
+ ret);
+ return;
+ }
+ }
+
+ line_len = strlen(line);
+ ret = sprintf_s(line + line_len, CHAR_BUF_LEN - line_len,
+ "%02x", buf[i]);
+ if (ret < 0) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_MISC,
+ "format dump byte string failed, ret:%d .\n",
+ ret);
+ return;
+ }
+ }
+
+ if (strlen(line) != 0) {
+ udma_err_limit(udma_dev->dev, UDMA_M_MISC, "%08x: %s\n",
+ ((i - DUMP_LINE_BYTE_NUM) / DUMP_LINE_BYTE_NUM) *
+ DUMP_LINE_BYTE_NUM,
+ line);
+ }
+}
+
+int udma_cos_valid_check(struct udma_device *udma_dev, u8 *cos)
+{
+ struct hinic5_dcb_state dcb = { 0 };
+ u8 func_cos_bitmap, port_cos_bitmap;
+ int ret;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_MISC, "Invalid parameter. udma_dev(%d) .\n",
+ !!udma_dev);
+ return -ENXIO;
+ }
+
+ ret = hinic5_cos_valid_bitmap(udma_dev->hwdev, &func_cos_bitmap,
+ &port_cos_bitmap);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "get cos valid bitmap failed, ret: %d\n", ret);
+ return -EFAULT;
+ }
+
+ if (*cos == udma_dev->default_cos.jfrc_cos) {
+ *cos = (u8)fls(func_cos_bitmap) - 1;
+ udma_info(
+ udma_dev->dev, UDMA_M_MISC,
+ "equal to jfrc_cos, mapped to the maximum effective cos %u\n",
+ *cos);
+ }
+
+ if ((func_cos_bitmap & BIT((*cos))) != 0) {
+ udma_info(udma_dev->dev, UDMA_M_MISC,
+ "cos %u, func cos bitmap %u\n", *cos,
+ func_cos_bitmap);
+ return 0;
+ }
+
+ if (hinic5_func_type(udma_dev->hwdev) == TYPE_VF) {
+ udma_info(udma_dev->dev, UDMA_M_MISC,
+ "vf cos %u, func cos bitmap %u\n", *cos,
+ func_cos_bitmap);
+ *cos = (u8)fls(func_cos_bitmap) - 1;
+ return 0;
+ }
+
+ ret = hinic5_get_dcb_state(udma_dev->hwdev, &dcb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "hinic5_get_dcb_state failed.ret: %d\n", ret);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_MISC,
+ "cos %u, func cos bitmap %u, default cos %u\n", *cos,
+ func_cos_bitmap, dcb.default_cos);
+
+ *cos = dcb.default_cos;
+
+ return 0;
+}
+
+int udma_get_dcb_cfg_default_cos(struct udma_device *udma_dev, u8 *cos)
+{
+ if (hinic5_func_type(udma_dev->hwdev) == TYPE_VF) {
+ *cos = (u8)(udma_dev->default_cos.vf_default_cos);
+ } else {
+ *cos = (u8)(udma_dev->default_cos.pf_default_cos);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_MISC, "default cos: %u\n", *cos);
+
+ return 0;
+}
+
+int udma_get_dcb_cfg_cos(struct udma_device *udma_dev, struct ub_sip_attr *sip,
+ u8 pri, u8 *cos, u8 flag)
+{
+ int ret;
+ struct hinic5_dcb_state dcb = { 0 };
+ u8 ta_flag = 1;
+ u8 mpri = pri;
+
+ if (flag == ta_flag) {
+ if (udma_dev->default_cos.cfg_cos_en == 0) {
+ return udma_get_dcb_cfg_default_cos(udma_dev, cos);
+ }
+ *cos = pri & COS_TA_MASK;
+ return udma_cos_valid_check(udma_dev, cos);
+ }
+
+ if (sip == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MISC, "sip is null\n");
+ return -EINVAL;
+ }
+
+ ret = hinic5_get_dcb_state(udma_dev->hwdev, &dcb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "hinic5_get_dcb_state failed.ret: %d\n", ret);
+ return -EINVAL;
+ }
+
+ *cos = dcb.default_cos;
+
+ sip->dw6.dw6_value = cpu_to_le32(sip->dw6.dw6_value);
+ if (sip->dw6.tag == VLAN_INVALID && dcb.trust == UDMA_DCB_PCP) {
+ udma_debug(udma_dev->dev, UDMA_M_MISC,
+ "pcp cfg & no vlan should use default cos\n");
+ return 0;
+ }
+
+ mpri = (dcb.trust == UDMA_DCB_PCP) ? (pri & COS_TP_MASK) :
+ (pri & COS_TP_DSCP_MASK);
+ //PCP mode or not send down past dscp when 依然 from nic get
+ if (dcb.trust == UDMA_DCB_PCP ||
+ (udma_dev->dscp_bitmap & BIT((u64)mpri)) == 0) {
+ ret = hinic5_get_cos_by_pri(udma_dev->hwdev, mpri, cos);
+ } else {
+ *cos = udma_dev->dscp2cos[mpri];
+ }
+
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "get_cos_by_pri failed.ret: %d, mask_pri:%u, dcb_on:%u, trust:%u.\n",
+ ret, mpri, dcb.dcb_on, dcb.trust);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int udma_get_cos_by_pri(struct udma_device *udma_dev, u8 pri, u8 *cos)
+{
+ struct hinic5_dcb_state dcb = { 0 };
+ u8 mpri = pri;
+
+ int ret = hinic5_get_dcb_state(udma_dev->hwdev, &dcb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "hinic5_get_dcb_state failed.ret: %d, fe_idx: %u\n",
+ ret, adapted_ue_idx(&udma_dev->ub_dev.cfg));
+ return -EINVAL;
+ }
+
+ mpri = (dcb.trust == UDMA_DCB_PCP) ? (pri & COS_TP_MASK) :
+ (pri & COS_TP_DSCP_MASK);
+ ret = hinic5_get_cos_by_pri(udma_dev->hwdev, mpri, cos);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "[UDMA]: get_cos_by_pri failed.ret: %d, mask_pri:%u, dcb_on:%u, trust:%u.\n",
+ ret, mpri, dcb.dcb_on, dcb.trust);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_rx_rate_limit_set_para(struct udma_device *udma_dev,
+ struct ub_rx_rate_limit_params *params)
+{
+ struct ub_rx_rate_limit_acc_cmd rx_rate_limit = { 0 };
+ u16 out_size = (u16)sizeof(rx_rate_limit);
+ int ret;
+
+ rx_rate_limit.para.pattern.down_period = params->down_period;
+ rx_rate_limit.para.pattern.up_period = params->up_period;
+ rx_rate_limit.para.pattern.alpha1 = params->alpha1;
+ rx_rate_limit.para.pattern.n1 = params->n1;
+ rx_rate_limit.para.pattern.alpha2 = params->alpha2;
+ rx_rate_limit.para.pattern.n2 = params->n2;
+ rx_rate_limit.para.pattern.alpha3 = params->alpha3;
+ rx_rate_limit.para.pattern.beta = params->beta;
+ rx_rate_limit.para.pattern.min_rate = params->min_rate;
+ rx_rate_limit.para.pattern.init_rate = params->init_rate;
+
+ udma_info(
+ udma_dev->dev, UDMA_M_MISC,
+ "set rx rate limit params ,dec_period:%u inc_period:%u alpha1:%u n1:%u alpha2:%u n2:%u alpha3:%u beta:%u min_rate:%u init_rate:%u.\n",
+ params->down_period, params->up_period, params->alpha1,
+ params->n1, params->alpha2, params->n2, params->alpha3,
+ params->beta, params->min_rate, params->init_rate);
+
+ ret = hinic5_msg_to_mgmt_sync(
+ udma_dev->hwdev, HINIC5_MOD_UB, UB_MPU_CMD_CFG_RRLT_ACC_PARA,
+ &rx_rate_limit, (u16)sizeof(rx_rate_limit), &rx_rate_limit,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (rx_rate_limit.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "set rx rate limit params failed. ret: %d, status(0x%x)\n",
+ ret, rx_rate_limit.head.status);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void udma_cc_para_cmd_update(struct ub_cc_para *para,
+ struct ub_cc_params *params)
+{
+ switch (params->ub_cc_algo) {
+ case UB_CC_ALGO_LDCP:
+ para->ldcp.wnd_min = params->wnd_min;
+ para->ldcp.init_wnd = params->init_wnd;
+ para->ldcp.alpha = params->alpha;
+ para->ldcp.beta = params->beta;
+ para->ldcp.gamma = params->gamma;
+ para->ldcp.eta = params->eta;
+ break;
+ case UB_CC_ALGO_CAQM:
+ para->caqm.alpha = params->alpha;
+ para->caqm.beta = params->beta;
+ para->caqm.eta = params->eta;
+ para->caqm.wnd_min = params->wnd_min;
+ para->caqm.init_wnd = params->init_wnd;
+ para->caqm.cc_unit = params->cc_unit;
+ break;
+ case UB_CC_ALGO_USER_1:
+ case UB_CC_ALGO_USER_2:
+ para->dw[DW_IDX0] = params->dw[DW_IDX0];
+ para->dw[DW_IDX1] = params->dw[DW_IDX1];
+ para->dw[DW_IDX2] = params->dw[DW_IDX2];
+ para->dw[DW_IDX3] = params->dw[DW_IDX3];
+ break;
+ default:
+ break;
+ }
+}
+
+int udma_rx_rate_limit_cfg_wred(struct udma_device *udma_dev, u32 cmd, u32 idx,
+ u32 *start_val, u32 *end_val)
+{
+ int ret;
+ struct ub_rx_rate_limit_wred_cmd cfg_wred_cmd = { 0 };
+ u16 buf_size = (u16)sizeof(cfg_wred_cmd);
+
+ if (udma_dev == NULL || start_val == NULL || end_val == NULL) {
+ return -EINVAL;
+ }
+ cfg_wred_cmd.cmd = cmd;
+ cfg_wred_cmd.wred_idx = idx;
+ cfg_wred_cmd.start_val = *start_val;
+ cfg_wred_cmd.end_val = *end_val;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_CFG_RRLT_WRED, &cfg_wred_cmd,
+ buf_size, &cfg_wred_cmd, &buf_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (buf_size == 0) || (cfg_wred_cmd.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MISC,
+ "set rx rate limit cfg wred failed. ret: %d, status(0x%x)\n",
+ ret, cfg_wred_cmd.head.status);
+ return -EIO;
+ }
+
+ if (cmd != 0) {
+ *start_val = cfg_wred_cmd.start_val;
+ *end_val = cfg_wred_cmd.end_val;
+ }
+
+ return 0;
+}
+
+int udma_cc_set_para(struct udma_device *udma_dev, struct ub_cc_params *params)
+{
+ struct ub_cc_para_cmd cc_para = { 0 };
+ u16 out_size = (u16)sizeof(cc_para);
+ int ret;
+ u8 i;
+
+ cc_para.algo = params->ub_cc_algo;
+ cc_para.index = params->index;
+ udma_cc_para_cmd_update(&cc_para.para, params);
+
+ for (i = 0; i < (u8)ARRAY_SIZE(cc_para.para.dw); i++) {
+ cc_para.para.dw[i] = cpu_to_be32(cc_para.para.dw[i]);
+ }
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_SET_CC_PARA, &cc_para,
+ (u16)sizeof(cc_para), &cc_para, &out_size,
+ 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (cc_para.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "set cc params failed. ret: %d, status(0x%x)\n", ret,
+ cc_para.head.status);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void udma_cc_params_update(struct ub_cc_params *params,
+ struct ub_cc_para *para)
+{
+ switch (params->ub_cc_algo) {
+ case UB_CC_ALGO_LDCP:
+ params->wnd_min = para->ldcp.wnd_min;
+ params->init_wnd = para->ldcp.init_wnd;
+ params->alpha = para->ldcp.alpha;
+ params->beta = para->ldcp.beta;
+ params->gamma = para->ldcp.gamma;
+ params->eta = para->ldcp.eta;
+ break;
+ case UB_CC_ALGO_CAQM:
+ params->alpha = para->caqm.alpha;
+ params->beta = para->caqm.beta;
+ params->eta = para->caqm.eta;
+ params->wnd_min = para->caqm.wnd_min;
+ params->init_wnd = para->caqm.init_wnd;
+ params->cc_unit = para->caqm.cc_unit;
+ break;
+ default:
+ break;
+ }
+}
+
+int udma_cc_query_para(struct udma_device *udma_dev,
+ struct ub_cc_params *params)
+{
+ struct ub_cc_para_cmd cc_para = { 0 };
+ struct ub_cc_para_cmd para_out = { 0 };
+ u16 out_size = (u16)sizeof(para_out);
+ int ret;
+ u8 i;
+
+ cc_para.index = params->index;
+ cc_para.algo = params->ub_cc_algo;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_CC_PARA, &cc_para,
+ (u16)sizeof(cc_para), ¶_out,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (para_out.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "query cc params failed. ret: %d, status(0x%x)\n", ret,
+ para_out.head.status);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < (u8)ARRAY_SIZE(para_out.para.dw); i++) {
+ para_out.para.dw[i] = be32_to_cpu(para_out.para.dw[i]);
+ }
+
+ udma_cc_params_update(params, ¶_out.para);
+
+ return 0;
+}
+
+static void udma_cc_entry_set(struct ubcore_cc_entry *cc_entry, u32 cnt,
+ enum ubcore_tp_cc_alg alg, u32 length)
+{
+ u32 j = 0, index = cnt;
+
+ for (j = 0; j < length; j++) {
+ cc_entry[index].alg = alg;
+ cc_entry[index].cc_pattern_idx = (u8)j;
+ cc_entry[index++].cc_priority = (u8)j;
+ }
+}
+
+struct ubcore_cc_entry *udma_query_cc(struct ubcore_device *ub_dev,
+ u32 *cc_entry_cnt)
+{
+ struct udma_device *udma_dev = NULL;
+ struct ubcore_cc_entry *cc_entry = NULL;
+ u32 cnt = 0;
+ int i = 0, array_num = 0;
+
+ struct {
+ enum ubcore_tp_cc_alg algo;
+ u32 pattern_num;
+ u32 support_ver;
+ } support_cc[] = {
+ { UBCORE_TP_CC_LDCP, LDCP_PATTERN_ARRAY_LEN,
+ UDMA_DEV_TYPE_HI1825_V100 },
+ { UBCORE_TP_CC_LDCP_L2_HEADER, LDCP_PATTERN_ARRAY_LEN,
+ UDMA_DEV_TYPE_HI1825_V100 },
+ { UBCORE_TP_CC_LDCP_TP_HEADER, LDCP_PATTERN_ARRAY_LEN,
+ UDMA_DEV_TYPE_HI1825_V100 },
+ { UBCORE_TP_CC_CUSTOM_1, USER_DEFINED_PATTERN_ARRAY_LEN,
+ UDMA_DEV_TYPE_HI1825_V100 },
+ { UBCORE_TP_CC_CUSTOM_2, USER_DEFINED_PATTERN_ARRAY_LEN,
+ UDMA_DEV_TYPE_HI1825_V100 },
+ };
+
+ if (ub_dev == NULL || cc_entry_cnt == NULL) {
+ udma_pr_err(
+ UDMA_M_MISC,
+ "%s: Invalid parameter, ub_dev(%d), cc_entry_cnt(%d)\n",
+ __func__, !!ub_dev, !!cc_entry_cnt);
+ return NULL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ array_num = (int)ARRAY_SIZE(support_cc);
+ for (i = 0; i < array_num; ++i) {
+ if (((u32)udma_dev->device_type & support_cc[i].support_ver) !=
+ 0) {
+ *cc_entry_cnt += support_cc[i].pattern_num;
+ }
+ }
+ if (*cc_entry_cnt == 0) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "no support cc for device type(%u).\n",
+ udma_dev->device_type);
+ return NULL;
+ }
+ cc_entry = (struct ubcore_cc_entry *)kzalloc(
+ *cc_entry_cnt * sizeof(struct ubcore_cc_entry), GFP_KERNEL);
+ if (cc_entry == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "cc_entry alloc failed.\n");
+ return NULL;
+ }
+
+ for (i = 0; i < array_num; ++i) {
+ if (((u32)udma_dev->device_type & support_cc[i].support_ver) !=
+ 0) {
+ udma_cc_entry_set(cc_entry, cnt, support_cc[i].algo,
+ support_cc[i].pattern_num);
+ cnt += support_cc[i].pattern_num;
+ }
+ }
+
+ return cc_entry;
+}
+
+int udma_dscp_cos_map(struct udma_device *udma_dev, u8 *dscp2cos, u32 size,
+ u8 opcode)
+{
+ struct hinic5_cmd_qos_map_cfg qos_msp = { 0 };
+ u16 out_size = (u16)sizeof(struct hinic5_cmd_qos_map_cfg);
+ int ret;
+
+ qos_msp.op_code = opcode;
+ qos_msp.cfg_bitmap = CMD_QOS_MAP_DSCP2COS;
+
+ ret = memcpy_s(qos_msp.dscp2cos, sizeof(qos_msp.dscp2cos), dscp2cos,
+ size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy failed, size:%u .\n", size);
+ return ret;
+ }
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_L2NIC,
+ HINIC5_NIC_CMD_QOS_MAP_CFG, &qos_msp,
+ out_size, &qos_msp, &out_size, 0,
+ HINIC5_CHANNEL_NIC);
+ if ((ret != 0) || (out_size == 0) || (qos_msp.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set qos failed, ret:%d, out_size:%u, status:%u .\n",
+ ret, out_size, qos_msp.head.status);
+ return -EFAULT;
+ }
+
+ ret = memcpy_s(dscp2cos, size, qos_msp.dscp2cos,
+ sizeof(qos_msp.dscp2cos));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy failed, size:%lu .\n",
+ sizeof(qos_msp.dscp2cos));
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_DFX, "set qos success\n");
+
+ return 0;
+}
+
+struct tag_cqm_queue *udma_object_queue_create(
+ struct udma_device *udma_dev, enum cqm_object_type object_type,
+ u32 object_size, void *object_priv, struct udma_object_n_record *record,
+ bool room_header_alloc, u32 xid, u32 bitmap_start, u32 bitmap_end)
+{
+ struct tag_cqm_queue *obj = NULL;
+ u32 record_start = record->num;
+
+ if ((bitmap_start > bitmap_end) || (xid == CQM_INDEX_INVALID))
+ return cqm5_object_rdma_queue_create(udma_dev->hwdev,
+ SERVICE_T_UB, object_type,
+ object_size, object_priv,
+ room_header_alloc, xid,
+ bitmap_start, bitmap_end);
+
+ udma_debug(udma_dev->dev, UDMA_M_MISC,
+ "Alloc %u object, record(%u), xid(%u), start(%u), end(%u)\n",
+ object_type, record->num, xid, bitmap_start, bitmap_end);
+ mutex_lock(&record->mutex);
+
+ if ((record_start < bitmap_start) || (record_start >= bitmap_end))
+ record_start = bitmap_start;
+
+ obj = cqm5_object_rdma_queue_create(udma_dev->hwdev, SERVICE_T_UB,
+ object_type, object_size,
+ object_priv, room_header_alloc, xid,
+ record_start, bitmap_end);
+ if ((obj != NULL) || (record_start == bitmap_start))
+ goto leave;
+
+ obj = cqm5_object_rdma_queue_create(udma_dev->hwdev, SERVICE_T_UB,
+ object_type, object_size,
+ object_priv, room_header_alloc, xid,
+ bitmap_start, bitmap_end);
+
+leave:
+ if (obj != NULL) {
+ record->num = obj->index + 1;
+ }
+ mutex_unlock(&record->mutex);
+ udma_debug(udma_dev->dev, UDMA_M_MISC,
+ "Alloced %u object, record(%u)\n", object_type, record->num);
+
+ return obj;
+}
+
+struct tag_cqm_qpc_mpt *
+udma_object_qpc_create(struct udma_device *udma_dev, u32 object_size,
+ void *object_priv, struct udma_object_n_record *record,
+ u32 xid, u32 bitmap_start, u32 bitmap_end)
+{
+ struct tag_cqm_qpc_mpt *obj = NULL;
+ u32 record_start = record->num;
+
+ if ((bitmap_start > bitmap_end) || (xid == CQM_INDEX_INVALID))
+ return cqm5_object_qpc_mpt_create(udma_dev->hwdev, SERVICE_T_UB,
+ CQM_OBJECT_SERVICE_CTX,
+ object_size, object_priv, xid,
+ bitmap_start, bitmap_end);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_MISC,
+ "Alloc qpc object, record(%u), xid(%u), start(%u), end(%u)\n",
+ record->num, xid, bitmap_start, bitmap_end);
+ mutex_lock(&record->mutex);
+
+ if ((record_start < bitmap_start) || (record_start >= bitmap_end))
+ record_start = bitmap_start;
+
+ obj = cqm5_object_qpc_mpt_create(udma_dev->hwdev, SERVICE_T_UB,
+ CQM_OBJECT_SERVICE_CTX, object_size,
+ object_priv, xid, record_start,
+ bitmap_end);
+ if ((obj != NULL) || (record_start == bitmap_start))
+ goto leave;
+
+ obj = cqm5_object_qpc_mpt_create(udma_dev->hwdev, SERVICE_T_UB,
+ CQM_OBJECT_SERVICE_CTX, object_size,
+ object_priv, xid, bitmap_start,
+ bitmap_end);
+
+leave:
+ if (obj != NULL) {
+ record->num = obj->xid + 1;
+ }
+ mutex_unlock(&record->mutex);
+ udma_debug(udma_dev->dev, UDMA_M_MISC,
+ "Alloced qpc object, record(%u)\n", record->num);
+
+ return obj;
+}
+
+int udma_get_feat_bitmap(struct udma_device *udev, u64 *feat_bitmap, u16 size)
+{
+ int ret;
+ ub_feat_nego_s nego_data;
+ u16 out_size = sizeof(ub_feat_nego_s);
+
+ if (feat_bitmap == NULL || size < UB_FEAT_BITMAP_U64_MAX) {
+ udma_err(udev->dev, UDMA_M_MISC,
+ "Invalid parameters, feat_bitmap(%u), size(%u).",
+ !!feat_bitmap, size);
+ return -EINVAL;
+ }
+
+ (void)memset_s(&nego_data, sizeof(ub_feat_nego_s), 0,
+ sizeof(ub_feat_nego_s));
+
+ ret = hinic5_msg_to_mgmt_sync(udev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_FEAT_NEGO_GET, &nego_data,
+ sizeof(ub_feat_nego_s), &nego_data,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if (nego_data.head.status ==
+ HINIC5_MGMT_CMD_UNSUPPORTED) { //compatible with older firmware version
+ udma_warn(udev->dev, UDMA_M_MISC,
+ "The firmware version is too old!\n");
+ (void)memset_s(feat_bitmap, sizeof(u64) * size, 0,
+ sizeof(u64) * size);
+ return 0;
+ } else if (ret != 0 || nego_data.head.status != 0 || out_size == 0) {
+ udma_err(
+ udev->dev, UDMA_M_MISC,
+ "Failed to get feature bitmap, ret(%d), status(%u), out_size(%u).\n",
+ ret, nego_data.head.status, out_size);
+ return -EIO;
+ }
+
+ (void)memcpy_s(feat_bitmap, sizeof(u64) * size, nego_data.feat_bitmap,
+ sizeof(u64) * UB_FEAT_BITMAP_U64_MAX);
+ udev->index_queue_en =
+ udev->device_type == UDMA_DEV_TYPE_HI1825_V100 ? true : false;
+
+ return 0;
+}
+
+int udma_set_feat_bitmap(struct udma_device *udev, u64 *feat_bitmap, u16 size)
+{
+ int ret;
+ ub_feat_nego_s nego_data;
+ u16 out_size = sizeof(ub_feat_nego_s);
+
+ if (feat_bitmap == NULL || size > UB_FEAT_BITMAP_U64_MAX) {
+ udma_err(udev->dev, UDMA_M_MISC,
+ "Invalid parameters, feat_bitmap(%u), size(%u).",
+ !!feat_bitmap, size);
+ return -EINVAL;
+ }
+
+ (void)memset_s(&nego_data, sizeof(ub_feat_nego_s), 0,
+ sizeof(ub_feat_nego_s));
+ (void)memcpy_s(nego_data.feat_bitmap,
+ sizeof(u64) * UB_FEAT_BITMAP_U64_MAX, feat_bitmap,
+ sizeof(u64) * size);
+
+ ret = hinic5_msg_to_mgmt_sync(udev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_FEAT_NEGO_SET, &nego_data,
+ sizeof(ub_feat_nego_s), &nego_data,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if (nego_data.head.status ==
+ HINIC5_MGMT_CMD_UNSUPPORTED) { //compatible with older firmware version
+ udma_warn(udev->dev, UDMA_M_MISC,
+ "The firmware version is too old!\n");
+ return 0;
+ } else if (ret != 0 || nego_data.head.status != 0 || out_size == 0) {
+ udma_err(
+ udev->dev, UDMA_M_MISC,
+ "Failed to set feature bitmap, ret(%d), status(%u), out_size(%u).\n",
+ ret, nego_data.head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+u32 udma_get_qpn_mod(struct udma_device *udma_dev, u32 default_mode,
+ u32 default_xid_low)
+{
+ u32 low_bit_mode = default_mode;
+ u32 xid_low = default_xid_low;
+
+ /* dfx set low bit align */
+ if (udma_sysfs_get_xid_low_3_bit(&udma_dev->sysfs_res, &xid_low)) {
+ low_bit_mode = CQM_XID_LOW_BIT_1_1_1;
+ }
+
+ return CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE, low_bit_mode, xid_low);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.h
new file mode 100644
index 000000000..39d29071e
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_misc.h
@@ -0,0 +1,131 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_MISC_H
+#define UDMA_MISC_H
+
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+
+#define UDMA_DCB_PCP 0
+#define UDMA_DCB_DSCP 1
+
+#define U64_BIT_SIZE 64
+#define UDMA_VERITY_FEAT_BIT(udev, shift) \
+ ({ \
+ u8 _ret = (shift) < (U64_BIT_SIZE * UB_FEAT_BITMAP_U64_MAX); \
+ _ret = _ret ? (((udev)->feat_bitmap[(shift) / U64_BIT_SIZE] >> \
+ ((shift) % U64_BIT_SIZE)) & \
+ 0x1) : \
+ 0; \
+ _ret; \
+ })
+
+struct udma_list {
+ struct list_head node;
+ struct mutex node_lock;
+ u32 cnt;
+};
+
+struct udma_device_res {
+ struct udma_list tpn_list;
+ struct udma_list jfs_list;
+ struct udma_list jfr_list;
+ struct udma_list jetty_list;
+ struct udma_list jfc_list;
+ struct udma_list seg_list;
+ struct udma_list jetty_group_list;
+ struct udma_list tpg_list;
+ struct udma_list rc_list;
+ struct udma_list vtp_list;
+ struct udma_list utp_list;
+};
+
+struct udma_device_ctx_res {
+ struct ubcore_res_list_val tp_list;
+ struct ubcore_res_list_val jfs_list;
+ struct ubcore_res_list_val jfr_list;
+ struct ubcore_res_list_val jetty_list;
+ struct ubcore_res_list_val jfc_list;
+ struct ubcore_res_seg_val seg_list;
+ struct ubcore_res_list_val jetty_group_list;
+ struct ubcore_res_list_val tpg_list;
+ struct ubcore_res_list_val rc_list;
+ struct ubcore_res_list_val vtp_list;
+ struct ubcore_res_list_val utp_list;
+};
+
+static inline u64 align_size(u32 size, u64 align)
+{
+ return ((size + align - 1) & (~(align - 1)));
+}
+
+int udma_dfx_device_init(struct udma_device *udma_dev);
+void udma_dfx_device_deinit(struct udma_device *udma_dev);
+int udma_query_res_dev(struct udma_device *udma_dev,
+ struct udma_device_ctx_res *dev_ctx_res);
+void udma_free_dev_ctx_res(struct udma_device_ctx_res *dev_ctx_res);
+int udma_user_ctl(struct ubcore_device *dev, struct ubcore_user_ctl *user_ctl);
+void udma_dump_dfx(struct udma_device *udma_dev, u64 istart, u32 ilen,
+ u64 buf_addr, u32 buf_size);
+void udma_dump_byte_err_dfx(struct udma_device *udma_dev, const u8 *buf,
+ u32 ilen);
+int udma_get_dcb_cfg_default_cos(struct udma_device *udma_dev, u8 *cos);
+int udma_get_dcb_cfg_cos(struct udma_device *udma_dev, struct ub_sip_attr *sip,
+ u8 pri, u8 *cos, u8 flag);
+int udma_get_cos_by_pri(struct udma_device *udma_dev, u8 pri, u8 *cos);
+int udma_cc_set_para(struct udma_device *udma_dev, struct ub_cc_params *params);
+int udma_rx_rate_limit_set_para(struct udma_device *udma_dev,
+ struct ub_rx_rate_limit_params *params);
+int udma_rx_rate_limit_cfg_wred(struct udma_device *udma_dev, u32 cmd, u32 idx,
+ u32 *start_val, u32 *end_val);
+int udma_cc_query_para(struct udma_device *udma_dev,
+ struct ub_cc_params *params);
+struct ubcore_cc_entry *udma_query_cc(struct ubcore_device *ub_dev,
+ u32 *cc_entry_cnt);
+void udma_store_list(struct udma_device *udma_dev, struct list_head *node,
+ struct udma_list *udma_list);
+void udma_delete_list(struct udma_device *udma_dev, struct list_head *node,
+ struct udma_list *udma_list);
+void udma_init_ub_dev_attr(struct udma_device *udma_dev,
+ struct ubcore_device_attr *attr);
+int udma_dscp_cos_map(struct udma_device *udma_dev, u8 *dscp2cos, u32 size,
+ u8 opcode);
+
+struct tag_cqm_queue *udma_object_queue_create(
+ struct udma_device *udma_dev, enum cqm_object_type object_type,
+ u32 object_size, void *object_priv, struct udma_object_n_record *record,
+ bool room_header_alloc, u32 xid, u32 bitmap_start, u32 bitmap_end);
+
+struct tag_cqm_qpc_mpt *
+udma_object_qpc_create(struct udma_device *udma_dev, u32 object_size,
+ void *object_priv, struct udma_object_n_record *record,
+ u32 xid, u32 bitmap_start, u32 bitmap_end);
+int udma_query_res_dev_tp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_jfs_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_jfr_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_jetty_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_jfc_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_seg_list(struct udma_device *udma_dev,
+ struct ubcore_res_seg_val *ret_val);
+int udma_query_res_dev_tpg_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_rc_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_vtp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_utp_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_query_res_dev_jetty_group_list(struct udma_device *udma_dev,
+ struct ubcore_res_list_val *ret_val);
+int udma_get_feat_bitmap(struct udma_device *udev, u64 *feat_bitmap, u16 size);
+int udma_set_feat_bitmap(struct udma_device *udev, u64 *feat_bitmap, u16 size);
+u32 udma_get_qpn_mod(struct udma_device *udma_dev, u32 default_mode,
+ u32 default_xid_low);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.c
new file mode 100644
index 000000000..0f9f03e8f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+
+#include "udma_mtt.h"
+
+static int udma_umem_write_mtt_check(const struct udma_device *udma_dev,
+ const struct mtt *mtt,
+ const struct ubcore_umem *umem)
+{
+ if ((udma_dev == NULL) || (mtt == NULL) || (umem == NULL)) {
+ udma_pr_err(UDMA_M_SEG, "%s: Rdev or mtt or umem is null\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_mem_write_mtt_update(struct udma_device *udma_dev, struct mtt *mtt,
+ struct scatterlist *sgl, u32 nr)
+{
+ struct scatterlist *sg = NULL;
+ u32 pages_in_chunk = 0; /* umem_chunk in single (count word) memory block of page count */
+ u64 *page_list = NULL;
+ u32 start_index = 0; /* need write mtt of page */
+ u32 npages = 0; /* already record of page count */
+ int ret = 0;
+ u32 i = 0;
+ u32 j = 0;
+
+ page_list = (u64 *)kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (page_list == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SEG,
+ "failed to allocate memory for page list, func_id(%u)\n",
+ hinic5_global_func_id(udma_dev->hwdev));
+ return -ENOMEM;
+ }
+
+ /* max page scenario sg_dma_len(sg) equal to page size, cause calculate of pages_in_chunk is 0, not will de execute hmm_mtt_write, need extra handle */
+ if (mtt->mtt_layers == MTT_ZERO_LAYER && nr != 0) {
+ page_list[0] = sg_dma_address(sgl);
+ ret = hmm_mtt_write(udma_dev->hwdev, mtt, 0, 0, page_list,
+ SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to write mtt, ret:%d, func_id(%u)\n",
+ ret, hinic5_global_func_id(udma_dev->hwdev));
+ }
+ goto out;
+ }
+
+ /* calculate 1(count word) memory block in page count, page size as 1 << page_shift */
+ for_each_sg(sgl, sg, nr, i) {
+ pages_in_chunk = UDMA_ROUND_UP(sg_dma_len(sg), PAGE_SIZE) >>
+ mtt->buf_page_shift;
+ for (j = 0; j < pages_in_chunk; ++j) {
+ page_list[npages] =
+ sg_dma_address(sg) + (PAGE_SIZE * j);
+ npages++;
+
+ /* page_list pointed by memory size as a page, at most can store PAGE_SIZE / sizeof(u64) pa, full one page after need write mtt */
+ if (npages != PAGE_SIZE / sizeof(u64)) {
+ continue;
+ }
+ ret = hmm_mtt_write(udma_dev->hwdev, mtt, start_index,
+ npages, page_list, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SEG,
+ "failed to write mtt, ret:%d, start_index:%u, func_id(%u)\n",
+ ret, start_index,
+ hinic5_global_func_id(udma_dev->hwdev));
+ goto out;
+ }
+ start_index += npages;
+ npages = 0;
+ }
+ }
+
+ if (npages != 0) {
+ ret = hmm_mtt_write(udma_dev->hwdev, mtt, start_index, npages,
+ page_list, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SEG,
+ "failed to write mtt, ret:%d, start_index:%u, func_id(%u)\n",
+ ret, start_index,
+ hinic5_global_func_id(udma_dev->hwdev));
+ goto out;
+ }
+ }
+
+out:
+ kfree(page_list);
+
+ return ret;
+}
+
+int udma_umem_write_mtt(struct udma_device *udma_dev, struct mtt *mtt,
+ struct ubcore_umem *umem)
+{
+ int ret;
+
+ ret = udma_umem_write_mtt_check(udma_dev, mtt, umem);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return udma_mem_write_mtt_update(udma_dev, mtt, umem->sg_head.sgl,
+ umem->nmap);
+}
+
+int udma_buf_write_mtt(struct udma_device *udma_dev, struct mtt *mtt,
+ struct tag_cqm_buf *buf)
+{
+ u64 *page_list = NULL;
+ int ret = 0;
+ u32 i = 0;
+
+ page_list =
+ (u64 *)kzalloc(buf->buf_number * sizeof *page_list, GFP_KERNEL);
+ if (page_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Failed to alloc memory for page list, func_id(%u)\n",
+ hinic5_global_func_id(udma_dev->hwdev));
+ return (-ENOMEM);
+ }
+
+ /* Each buf is written to MTT as a page, buf_size is 2^n times PAGE_SIZE */
+ for (i = 0; i < buf->buf_number; ++i)
+ page_list[i] = buf->buf_list[i].pa;
+
+ ret = hmm_mtt_write(udma_dev->hwdev, mtt, 0, buf->buf_number, page_list,
+ SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Failed to write mtt, func_id(%u)\n",
+ hinic5_global_func_id(udma_dev->hwdev));
+ }
+
+ kfree(page_list);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.h
new file mode 100644
index 000000000..8e81eae51
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/common/udma_mtt.h
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_MTT_H
+#define UDMA_MTT_H
+
+#include "udma_common.h"
+
+#define UDMA_ROUND_UP(n, d) (DIV_ROUND_UP(n, d) * (d))
+
+int udma_umem_write_mtt(struct udma_device *udma_dev, struct mtt *mtt,
+ struct ubcore_umem *umem);
+int udma_mem_write_mtt_update(struct udma_device *udma_dev, struct mtt *mtt,
+ struct scatterlist *sgl, u32 nr);
+int udma_buf_write_mtt(struct udma_device *udma_dev, struct mtt *mtt,
+ struct tag_cqm_buf *buf);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.c b/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.c
new file mode 100644
index 000000000..e80c7bc23
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.c
@@ -0,0 +1,81 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include "udma_common.h"
+#include "udma_misc.h"
+#include "udma_db.h"
+
+int udma_db_map_user(struct udma_context *ctx, u64 virt, struct udma_db *db)
+{
+ u64 page_addr = virt & PAGE_MASK;
+ union ubcore_umem_flag access = { 0 };
+ struct udma_user_db_page *page = NULL;
+ u64 offset;
+ int ret = 0;
+
+ if (ctx == NULL) {
+ udma_pr_err(UDMA_M_DB, "Invalid parameter. ctx(%d) .\n", !!ctx);
+ return -EINVAL;
+ }
+
+ mutex_lock(&ctx->db_page_mutex);
+
+ list_for_each_entry(page, &ctx->db_page_list, list) {
+ if (page->user_virt == page_addr)
+ goto found;
+ }
+
+ page = (struct udma_user_db_page *)kmalloc(sizeof(*page), GFP_KERNEL);
+ if (page == NULL) {
+ udma_err(ctx->udma_dev->dev, UDMA_M_DB,
+ "alloc doorbell page failed.\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ page->refcount = 0;
+ page->user_virt = page_addr;
+ access.bs.non_pin = 0;
+ access.bs.writable = 1;
+ page->umem = ubcore_umem_get(&ctx->udma_dev->ub_dev, page_addr,
+ PAGE_SIZE, access);
+ if (IS_ERR_OR_NULL(page->umem)) {
+ udma_err(ctx->udma_dev->dev, UDMA_M_DB,
+ "umem get db page failed.\n");
+ ret = -EINVAL;
+ kfree(page);
+ goto out;
+ }
+
+ list_add(&page->list, &ctx->db_page_list);
+
+found:
+ offset = virt - page_addr;
+ db->dma = sg_dma_address(page->umem->sg_head.sgl) + offset;
+ db->virt_addr = (char *)sg_virt(page->umem->sg_head.sgl) + offset;
+ db->user_page = page;
+ ++page->refcount;
+
+out:
+ mutex_unlock(&ctx->db_page_mutex);
+
+ return ret;
+}
+
+void udma_db_unmap_user(struct udma_context *ctx, struct udma_db *db)
+{
+ mutex_lock(&ctx->db_page_mutex);
+
+ if ((--db->user_page->refcount) == 0) {
+ list_del(&db->user_page->list);
+ ubcore_umem_release(db->user_page->umem);
+ kfree(db->user_page);
+ db->user_page = NULL;
+ }
+
+ mutex_unlock(&ctx->db_page_mutex);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.h b/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.h
new file mode 100644
index 000000000..37d05d32b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/base/db/udma_db.h
@@ -0,0 +1,40 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+#ifndef _UDMA_DB_H
+#define _UDMA_DB_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include "ubcore_api.h"
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+
+#define TP_DB_SIZE 8
+
+struct udma_db {
+ u32 *db_record;
+ struct udma_user_db_page *user_page;
+ u64 dma;
+ void *virt_addr;
+};
+
+struct udma_user_db_page {
+ struct list_head list;
+ struct ubcore_umem *umem;
+ u64 user_virt;
+ int refcount;
+};
+
+struct udma_kdb {
+ u32 *db_record;
+ dma_addr_t dma;
+ void *virt_addr;
+ u16 idx; //only for dca
+};
+
+int udma_db_map_user(struct udma_context *ctx, u64 virt, struct udma_db *db);
+void udma_db_unmap_user(struct udma_context *ctx, struct udma_db *db);
+
+#endif /* _UDMA_DB_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond.h b/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond.h
new file mode 100644
index 000000000..49a68f472
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond.h
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_BOND_H
+#define UDMA_BOND_H
+
+int udma_bond_init(void);
+void udma_bond_uninit(void);
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond_common.c b/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond_common.c
new file mode 100644
index 000000000..991c54833
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/bond/udma_bond_common.c
@@ -0,0 +1,163 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved.
+
+#include <net/bonding.h>
+#include <linux/netdevice.h>
+#include "hinic5_hw.h"
+#include "hinic5_srv_nic.h"
+
+#include "drv_bond_api.h"
+#include "udma_log.h"
+#include "udma_bond.h"
+
+struct udma_bond_resource {
+ atomic_t bond_id;
+};
+
+#define UDMA_BOND_2_FUNC_NUM 2
+#define UDMA_INVALID_BOND_ID 0xFF
+
+static struct udma_bond_resource g_udma_bond_res;
+
+static enum netdev_lag_tx_type udma_get_tx_type_by_bond_mode(u16 bond_mode)
+{
+ switch (bond_mode) {
+ case BOND_MODE_8023AD:
+ return NETDEV_LAG_TX_TYPE_HASH;
+ case BOND_MODE_ACTIVEBACKUP:
+ return NETDEV_LAG_TX_TYPE_ACTIVEBACKUP;
+ default:
+ return NETDEV_LAG_TX_TYPE_UNKNOWN;
+ }
+}
+
+static bool udma_bond_mode_is_supported(u16 bond_mode)
+{
+ enum netdev_lag_tx_type tx_type =
+ udma_get_tx_type_by_bond_mode(bond_mode);
+ if ((tx_type != NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) &&
+ (tx_type != NETDEV_LAG_TX_TYPE_HASH)) {
+ udma_pr_err(UDMA_M_BOND, "Failed to support bond mode(%d)\n",
+ bond_mode);
+ return false;
+ }
+ return true;
+}
+
+static bool udma_can_do_bond(struct bonding *bond)
+{
+ bool ret = false;
+ int slave_cnt = 0;
+ struct slave *slave = NULL;
+ struct list_head *iter = NULL;
+ struct hinic5_lld_dev *lld_dev = NULL;
+ struct hinic5_lld_dev *ppf_dev = NULL;
+
+ if (!bond || !udma_bond_mode_is_supported((u16)(bond->params.mode))) {
+ return ret;
+ }
+
+ rcu_read_lock();
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ lld_dev = hinic5_get_lld_dev_by_netdev(slave->dev);
+ if (!lld_dev) {
+ goto out;
+ }
+
+ if (!ppf_dev) {
+ ppf_dev = hinic5_get_ppf_lld_dev_unsafe(lld_dev);
+ if (!ppf_dev) {
+ goto out;
+ }
+ }
+
+ if (hinic5_get_ppf_lld_dev_unsafe(lld_dev) != ppf_dev) {
+ goto out;
+ }
+ slave_cnt++;
+ udma_pr_info(UDMA_M_BOND,
+ "%s:can do bond? slave_cnt(%d), slave_name(%s)",
+ __func__, slave_cnt, slave->dev->name);
+ }
+
+ ret = (slave_cnt == UDMA_BOND_2_FUNC_NUM);
+out:
+ rcu_read_unlock();
+ return ret;
+}
+
+static void udma_before_bond_active(const char *bond_name,
+ struct bond_attr *attr, int err)
+{
+ atomic_set(&g_udma_bond_res.bond_id, attr->bond_id);
+ return;
+}
+
+static void udma_after_bond_modify(const char *bond_name,
+ struct bond_attr *attr, int err)
+{
+ struct bond_tracker tracker;
+ int ret;
+
+ if (bond_name == NULL || attr == NULL) {
+ udma_pr_err(UDMA_M_BOND, "udma bond_name or attr is NULL.");
+ return;
+ }
+
+ ret = hinic5_bond_get_tracker_by_name(bond_name, &tracker);
+ if (ret != 0) {
+ udma_pr_err(
+ UDMA_M_BOND,
+ "Failed to get bond tracker, bond name(%s), ret(%d).",
+ bond_name, ret);
+ return;
+ }
+}
+
+static void udma_before_bond_deactive(const char *bond_name,
+ struct bond_attr *attr, int err)
+{
+ atomic_set(&g_udma_bond_res.bond_id, UDMA_INVALID_BOND_ID);
+}
+
+int udma_bond_init(void)
+{
+ int ret;
+ struct bond_srv_func ub_bond_attr = {
+ .before_active = udma_before_bond_active,
+ .after_active = NULL,
+ .before_modify = NULL,
+ .after_modify = udma_after_bond_modify,
+ .before_deactive = udma_before_bond_deactive,
+ .after_deactive = NULL,
+ .can_attach = udma_can_do_bond
+ };
+
+ atomic_set(&g_udma_bond_res.bond_id, UDMA_INVALID_BOND_ID);
+
+ ret = hinic5_bond_register(HINIC5_BOND_USER_UB, &ub_bond_attr);
+ if (ret != 0) {
+ udma_pr_err(
+ UDMA_M_BOND,
+ "%s: Failed to register bond service func, ret(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+ udma_pr_info(UDMA_M_BOND, "udma bond init success\n");
+
+ return 0;
+}
+
+void udma_bond_uninit(void)
+{
+ int ret;
+
+ ret = hinic5_bond_unregister(HINIC5_BOND_USER_UB);
+ if (ret != 0) {
+ udma_pr_err(
+ UDMA_M_BOND,
+ "%s: Failed to unregister bond service func, ret(%d).",
+ __func__, ret);
+ return;
+ }
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.c b/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.c
new file mode 100644
index 000000000..31e08f760
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.c
@@ -0,0 +1,325 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/semaphore.h>
+#include <linux/mm.h>
+
+#include "ubcore_api.h"
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_resource.h"
+#include "udma_abi.h"
+#include "udma_ucontext.h"
+
+static void udma_alloc_ucontext_resp_set(struct udma_device *udma_dev,
+ const struct udma_context *udma_ctx,
+ struct ub_create_ctx_resp *resp)
+{
+ struct ub_dev_cap *ub_cap = &udma_dev->ub_cap.dev_cap;
+
+ resp->max_jfc = ub_cap->max_jfc;
+ resp->max_jfs = ub_cap->max_jfs;
+ resp->max_jfr = ub_cap->max_jfr;
+ resp->max_jetty = ub_cap->max_jetty;
+ resp->max_jfs_inline_size = ub_cap->max_jfs_inline_size;
+ resp->max_jfs_sge = ub_cap->max_jfs_sge;
+ resp->max_jfs_rsge = ub_cap->max_jfs_rsge;
+ resp->max_jfr_sge = ub_cap->max_jfr_sge;
+ resp->dwqe_size = udma_dev->ub_cap.dev_cap_res.udma_res.direct_wqe_size;
+
+ resp->db_offset = udma_ctx->db_dma_addr & ((1 << PAGE_SHIFT) - 1);
+ resp->dwqe_offset = udma_ctx->dwqe_dma_addr & ((1 << PAGE_SHIFT) - 1);
+ if (udma_ctx->dwqe_dma_addr == 0)
+ resp->dwqe_size = 0;
+ resp->dwqe_dis = udma_sysfs_get_dwqe_dis(&udma_dev->sysfs_res);
+ resp->device_type = udma_dev->device_type;
+ resp->env_type = udma_dev->env_type;
+ resp->mtt_pro_en = udma_dev->ub_cap.dev_cap.mtt_pro_en;
+ resp->debug_en = udma_dev->sysfs_res.dfx_ctx.debug_en;
+ resp->dcs_en = udma_dev->ub_cap.dev_cap.dcs_en;
+ resp->index_queue_en = udma_get_index_queue_en(udma_dev);
+ resp->fis_en = udma_sysfs_get_fis_en(&udma_dev->sysfs_res);
+}
+
+struct ubcore_ucontext *udma_alloc_ucontext(struct ubcore_device *ub_dev,
+ u32 eid_index,
+ struct ubcore_udrv_priv *udrv_data)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_context *udma_ctx = NULL;
+ struct ub_create_ctx_resp resp = { 0 };
+ u32 mtt_pro_en = 0;
+ int ret;
+
+ if (ub_dev == NULL || udrv_data == NULL) {
+ udma_pr_err(
+ UDMA_M_DEV,
+ "parameters is incorrect, ub_dev(%d), udrv_data(%d).\n",
+ !!ub_dev, !!udrv_data);
+ return ERR_PTR(-EINVAL);
+ }
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "tpf not support this function.\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_ctx = kzalloc(sizeof(struct udma_context), GFP_KERNEL);
+ if (udma_ctx == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "udma_ctx context allocation failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ udma_ctx->udma_dev = udma_dev;
+
+ /* Alloc user space context Doorbell and DWQE */
+ ret = hinic5_alloc_db_phy_addr(udma_dev->hwdev, &udma_ctx->db_dma_addr,
+ &udma_ctx->dwqe_dma_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to alloc DB pa, ret(%d)\n", ret);
+ goto err_db_phy_addr_alloc;
+ }
+
+ /* init software doorbell */
+ INIT_LIST_HEAD(&udma_ctx->db_page_list);
+ mutex_init(&udma_ctx->db_page_mutex);
+
+ ret = udma_sysfs_get_mtt_pro_en(&udma_dev->sysfs_res, &mtt_pro_en);
+ if (ret != 0) {
+ goto err_resp;
+ }
+ udma_dev->ub_cap.dev_cap.mtt_pro_en = mtt_pro_en;
+ udma_alloc_ucontext_resp_set(udma_dev, udma_ctx, &resp);
+
+ /* fill create ctx cmd resp */
+ if (copy_to_user((void *)(uintptr_t)udrv_data->out_addr, &resp,
+ min((u32)udrv_data->out_len, (u32)sizeof(resp))) !=
+ 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "fill create ctx resp failed\n");
+ goto err_resp;
+ }
+
+ return &udma_ctx->base;
+err_resp:
+ mutex_destroy(&udma_ctx->db_page_mutex);
+
+ hinic5_free_db_phy_addr(udma_dev->hwdev, udma_ctx->db_dma_addr,
+ udma_ctx->dwqe_dma_addr);
+err_db_phy_addr_alloc:
+ kfree(udma_ctx);
+ return ERR_PTR(-EFAULT);
+}
+
+int udma_free_ucontext(struct ubcore_ucontext *ucontext)
+{
+ struct udma_context *udma_ctx = NULL;
+ struct udma_device *udma_dev = NULL;
+
+ if (ucontext == NULL) {
+ udma_pr_err(UDMA_M_DEV,
+ "parameters is incorrect, ucontext(%d).\n",
+ !!ucontext);
+ return -EINVAL;
+ }
+ udma_ctx = to_udma_ctx(ucontext);
+ udma_dev = udma_ctx->udma_dev;
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_DEV, "udma_dev is null\n");
+ return -EINVAL;
+ }
+
+ hinic5_free_db_phy_addr(udma_dev->hwdev, udma_ctx->db_dma_addr,
+ udma_ctx->dwqe_dma_addr);
+ mutex_destroy(&udma_ctx->db_page_mutex);
+ udma_info(udma_dev->dev, UDMA_M_DEV, "free ucontext success.\n");
+ kfree(udma_ctx);
+
+ return 0;
+}
+
+static void udma_vma_close(struct vm_area_struct *vma)
+{
+ struct udma_queue_buffer_info *buf = vma->vm_private_data;
+
+ if (buf != NULL) {
+ hinic5_dma_free_coherent_align(buf->dev, &buf->mem_align);
+ kfree(buf);
+ }
+}
+
+static const struct vm_operations_struct udma_vm_ops = {
+ .close = udma_vma_close,
+};
+
+static bool udma_buffer_is_page_align(struct udma_device *udma_dev,
+ struct vm_area_struct *vma)
+{
+ size_t size = ((size_t)vma->vm_end - vma->vm_start);
+
+ if (size % PAGE_SIZE != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "(Vm_end - vm_start) is not align to PAGE_SIZE\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void udma_fill_mmap_queue_buf_info(struct udma_device *udma_dev,
+ size_t buf_size,
+ struct udma_queue_buffer_info *buf)
+{
+ buf->buf_va = buf->mem_align.align_vaddr;
+ buf->dma_addr = buf->mem_align.align_paddr;
+ buf->size = buf_size;
+ buf->dev = udma_dev->dev;
+}
+
+static int udma_queue_dma_alloc(struct udma_device *udma_dev,
+ struct vm_area_struct *vma,
+ struct udma_queue_buffer_info *buf)
+{
+ size_t size;
+ int ret;
+
+ size = ((size_t)vma->vm_end - vma->vm_start);
+ ret = hinic5_dma_zalloc_coherent_align(udma_dev->dev, size, size,
+ GFP_KERNEL, &buf->mem_align);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to alloc dma addr, ret = %d\n", ret);
+ return -ENOMEM;
+ }
+
+ udma_fill_mmap_queue_buf_info(udma_dev, size, buf);
+ return 0;
+}
+
+int udma_mmap_queue_buffer(struct udma_device *udma_dev,
+ struct vm_area_struct *vma)
+{
+ struct udma_queue_buffer_info *buf = NULL;
+ size_t size;
+ struct iommu_domain *dom = NULL;
+ phys_addr_t phy_addr;
+
+ if (!udma_buffer_is_page_align(udma_dev, vma)) {
+ return -EINVAL;
+ }
+
+ buf = kzalloc(sizeof(struct udma_queue_buffer_info), GFP_KERNEL);
+ if (buf == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "Failed to alloc buf\n");
+ return -ENOMEM;
+ }
+
+ if (udma_queue_dma_alloc(udma_dev, vma, buf) != 0) {
+ kfree(buf);
+ return -ENOMEM;
+ }
+
+ size = ((size_t)vma->vm_end - vma->vm_start);
+#ifndef __aarch64__
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#endif
+ dom = iommu_get_domain_for_dev(udma_dev->dev);
+ phy_addr = dom ? iommu_iova_to_phys(dom, buf->dma_addr) : buf->dma_addr;
+ if (io_remap_pfn_range(vma, vma->vm_start, phy_addr >> PAGE_SHIFT, size,
+ vma->vm_page_prot) != 0) {
+ hinic5_dma_free_coherent_align(udma_dev->dev, &buf->mem_align);
+ kfree(buf);
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to do queue buf io remap\n");
+ return -EAGAIN;
+ }
+
+ vma->vm_private_data = buf;
+ vma->vm_ops = &udma_vm_ops;
+ return 0;
+}
+
+int udma_mmap(struct ubcore_ucontext *ucontext, struct vm_area_struct *vma)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_context *udma_ctx = NULL;
+ unsigned long db_pfn = 0;
+ unsigned long dwqe_pfn = 0;
+ s64 size;
+
+ if (ucontext == NULL || ucontext->ub_dev == NULL || vma == NULL) {
+ udma_pr_err(UDMA_M_DEV,
+ "ucontext(%d), vma(%d) or ub_dev is NULL.\n",
+ !!ucontext, !!vma);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ucontext->ub_dev);
+ udma_ctx = to_udma_ctx(ucontext);
+
+ db_pfn = udma_ctx->db_dma_addr >> PAGE_SHIFT;
+ dwqe_pfn = udma_ctx->dwqe_dma_addr >> PAGE_SHIFT;
+ size = (s64)vma->vm_end - (s64)vma->vm_start;
+
+ /* Map hardware doorbell from physical address to virtual address */
+ if (vma->vm_pgoff == USR_MMAP_DB_OFFSET) {
+ if (size % PAGE_SIZE != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DEV,
+ "(Vm_end - vm_start) is not equal to PAGE_SIZE\n");
+ return -EINVAL;
+ }
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ /* construct vm_start~vm_start+PAGE_SIZE page table
+ * db_pfn is page number
+ * vm_page_prot means attr
+ */
+ if (io_remap_pfn_range(vma, vma->vm_start, db_pfn, PAGE_SIZE,
+ vma->vm_page_prot) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "%s: Failed to do db io remap\n", __func__);
+ return -EAGAIN;
+ }
+ return 0;
+ }
+
+ /* Map dwqe from physical address to virtual address */
+ if ((vma->vm_pgoff == USR_MMAP_DWQE_OFFSET) &&
+ (udma_dev->ub_cap.dev_cap_res.udma_res.direct_wqe_size != 0)) {
+ if (size % PAGE_SIZE != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DEV,
+ "%s: (Vm_end - vm_start) is not equal to PAGE_SIZE\n",
+ __func__);
+ return -EINVAL;
+ }
+
+#ifdef __aarch64__
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#else
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#endif
+
+ if (io_remap_pfn_range(vma, vma->vm_start, dwqe_pfn, PAGE_SIZE,
+ vma->vm_page_prot) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "%s: Failed to do dwqe io remap\n", __func__);
+ return -EAGAIN;
+ }
+ return 0;
+ }
+
+ if (vma->vm_pgoff == USR_MMAP_QBUF_OFFSET) {
+ return udma_mmap_queue_buffer(udma_dev, vma);
+ }
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.h b/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.h
new file mode 100644
index 000000000..1d6bbdd6b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/context/udma_ucontext.h
@@ -0,0 +1,51 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_UCONTEXT_H
+#define UDMA_UCONTEXT_H
+
+#include "ubcore_api.h"
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+enum { USR_MMAP_DB_OFFSET = 0, USR_MMAP_DWQE_OFFSET, USR_MMAP_QBUF_OFFSET };
+
+struct udma_context {
+ struct ubcore_ucontext base;
+ struct udma_device *udma_dev;
+ u64 db_dma_addr;
+ u64 dwqe_dma_addr;
+ u32 uasid;
+ struct list_head db_page_list; /* software doorbell page list */
+ struct mutex db_page_mutex; /* software doorbell page mutex */
+};
+
+struct udma_queue_buffer_info {
+ dma_addr_t dma_addr; /* queue dma addr */
+ void *buf_va; /* queue va */
+ u64 size; /* queue size */
+ struct hinic5_dma_addr_align mem_align;
+ struct device *dev;
+};
+
+static inline struct udma_context *
+to_udma_ctx(const struct ubcore_ucontext *ucontext)
+{
+ return (struct udma_context *)udma_container_of(
+ ucontext, struct udma_context, base);
+}
+
+static inline struct ubcore_ucontext *udma_get_uctx(struct ubcore_udata *udata)
+{
+ return ((udata == NULL) || (udata->udrv_data == NULL)) ? NULL :
+ udata->uctx;
+}
+
+struct ubcore_ucontext *udma_alloc_ucontext(struct ubcore_device *ub_dev,
+ u32 eid_index,
+ struct ubcore_udrv_priv *udrv_data);
+int udma_free_ucontext(struct ubcore_ucontext *ucontext);
+int udma_mmap(struct ubcore_ucontext *ucontext, struct vm_area_struct *vma);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.c
new file mode 100644
index 000000000..84c9a87f9
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#include <linux/device.h>
+#include <linux/iommu.h>
+#include <linux/delay.h>
+
+#include "udma_common.h"
+#include "ub_mpu_cmd.h"
+#include "comm_defs.h"
+#include "udma_srq.h"
+#include "udma_cqm.h"
+#include "udma_cmd.h"
+
+int udma_set_func_attr(struct udma_device *udma_dev, u16 func_id,
+ struct ub_cmd_func_attr *func_attr)
+{
+ u16 out_size = sizeof(struct ub_cmd_func_attr);
+ int ret;
+
+ if (udma_dev == NULL || func_attr == NULL) {
+ udma_pr_err(
+ UDMA_M_CMD,
+ "parameters is incorrect, ub_dev(%d), func_attr(%d).\n",
+ !!udma_dev, !!func_attr);
+ return -EINVAL;
+ }
+
+ func_attr->func_id = func_id;
+
+ if (func_attr->attr1_mask.value == 0 &&
+ func_attr->attr2_mask.value == 0) {
+ udma_info(udma_dev->dev, UDMA_M_CMD,
+ "mask is zero, return 0\n");
+ return 0;
+ }
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_SET_FUNC_ATTR, func_attr,
+ out_size, func_attr, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (func_attr->head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CMD,
+ "cmd set func attr failed, ret:%d, out_size:%u, status:%u",
+ ret, out_size, func_attr->head.status);
+ return -EFAULT;
+ }
+ udma_info(udma_dev->dev, UDMA_M_CMD, "set func(%d) table success,",
+ func_id);
+ return 0;
+}
+
+int udma_cfg_ipsu_tbl_ipaddr(struct udma_device *udma_dev,
+ struct cmd_mpu_addr_info *addr_info,
+ enum cmd_mpu_ipsu_type type)
+{
+ struct ub_cmd_ipsu_ip_entry ipsu_ip_entry_param = { 0 };
+ struct ub_cmd_ipsu_ip_entry ipsu_ip_entry_resp = { 0 };
+ union ub_ip_info *ip_addr = &addr_info->ip_addr;
+ u16 out_size = sizeof(ipsu_ip_entry_resp);
+ u16 ipsu_type;
+ int ret;
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(ip_addr->dw); i++)
+ ip_addr->dw[i] = htonl(ip_addr->dw[i]);
+
+ ipsu_ip_entry_param.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ ipsu_ip_entry_param.ip_ver = addr_info->ip_ver;
+ ipsu_ip_entry_param.port_id = 0; // from tpf send down request, port_id no has meaning
+ (void)memcpy_s(&ipsu_ip_entry_param.ip, sizeof(union ub_ip_info),
+ ip_addr, sizeof(union ub_ip_info));
+
+ udma_info(udma_dev->dev, UDMA_M_CMD,
+ "udma cfg ipsu tbl ipaddr: ip_type:%d,portid=%u\n",
+ ipsu_ip_entry_param.ip_ver, ipsu_ip_entry_param.port_id);
+
+ ipsu_type = (type == TYPE_MPU_IPSU_ADD) ? UB_MPU_CMD_ADD_IP_ENTRY :
+ UB_MPU_CMD_DEL_IP_ENTRY;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ (u16)ipsu_type, &ipsu_ip_entry_param,
+ sizeof(ipsu_ip_entry_param),
+ &ipsu_ip_entry_resp, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) ||
+ (ipsu_ip_entry_resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CMD,
+ "Failed to type:%d ip entry, err(%d), status(0x%x), out size(0x%x)\n",
+ ipsu_type, ret, ipsu_ip_entry_resp.head.status,
+ out_size);
+ if (ipsu_ip_entry_resp.head.status == ENXIO) {
+ udma_err(udma_dev->dev, UDMA_M_CMD,
+ "ip entry exist. \n");
+ return -EEXIST;
+ }
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int udma_del_func_res(struct udma_device *udma_dev)
+{
+ struct ub_cmd_func_attr func_state_info = { 0 };
+ u16 out_size = sizeof(func_state_info);
+ int ret;
+
+ func_state_info.func_id = hinic5_global_func_id(udma_dev->hwdev);
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DEL_FUNC_RES, &func_state_info,
+ out_size, &func_state_info, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) ||
+ (func_state_info.head.status != 0)) {
+ udma_warn(
+ udma_dev->dev, UDMA_M_CMD,
+ "cmd set func res failed, ret:%d, out_size:%u, status:%u",
+ ret, out_size, func_state_info.head.status);
+ return -EFAULT;
+ }
+ if (udma_dev->fake_dma_addr.va != NULL) {
+ dma_free_coherent(udma_dev->dev, (size_t)PAGE_SIZE_4K,
+ udma_dev->fake_dma_addr.va,
+ udma_dev->fake_dma_addr.pa);
+ udma_dev->fake_dma_addr.va = NULL;
+ udma_dev->fake_dma_addr.pa = 0;
+ }
+ udma_info(udma_dev->dev, UDMA_M_CMD, "udma_del_func_res success");
+ return 0;
+}
+
+void udma_get_bus_info(struct device *dev, struct udma_bus_addr *bus_addr)
+{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ uint32_t dbdf = UDMA_PCI_DEV_DBDF(pdev);
+
+ bus_addr->domain = UDMA_PCI_DBDF_DOM(dbdf);
+ bus_addr->bus = UDMA_PCI_DBDF_BUS(dbdf);
+ bus_addr->devid = UDMA_PCI_DBDF_DEVID(dbdf);
+ bus_addr->function = UDMA_PCI_DBDF_FUNCTION(dbdf);
+}
+
+int udma_query_mig_vf_status(struct udma_device *udma_dev, u16 func_id)
+{
+ struct udma_dev_bdf_info *bdf_info = udma_dev->bdf_info;
+ struct hinic5_lld_dev *spu_lld_dev = NULL;
+ struct hinic5_lld_dev *ppf_lld_dev = NULL;
+ struct udma_bus_addr bus_addr;
+ u8 vm_status = HIMIGR_VF_FREE;
+ u16 size = sizeof(vm_status);
+ void *ppf_hw_dev = NULL;
+ u32 dbdf;
+ int ret;
+
+ if (bdf_info == NULL || func_id >= UB_FUNCTION_MAX_NUM ||
+ bdf_info[func_id].bdf_info_vld == 0) {
+ udma_err(udma_dev->dev, UDMA_M_CMD,
+ "function %d bdf info is not valid\n", func_id);
+ return MIG_VF_INVAL;
+ }
+
+ udma_get_bus_info(udma_dev->dev, &bus_addr);
+ dbdf = UDMA_QUERY_DBDF_BY_BDF_INFO(&bus_addr);
+
+ udma_info(udma_dev->dev, UDMA_M_CMD, "[DFX] dbdf is %d\n", dbdf);
+ spu_lld_dev = hinic5_get_lld_dev_by_netdev(udma_dev->ndev);
+ if (spu_lld_dev == NULL) {
+ udma_pr_err(UDMA_M_CMD,
+ "get spu lld dev failed, lld dev is null.\n");
+ return MIG_VF_INVAL;
+ }
+ ppf_lld_dev = hinic5_get_ppf_lld_dev(spu_lld_dev);
+ if (ppf_lld_dev == NULL) {
+ udma_pr_err(UDMA_M_CMD,
+ "get ppf lld dev failed, lld dev is null.\n");
+ return MIG_VF_INVAL;
+ }
+ ppf_hw_dev = ppf_lld_dev->hwdev;
+ if (ppf_hw_dev == NULL) {
+ udma_pr_err(UDMA_M_CMD, "get ppf failed, ppf dev is null.\n");
+ hinic5_lld_dev_put(ppf_lld_dev);
+ return MIG_VF_INVAL;
+ }
+ ret = hinic5_mbox_ppf_to_host(ppf_hw_dev, HINIC5_MOD_MIGRATE, 0, 0,
+ &dbdf, sizeof(dbdf), &vm_status, &size, 0,
+ HINIC5_CHANNEL_UB);
+ hinic5_lld_dev_put(ppf_lld_dev);
+ if (ret != 0 || size != sizeof(vm_status)) {
+ udma_err(udma_dev->dev, UDMA_M_CMD,
+ "failed send msg to host %u ret:%d\n", SPU_HOST_ID,
+ ret);
+ return MIG_VF_INVAL;
+ }
+ if (vm_status == HIMIGR_VF_IN_VM) {
+ return MIG_VF_IN_VM;
+ }
+ return MIG_VF_NOT_IN_VM;
+}
+
+int udma_ipsu_ta_vf_ipaddr(struct udma_device *udma_dev,
+ struct cmd_mpu_ueid_addr_info *addr_info,
+ enum cmd_mpu_ipsu_type type, u16 vf_id)
+{
+ struct ub_cmd_ipsu_ta_ip_entry ipsu_ip_entry_param = { 0 };
+ struct ub_cmd_ipsu_ta_ip_entry ipsu_ip_entry_resp = { 0 };
+ union ub_ip_info *ip_addr = &addr_info->ip;
+ u16 out_size = sizeof(ipsu_ip_entry_resp);
+ u16 ipsu_type;
+ int ret;
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(ip_addr->dw); i++) {
+ ip_addr->dw[i] = htonl(ip_addr->dw[i]);
+ }
+ (void)memcpy_s(&ipsu_ip_entry_param.ip, sizeof(union ub_ip_info),
+ ip_addr, sizeof(union ub_ip_info));
+
+ if (udma_dev->ub_dev.cfg.pattern ==
+ UBCORE_PATTERN_1) { /** pattern1 mode, send down ip */
+ ipsu_ip_entry_param.nlp = 0;
+ if (udma_dev->ub_dev.sip_table.entry->sip_info.addr.type ==
+ UBCORE_NET_ADDR_TYPE_IPV4) {
+ ipsu_ip_entry_param.ip_ver = 0;
+ } else {
+ ipsu_ip_entry_param.ip_ver = 1;
+ }
+ } else { /** pattern3 mode, send down upi+eid */
+ ipsu_ip_entry_param.nlp = 1;
+ ipsu_ip_entry_param.upi = addr_info->upi;
+ }
+ ipsu_ip_entry_param.func_id = vf_id;
+
+ ipsu_type = (type == TYPE_MPU_IPSU_ADD) ? UB_MPU_CMD_ADD_TA_IP_ENTRY :
+ UB_MPU_CMD_DEL_TA_IP_ENTRY;
+ udma_info(udma_dev->dev, UDMA_M_CMD,
+ "ipsu_type:%d, upi:0x%x, vf_id:0x%x\n", ipsu_type,
+ ipsu_ip_entry_param.upi, ipsu_ip_entry_param.func_id);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ (u16)ipsu_type, &ipsu_ip_entry_param,
+ sizeof(ipsu_ip_entry_param),
+ &ipsu_ip_entry_resp, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) ||
+ (ipsu_ip_entry_resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CMD,
+ "Failed to type:%d ip entry, err(%d), status(0x%x), out size(0x%x)\n",
+ ipsu_type, ret, ipsu_ip_entry_resp.head.status,
+ out_size);
+ if (ipsu_ip_entry_resp.head.status == ENXIO) {
+ udma_err(udma_dev->dev, UDMA_M_CMD,
+ "ip entry exist.\n");
+ return -EEXIST;
+ }
+ return -EFAULT;
+ }
+ return 0;
+}
+
+void udma_cmdq_rtt_statistic_init(struct cmdq_rtt *rtt)
+{
+ atomic64_set(&rtt->times, 0);
+ atomic64_set(&rtt->cmdq_rtt_sum, 0);
+ atomic64_set(&rtt->cmdq_npu_rtt_sum, 0);
+}
+
+void udma_print_cmdq_rtt_stat(struct udma_device *udma_dev, const char *mod,
+ u32 idx, struct cmdq_rtt *rtt)
+{
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CMD,
+ "module[%s] idx(%u) times(%llu) cmdq_rtt_sum(%llu) cmdq_npu_rtt_sum(%llu)\n",
+ mod, idx, (u64)atomic64_read(&rtt->times),
+ (u64)atomic64_read(&rtt->cmdq_rtt_sum),
+ (u64)atomic64_read(&rtt->cmdq_npu_rtt_sum));
+ }
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.h
new file mode 100644
index 000000000..0d5548733
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_cmd.h
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#ifndef UDMA_CMD_H
+#define UDMA_CMD_H
+
+#include <linux/fwnode.h>
+#include <linux/irqdomain.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/iommu.h>
+
+#include "udma_common.h"
+
+#define HIMIGR_VF_FREE 0
+#define HIMIGR_VF_IN_VM 1
+#define MIG_VF_IN_VM 0 // user ctrl opcode 0x4 message return value, 0: indicates VF is in VM in
+#define MIG_VF_NOT_IN_VM \
+ 1 // user ctrl opcode 0x4 message return value, 1: indicates VF not is in VM in
+#define MIG_VF_INVAL 2 // user ctrl opcode 0x4 message return value, 2: other error
+
+/**
+ * @brief set func table attribute value and same when set corresponding to mask bit
+ * @param func_attr must is struct ub_cmd_func_attr type of change amount (cannot is pointer)
+ * @param dw func_attr struct pointed by in some (count word) union member of name, the union contains specific attribute fields.
+ * @param attr name of attribute field to set (exists in both dw struct member pointed by and dw##_mask.bs bitfield in).
+ * @param value value to assign to attribute field.
+ */
+#define SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, dw, attr, value) \
+ do { \
+ (func_attr).dw.attr = (value); \
+ (func_attr).dw##_mask.bs.attr = 1; \
+ } while (0)
+
+/**
+ * @brief via pointer set func table attribute value and set corresponding to mask bit
+ * @param func_attr pointed by struct ub_cmd_func_attr type of pointer (cannot is empty)
+ * @param dw func_attr struct pointed by in some (count word) union member of name, the union contains specific attribute fields.
+ * @param attr name of attribute field to set (exists in both dw struct member pointed by and dw##_mask.bs bitfield in).
+ * @param value value to assign to attribute field.
+ */
+#define SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, dw, attr, value) \
+ do { \
+ (func_attr)->dw.attr = (value); \
+ (func_attr)->dw##_mask.bs.attr = 1; \
+ } while (0)
+
+enum cmd_mpu_ipsu_type { TYPE_MPU_IPSU_ADD, TYPE_MPU_IPSU_DEL };
+
+struct cmd_mpu_addr_info {
+ u8 ip_ver; // 0x0:IPv4; 0x1:IPv6。
+ u8 rsvd[3];
+ union ub_ip_info ip_addr;
+};
+
+struct cmd_mpu_ueid_addr_info {
+ u8 ip_ver; // 0x0:IPv4; 0x1:IPv6; 0x2:upi。
+ u8 nlp;
+ u8 rsvd[2];
+ union ub_ip_info ip;
+ u32 upi;
+};
+
+int udma_set_func_attr(struct udma_device *udma_dev, u16 func_id,
+ struct ub_cmd_func_attr *func_attr);
+int udma_cfg_ipsu_tbl_ipaddr(struct udma_device *udma_dev,
+ struct cmd_mpu_addr_info *addr_info,
+ enum cmd_mpu_ipsu_type type);
+int udma_del_func_res(struct udma_device *udma_dev);
+int udma_ipsu_ta_vf_ipaddr(struct udma_device *udma_dev,
+ struct cmd_mpu_ueid_addr_info *addr_info,
+ enum cmd_mpu_ipsu_type type, u16 vf_id);
+void udma_cmdq_rtt_statistic_init(struct cmdq_rtt *rtt);
+void udma_print_cmdq_rtt_stat(struct udma_device *udma_dev, const char *mod,
+ u32 idx, struct cmdq_rtt *rtt);
+int udma_query_mig_vf_status(struct udma_device *udma_dev, u16 func_id);
+void udma_get_bus_info(struct device *dev, struct udma_bus_addr *bus_addr);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_comp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_comp.h
new file mode 100644
index 000000000..275533f2a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_comp.h
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Hisilicon Technologies Co., Ltd. 2021. All rights reserved.
+
+#ifndef _UDMA_COMP_H
+#define _UDMA_COMP_H
+
+#include "hmm_common.h"
+#include "hmm_em_inner.h"
+
+#define UBRC_MIN_DEPTH 1
+#define UBRC_MAX_DEPTH 512
+#define UBRC_EXT_ENTRY 16
+#define UBRC_MIN_ENTRY 8 /* min entry aligned required by engine */
+#define UBRC_MAXSIZE_OFFSET 8
+#define UB_INVALID_INDEX 0xFFFFFFFF
+#define MAX_DEST_RM_ATOMIC 128
+
+struct ub_own_cap {
+ u32 cmtt_cl_start;
+ u32 cmtt_cl_end;
+ u32 cmtt_cl_sz;
+ u32 wqe_cl_start;
+ u32 wqe_cl_end;
+ u32 wqe_cl_sz;
+ u32 ubrc_depth;
+ u32 ubrc_entry_sz;
+ u32 log_ubrc_seg;
+};
+
+struct udma_comp_priv {
+ struct hmm_comp_priv hmm_priv;
+ struct ub_own_cap ub_cap;
+ struct hmm_buddy ubrc_buddy;
+ struct hmm_em_table ubrc_em_table;
+ void *udma_dev;
+};
+
+struct ubrc {
+ u32 offset; /* allocate continuous index of first index */
+ u32 order; /* allocate of ubrc of order, represents (done) count */
+ u32 ext_order; /* contain rc table and extension table count */
+ u64 dma_addr;
+ void *vaddr;
+};
+
+#endif
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.c
new file mode 100644
index 000000000..ab11c5ad4
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+
+#include "ubcore_api.h"
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "udma_net.h"
+#include "udma_rc_table.h"
+
+#define MAX_IO_SIZE 0x80000000 /** supports UB device read/write maximum max IO specification 2G */
+
+enum ub_port_speed {
+ UB_SPEED_SDR = 1,
+ UB_SPEED_DDR = 2,
+ UB_SPEED_QDR = 4,
+ UB_SPEED_FDR10 = 8,
+ UB_SPEED_FDR = 16,
+ UB_SPEED_EDR = 32
+};
+
+enum ub_port_width {
+ UB_WIDTH_1X = 1,
+ UB_WIDTH_4X = 2,
+ UB_WIDTH_8X = 4,
+ UB_WIDTH_12X = 8
+};
+
+static void udma_init_dev_feature(struct udma_device *udma_dev,
+ struct ubcore_device_attr *attr)
+{
+ struct ub_dev_cap *dev_cap = &udma_dev->ub_cap.dev_cap;
+
+ attr->dev_cap.feature.bs.oor = dev_cap->feature.bs.oor;
+ attr->dev_cap.feature.bs.selective_retrans =
+ dev_cap->feature.bs.selective_retrans;
+ attr->dev_cap.feature.bs.dca =
+ (dev_cap->feature.bs.dca_rx & dev_cap->feature.bs.dca_tx);
+ attr->dev_cap.feature.bs.jfc_inline = dev_cap->feature.bs.jfc_inline;
+}
+
+void udma_init_dev_atomic(struct udma_device *udma_dev,
+ struct ubcore_device_attr *attr)
+{
+ attr->dev_cap.atomic_feat.value = 0;
+ attr->dev_cap.max_cas_size = 0;
+ attr->dev_cap.max_swap_size = 0;
+ attr->dev_cap.max_fetch_and_add_size = 0;
+ attr->dev_cap.max_fetch_and_sub_size = 0;
+ attr->dev_cap.max_fetch_and_and_size = 0;
+ attr->dev_cap.max_fetch_and_or_size = 0;
+ attr->dev_cap.max_fetch_and_xor_size = 0;
+}
+
+void udma_init_ub_dev_attr(struct udma_device *udma_dev,
+ struct ubcore_device_attr *attr)
+{
+ struct ub_dev_cap *dev_cap = &udma_dev->ub_cap.dev_cap;
+ struct ub_dev_cap_udma_res *udma_res =
+ &udma_dev->ub_cap.dev_cap_res.udma_res;
+ struct ub_net_dev_cap *net_dev_cap = &udma_dev->ub_cap.net_dev_cap;
+ int i;
+
+ udma_init_dev_feature(udma_dev, attr);
+ udma_init_dev_atomic(udma_dev, attr);
+
+ attr->dev_cap.max_jfc = dev_cap->max_jfc;
+ attr->dev_cap.max_jfs = dev_cap->max_jfs;
+ attr->dev_cap.max_jfr = dev_cap->max_jfr;
+ attr->dev_cap.max_jetty = dev_cap->max_jetty;
+ attr->dev_cap.max_jetty_grp = dev_cap->max_jetty_grp;
+ attr->dev_cap.max_jetty_in_jetty_grp = dev_cap->max_jetty_in_jetty_grp;
+ attr->dev_cap.max_jfc_depth = dev_cap->max_jfc_depth;
+ attr->dev_cap.max_jfs_depth = dev_cap->max_jfs_depth;
+ attr->dev_cap.max_jfr_depth = dev_cap->max_jfr_depth;
+ attr->dev_cap.max_jfs_inline_size = dev_cap->max_jfs_inline_size;
+ attr->dev_cap.max_jfs_sge = dev_cap->max_jfs_sge;
+ attr->dev_cap.max_jfs_rsge = dev_cap->max_jfs_rsge;
+ attr->dev_cap.max_jfr_sge = dev_cap->max_jfr_sge;
+ attr->dev_cap.max_msg_size = dev_cap->max_msg_size;
+ attr->dev_cap.max_rc_outstd_cnt = dev_cap->max_rc_outstd_cnt;
+ attr->dev_cap.trans_mode = UBCORE_TP_RM | UBCORE_TP_RC | UBCORE_TP_UM;
+ attr->dev_cap.ceq_cnt = (uint16_t)net_dev_cap->comp_vector_cnt;
+ attr->dev_cap.max_rc = udma_res->max_jfrc_num;
+ attr->dev_cap.max_rc_depth = udma_res->jfrc_depth;
+ attr->dev_cap.min_slice = dev_cap->min_slice;
+ attr->dev_cap.max_slice = dev_cap->max_slice;
+ attr->dev_cap.max_read_size = MAX_IO_SIZE;
+ attr->dev_cap.max_write_size = MAX_IO_SIZE;
+
+ attr->dev_cap.max_sip_cnt_per_ue = dev_cap->max_sip_cnt_per_vf;
+ attr->dev_cap.max_dip_cnt_per_ue = dev_cap->max_dip_cnt_per_vf;
+ attr->dev_cap.max_seid_cnt_per_ue = dev_cap->max_seid_cnt_per_vf;
+ attr->dev_cap.max_ue_cnt = net_dev_cap->vf_cnt;
+
+ attr->dev_cap.max_oor_cnt = dev_cap->max_oor_cnt;
+ attr->dev_cap.max_tp_in_tpg = dev_cap->max_tp_in_tpg;
+ attr->virtualization = (dev_cap->virtualization == 1) ? true : false;
+ adapted_ue_idx(attr) = hinic5_global_func_id(udma_dev->hwdev);
+ attr->dev_cap.max_upi_cnt = dev_cap->max_upi_cnt;
+ attr->port_cnt = (uint8_t)net_dev_cap->port_cnt;
+
+ for (i = 0; i < UBCORE_MAX_PORT_CNT; i++) {
+ attr->port_attr[i].max_mtu =
+ udma_mtu_int_to_enum(net_dev_cap->max_mtu);
+ }
+ attr->tp_maintainer = (net_dev_cap->is_tpf == 1) ? true : false;
+
+ attr->dev_cap.max_eid_cnt = dev_cap->max_eid_cnt;
+ attr->pattern =
+ (udma_dev->ub_cap.dev_cap.pattern_type == PATTERN_TYPE_3) ?
+ UBCORE_PATTERN_3 :
+ UBCORE_PATTERN_1;
+}
+
+int udma_query_device_attr(struct ubcore_device *ub_dev,
+ struct ubcore_device_attr *attr)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev == NULL || attr == NULL) {
+ udma_pr_err(
+ UDMA_M_DEV,
+ "query device attr invalid parameter. udma_dev(%d), attr(%d).\n",
+ !!udma_dev, !!attr);
+ return -EINVAL;
+ }
+
+ udma_init_ub_dev_attr(udma_dev, attr);
+
+ return 0;
+}
+
+static void udma_set_port_attr(struct ubcore_port_status *port_status)
+{
+ port_status->active_mtu = UBCORE_MTU_256;
+ port_status->state = UBCORE_PORT_DOWN;
+}
+
+static void udma_set_speed(enum mag_cmd_port_speed speed,
+ struct ubcore_port_status *port_status)
+{
+ switch (speed) {
+ /* 10G <==> 1X x 10G */
+ case PORT_SPEED_10GB:
+ port_status->active_width = UBCORE_LINK_X1;
+ port_status->active_speed = UBCORE_SP_10G;
+ break;
+
+ /* 25G <==> 1X x 25G */
+ case PORT_SPEED_25GB:
+ port_status->active_width = UBCORE_LINK_X1;
+ port_status->active_speed = UBCORE_SP_25G;
+ break;
+
+ /* 40G <==> 4X x 10G */
+ case PORT_SPEED_40GB:
+ port_status->active_width = UBCORE_LINK_X4;
+ port_status->active_speed = UBCORE_SP_40G;
+ break;
+
+ /* 100G <==> 4X x 25G */
+ case PORT_SPEED_100GB:
+ port_status->active_width = UBCORE_LINK_X4;
+ port_status->active_speed = UBCORE_SP_100G;
+ break;
+
+ default:
+ port_status->active_width = 0;
+ port_status->active_speed = 0;
+ break;
+ }
+}
+
+int udma_query_device_status(struct ubcore_device *dev,
+ struct ubcore_device_status *status)
+{
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ enum mag_cmd_port_speed speed = PORT_SPEED_10GB;
+ struct net_device *net_dev = NULL;
+ enum ubcore_mtu net_dev_mtu;
+ enum ubcore_mtu mtu;
+ u32 port_nums;
+ u32 length;
+ int ret;
+ u32 i;
+
+ if (udma_dev == NULL || status == NULL) {
+ udma_pr_err(
+ UDMA_M_DEV,
+ "query query device status invalid parameter. udma_dev(%d), status(%d).\n",
+ !!udma_dev, !!status);
+ return -EINVAL;
+ }
+
+ port_nums = udma_dev->ub_cap.net_dev_cap.port_cnt;
+ length = (sizeof(status->port_status) /
+ sizeof(struct ubcore_port_status));
+ if (port_nums > length) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "port_nums is %u, port_status length is %u!\n",
+ port_nums, length);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < port_nums; i++) {
+ net_dev = udma_dev->ndev;
+ udma_set_port_attr(&status->port_status[i]);
+
+ if (udma_dev->speed == PORT_SPEED_NOT_SET) {
+ ret = hinic5_get_speed(udma_dev->hwdev, &speed,
+ HINIC5_CHANNEL_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "failed to get speed!\n");
+ status->port_status[i].active_speed = 0;
+ status->port_status[i].active_mtu = 0;
+ return ret;
+ }
+ udma_dev->speed = speed;
+ }
+ speed = udma_dev->speed;
+ udma_set_speed(speed, &status->port_status[i]);
+
+ if (netif_running(net_dev)) {
+ status->port_status[i].state = UBCORE_PORT_ACTIVE;
+ }
+ status->port_status[i].active_mtu = UBCORE_MTU_1024;
+ net_dev_mtu = udma_mtu_int_to_enum(
+ udma_dev->ub_cap.net_dev_cap.max_mtu);
+ mtu = ubcore_get_mtu((int)net_dev->mtu);
+ if (mtu != 0)
+ status->port_status[i].active_mtu =
+ udma_get_support_mtu(
+ min((u32)net_dev_mtu, (u32)mtu));
+ }
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.h
new file mode 100644
index 000000000..3c30e8cd4
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_device.h
@@ -0,0 +1,15 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DEVICE_H
+#define UDMA_DEVICE_H
+
+#include "ubcore_types.h"
+
+int udma_query_device_attr(struct ubcore_device *ub_dev,
+ struct ubcore_device_attr *attr);
+int udma_query_device_status(struct ubcore_device *dev,
+ struct ubcore_device_status *status);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.c
new file mode 100644
index 000000000..705c2025b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.c
@@ -0,0 +1,787 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#include "comm_defs.h"
+#include "hinic5_crm.h"
+#include "hinic5_profile.h"
+#include "hinic5_common.h"
+#include "ub_mpu_cmd.h"
+#include "ub_npu_upi_cmd_defs.h"
+#include "ub_npu_eid_cmd_defs.h"
+#include "ubcore_api.h"
+#include "ubcore_msg.h"
+#include "udma_common.h"
+#include "udma_comp.h"
+#include "udma_cqm.h"
+#include "udma_query.h"
+#include "udma_misc.h"
+#include "udma_rc_table.h"
+#include "udma_resource.h"
+#include "udma_vtp.h"
+#include "udma_cmd_eid.h"
+#include "udma_cmd_com.h"
+#include "fast_msg_common_define.h"
+#include "hinic5_fast_msg.h"
+#include "udma_fast_msg.h"
+
+#define MAX_DEV_REG_NUM 128
+#define FUNC_ID_BOUND_FOR_PF 32
+#define UDMA_IS_FST_MSG_START(opcode) \
+ ((opcode) == ((enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_START))
+#define UDMA_IS_FST_MSG_END(opcode) \
+ ((opcode) == ((enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_END))
+#define UDMA_IS_FST_MSG_FLS_MODIFY(opcode) \
+ ((opcode) == ((enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_FLS_MODIFY))
+#define UDMA_FST_MSG_NEED_RSP(opcode) \
+ (UDMA_IS_FST_MSG_START(opcode) || UDMA_IS_FST_MSG_END(opcode) || \
+ UDMA_IS_FST_MSG_FLS_MODIFY(opcode))
+#define UDMA_IS_FST_MSG_RESTORE_VTP(opcode) \
+ (((opcode) >= ((enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_START)) && \
+ ((opcode) <= \
+ ((enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_FLS_MODIFY)))
+#define UDMA_IS_FST_UPDATE_UPI_NORM(opcode) \
+ ((opcode) == ((enum ubcore_msg_opcode)UB_MIG_UPDATE_UPI_NORM))
+#define UDMA_IS_FST_UPDATE_UPI_MIG(opcode) \
+ ((opcode) == ((enum ubcore_msg_opcode)UB_MIG_UPDATE_UPI_MIG))
+#define UDMA_IS_FST_UPDATE_UPI(opcode) \
+ (((opcode) >= ((enum ubcore_msg_opcode)UB_MIG_UPDATE_UPI_NORM)) && \
+ ((opcode) <= ((enum ubcore_msg_opcode)UB_MIG_UPDATE_UPI_MIG)))
+
+struct udma_msg_dev_info {
+ u32 used;
+ u32 func_id;
+ struct udma_device *udma_dev;
+};
+
+static struct udma_msg_dev_info g_devs_info[MAX_DEV_REG_NUM];
+
+int udma_get_func_id(struct udma_device *udma_dev, u32 *func_id)
+{
+ int ret;
+ struct ub_cmd_get_func_id cmd_in = { 0 };
+ struct ub_cmd_get_func_id_resp cmd_out = { 0 };
+ u16 out_size = sizeof(struct ub_cmd_get_func_id_resp);
+ u16 in_size = sizeof(struct ub_cmd_get_func_id);
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_FUNC_ID, &cmd_in, in_size,
+ &cmd_out, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (cmd_out.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_FMSG,
+ "cmd get func id failed, ret:%d, out_size:%u, status:%u\n",
+ ret, out_size, cmd_out.head.status);
+ return -EFAULT;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_FMSG,
+ "cmd get func id success, func id:%u, tpf id:%u\n",
+ cmd_out.func_id, cmd_out.tpf_id);
+
+ *func_id = cmd_out.func_id;
+
+ return 0;
+}
+
+void udma_fast_msg_handler(struct hisdk5_fast_msg_buf *fast_msg,
+ void *priv_data);
+int udma_mbox_msg_vf_handler(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size);
+
+int udma_msg_dev_register(struct udma_device *udma_dev)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEV_REG_NUM; i++) {
+ if (g_devs_info[i].used != 0) {
+ continue;
+ }
+
+ g_devs_info[i].used = 1;
+ g_devs_info[i].udma_dev = udma_dev;
+ g_devs_info[i].func_id = hinic5_global_func_id(udma_dev->hwdev);
+ break;
+ }
+
+ /* new VM driver compatible with old firmware and SPU driver */
+ if (hinic5_func_type(udma_dev->hwdev) == TYPE_VF &&
+ hinic5_support_fast_msg(udma_dev->hwdev) == false) {
+ return hinic5_register_vf_mbox_cb(udma_dev->hwdev,
+ HINIC5_MOD_FAKE_FMSG,
+ udma_dev,
+ udma_mbox_msg_vf_handler);
+ }
+
+ return hinic5_fast_msg_register_cb(udma_dev->hwdev, HINIC5_MOD_UB,
+ udma_fast_msg_handler, udma_dev);
+}
+
+int udma_msg_dev_unregister(struct udma_device *udma_dev)
+{
+ int i;
+
+ udma_info(udma_dev->dev, UDMA_M_FMSG, "msg dev unregister: %s\n",
+ udma_dev->ub_dev.dev_name);
+ for (i = 0; i < MAX_DEV_REG_NUM; i++) {
+ if ((g_devs_info[i].used != 0) &&
+ (g_devs_info[i].udma_dev == udma_dev)) {
+ g_devs_info[i].used = 0;
+ break;
+ }
+ }
+
+ if (hinic5_func_type(udma_dev->hwdev) == TYPE_VF &&
+ hinic5_support_fast_msg(udma_dev->hwdev) == false) {
+ hinic5_unregister_vf_mbox_cb(udma_dev->hwdev,
+ HINIC5_MOD_FAKE_FMSG);
+ } else {
+ hinic5_fast_msg_unregister_cb(udma_dev->hwdev, HINIC5_MOD_UB);
+ }
+
+ return 0;
+}
+
+#define FAST_MSG_BUFFER_NOT_ENOUGH 2
+#define FAST_MSG_RETRY_CNT 10
+static int udma_send_fast_msg(struct udma_device *udma_dev,
+ struct hinic5_cmd_buf *cmd_buf)
+{
+ struct hisdk5_fast_msg_header *fmsg_head = cmd_buf->buf;
+ u64 out_param = 0;
+ u16 retry_cnt;
+ int ret;
+
+ cmd_buf->size =
+ fmsg_head->data_len + sizeof(struct hisdk5_fast_msg_header);
+ hinic5_cpu_to_be32(cmd_buf->buf, cmd_buf->size);
+
+ retry_cnt = 0;
+ do {
+ ret = hinic5_fast_msg_send(udma_dev->hwdev, cmd_buf,
+ &out_param);
+ if (out_param != FAST_MSG_BUFFER_NOT_ENOUGH && ret != -EBUSY) {
+ break;
+ }
+ msleep(1);
+ retry_cnt++;
+ } while (retry_cnt < FAST_MSG_RETRY_CNT);
+
+ if (ret != 0 || out_param != 0) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "fast msg send failed, ret:%d, out_param: 0x%llx\n",
+ ret, out_param);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static bool udma_is_from_same_card(struct udma_device *dev_a,
+ struct udma_device *dev_b)
+{
+ return (dev_a->dev_bus_type == dev_b->dev_bus_type) &&
+ (dev_a->card_id == dev_b->card_id);
+}
+
+static struct udma_device *
+udma_msg_find_tp_function(struct udma_device *udma_dev, u32 src_func_id)
+{
+ struct udma_device *tmp_tpf = NULL;
+ int i;
+
+ for (i = 0; i < MAX_DEV_REG_NUM; i++) {
+ if ((g_devs_info[i].used != 0) &&
+ (g_devs_info[i].udma_dev->ub_dev.attr.tp_maintainer) &&
+ udma_is_from_same_card(g_devs_info[i].udma_dev, udma_dev) &&
+ (g_devs_info[i].udma_dev->host_id == udma_dev->host_id)) {
+ tmp_tpf = g_devs_info[i].udma_dev;
+ /* tuningfirst per odd/even func_id match tpf, compatible single tpf scenario */
+ if ((g_devs_info[i].func_id & 0x1) ==
+ (src_func_id & 0x1)) {
+ return tmp_tpf;
+ }
+ }
+ }
+
+ return tmp_tpf;
+}
+
+struct udma_device *udma_find_dev_by_fe_idx(struct udma_device *udma_dev,
+ u32 func_id)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEV_REG_NUM; i++) {
+ if ((g_devs_info[i].used != 0) &&
+ (g_devs_info[i].func_id == func_id) &&
+ udma_is_from_same_card(udma_dev, g_devs_info[i].udma_dev) &&
+ (g_devs_info[i].udma_dev->host_id == udma_dev->host_id)) {
+ return g_devs_info[i].udma_dev;
+ }
+ }
+
+ return NULL;
+}
+
+int udma_rsp_msg_to_mig(struct udma_device *dst_dev,
+ struct ubcore_req_host *req_host, int status)
+{
+ int ret;
+ struct ubcore_resp_host *resp_host = NULL;
+ struct ubcore_function_mig_resp *resp_msg = NULL;
+ struct ubcore_function_mig_req *req_msg =
+ (struct ubcore_function_mig_req *)req_host->req.data;
+ struct hisdk5_fast_msg_header *fmsg_head = NULL;
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "[dst dev] opcode: %u, func id: %u\n", req_host->req.opcode,
+ adapted_type_ue_idx(req_msg, mig));
+
+ cmd_buf = hinic5_alloc_cmd_buf(dst_dev->hwdev);
+ if (cmd_buf == NULL) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG, "alloc cmd buf failed\n");
+ return -ENOMEM;
+ }
+
+ fmsg_head = cmd_buf->buf;
+ resp_host = cmd_buf->buf + sizeof(struct hisdk5_fast_msg_header);
+ adapted_type_ue_idx(resp_host, dst) = 0;
+ resp_host->resp.msg_id = req_host->req.msg_id;
+ resp_host->resp.opcode = req_host->req.opcode;
+ resp_host->resp.len = sizeof(struct ubcore_function_mig_resp);
+
+ resp_msg = (struct ubcore_function_mig_resp *)resp_host->resp.data;
+ adapted_type_ue_idx(resp_msg, mig) = adapted_type_ue_idx(req_msg, mig);
+ resp_msg->status = status;
+
+ fmsg_head->status = 0;
+ fmsg_head->mod = HINIC5_MOD_UB;
+ fmsg_head->cmd = UB_MSG_WITH_MIG;
+ fmsg_head->dst_func_id = adapted_type_ue_idx(resp_host, dst);
+ fmsg_head->send = false;
+ fmsg_head->data_len =
+ resp_host->resp.len + sizeof(struct ubcore_resp_host);
+ fmsg_head->nack = 0;
+ fmsg_head->ulp_format = HISDK5_FAST_MSG_ULP_FROMAT_NONE;
+ fmsg_head->rsvd = 0;
+ fmsg_head->rsvd1 = 0;
+ ret = udma_send_fast_msg(dst_dev, cmd_buf);
+ hinic5_free_cmd_buf(dst_dev->hwdev, cmd_buf);
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "[FMSG] send mig msg resp, ret: %d\n", ret);
+
+ return ret;
+}
+
+static int udma_fastmsg_restore_start(struct udma_device *dst_dev,
+ struct udma_vtp_buf *buf)
+{
+ int ret;
+
+ ret = udma_restore_all_vtp_cmd(dst_dev, buf);
+ if (ret != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: [START], restore all vtp failed, ret:%d\n",
+ ret);
+ } else {
+ buf->mig_sts = UDMA_MIG_INCREMENTAL;
+ }
+ return ret;
+}
+
+static int udma_fastmsg_restore_end(struct udma_device *dst_dev,
+ struct udma_vtp_buf *buf)
+{
+ int ret;
+
+ ret = udma_cmd_restore_vtp_remain_vtpn(dst_dev, buf);
+ if (ret != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: [END] restore remain vtp failed, ret:%d\n",
+ ret);
+ } else {
+ buf->mig_sts = UDMA_MIG_INCREMENTAL_MODIFY;
+ }
+ return ret;
+}
+
+int udma_fastmsg_restore_fls_modify(struct udma_device *dst_dev,
+ struct udma_vtp_buf *buf)
+{
+ int ret;
+
+ ret = udma_flush_remain_modify(dst_dev, buf);
+ if (ret != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: [FLUSH MODIFY] Fls remain failed, ret:%d\n",
+ ret);
+ } else {
+ buf->mig_sts = UDMA_MIG_NORMAL;
+ }
+ return ret;
+}
+
+int udma_vtp_restore_handle(void *buf_in, struct udma_device *dst_dev,
+ struct udma_vtp_buf *buf)
+{
+ struct ubcore_req_host *req_host = (struct ubcore_req_host *)buf_in;
+ u16 vfid = buf->func_id;
+ int rsp_msg_ret = 0;
+ int ret = 0;
+ int status;
+
+ if (req_host->req.opcode ==
+ (enum ubcore_msg_opcode)UB_MIG_VTP_RESTORE_CANCEL) {
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: vf:%u recv CANCEL msg.\n", vfid);
+ if (!UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: vf:%u is idle.\n", vfid);
+ return 0;
+ }
+ udma_set_vtp_buf_idle(dst_dev, buf);
+ return 0;
+ }
+
+ if (UDMA_FST_MSG_NEED_RSP(req_host->req.opcode)) {
+ mutex_lock(&buf->vf_mutex);
+ if (!UDMA_IS_VF_MIGRATING(
+ buf->mig_sts)) { // may this when UVS already trigger (done) rollback free (done) buf, because this in this determine status
+ mutex_unlock(&buf->vf_mutex);
+ udma_warn(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: vf:%u is already idle.\n", vfid);
+ return udma_rsp_msg_to_mig(dst_dev, req_host,
+ UBCORE_MIG_MSG_PROC_SUCCESS);
+ }
+
+ if (UDMA_IS_FST_MSG_START(req_host->req.opcode)) {
+ ret = udma_fastmsg_restore_start(dst_dev, buf);
+ } else if (UDMA_IS_FST_MSG_END(req_host->req.opcode)) {
+ ret = udma_fastmsg_restore_end(dst_dev, buf);
+ } else if (UDMA_IS_FST_MSG_FLS_MODIFY(req_host->req.opcode)) {
+ ret = udma_fastmsg_restore_fls_modify(dst_dev, buf);
+ }
+ mutex_unlock(&buf->vf_mutex);
+ status = (ret == 0) ? UBCORE_MIG_MSG_PROC_SUCCESS :
+ UBCORE_MIG_MSG_PROC_FAILURE;
+ rsp_msg_ret = udma_rsp_msg_to_mig(dst_dev, req_host, status);
+ if (UDMA_IS_FST_MSG_FLS_MODIFY(req_host->req.opcode)) {
+ udma_set_vtp_buf_idle(dst_dev, buf);
+ }
+ }
+
+ return (ret | rsp_msg_ret);
+}
+
+static int udma_update_upi_mig_status(struct ubcore_req_host *req_host,
+ struct udma_device *dst_dev, u16 vfid,
+ ub_upi_mig_state_e upi_mig_sts)
+{
+ ub_seid_ctx_info_s seid_ctx = { 0 };
+ int status, ret;
+ u32 idx;
+
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "Start to update upi vf:%u mig_sts:%u\n", vfid, upi_mig_sts);
+
+ for (idx = 0; idx < UDMA_SEID_LOOP; idx++) {
+ (void)memset_s(&seid_ctx, sizeof(ub_seid_ctx_info_s), 0,
+ sizeof(ub_seid_ctx_info_s));
+ ret = udma_cmd_seid_query_ignore_ub_disable_err(
+ dst_dev, vfid, idx, &seid_ctx,
+ sizeof(ub_seid_ctx_info_s));
+ if (ret != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Update upi: get seid failed, vf:%u, ret:%d\n",
+ vfid, ret);
+ goto out;
+ }
+ // seid from microcode read out to of time already is big-endian, later send to microcode also need is big-endian, this at not do convert
+ udma_be32_to_cpu(&seid_ctx, sizeof(seid_ctx.dw0_value) +
+ sizeof(seid_ctx.upi));
+
+ if (seid_ctx.vld == 0) {
+ continue;
+ }
+
+ ret = udma_cmd_update_upi(dst_dev, vfid, &seid_ctx,
+ upi_mig_sts);
+ if (ret != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Update upi failed, vf:%u, ret:%d\n", vfid,
+ ret);
+ goto out;
+ }
+ udma_info(dst_dev->dev, UDMA_M_FMSG,
+ "Update upi success, vf:%u seid_idx:%u\n", vfid, idx);
+ }
+
+out:
+ status = (ret == 0) ? UBCORE_MIG_MSG_PROC_SUCCESS :
+ UBCORE_MIG_MSG_PROC_FAILURE;
+ return udma_rsp_msg_to_mig(dst_dev, req_host, status);
+}
+
+int udma_mig_msg_handler(struct udma_device *udma_dev,
+ struct hisdk5_fast_msg_buf *fast_msg)
+{
+ struct ubcore_function_mig_req *req_msg = NULL;
+ struct ubcore_req_host *req_host = NULL;
+ struct udma_device *dst_dev = udma_dev;
+ struct udma_vtp_buf *buf = NULL;
+ u32 upi_mig_sts;
+ int opcode;
+
+ if ((udma_dev == NULL) || (fast_msg == NULL)) {
+ udma_pr_err(UDMA_M_FMSG,
+ "ub mig msg handler input para is null.\n");
+ return -EINVAL;
+ }
+
+ req_host = (struct ubcore_req_host *)fast_msg->fast_msg_data;
+ req_msg = (struct ubcore_function_mig_req *)req_host->req.data;
+
+ opcode = req_host->req.opcode;
+ udma_info(dst_dev->dev, UDMA_M_FMSG, "Fast msg: opcode:0x%x, vf:%u\n",
+ opcode, adapted_type_ue_idx(req_msg, mig));
+
+ if (fast_msg->fast_msg_header.src_func_id != 0) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: src_func_id:%u is not migrate, vfid:%u\n",
+ fast_msg->fast_msg_header.src_func_id,
+ adapted_type_ue_idx(req_msg, mig));
+ return -EINVAL;
+ }
+
+ if (!UDMA_IS_MIG_VFID(adapted_type_ue_idx(req_msg, mig))) {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: func id:%u invalid\n",
+ adapted_type_ue_idx(req_msg, mig));
+ return -EINVAL;
+ }
+
+ if (UDMA_IS_FST_MSG_RESTORE_VTP(opcode)) {
+ buf = udma_mig_get_vf_buf(dst_dev,
+ adapted_type_ue_idx(req_msg, mig));
+ return udma_vtp_restore_handle(req_host, dst_dev, buf);
+ } else if (UDMA_IS_FST_UPDATE_UPI(opcode)) {
+ upi_mig_sts = UDMA_IS_FST_UPDATE_UPI_NORM(opcode) ?
+ UB_UPI_NORM :
+ UB_UPI_MIGR;
+ return udma_update_upi_mig_status(
+ req_host, dst_dev, adapted_type_ue_idx(req_msg, mig),
+ upi_mig_sts);
+ } else {
+ udma_err(dst_dev->dev, UDMA_M_FMSG,
+ "Fast msg: opcode:%u invalid, vf:%u\n", opcode,
+ adapted_type_ue_idx(req_msg, mig));
+ return -EINVAL;
+ }
+}
+
+void udma_fast_msg_drain_handler(struct ubcore_fastmsg_buf *fastmsg_buf)
+{
+ ubcore_recv_req(&fastmsg_buf->udma_dev->ub_dev, &fastmsg_buf->req_host);
+ udma_info(fastmsg_buf->udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] drain handler callback\n");
+ kfree(fastmsg_buf);
+ return;
+}
+
+void udma_fast_msg_handler(struct hisdk5_fast_msg_buf *fast_msg,
+ void *priv_data)
+{
+ struct udma_device *udma_dev = priv_data;
+ struct ubcore_req_host *req_host = NULL;
+ struct ubcore_resp_host *resp_host = NULL;
+ struct ubcore_function_mig_req *req_msg = NULL;
+ struct ubcore_fastmsg_buf *fastmsg_buf = NULL;
+ u16 fastmsg_buf_len;
+ u16 req_host_len;
+
+ if (udma_dev == NULL || fast_msg == NULL) {
+ udma_pr_err(UDMA_M_FMSG,
+ "fast msg handler input para is null.\n");
+ return;
+ }
+
+ req_host = (struct ubcore_req_host *)fast_msg->fast_msg_data;
+ req_msg = (struct ubcore_function_mig_req *)req_host->req.data;
+ if (fast_msg->fast_msg_header.ulp_format ==
+ HISDK5_FAST_MSG_ULP_FROMAT_MIG) {
+ /* live migration message from pf0 send out, even data tpf receive, per live migration message format parse get vf, find corresponding odd/even tpf */
+ udma_dev = udma_msg_find_tp_function(
+ udma_dev, adapted_type_ue_idx(req_msg, mig));
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_FMSG,
+ "udma tpf not found, src fe idx: %u.\n",
+ adapted_type_ue_idx(req_msg, mig));
+ return;
+ }
+ }
+
+ /* intercept VM sent live migration message */
+ if ((req_host->req.opcode <= UBCORE_MSG_MIG_VM_START &&
+ req_host->req.opcode >= UBCORE_MSG_STOP_PROC_VTP_MSG) ||
+ req_host->req.opcode == UBCORE_MSG_NOTIFY_FASTMSG_DRAIN) {
+ if (fast_msg->fast_msg_header.src_func_id != 0) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] err src_func_id(%u).\n",
+ fast_msg->fast_msg_header.src_func_id);
+ return;
+ }
+ }
+
+ if (fast_msg->fast_msg_header.cmd == UB_MSG_WITH_MIG) {
+ udma_mig_msg_handler(udma_dev, fast_msg);
+ return;
+ }
+
+ if (req_host->req.opcode == UBCORE_MSG_NOTIFY_FASTMSG_DRAIN) {
+ udma_info(
+ udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] func %u recv req msg, src func: %u, opcode: %u\n",
+ hinic5_global_func_id(udma_dev->hwdev),
+ adapted_type_ue_idx(req_host, src),
+ req_host->req.opcode);
+ req_host_len = sizeof(struct ubcore_req_host) +
+ sizeof(struct ubcore_function_mig_req);
+ fastmsg_buf_len = sizeof(struct ubcore_fastmsg_buf) +
+ sizeof(struct ubcore_function_mig_req);
+ fastmsg_buf = kzalloc(fastmsg_buf_len, GFP_KERNEL);
+ if (fastmsg_buf == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] fast msg mem alloc failed.\n");
+ return;
+ }
+
+ fastmsg_buf->udma_dev = udma_dev;
+ (void)memcpy_s(&fastmsg_buf->req_host, req_host_len, req_host,
+ req_host_len);
+ hinic5_fast_msg_forward(udma_dev->hwdev,
+ adapted_type_ue_idx(req_msg, mig),
+ fastmsg_buf,
+ (void *)udma_fast_msg_drain_handler);
+ return;
+ }
+
+ if (fast_msg->fast_msg_header.send == 1) {
+ if (adapted_type_ue_idx(req_host, src) !=
+ fast_msg->fast_msg_header.src_func_id) {
+ udma_err(
+ udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] src_fe_idx(%u) src_func_id(%u) is inconsistent.\n",
+ adapted_type_ue_idx(req_host, src),
+ fast_msg->fast_msg_header.src_func_id);
+ return;
+ }
+
+ udma_info(
+ udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] func %u recv req msg, src func: %u, opcode: %u\n",
+ hinic5_global_func_id(udma_dev->hwdev),
+ adapted_type_ue_idx(req_host, src),
+ req_host->req.opcode);
+ ubcore_recv_req(&udma_dev->ub_dev, req_host);
+ return;
+ }
+
+ resp_host = (struct ubcore_resp_host *)fast_msg->fast_msg_data;
+ udma_info(
+ udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] func %u recv resp msg, dst func: %u opcode:%u data:0x%llx len:%u\n",
+ hinic5_global_func_id(udma_dev->hwdev),
+ adapted_type_ue_idx(resp_host, dst), resp_host->resp.opcode,
+ *((u64 *)resp_host->resp.data), (u32)(resp_host->resp.len));
+ ubcore_recv_resp(&udma_dev->ub_dev, &resp_host->resp);
+}
+
+int udma_mbox_msg_vf_handler(void *pri_handle, u16 cmd, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct udma_device *udma_dev = pri_handle;
+ struct ubcore_resp_host *resp_host = (struct ubcore_resp_host *)buf_in;
+
+ if (pri_handle == NULL || buf_in == NULL) {
+ udma_pr_err(
+ UDMA_M_FMSG,
+ "Invalid input parameter, pri_handle: %d, buf_in: %d.\n",
+ !!pri_handle, !!buf_in);
+ return -EINVAL;
+ }
+
+ if (in_size < sizeof(struct ubcore_resp_host)) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[=MB=] Invalid in_size: %u, expect: %zu\n", in_size,
+ sizeof(struct ubcore_resp_host));
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_FMSG,
+ "[=MB=] [dst dev] ep: %u, opcode: %u\n",
+ adapted_type_ue_idx(resp_host, dst), resp_host->resp.opcode);
+
+ return ubcore_recv_resp(&udma_dev->ub_dev, &resp_host->resp);
+}
+
+static void udma_build_fast_msg_header(struct hisdk5_fast_msg_header *fmsg_head,
+ bool is_req, u16 dst_func_id,
+ u16 data_len)
+{
+ fmsg_head->status = 0;
+ fmsg_head->mod = HINIC5_MOD_UB;
+ fmsg_head->cmd = UB_MSG_WITH_UVS;
+ fmsg_head->dst_func_id = dst_func_id; /* microcode will for this field do check */
+ fmsg_head->send = is_req;
+ fmsg_head->data_len = data_len;
+ fmsg_head->nack = 0;
+ fmsg_head->ulp_format = HISDK5_FAST_MSG_ULP_FROMAT_NONE;
+ fmsg_head->rsvd = 0;
+ fmsg_head->rsvd1 = 0;
+}
+
+int udma_send_msg_to_tpf(struct ubcore_device *dev, struct ubcore_req *req)
+{
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ struct udma_device *peer_dev = NULL;
+ struct ubcore_req_host *req_host = NULL;
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ u16 req_len, reqh_len, fmsg_max_size;
+ u32 src_fe_idx = 0;
+ int ret;
+
+ if (udma_dev == NULL || req == NULL) {
+ udma_pr_err(
+ UDMA_M_FMSG,
+ "send msg to tpf invalid parameter. udma_dev(%d), req(%d).\n",
+ !!udma_dev, !!req);
+ return -EINVAL;
+ }
+
+ ret = udma_get_func_id(udma_dev, &src_fe_idx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] get func id failed\n");
+ return -EINVAL;
+ }
+
+ cmd_buf = hinic5_alloc_cmd_buf(udma_dev->hwdev);
+ if (cmd_buf == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] alloc cmd buf failed\n");
+ return -ENOMEM;
+ }
+
+ req_len = (u16)req->len + sizeof(struct ubcore_req);
+ reqh_len = (u16)req->len + sizeof(struct ubcore_req_host);
+ fmsg_max_size = cmd_buf->size - sizeof(struct hisdk5_fast_msg_header);
+ req_host = cmd_buf->buf + sizeof(struct hisdk5_fast_msg_header);
+ adapted_type_ue_idx(req_host, src) = src_fe_idx & 0xffff;
+
+ ret = memcpy_s(&req_host->req,
+ fmsg_max_size -
+ sizeof(adapted_type_ue_idx(req_host, src)),
+ req, req_len);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] memcpy err, ret:%d, destMax:%lu, count:%u\n",
+ ret,
+ fmsg_max_size -
+ sizeof(adapted_type_ue_idx(req_host, src)),
+ req_len);
+ goto free_cmd_buf;
+ }
+
+ peer_dev = udma_msg_find_tp_function(udma_dev, src_fe_idx);
+ if (adapted_type_ue_idx(req_host, src) < FUNC_ID_BOUND_FOR_PF &&
+ peer_dev != NULL) {
+ ret = ubcore_recv_req(&peer_dev->ub_dev, req_host);
+ } else {
+ /* new VM driver compatible with old firmware and SPU driver */
+ if (hinic5_func_type(udma_dev->hwdev) == TYPE_VF &&
+ hinic5_support_fast_msg(udma_dev->hwdev) == false) {
+ ret = hinic5_mbox_to_pf(udma_dev->hwdev,
+ HINIC5_MOD_FAKE_FMSG, 0,
+ (void *)req_host, reqh_len,
+ NULL, NULL, 0,
+ HINIC5_CHANNEL_UB);
+ } else {
+ /* primary dynamic sent message, dst_func_id by microcode to cover fill in */
+ udma_build_fast_msg_header(cmd_buf->buf, true, 0xFFFF,
+ reqh_len);
+ ret = udma_send_fast_msg(udma_dev, cmd_buf);
+ }
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] send msg to tpf from func_%u, ret: %d\n", src_fe_idx,
+ ret);
+
+free_cmd_buf:
+ hinic5_free_cmd_buf(udma_dev->hwdev, cmd_buf);
+ return ret;
+}
+
+int udma_send_msg_from_tpf(struct ubcore_device *dev,
+ struct ubcore_resp_host *resp_host)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_device *peer_dev = NULL;
+ struct hinic5_cmd_buf *cmd_buf = NULL;
+ u16 resp_len, fmsg_max_size;
+ int ret;
+
+ if (dev == NULL || resp_host == NULL) {
+ udma_pr_err(UDMA_M_FMSG,
+ "Invalid parameter. dev(%d), resp_host(%d).\n",
+ !!dev, !!resp_host);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(dev);
+
+ peer_dev = udma_find_dev_by_fe_idx(udma_dev,
+ adapted_type_ue_idx(resp_host, dst));
+ if (adapted_type_ue_idx(resp_host, dst) < FUNC_ID_BOUND_FOR_PF &&
+ peer_dev != NULL) {
+ ret = ubcore_recv_resp(&peer_dev->ub_dev, &resp_host->resp);
+ } else {
+ cmd_buf = hinic5_alloc_cmd_buf(udma_dev->hwdev);
+ if (cmd_buf == NULL) {
+ udma_err(udma_dev->hwdev, UDMA_M_FMSG,
+ "[FMSG] alloc cmd buf failed\n");
+ return -ENOMEM;
+ }
+
+ resp_len =
+ resp_host->resp.len + sizeof(struct ubcore_resp_host);
+ fmsg_max_size =
+ cmd_buf->size - sizeof(struct hisdk5_fast_msg_header);
+ ret = memcpy_s(cmd_buf->buf +
+ sizeof(struct hisdk5_fast_msg_header),
+ fmsg_max_size, resp_host, resp_len);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->hwdev, UDMA_M_FMSG,
+ "[FMSG] memcpy err, ret:%d, destMax:%u, count:%u\n",
+ ret, fmsg_max_size, resp_len);
+ } else {
+ udma_build_fast_msg_header(
+ cmd_buf->buf, false,
+ adapted_type_ue_idx(resp_host, dst), resp_len);
+ ret = udma_send_fast_msg(udma_dev, cmd_buf);
+ }
+
+ hinic5_free_cmd_buf(udma_dev->hwdev, cmd_buf);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_FMSG,
+ "[FMSG] send msg from tpf to func_%u, ret: %u\n",
+ adapted_type_ue_idx(resp_host, dst), ret);
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.h
new file mode 100644
index 000000000..652a2d289
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_fast_msg.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_FAST_MSG_H
+#define UDMA_FAST_MSG_H
+
+#include "udma_common.h"
+
+#define UB_MSG_WITH_UVS 0
+#define UB_MSG_WITH_MIG 1
+#define MIG_UB_CMD 1
+
+enum {
+ UB_MIG_VTP_RESTORE_START = 0x20, // notify UDMA perform VTP full flush down
+ UB_MIG_VTP_RESTORE_END, // notify UDMA remaining of incremental request flush down
+ UB_MIG_VTP_RESTORE_CANCEL, // notify UDMA rollback
+ UB_MIG_VTP_RESTORE_FLS_MODIFY, // complete FLUSH DMA, notify UDMA remaining of modify request flush down
+ UB_MIG_UPDATE_UPI_NORM, // live migration process in, activate and cancel handle in, if notify UVS failure, primary dynamic update UPI is NORM
+ UB_MIG_UPDATE_UPI_MIG, // live migration process in, deactivate stage segment primary dynamic update UPI is MIG(later adaptation)
+};
+
+struct ubcore_fastmsg_buf {
+ struct udma_device *udma_dev;
+ struct ubcore_req_host req_host;
+};
+
+int udma_msg_dev_register(struct udma_device *udma_dev);
+int udma_msg_dev_unregister(struct udma_device *udma_dev);
+int udma_send_msg_to_tpf(struct ubcore_device *dev, struct ubcore_req *req);
+int udma_send_msg_from_tpf(struct ubcore_device *dev,
+ struct ubcore_resp_host *resp_host);
+struct udma_device *udma_find_dev_by_fe_idx(struct udma_device *udma_dev,
+ u32 func_id);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_main.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_main.c
new file mode 100644
index 000000000..1b6704146
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_main.c
@@ -0,0 +1,1044 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include "linux/nodemask.h"
+
+#include "securec.h"
+#include "hinic5_crm.h"
+#include "hinic5_profile.h"
+#include "ubcore_api.h"
+#include "udma_bond.h"
+#include "udma_common.h"
+#include "udma_device.h"
+#include "udma_comp.h"
+#include "udma_cqm.h"
+#include "udma_cmd.h"
+#include "udma_tp.h"
+#include "udma_tpg.h"
+#include "udma_query.h"
+#include "udma_jfc.h"
+#include "udma_jetty.h"
+#include "udma_segment.h"
+#include "udma_key.h"
+#include "udma_rc_table.h"
+#include "udma_mtt.h"
+#include "udma_net.h"
+#include "udma_dfx.h"
+#include "udma_misc.h"
+#include "udma_rc_table.h"
+#include "udma_resource.h"
+#include "udma_sysfs_api.h"
+#include "udma_vtp.h"
+#include "udma_utp.h"
+#include "udma_fast_msg.h"
+#include "udma_ucontext.h"
+#include "udma_device.h"
+#include "udma_cmd_event.h"
+#include "udma_cmd_eid.h"
+#include "udma_dfx_capture.h"
+#include "udma_dfx_drop.h"
+#include "udma_dfx_modify.h"
+#include "udma_vram.h"
+#include "udma_vram_mem.h"
+#include "udma_shm_manage.h"
+
+#define UDMA_IS_EVEN_NUM(num) (((num)&0x1) == 0)
+#define PARITY_DIVISOR 2
+
+u32 g_mtt_page_size = 0U;
+u32 g_double_tpf_en = 1U;
+u32 g_env_type = UB_ENV_FPGA;
+u32 g_udma_fast_path_timer_disable = 0U;
+static char g_ub_uld_dev_name[IFNAMSIZ] = { 0 };
+module_param(g_mtt_page_size, uint, S_IRUGO);
+module_param(g_double_tpf_en, uint, S_IRUGO);
+module_param(g_env_type, uint, S_IRUGO);
+module_param(g_udma_fast_path_timer_disable, uint, 0664);
+MODULE_PARM_DESC(g_mtt_page_size, "0:4K,1:64K,2:2M,default:4K");
+MODULE_PARM_DESC(g_double_tpf_en, "use for enable double TPF");
+MODULE_PARM_DESC(g_env_type, "0:asic, 1:esl, 2:fpga, 3: emu, default:fpga");
+MODULE_PARM_DESC(g_udma_fast_path_timer_disable, "0: enable, 1: disable");
+
+static struct ubcore_ops g_dev_ops = {
+ .owner = THIS_MODULE,
+ .driver_name = "ub_hal",
+ .abi_version = 0,
+ .add_ueid = udma_cmd_ueid_add,
+ .delete_ueid = udma_cmd_ueid_delete,
+ .query_device_attr = udma_query_device_attr,
+ .query_device_status = udma_query_device_status,
+ .alloc_ucontext = udma_alloc_ucontext,
+ .free_ucontext = udma_free_ucontext,
+ .mmap = udma_mmap,
+ .config_device = udma_config_device,
+ .add_net_addr = udma_add_netaddr,
+ .delete_net_addr = udma_del_netaddr,
+ .create_jetty = udma_create_jetty,
+ .destroy_jetty = udma_destroy_jetty,
+ .modify_jetty = udma_modify_jetty,
+ .flush_jetty = udma_flush_jetty,
+ .query_jetty = udma_query_jetty,
+ .create_jfc = udma_create_jfc,
+ .modify_jfc = udma_modify_jfc,
+ .destroy_jfc = udma_destroy_jfc,
+ .rearm_jfc = udma_rearm_jfc,
+ .create_jfs = udma_create_jfs,
+ .query_jfs = udma_query_jfs,
+ .destroy_jfs = udma_destroy_jfs,
+ .modify_jfs = udma_modify_jfs,
+ .flush_jfs = udma_flush_jfs,
+ .create_jfr = udma_create_jfr,
+ .query_jfr = udma_query_jfr,
+ .destroy_jfr = udma_destroy_jfr,
+ .import_jfr = udma_import_jfr,
+ .unimport_jfr = udma_unimport_jfr,
+ .modify_jfr = udma_modify_jfr,
+ .import_jetty = udma_import_jetty,
+ .unimport_jetty = udma_unimport_jetty,
+ .bind_jetty = udma_bind_jetty,
+ .unbind_jetty = udma_unbind_jetty,
+ .create_jetty_grp = udma_create_jetty_grp,
+ .delete_jetty_grp = udma_destroy_jetty_grp,
+ .alloc_token_id = udma_alloc_key_id,
+ .free_token_id = udma_free_key_id,
+ .register_seg = udma_register_seg,
+ .unregister_seg = udma_unregister_seg,
+ .import_seg = udma_import_seg,
+ .unimport_seg = udma_unimport_seg,
+ .create_tp = udma_create_tp,
+ .modify_tp = udma_modify_tp,
+ .modify_user_tp = NULL,
+ .create_vtp = udma_create_vtp,
+ .alloc_vtpn = udma_alloc_vtpn,
+ .destroy_vtp = udma_destroy_vtp,
+ .free_vtpn = udma_free_vtpn,
+ .modify_vtp = udma_modify_vtp,
+ .create_utp = udma_create_utp,
+ .destroy_utp = udma_destroy_utp,
+ .query_res = udma_query_res,
+ .query_ue_idx = udma_query_fe_idx,
+ .destroy_tp = udma_destroy_tp,
+ .create_multi_tp = udma_create_multi_tp,
+ .destroy_multi_tp = udma_destroy_multi_tp,
+ .modify_multi_tp = udma_modify_multi_tp,
+ .create_tpg = udma_create_tpg,
+ .destroy_tpg = udma_destroy_tpg,
+ .post_jetty_recv_wr = udma_post_jetty_recv_wr,
+ .post_jetty_send_wr = udma_post_jetty_send_wr,
+ .post_jfs_wr = udma_post_jfs_wr,
+ .post_jfr_wr = udma_post_jfr_wr,
+ .poll_jfc = udma_poll_jfc,
+ .user_ctl = udma_user_ctl,
+ .send_req = udma_send_msg_to_tpf,
+ .send_resp = udma_send_msg_from_tpf,
+ .query_cc = udma_query_cc,
+ .config_dscp_vl = udma_config_dscp_vl,
+ .query_dscp_vl = udma_query_dscp_vl,
+ .config_function_migrate_state = udma_config_function_migrate_state,
+ .query_ue_stats = udma_query_fe_stats,
+ .disassociate_ucontext = NULL,
+};
+
+static int udma_register_netdev_event(struct udma_device *udma_dev)
+{
+ int ret;
+
+ udma_dev->netdev_nb.notifier_call = udma_dev_event;
+ ret = register_netdevice_notifier(&udma_dev->netdev_nb);
+ if (ret != 0) {
+ udma_err(udma_dev->hwdev, UDMA_M_MAIN,
+ "register netdev notifier failed\n");
+ udma_dev->netdev_nb.notifier_call = NULL;
+ }
+
+ return ret;
+}
+
+static void udma_unregister_netdev_event(struct udma_device *udma_dev)
+{
+ unregister_netdevice_notifier(&udma_dev->netdev_nb);
+ if (udma_dev->netdev_nb.notifier_call != NULL) {
+ udma_dev->netdev_nb.notifier_call = NULL;
+ }
+}
+
+void udma_get_dev_name(struct udma_device *udma_dev)
+{
+ struct udma_bus_addr bus_addr = { 0 };
+
+ if (udma_dev->dev_bus_type == HINIC5_DEVICE_T_PCI) {
+ udma_get_bus_info(udma_dev->dev, &bus_addr);
+ } else if (udma_dev->dev_bus_type ==
+ HINIC5_DEVICE_T_UB) { /* todo ubc scenario need adaptation */
+ bus_addr.function = hinic5_global_func_id(udma_dev->hwdev) &
+ 0xff;
+ }
+
+ scnprintf(udma_dev->dev_name, UDMA_MAX_DEV_NAME, "hiudma5_p%us%uf%u",
+ bus_addr.bus, bus_addr.devid, bus_addr.function);
+
+ /* uld_dev_name is for internal use */
+ scnprintf(g_ub_uld_dev_name, sizeof(g_ub_uld_dev_name) - 1,
+ "ub%us%uf%u", bus_addr.bus, bus_addr.devid,
+ bus_addr.function);
+}
+
+static void udma_init_ub_dev(struct ubcore_device *ub_dev,
+ struct hinic5_lld_dev *lld_dev,
+ struct udma_device *udma_dev)
+{
+ ub_dev->transport_type = UBCORE_TRANSPORT_UB;
+ ub_dev->ops = &g_dev_ops;
+ ub_dev->dev.parent = udma_dev->dev;
+ ub_dev->netdev = udma_dev->ndev;
+ ub_dev->dma_dev = ub_dev->dev.parent;
+
+ udma_get_dev_name(udma_dev);
+
+ strlcpy(ub_dev->dev_name, udma_dev->dev_name, UDMA_MAX_DEV_NAME);
+
+ udma_init_ub_dev_attr(udma_dev, &ub_dev->attr);
+
+ ub_dev->cfg.pattern =
+ (udma_dev->ub_cap.dev_cap.pattern_type == PATTERN_TYPE_3) ?
+ UBCORE_PATTERN_3 :
+ UBCORE_PATTERN_1;
+ ub_dev->cfg.virtualization =
+ (udma_dev->ub_cap.dev_cap.virtualization == 1) ? true : false;
+}
+
+static int udma_register_ub_device_base(struct udma_device *udma_dev)
+{
+ struct ubcore_device *ub_dev = &udma_dev->ub_dev;
+ int ret;
+
+ if (udma_vram5_get_kexec_flag() == 0) {
+ udma_pr_info(UDMA_M_MAIN,
+ "first OS: about to register dev: %s\n",
+ udma_dev->dev_name);
+ ret = ubcore_register_device(ub_dev);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MAIN,
+ "register udma dev to ubcore failed, ret(%d)\n",
+ ret);
+ }
+ return ret;
+ }
+
+#ifdef UBCORE_EN
+ udma_pr_err(UDMA_M_VRAM, "second OS, about to register dev: %s\n",
+ udma_dev->dev_name);
+ ret = ubcore_recover_from_udma(UDMA_VRAM_TYPE_DEV, udma_dev);
+ if (ret) {
+ udma_pr_err(UDMA_M_VRAM,
+ "ubcore recover failed failed. type:%d\n",
+ UDMA_VRAM_TYPE_DEV);
+ return -EINVAL;
+ }
+#endif
+
+ return 0;
+}
+
+static void ubcore_unregister_device_base(struct ubcore_device *ub_dev)
+{
+ if (udma_vram5_get_kexec_flag() == 0) {
+ ubcore_unregister_device(ub_dev);
+ }
+}
+
+static int udma_register_ub_device(struct hinic5_lld_dev *lld_dev,
+ struct udma_device *udma_dev)
+{
+ int ret;
+ u8 port_id;
+ struct ubcore_device *ub_dev = &udma_dev->ub_dev;
+
+ udma_init_ub_dev(ub_dev, lld_dev, udma_dev);
+
+ ret = udma_msg_dev_register(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "register udma dev failed, ret(%d)\n", ret);
+ return ret;
+ }
+
+ ret = udma_register_ub_device_base(udma_dev);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MAIN,
+ "register udma dev to ub device base failed, ret(%d)\n",
+ ret);
+ goto err_ubcore_register;
+ }
+
+ ret = udma_register_netdev_event(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "register netdev event failed, ret(%d)\n", ret);
+ goto err_register_netdev_event;
+ }
+
+ port_id = hinic5_physical_port_id(udma_dev->hwdev);
+ udma_info(udma_dev->hwdev, UDMA_M_MAIN, "find port id:%u\n", port_id);
+
+ ret = ubcore_set_port_netdev(ub_dev, ub_dev->netdev, port_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "set port netdev failed, ret(%d)\n", ret);
+ goto err_set_port;
+ }
+
+ if (udma_dev->ub_dev.attr.tp_maintainer &&
+ udma_vram5_get_kexec_flag() == 0) {
+ ret = udma_cmd_async_event_credit_init(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "init asyn event credit failed, ret(%d)\n",
+ ret);
+ goto err_init_credit;
+ }
+ }
+
+ return ret;
+
+err_init_credit:
+ ubcore_put_port_netdev(&udma_dev->ub_dev);
+err_set_port:
+ udma_unregister_netdev_event(udma_dev);
+err_register_netdev_event:
+ udma_delete_rc_table(
+ udma_dev); //ubcore_register_device of config_device called in, in when destroying device destroy RC table
+ udma_destroy_tp_latch_tpg(udma_dev); /* config_device created in */
+ ubcore_unregister_device_base(&udma_dev->ub_dev);
+err_ubcore_register:
+ udma_msg_dev_unregister(udma_dev);
+
+ return ret;
+}
+
+static void udma_unregister_ub_device(struct udma_device *udma_dev)
+{
+ ubcore_put_port_netdev(&udma_dev->ub_dev);
+ udma_unregister_netdev_event(udma_dev);
+ udma_delete_rc_table(
+ udma_dev); //ubcore_register_device of config_device called in, in when destroying device destroy RC table
+ udma_destroy_tp_latch_tpg(udma_dev); /* config_device created in */
+ ubcore_unregister_device(&udma_dev->ub_dev);
+ udma_msg_dev_unregister(udma_dev);
+}
+
+static u64 udma_get_card_id(struct hinic5_lld_dev *lld_dev)
+{
+ struct hinic5_device_info info = { 0 };
+
+ hinic5_get_device_info(lld_dev, &info);
+ return info.id;
+}
+
+static int udma_get_dev(struct hinic5_lld_dev *lld_dev,
+ struct udma_device *udma_dev)
+{
+ udma_dev->dev = lld_dev->dev;
+ udma_dev->hwdev = lld_dev->hwdev;
+ udma_dev->ndev = hinic5_get_netdev_by_lld(lld_dev);
+ if (udma_dev->ndev == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN, "failed to get net dev\n");
+ return -EINVAL;
+ }
+ udma_dev->device_type = UDMA_DEV_TYPE_HI1825_V100;
+ udma_dev->env_type = g_env_type;
+ udma_dev->dev_bus_type = lld_dev->dev_type;
+ udma_dev->card_id = udma_get_card_id(lld_dev);
+ udma_dev->host_id = hinic5_host_id(lld_dev->hwdev);
+
+ udma_info(udma_dev->dev, UDMA_M_MAIN,
+ "card_id:%llu, host_id:%u, function_id:%u\n",
+ udma_dev->card_id, udma_dev->host_id,
+ hinic5_global_func_id(udma_dev->hwdev));
+ return 0;
+}
+
+static int udma_tpg_bitmap_alloc(struct udma_device *udma_dev)
+{
+ if (udma_dev->ub_cap.net_dev_cap.is_tpf != 0) {
+ udma_dev->bitmap =
+ udma_bitmap_alloc(udma_dev->ub_cap.dev_cap.max_tpg);
+ if (udma_dev->bitmap == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to allocate bitmap.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static void udma_tpg_bitmap_free(struct udma_device *udma_dev)
+{
+ if (udma_dev->ub_cap.net_dev_cap.is_tpf != 0) {
+ udma_bitmap_free(udma_dev->bitmap);
+ udma_dev->bitmap = NULL;
+ }
+}
+
+static int udma_create_tp_res(struct udma_device *udma_dev)
+{
+ int ret;
+
+ ret = udma_tpg_bitmap_alloc(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to allocate tpg bitmap.\n");
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_free_tp_res(struct udma_device *udma_dev)
+{
+ udma_tpg_bitmap_free(udma_dev);
+}
+
+void udma_init_mig_vf_mgt(struct udma_device *udma_dev)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ struct udma_vtp_buf *buf = NULL;
+ int i;
+
+ mutex_init(&mig_mgt->mig_vf_mgt_mutex);
+ mig_mgt->migrating_num = 0;
+
+ for (i = 0; i < ARRAY_SIZE(mig_mgt->buf_array); i++) {
+ buf = &mig_mgt->buf_array[i];
+ mutex_init(&buf->vf_mutex);
+ buf->addr = NULL;
+ buf->cqm_cmd_buf = NULL;
+ buf->total = 0;
+ buf->cur_idx = 0;
+ buf->mig_sts = UDMA_MIG_IDLE;
+ buf->func_id = UDMA_MIG_VFID_MIN + i;
+ }
+}
+
+void udma_deinit_mig_vf_mgt(struct udma_device *udma_dev)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ struct udma_vtp_buf *buf = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mig_mgt->buf_array); i++) {
+ buf = &mig_mgt->buf_array[i];
+ mutex_destroy(&buf->vf_mutex);
+ }
+ mutex_destroy(&mig_mgt->mig_vf_mgt_mutex);
+}
+
+static void udma_misc_init(struct udma_device *udma_dev)
+{
+ if (udma_vram5_get_kexec_flag() == 1) {
+ return;
+ }
+
+ udma_dev->jfs_current_cnt = 0;
+ atomic_set(&udma_dev->jfs_hash, 0);
+ atomic_set(&udma_dev->jfr_hash, 0);
+ atomic_set(&udma_dev->rs_hash, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.post_send_wr_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.post_recv_wr_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_total_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_sq_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_rq_num, 0);
+
+ atomic_set(&udma_dev->task_jfs_num, 0);
+
+ mutex_init(&udma_dev->jettyn_record.mutex);
+ mutex_init(&udma_dev->tpn_record.mutex);
+ mutex_init(&udma_dev->jfcn_record.mutex);
+ mutex_init(&udma_dev->vtpn_record.mutex);
+ mutex_init(&udma_dev->utpn_record.mutex);
+ mutex_init(&udma_dev->tpgn_record.mutex);
+ mutex_init(&udma_dev->jetty_grpn_record.mutex);
+ mutex_init(&udma_dev->srqn_record.mutex);
+ mutex_init(&udma_dev->dev_mutex);
+ mutex_init(&udma_dev->tp_mutex);
+ spin_lock_init(&udma_dev->dwqe_lock);
+}
+
+static void udma_misc_deinit(struct udma_device *udma_dev)
+{
+ if (udma_vram5_get_kexec_flag() == 1) {
+ return;
+ }
+
+ mutex_destroy(&udma_dev->jettyn_record.mutex);
+ mutex_destroy(&udma_dev->tpn_record.mutex);
+ mutex_destroy(&udma_dev->jfcn_record.mutex);
+ mutex_destroy(&udma_dev->vtpn_record.mutex);
+ mutex_destroy(&udma_dev->utpn_record.mutex);
+ mutex_destroy(&udma_dev->tpgn_record.mutex);
+ mutex_destroy(&udma_dev->jetty_grpn_record.mutex);
+ mutex_destroy(&udma_dev->srqn_record.mutex);
+ mutex_destroy(&udma_dev->dev_mutex);
+ mutex_destroy(&udma_dev->tp_mutex);
+}
+
+static int udma_reload_device_cap(struct hinic5_lld_dev *lld_dev,
+ struct ub_service_cap *ub_cap)
+{
+ int ret;
+
+ if (udma_vram5_get_kexec_flag() == 1) {
+ return 0;
+ }
+
+ /* VF scenario from MPU get ub resource information and update to SDK, avoid resource dynamic allocate not generatevalid */
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_VF) {
+ ret = hinic5_get_dev_cap(lld_dev->hwdev);
+ if (ret != 0) {
+ udma_err(lld_dev->dev, UDMA_M_MAIN,
+ "Failed to get dev cap, ret:%d\n", ret);
+ return ret;
+ }
+ /* update localpartchange amount ub_cap, this when hwdev one certain valid and supports UB */
+ (void)hinic5_support_ub(lld_dev->hwdev, ub_cap);
+ }
+
+ return 0;
+}
+
+static int udma_device_cap_init(struct hinic5_lld_dev *lld_dev,
+ struct udma_device *udma_dev,
+ struct ub_service_cap *ub_cap)
+{
+ int ret;
+
+ ret = udma_reload_device_cap(lld_dev, ub_cap);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "Failed to reload device cap, ret:%d\n", ret);
+ return ret;
+ }
+
+ ret = udma_get_device_cap(udma_dev, ub_cap);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "Failed to get device cap\n");
+ return ret;
+ }
+
+ ret = udma_get_feat_bitmap(udma_dev, udma_dev->feat_bitmap,
+ UB_FEAT_BITMAP_U64_MAX);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "Failed to get feature bitmap.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dev_init(struct hinic5_lld_dev *lld_dev,
+ struct udma_device *udma_dev,
+ struct ub_service_cap *ub_cap)
+{
+ int ret;
+
+ udma_misc_init(udma_dev);
+
+ ret = udma_get_dev(lld_dev, udma_dev);
+ if (ret != 0) {
+ goto error_init_res;
+ }
+
+ ret = udma_device_cap_init(lld_dev, udma_dev, ub_cap);
+ if (ret != 0) {
+ goto error_init_res;
+ }
+
+ udma_init_mig_vf_mgt(udma_dev);
+ ret = udma_init_sysfs(&udma_dev->sysfs_res);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to init sysfs, ret:%d\n", ret);
+ goto error_init_mig_vf_mgt;
+ }
+
+ ret = udma_init_res(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "udma init resource failed, ret:%d", ret);
+ goto error_init_sysfs;
+ }
+
+ ret = udma_dfx_device_init(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "udma init dfx resource failed, ret:%d", ret);
+ goto error_init_dfx;
+ }
+
+ ret = udma_create_tp_res(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to create tp res, ret:%d\n", ret);
+ goto error_tp_res;
+ }
+
+ ret = udma_register_ub_device(lld_dev, udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to register udma dev, ret:%d\n", ret);
+ goto error_register;
+ }
+
+ return 0;
+
+error_register:
+ udma_free_tp_res(udma_dev);
+error_tp_res:
+ udma_dfx_device_deinit(udma_dev);
+error_init_dfx:
+ udma_free_res(udma_dev);
+error_init_sysfs:
+ udma_remove_sysfs(&udma_dev->sysfs_res);
+error_init_mig_vf_mgt:
+ udma_deinit_mig_vf_mgt(udma_dev);
+error_init_res:
+ udma_misc_deinit(udma_dev);
+ return ret;
+}
+
+/* TODO this interface only use in vram scenario, not in c00 interact付 range, current only supports pcie scenario */
+static void udma_get_dev_name_by_dev(char device_name[], u32 dev_name_len,
+ struct device *dev)
+{
+ struct udma_bus_addr bus_addr = { 0 };
+
+ udma_get_bus_info(dev, &bus_addr);
+
+ scnprintf((char *)device_name, dev_name_len, "hiudma5_p%us%uf%u",
+ bus_addr.bus, bus_addr.devid, bus_addr.function);
+}
+
+static struct udma_device *udma_dev_vram_find(struct device *dev)
+{
+ struct udma_vram_header *vram_header = NULL;
+ struct udma_vram_block *block = NULL;
+ struct udma_device *node = NULL;
+ char device_name[UDMA_MAX_DEV_NAME];
+ u32 max_num;
+ u32 index;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_err(dev, UDMA_M_MAIN,
+ "vram_header get is NULL in udma_dev_vram_find\n");
+ return NULL;
+ }
+ block = vram_header->header[UDMA_VRAM_TYPE_DEV].block;
+ max_num = block->node_num;
+
+ udma_err(dev, UDMA_M_MAIN, "max_num is %d\n", max_num);
+
+ udma_get_dev_name_by_dev(device_name, UDMA_MAX_DEV_NAME, dev);
+
+ for (index = 0; index < max_num; index++) {
+ if (test_bit(index, (const unsigned long *)block->bitmap) ==
+ 0) {
+ continue;
+ }
+ node = (void *)((u8 *)block->buf + index * block->node_size);
+ if (strncmp((const char *)node->dev_name,
+ (const char *)device_name,
+ sizeof(node->dev_name)) == 0) {
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
+static struct udma_device *udma_dev_create(struct hinic5_lld_dev *lld_dev,
+ struct ub_service_cap *ub_cap)
+{
+ struct device *dev = lld_dev->dev;
+ struct udma_device *udma_dev = NULL;
+ int numa_original_node_id = 0;
+ bool numa_original_node_id_valid = false;
+
+ if ((hinic5_host_id(lld_dev->hwdev) == UB_SPU_HOST_ID) &&
+ (num_online_nodes() > 1)) {
+ numa_original_node_id = dev_to_node(dev);
+ numa_original_node_id_valid = true;
+ set_dev_node(
+ dev,
+ hinic5_global_func_id(lld_dev->hwdev) %
+ PARITY_DIVISOR); //set numa node by the parity of function id.
+ }
+
+ if (udma_vram5_get_kexec_flag() == 0) {
+ udma_dev = (struct udma_device *)udma_vram_kzalloc(
+ dev, UDMA_VRAM_TYPE_DEV, sizeof(struct udma_device),
+ GFP_KERNEL);
+ } else {
+ udma_dev = udma_dev_vram_find(dev);
+ }
+ if (udma_dev == NULL) {
+ udma_err(dev, UDMA_M_MAIN,
+ "failed to allocate udma dev, kexec flag: %u\n",
+ udma_vram5_get_kexec_flag());
+ return NULL;
+ }
+
+ if (udma_dev_init(lld_dev, udma_dev, ub_cap) != 0) {
+ goto error_create_dev;
+ }
+
+ udma_dev->numa_original_node_id_valid = numa_original_node_id_valid;
+ if (numa_original_node_id_valid == true) {
+ udma_dev->numa_original_node_id = numa_original_node_id;
+ }
+
+ return udma_dev;
+
+error_create_dev:
+ udma_vram_kfree(dev, udma_dev, UDMA_VRAM_TYPE_DEV);
+ return NULL;
+}
+
+static void udma_dev_deinit(struct udma_device *udma_dev)
+{
+ udma_unregister_ub_device(udma_dev);
+ udma_free_tp_res(udma_dev);
+ udma_dfx_device_deinit(udma_dev);
+ udma_free_res(udma_dev);
+ udma_remove_sysfs(&udma_dev->sysfs_res);
+ udma_misc_deinit(udma_dev);
+}
+
+static void udma_dev_destroy(struct device *dev, struct udma_device *udma_dev)
+{
+ int numa_original_node_id = udma_dev->numa_original_node_id;
+ bool numa_original_node_id_valid =
+ udma_dev->numa_original_node_id_valid;
+
+ /* capture packet still in perform, first disable capture packet */
+ if (udma_dev->capture_en == true) {
+ udma_warn(udma_dev->dev, UDMA_M_MAIN,
+ "%s: capture is still running, now stop\n", __func__);
+ udma_dfx_stop_cap_pkt(udma_dev, NULL, NULL);
+ }
+
+ /* disable packet drop */
+ udma_stop_all_drop_pkt(udma_dev);
+ udma_dev_deinit(udma_dev);
+
+ udma_info(udma_dev->dev, UDMA_M_MAIN, "udma free resource success\n");
+
+ /* offload driver when none (classifier) file free memory resource */
+ udma_vram_kfree(dev, udma_dev, UDMA_VRAM_TYPE_DEV);
+
+ if (numa_original_node_id_valid == true) {
+ set_dev_node(dev, numa_original_node_id);
+ }
+}
+
+static int udma_get_plug_attach_en(struct hinic5_lld_dev *lld_dev)
+{
+ struct device *dev = lld_dev->dev;
+ void *hwdev = lld_dev->hwdev;
+ u8 attach_en = 0;
+ int ret;
+
+ if (!hinic5_is_slave_host(hwdev)) {
+ udma_info(dev, UDMA_M_MAIN,
+ "no need to check attach_en flag.\n");
+ return 0;
+ }
+
+ ret = hisdk5_get_plug_srv_bitmap(hwdev, COMM_PLUG_SRV_UB,
+ hinic5_global_func_id(hwdev),
+ &attach_en);
+ if (ret != 0) {
+ udma_err(dev, UDMA_M_MAIN,
+ "get plug service bitmap failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ if (attach_en == 0) {
+ udma_err(dev, UDMA_M_MAIN, "attach_en flag is invalid.\n");
+ return -EFAULT;
+ }
+
+ udma_info(dev, UDMA_M_MAIN,
+ "attach_en flag is valid, udma probe begin.\n");
+ return 0;
+}
+
+static void cleanup_udma_device(struct hinic5_lld_dev *lld_dev)
+{
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_PF) {
+ if (!hinic5_is_slave_host(lld_dev->hwdev) &&
+ !hinic5_is_master_host(lld_dev->hwdev)) {
+ struct hinic5_lld_dev *ppf_lld_dev =
+ hinic5_get_ppf_lld_dev_unsafe(lld_dev);
+ hinic5_stateful_deinit(ppf_lld_dev->hwdev);
+ }
+ }
+}
+
+static bool udma_double_tpf_invalid(struct hinic5_lld_dev *lld_dev,
+ struct ub_service_cap *ub_cap)
+{
+ return g_double_tpf_en == 0 &&
+ UDMA_IS_EVEN_NUM(hinic5_global_func_id(lld_dev->hwdev)) &&
+ !!ub_cap->net_dev_cap.is_tpf;
+}
+
+static int udma_ppf_init(struct hinic5_lld_dev *lld_dev)
+{
+ struct hinic5_lld_dev *ppf_lld_dev = NULL;
+ int ret;
+
+ if (hinic5_func_type(lld_dev->hwdev) != TYPE_PF) {
+ return 0;
+ }
+
+ if (hinic5_is_slave_host(lld_dev->hwdev) ||
+ hinic5_is_master_host(lld_dev->hwdev)) {
+ return 0;
+ }
+
+ /* hwdev device type is TPYE_PF, hwdev device not is primary or prepare type, need get ppf, for ppf device perform init stateful */
+ ppf_lld_dev = hinic5_get_ppf_lld_dev_unsafe(lld_dev);
+ /* get ppf when exist return NULL of exception scenario, need check non-null avoid oops */
+ if (ppf_lld_dev == NULL) {
+ udma_err(lld_dev->dev, UDMA_M_MAIN,
+ "Failed to find ppf resource\n");
+ return -ENXIO;
+ }
+ ret = hinic5_stateful_init(ppf_lld_dev->hwdev);
+ if (ret != 0) {
+ udma_err(lld_dev->dev, UDMA_M_MAIN,
+ "Failed to init stateful ppf resource ret:%d\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static void udma_ppf_deinit(struct hinic5_lld_dev *lld_dev)
+{
+ struct hinic5_lld_dev *ppf_lld_dev = NULL;
+
+ if (hinic5_func_type(lld_dev->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ if (hinic5_is_slave_host(lld_dev->hwdev) ||
+ hinic5_is_master_host(lld_dev->hwdev)) {
+ return;
+ }
+
+ /* hwdev device type is TPYE_PF, hwdev device not is primary or prepare type, need get ppf, for ppf device perform deinit stateful */
+ ppf_lld_dev = hinic5_get_ppf_lld_dev_unsafe(lld_dev);
+ /* get ppf when exist return NULL of exception scenario, need check non-null avoid oops */
+ if (ppf_lld_dev == NULL) {
+ udma_err(lld_dev->dev, UDMA_M_MAIN,
+ "Failed to find ppf resource\n");
+ return;
+ }
+ hinic5_stateful_deinit(ppf_lld_dev->hwdev);
+}
+
+static int udma_probe(struct hinic5_lld_dev *lld_dev, void **uld_dev,
+ char *uld_dev_name)
+{
+ struct device *dev = lld_dev->dev;
+ struct ub_service_cap ub_cap = { 0 };
+ struct udma_device *udma_dev = NULL;
+ int ret = 0;
+
+ udma_info(dev, UDMA_M_MAIN,
+ "udma(function id:%u, dev type:%d) probe begin\n",
+ hinic5_global_func_id(lld_dev->hwdev), lld_dev->dev_type);
+
+ if (!hinic5_support_ub(lld_dev->hwdev, &ub_cap)) {
+ if (hinic5_func_type(lld_dev->hwdev) ==
+ TYPE_PPF) { //version number from ppf on read
+ udma_info(dev, UDMA_M_MAIN,
+ "register ppf for udma version\n");
+ *uld_dev = lld_dev;
+ return 0;
+ }
+ udma_info(dev, UDMA_M_MAIN, "hardware NOT support udma\n");
+ *uld_dev = NULL;
+ return 0;
+ }
+
+ if (udma_double_tpf_invalid(lld_dev, &ub_cap)) {
+ udma_info(dev, UDMA_M_MAIN,
+ "tpf with even function id not supported\n");
+ *uld_dev = NULL;
+ return 0;
+ }
+
+ if (udma_get_plug_attach_en(lld_dev) != 0) {
+ return -EINVAL;
+ }
+
+ ret = udma_ppf_init(lld_dev);
+ if (ret != 0) {
+ udma_err(dev, UDMA_M_MAIN, "Failed to init ppf, ret = %d\n",
+ ret);
+ return ret;
+ }
+
+ udma_dev = udma_dev_create(lld_dev, &ub_cap);
+ if (udma_dev == NULL) {
+ cleanup_udma_device(lld_dev);
+ udma_err(dev, UDMA_M_MAIN, "failed to create udma dev\n");
+ return -ENOMEM;
+ }
+
+ *uld_dev = udma_dev;
+ ret = memcpy_s(uld_dev_name, IFNAMSIZ, g_ub_uld_dev_name,
+ strlen(g_ub_uld_dev_name) + 1);
+ if (ret != 0) {
+ udma_err(dev, UDMA_M_MAIN, "memcpy_s failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ udma_info(dev, UDMA_M_MAIN, "udma probe ret = %d\n", ret);
+
+ return 0;
+}
+
+static void udma_remove(struct hinic5_lld_dev *lld_dev, void *adapter)
+{
+ struct device *dev = lld_dev->dev;
+
+ udma_info(dev, UDMA_M_MAIN, "udma remove, func_id:%u\n",
+ hinic5_global_func_id(lld_dev->hwdev));
+
+ if (!hinic5_support_ub(lld_dev->hwdev, NULL)) {
+ if (hinic5_func_type(lld_dev->hwdev) == TYPE_PPF) {
+ udma_info(dev, UDMA_M_MAIN,
+ "udma remove, func_id:%u is ppf\n",
+ hinic5_global_func_id(lld_dev->hwdev));
+ }
+ return;
+ }
+
+ if (adapter == NULL) {
+ udma_pr_err(UDMA_M_MAIN, "udma remove failed\n");
+ return;
+ }
+
+ udma_dev_destroy(dev, adapter);
+
+ udma_ppf_deinit(lld_dev);
+
+ udma_pr_info(UDMA_M_MAIN, "udma remove success\n");
+
+ return;
+}
+
+static struct hinic5_uld_info g_udma_uld_info = {
+ .probe = udma_probe,
+ .remove = udma_remove,
+ .suspend = NULL,
+ .resume = NULL,
+ .event = udma_event,
+ .ioctl = udma_ioctl,
+};
+
+static int __init udma_lld_init(void)
+{
+ int ret;
+
+ udma_pr_info(UDMA_M_MAIN, "%s - version %s\n", UDMA_DRV_DESC,
+ UDMA_DRV_VERSION);
+
+ ret = udma_init_shm_related_symbols();
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN,
+ "shm related symbols init failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ ret = udma_vram_mem_manager_init();
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN,
+ "vram mem manager init failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ ret = hinic5_register_uld(SERVICE_T_UB, &g_udma_uld_info);
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN, "register hinic5 uld failed, ret:%d\n",
+ ret);
+ goto error_register_uld;
+ }
+
+ ret = udma_vram_mem_obj_recover();
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN,
+ "vram mem obj recover failed, ret:%d\n", ret);
+ goto error_mem_obj_recover;
+ }
+
+ ret = hinic5_module_pre_init();
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN, "hinic5 pre-init failed, ret:%d\n",
+ ret);
+ goto error_mem_obj_recover;
+ }
+
+ ret = udma_bond_init();
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_MAIN, "udma_bond_init failed, ret:%d\n",
+ ret);
+ goto error_bond_init;
+ }
+
+ return 0;
+
+error_bond_init:
+ hinic5_module_post_exit();
+error_mem_obj_recover:
+ hinic5_unregister_uld(SERVICE_T_UB);
+error_register_uld:
+ udma_vram_mem_manager_uninit();
+
+ return ret;
+}
+
+static void __exit udma_lld_exit(void)
+{
+ udma_bond_uninit();
+ hinic5_unregister_uld(SERVICE_T_UB);
+ udma_vram_mem_manager_uninit();
+ hinic5_module_post_exit();
+ udma_uninit_shm_related_symbols();
+}
+
+module_init(udma_lld_init);
+module_exit(udma_lld_exit);
+
+MODULE_AUTHOR("Huawei Technologies CO., Ltd");
+MODULE_DESCRIPTION(UDMA_DRV_DESC);
+MODULE_VERSION(UDMA_DRV_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.c
new file mode 100644
index 000000000..7be0eae84
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.c
@@ -0,0 +1,332 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+
+#include "comm_defs.h"
+#include "ub_mpu_cmd.h"
+#include "udma_vtp.h"
+#include "udma_tp.h"
+#include "udma_jetty.h"
+#include "udma_segment.h"
+#include "udma_misc.h"
+#include "udma_tpg.h"
+#include "udma_resource.h"
+#include "udma_query.h"
+
+static int udma_query_res_list(struct udma_device *udma_dev,
+ const struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_list_val *ret_val =
+ (struct ubcore_res_list_val *)(uintptr_t)val->addr;
+ switch (key->type) {
+ case UBCORE_RES_KEY_TP:
+ return udma_query_res_dev_tp_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_JFS:
+ return udma_query_res_dev_jfs_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_JFR:
+ return udma_query_res_dev_jfr_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_JFC:
+ return udma_query_res_dev_jfc_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_JETTY:
+ return udma_query_res_dev_jetty_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_JETTY_GROUP:
+ return udma_query_res_dev_jetty_group_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_TPG:
+ return udma_query_res_dev_tpg_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_VTP:
+ return udma_query_res_dev_vtp_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_UTP:
+ return udma_query_res_dev_utp_list(udma_dev, ret_val);
+ case UBCORE_RES_KEY_RC:
+ return udma_query_res_dev_rc_list(udma_dev, ret_val);
+ default:
+ udma_warn(
+ udma_dev->dev, UDMA_M_QUERY,
+ "key type:%u is not supported currently for query res list.\n",
+ key->type);
+ return -EINVAL;
+ }
+}
+
+static int udma_query_res_dev_ta(struct udma_device *udma_dev,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_dev_ta_val *ret_val =
+ (struct ubcore_res_dev_ta_val *)(uintptr_t)val->addr;
+
+ ret_val->seg_cnt = udma_dev->device_res->seg_list.cnt;
+ ret_val->jfs_cnt = udma_dev->device_res->jfs_list.cnt;
+ ret_val->jfr_cnt = udma_dev->device_res->jfr_list.cnt;
+ ret_val->jfc_cnt = udma_dev->device_res->jfc_list.cnt;
+ ret_val->jetty_cnt = udma_dev->device_res->jetty_list.cnt;
+ ret_val->jetty_group_cnt = udma_dev->device_res->jetty_group_list.cnt;
+ ret_val->rc_cnt = udma_dev->device_res->rc_list.cnt;
+
+ return 0;
+}
+
+static int udma_query_res_dev_tp(struct udma_device *udma_dev,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_dev_tp_val *ret_val =
+ (struct ubcore_res_dev_tp_val *)(uintptr_t)val->addr;
+
+ ret_val->vtp_cnt = udma_dev->device_res->vtp_list.cnt;
+ ret_val->tp_cnt = udma_dev->device_res->tpn_list.cnt;
+ ret_val->tpg_cnt = udma_dev->device_res->tpg_list.cnt;
+ ret_val->utp_cnt = udma_dev->device_res->utp_list.cnt;
+
+ return 0;
+}
+
+int udma_query_res_pre_check(const struct ubcore_device *dev,
+ const struct ubcore_res_key *key,
+ const struct ubcore_res_val *val)
+
+{
+ struct udma_device *udma_dev = NULL;
+ if (dev == NULL || key == NULL || val == NULL) {
+ udma_pr_err(
+ UDMA_M_QUERY,
+ "parameters is incorrect, dev(%d), key(%d), val(%d).\n",
+ !!dev, !!key, !!val);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(dev);
+
+ if (key->type < UBCORE_RES_KEY_VTP ||
+ key->type > UBCORE_RES_KEY_DEV_TP) {
+ udma_err(udma_dev->dev, UDMA_M_QUERY,
+ "key type:%u is invalid.\n", key->type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_query_res(struct ubcore_device *dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct udma_device *udma_dev = NULL;
+ int ret = 0;
+
+ ret = udma_query_res_pre_check(dev, key, val);
+ if (ret != 0) {
+ return ret;
+ }
+ udma_dev = to_udma_dev(dev);
+
+ if (key->key_cnt == 0 && key->type != UBCORE_RES_KEY_DEV_TA &&
+ key->type != UBCORE_RES_KEY_DEV_TP &&
+ key->type != UBCORE_RES_KEY_SEG) {
+ return udma_query_res_list(udma_dev, key, val);
+ }
+
+ switch (key->type) {
+ case UBCORE_RES_KEY_TP:
+ return udma_query_res_tp(udma_dev, key, val);
+ case UBCORE_RES_KEY_JFS:
+ return udma_query_res_jfs(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_JFR:
+ return udma_query_res_jfr(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_JFC:
+ return udma_query_res_jfc(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_JETTY:
+ return udma_query_res_jetty(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_JETTY_GROUP:
+ return udma_query_res_jetty_group(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_SEG:
+ return udma_query_res_segment(udma_dev, dev, key, val);
+ case UBCORE_RES_KEY_TPG:
+ return udma_query_res_tpg(udma_dev, key, val);
+ case UBCORE_RES_KEY_VTP:
+ return udma_query_res_vtp(udma_dev, key, val);
+ case UBCORE_RES_KEY_DEV_TA:
+ return udma_query_res_dev_ta(udma_dev, val);
+ case UBCORE_RES_KEY_DEV_TP:
+ return udma_query_res_dev_tp(udma_dev, val);
+ default:
+ udma_warn(
+ udma_dev->dev, UDMA_M_QUERY,
+ "key type:%u is not supported currently for query res.\n",
+ key->type);
+ return -EINVAL;
+ }
+}
+
+int udma_query_ctx(const struct ubcore_device *dev, struct ubcore_res_key *key,
+ void *val)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if (dev == NULL) {
+ udma_pr_err(UDMA_M_QUERY, "Invalid parameter: ub_dev(%d).\n",
+ !!dev);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_QUERY, "to_udma_dev failed.\n");
+ return -EINVAL;
+ }
+
+ if (key->type < UBCORE_RES_KEY_VTP ||
+ key->type > UBCORE_RES_KEY_DEV_TP) {
+ udma_err(udma_dev->dev, UDMA_M_QUERY,
+ "key type:%u is invalid.\n", key->type);
+ return -EINVAL;
+ }
+
+ switch (key->type) {
+ case UBCORE_RES_KEY_TP:
+ return udma_query_tpc(udma_dev, key,
+ (struct ub_dfx_tp_ctx_query *)val);
+ default:
+ udma_warn(udma_dev->dev, UDMA_M_QUERY,
+ "key type:%u is not supported currently.\n",
+ key->type);
+ return -EINVAL;
+ }
+}
+
+static int udma_query_fe_idx_from_bdf_list(struct ubcore_device *dev,
+ const struct ubcore_devid *devid,
+ u16 *fe_idx)
+{
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ u8 bus_id, device_id, func_id;
+ u32 i;
+ if (dev == NULL) {
+ udma_pr_err(UDMA_M_QUERY, "Invalid parameter: ub_dev(%d).\n",
+ !!dev);
+ return -EINVAL;
+ }
+
+ if (udma_dev == NULL || udma_dev->bdf_info == NULL) {
+ udma_pr_err(
+ UDMA_M_QUERY,
+ "query fe_idx invalid parameter. udma_dev(%d), udma_bdf_info(%d).\n",
+ !!udma_dev, !!udma_dev->bdf_info);
+ return -EINVAL;
+ }
+
+ bus_id = *(u8 *)(&devid->raw[UB_DEVID_BUS_U8_OFF]);
+ device_id = *(u8 *)(&devid->raw[UB_DEVID_DEVICE_U8_OFF]);
+ func_id = *(u8 *)(&devid->raw[0]);
+
+ udma_info(udma_dev->dev, UDMA_M_QUERY,
+ "bus_id:%u, device_id:%u, func_id:%u.\n", bus_id, device_id,
+ func_id);
+
+ mutex_lock(&udma_dev->bdf_mutex);
+ for (i = 0; i < udma_dev->bdf_cnt; i++) {
+ if (udma_dev->bdf_info[i].bdf_info_vld != 0 &&
+ udma_dev->bdf_info[i].bus_id == bus_id &&
+ udma_dev->bdf_info[i].device_id == device_id &&
+ udma_dev->bdf_info[i].func_id == func_id) {
+ *fe_idx = (u16)i;
+ mutex_unlock(&udma_dev->bdf_mutex);
+ return 0;
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_QUERY,
+ "devid(bus_id:%u, device_id:%u, func_id:%u) not found.\n",
+ bus_id, device_id, func_id);
+ mutex_unlock(&udma_dev->bdf_mutex);
+
+ return -EINVAL;
+}
+
+int udma_query_fe_idx(struct ubcore_device *dev, struct ubcore_devid *devid,
+ u16 *fe_idx)
+{
+ struct ubcore_devid zero_devid = { 0 };
+ struct udma_device *udma_dev = to_udma_dev(dev);
+ int ret = 0;
+
+ if (udma_dev == NULL || devid == NULL || fe_idx == NULL) {
+ udma_pr_err(
+ UDMA_M_QUERY,
+ "query fe_idx invalid parameter. udma_dev(%d), devid(%d), fe_idx(%d).\n",
+ !!udma_dev, !!devid, !!fe_idx);
+ return -EINVAL;
+ }
+
+ if (udma_dev->dev_bus_type != HINIC5_DEVICE_T_PCI) {
+ udma_pr_err(UDMA_M_QUERY,
+ "dev(%s) with dev bus type(%d) is not supported.\n",
+ udma_dev->dev_name, udma_dev->dev_bus_type);
+ return -EINVAL;
+ }
+
+ if (!memcmp(devid->raw, zero_devid.raw, UBCORE_DEVID_SIZE)) {
+ *fe_idx = hinic5_global_func_id(udma_dev->hwdev);
+ udma_info(udma_dev->dev, UDMA_M_QUERY,
+ "all zero devid get fe_idx:%u\n", *fe_idx);
+ return 0;
+ }
+
+ ret = udma_query_fe_idx_from_bdf_list(dev, devid, fe_idx);
+ if (ret != 0) {
+ udma_warn(udma_dev->dev, UDMA_M_QUERY,
+ "bdf not found, reload bdf info\n");
+ ret = udma_get_pcie_bdf_info(udma_dev);
+ if (ret == 0)
+ ret = udma_query_fe_idx_from_bdf_list(dev, devid,
+ fe_idx);
+ }
+
+ return ret;
+}
+
+int udma_query_fe_stats(struct ubcore_device *dev, u32 cnt, u16 *fe_idx,
+ adapted_ubcore_ue_stats *stats)
+{
+ struct ub_dfx_vf_statistics_cmd_inbuf cmd_in = { 0 };
+ struct ub_dfx_port_statistics_cmd cmd_out = { 0 };
+ u16 out_size = (u16)sizeof(struct ub_dfx_port_statistics_cmd);
+ struct udma_device *udma_dev = NULL;
+ u32 i = 0;
+ int ret = 0;
+
+ if (dev == NULL || fe_idx == NULL || stats == NULL || cnt == 0) {
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ for (i = 0; i < cnt; i++) {
+ cmd_in.vf_id = (u8)fe_idx[i];
+ ret = hinic5_msg_to_mgmt_sync(
+ udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_READ_VF_STA, &cmd_in,
+ sizeof(ub_dfx_vf_statistics_cmd_inbuf_s), &cmd_out,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || cmd_out.head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_QUERY,
+ "query vf statistics counter failed, err(%d), status(0x%x), "
+ "func id(0x%x), idx(0x%x)\n",
+ ret, cmd_out.head.status, fe_idx[i], i);
+ return -EFAULT;
+ }
+
+ stats[i].rx_bytes = cmd_out.ctr_array_cur.dp_rx.pkt_bytes;
+ stats[i].rx_pkt = cmd_out.ctr_array_cur.dp_rx.pkt_num;
+ stats[i].tx_bytes = cmd_out.ctr_array_cur.dp_tx.pkt_bytes;
+ stats[i].tx_pkt = cmd_out.ctr_array_cur.dp_tx.pkt_num;
+
+ udma_info(
+ udma_dev->dev, UDMA_M_QUERY,
+ "query vf statistics counter rx_bytes(0x%llx), rx_pkt(0x%llx), "
+ "tx_bytes(0x%llx), tx_pkt(0x%llx) func id(0x%x)\n",
+ stats[i].rx_bytes, stats[i].rx_pkt, stats[i].tx_bytes,
+ stats[i].tx_pkt, fe_idx[i]);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.h
new file mode 100644
index 000000000..d193e4675
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_query.h
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_QUERY_H
+#define UDMA_QUERY_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+int udma_query_res(struct ubcore_device *dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+int udma_query_ctx(const struct ubcore_device *dev, struct ubcore_res_key *key,
+ void *val);
+int udma_query_fe_idx(struct ubcore_device *dev, struct ubcore_devid *devid,
+ u16 *fe_idx);
+int udma_query_fe_stats(struct ubcore_device *dev, u32 cnt, u16 *fe_idx,
+ adapted_ubcore_ue_stats *stats);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.c
new file mode 100644
index 000000000..a4351dfa6
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.c
@@ -0,0 +1,153 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include "hinic5_hw.h"
+#include "hmm_em_inner.h"
+#include "hmm_buddy.h"
+#include "udma_common.h"
+#include "udma_comp.h"
+
+static int udma_ubrc_alloc_check(struct udma_comp_priv **comp_priv,
+ struct udma_device *udma_dev, u32 num)
+{
+ *comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (*comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Comp_priv is null\n");
+ return -EINVAL;
+ }
+
+ if ((num < UBRC_MIN_DEPTH) || (num > UBRC_MAX_DEPTH)) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Num is invalid, ret(%d)\n", -EINVAL);
+ *comp_priv = NULL;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void udma_ubrc_attr_init(struct udma_device *udma_dev, struct ubrc *ubrc,
+ u32 num, u32 log_ubrc_per_seg)
+{
+ u32 chip_num = (num < UBRC_MIN_ENTRY) ? UBRC_MIN_ENTRY : num;
+ u32 ext_num = num + UBRC_EXT_ENTRY;
+ u32 ext_order = 0;
+ u32 order = 0;
+ u32 i = 0;
+
+ for (i = 1; i < chip_num; i <<= 1)
+ order++;
+
+ for (i = 1; i < ext_num; i <<= 1)
+ ext_order++;
+
+ ubrc->order = order;
+ ubrc->ext_order = (ext_order > log_ubrc_per_seg) ? ext_order :
+ log_ubrc_per_seg;
+}
+
+int udma_ubrc_alloc(struct udma_device *udma_dev, u32 num, struct ubrc *ubrc)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+ void *vaddr = NULL;
+ u32 log_ubrc_per_seg = 0;
+ u32 ext_order;
+ u32 offset = 0;
+ int ret = 0;
+
+ if (ubrc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP, "ubrc is null\n");
+ return -EINVAL;
+ }
+
+ ret = udma_ubrc_alloc_check(&comp_priv, udma_dev, num);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "udma ubrc alloc check failed\n");
+ return ret;
+ }
+
+ log_ubrc_per_seg = comp_priv->ub_cap.log_ubrc_seg;
+
+ udma_ubrc_attr_init(udma_dev, ubrc, num, log_ubrc_per_seg);
+ ext_order = ubrc->ext_order - log_ubrc_per_seg;
+
+ offset = hmm_buddy_alloc(&comp_priv->ubrc_buddy, ext_order);
+ if (offset == UB_INVALID_INDEX) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Alloc ubrc index failed, ret(%d)\n", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ ubrc->offset = offset << log_ubrc_per_seg;
+
+ ret = hmm_em_table_get_range(
+ comp_priv->hmm_priv.dev, &comp_priv->ubrc_em_table,
+ ubrc->offset, ubrc->offset + (1U << ubrc->ext_order) - 1);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Alloc ubrc entry failed, ret(%d)\n", -ENOMEM);
+ goto err_table_get;
+ }
+
+ vaddr = hmm_em_table_find(&comp_priv->ubrc_em_table, ubrc->offset,
+ &ubrc->dma_addr);
+ if (vaddr == NULL) {
+ ret = -ENOMEM;
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Can't find va and pa of ubrc entry, ret(%d)\n",
+ -ENOMEM);
+ goto err_ubrc_find;
+ }
+ ubrc->vaddr = vaddr;
+ (void)memset_s(vaddr, ((u64)1U << (ext_order + UBRC_MAXSIZE_OFFSET)), 0,
+ ((u64)1U << (ext_order + UBRC_MAXSIZE_OFFSET)));
+
+ return 0;
+
+err_ubrc_find:
+ hmm_em_table_put_range(comp_priv->hmm_priv.dev,
+ &comp_priv->ubrc_em_table, ubrc->offset,
+ ubrc->offset + (1U << ubrc->ext_order) - 1);
+err_table_get:
+ hmm_buddy_free(&comp_priv->ubrc_buddy, offset, ext_order);
+
+ return ret;
+}
+
+void udma_ubrc_free(struct udma_device *udma_dev, struct ubrc *ubrc)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+ u32 log_ubrc_per_seg = 0;
+ u32 offset = 0;
+ u32 order = 0;
+
+ if (ubrc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP, "ubrc is null\n");
+ return;
+ }
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UBRC_COMP,
+ "Comp_priv is null\n");
+ return;
+ }
+
+ hmm_em_table_put_range(comp_priv->hmm_priv.dev,
+ &comp_priv->ubrc_em_table, ubrc->offset,
+ ubrc->offset + (1U << ubrc->ext_order) - 1);
+ log_ubrc_per_seg = comp_priv->ub_cap.log_ubrc_seg;
+
+ order = ubrc->ext_order - log_ubrc_per_seg;
+ offset = ubrc->offset >> log_ubrc_per_seg;
+
+ hmm_buddy_free(&comp_priv->ubrc_buddy, offset, order);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.h
new file mode 100644
index 000000000..64e67b45e
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_ubrc_comp.h
@@ -0,0 +1,15 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_UBRC_COMP_H
+#define UDMA_UBRC_COMP_H
+
+#include "udma_common.h"
+
+int udma_ubrc_alloc(struct udma_device *udma_dev, u32 num, struct ubrc *ubrc);
+void udma_ubrc_free(struct udma_device *udma_dev, struct ubrc *ubrc);
+void udma_ubrc_attr_init(struct udma_device *udma_dev, struct ubrc *ubrc,
+ u32 num, u32 log_ubrc_per_seg);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.c
new file mode 100644
index 000000000..0b60d76a9
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+
+#include "comm_defs.h"
+#include "ub_mpu_cmd.h"
+#include "ubcore_types.h"
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+#include "udma_xid_cfg.h"
+
+int udma_vm_glb_xid_cfg_set(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ struct ub_vm_global_xid_cfg_cmd xid_cfg_cmd = { 0 };
+ u16 out_size = sizeof(struct ub_vm_global_xid_cfg_cmd);
+ int ret;
+
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ /* only has tp maintainer has permission set xid cfg, normal return, not affect outside layer call function */
+ udma_info(udma_dev->dev, UDMA_M_GLB_XID_CFG,
+ "device of func_id(%u) is not tp maintainer\n",
+ adapted_ue_idx(cfg));
+ return 0;
+ }
+
+ if (adapted_ue_idx(cfg) < PF_MAX_NUM) {
+ /* description not is vf scenario, normal return, not affect outside layer call function */
+ udma_info(udma_dev->dev, UDMA_M_GLB_XID_CFG,
+ "func_id(%u) is not vfid\n", adapted_ue_idx(cfg));
+ return 0;
+ }
+
+ if (cfg->mask.bs.max_jetty_cnt == 0 &&
+ cfg->mask.bs.min_jetty_cnt == 0) {
+ /* no has set jetty_cnt, normal return, not affect outside layer call function */
+ udma_info(udma_dev->dev, UDMA_M_GLB_XID_CFG,
+ "func_id(%u) jetty mask is not set!\n",
+ adapted_ue_idx(cfg));
+ return 0;
+ }
+
+ xid_cfg_cmd.vfid = adapted_ue_idx(cfg);
+
+ xid_cfg_cmd.xid_cfg.min_jetty_num = cfg->min_jetty_cnt;
+ xid_cfg_cmd.xid_cfg.mask.bs.min_jetty_num = cfg->mask.bs.min_jetty_cnt;
+ xid_cfg_cmd.xid_cfg.max_jetty_num = cfg->max_jetty_cnt;
+ xid_cfg_cmd.xid_cfg.mask.bs.max_jetty_num = cfg->mask.bs.max_jetty_cnt;
+ xid_cfg_cmd.xid_cfg.min_jfr_num = cfg->min_jfr_cnt;
+ xid_cfg_cmd.xid_cfg.mask.bs.min_jfr_num = cfg->mask.bs.min_jfr_cnt;
+ xid_cfg_cmd.xid_cfg.max_jfr_num = cfg->max_jfr_cnt;
+ xid_cfg_cmd.xid_cfg.mask.bs.max_jfr_num = cfg->mask.bs.max_jfr_cnt;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_SET_VM_XID_CFG, &xid_cfg_cmd,
+ sizeof(xid_cfg_cmd), &xid_cfg_cmd,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || xid_cfg_cmd.head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_GLB_XID_CFG,
+ "set xid cfg failed, ret(%d), status(0x%x), out size(0x%x)\n",
+ ret, xid_cfg_cmd.head.status, out_size);
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_GLB_XID_CFG, "success, vfid(%u)\n",
+ adapted_ue_idx(cfg));
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.h
new file mode 100644
index 000000000..75c5fdee1
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/device/udma_xid_cfg.h
@@ -0,0 +1,16 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_XID_CFG_H
+#define UDMA_XID_CFG_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+#define PF_MAX_NUM 32
+
+int udma_vm_glb_xid_cfg_set(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg);
+
+#endif //UDMA_XID_CFG_H
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.c
new file mode 100644
index 000000000..2964a1e1a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.c
@@ -0,0 +1,2625 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <asm/io.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/security.h>
+
+#include "hinic5_mt.h"
+#include "mig_mpu_cmd.h"
+#include "mig_mpu_cmd_defs.h"
+#include "mpu_inband_cmd.h"
+#include "comm_defs.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "udma_cmd_segment.h"
+#include "udma_dfx_attack.h"
+#include "udma_dfx_capture.h"
+#include "udma_cqm.h"
+#include "udma_cmd_event.h"
+#include "udma_cmd_jfc.h"
+#include "udma_jetty.h"
+#include "udma_net.h"
+#include "ub_npu_jfrc_cmd_defs.h"
+#include "udma_rc_table.h"
+#include "ubcore_uapi.h"
+#include "udma_misc.h"
+#include "udma_device.h"
+#include "udma_ucontext.h"
+#include "ubcore_types.h"
+#include "udma_query.h"
+#include "udma_tp.h"
+#include "udma_srq.h"
+#include "udma_vtp.h"
+#include "udma_tpg.h"
+#include "udma_utp.h"
+#include "udma_dfx_port_sta.h"
+#include "udma_dfx_perf_ctr.h"
+#include "udma_dfx_cqm_modify.h"
+#include "udma_dfx_modify.h"
+#include "udma_dfx_query_tp.h"
+#include "udma_cmd_srq.h"
+#include "udma_cmd_eid.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_tpg.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_vtp.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_jfs.h"
+#include "udma_cmd_jfc.h"
+#include "udma_cmd_jfr.h"
+#include "udma_cmd_jfrc.h"
+#include "udma_resource.h"
+#include "udma_cmd_mig.h"
+#include "ub_mpu_cmd.h"
+#include "ub_mpu_cmd_defs.h"
+#include "udma_dfx_latch.h"
+#include "udma_dfx_l2d.h"
+#include "udma_dfx_perf_query.h"
+#include "udma_dfx.h"
+
+int udma_dfx_obj_put(struct udma_device *udev, u32 type, void *obj, u32 xid)
+{
+ if (obj == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX, "xid:%u not find in type: %u\n",
+ xid, type);
+ return -EINVAL;
+ }
+ switch (type) {
+ case UB_QUERY_TYPE_JFS:
+ udma_jfs_put(obj);
+ break;
+ case UB_QUERY_TYPE_JFR:
+ udma_jfr_put(obj);
+ break;
+ case UB_QUERY_TYPE_JFC:
+ udma_jfc_put(obj);
+ break;
+ case UB_QUERY_TYPE_JETTY:
+ udma_jetty_put(obj);
+ break;
+ case UB_QUERY_TYPE_JETTY_GROUP:
+ udma_jetty_group_put(obj);
+ break;
+ case UB_QUERY_TYPE_TP:
+ udma_tp_put(obj);
+ break;
+ case UB_QUERY_TYPE_TPG:
+ udma_tpg_put(obj);
+ break;
+ case UB_QUERY_TYPE_VTP:
+ udma_vtp_put(obj);
+ break;
+ case UB_QUERY_TYPE_SEG:
+ udma_seg_put(obj);
+ break;
+ default:
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Put obj error, type is (%d).\n", type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int udma_dfx_check_xid(struct udma_device *udev, u32 type,
+ struct ub_query_inbuf *query_inbuf)
+{
+ void *ptr = NULL;
+ int ret = 0;
+
+ if (query_inbuf == NULL) {
+ udma_pr_err(UDMA_M_DFX,
+ "Invalid parameter. query_inbuf(%d) .\n",
+ !!query_inbuf);
+ return -EINVAL;
+ }
+ switch (type) {
+ case UB_QUERY_TYPE_JFS:
+ ptr = (void *)udma_find_jfs(udev, query_inbuf->jfsid);
+ break;
+ case UB_QUERY_TYPE_JFR:
+ ptr = (void *)udma_find_jfr(udev, query_inbuf->jfrid);
+ break;
+ case UB_QUERY_TYPE_JFC:
+ ptr = (void *)udma_find_jfc(udev, query_inbuf->jfcid);
+ break;
+ case UB_QUERY_TYPE_JETTY:
+ ptr = (void *)udma_find_jetty(udev, query_inbuf->jettyid);
+ break;
+ case UB_QUERY_TYPE_JETTY_GROUP:
+ ptr = (void *)udma_find_jetty_group(
+ udev, query_inbuf->jetty_group_id);
+ break;
+ case UB_QUERY_TYPE_TP:
+ ptr = (void *)udma_find_tp(udev, query_inbuf->tpn);
+ break;
+ case UB_QUERY_TYPE_TPG:
+ ptr = (void *)udma_get_tpg_by_id(udev, query_inbuf->tpg_id);
+ break;
+ case UB_QUERY_TYPE_VTP:
+ ptr = (void *)udma_get_vtp_by_id(udev, query_inbuf->vtp_id,
+ query_inbuf->vfid);
+ break;
+ default:
+ return ret;
+ }
+ ret = udma_dfx_obj_put(udev, type, ptr, query_inbuf->xid);
+ return ret;
+}
+
+static int udma_dfx_get_drv_version(const void *buf_in, u32 in_size,
+ void *buf_out, const u32 *out_size)
+{
+ struct drv_version_info *info = buf_out;
+ int rc;
+
+ if (!buf_out || !out_size) {
+ udma_pr_err(UDMA_M_DFX, "Input params is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(*info)) {
+ udma_pr_err(
+ UDMA_M_DFX,
+ "Unexpect out buf size from user :%u, expect: %lu\n",
+ *out_size, sizeof(*info));
+ return -EINVAL;
+ }
+
+ rc = snprintf_s(info->ver, sizeof(info->ver), sizeof(info->ver) - 1,
+ "%s %s", UDMA_DRV_VERSION, __TIME_STR__);
+ if (rc == -1) {
+ udma_pr_err(UDMA_M_DFX, "Snprintf udma version err\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int udma_dfx_query_prepare(struct udma_device *udma_dev, void *buf_out,
+ u32 *out_size)
+{
+ int ret = 0;
+
+ ret = memset_s(buf_out, *out_size, 0, *out_size);
+ if (ret != EOK) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx query prepare memset error ret:%d\n", ret);
+ return -EFAULT;
+ }
+
+ if (*out_size < (u32)sizeof(union ub_query_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx query prepare buffer out size too small\n");
+ return -EFAULT;
+ }
+ *out_size = (u32)sizeof(union ub_query_outbuf);
+
+ return 0;
+}
+
+static int udma_dfx_query_seg_mpt_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_mapt_ctx_query *mpt_entry = &outbuf->mpt;
+ u32 tokenid = inbuf->tokenid;
+ int ret;
+
+ (void)memset_s(mpt_entry, sizeof(struct ub_mapt_ctx_query), 0,
+ sizeof(struct ub_mapt_ctx_query));
+
+ ret = udma_cmd_seg_query_ctx(udev, tokenid, mpt_entry);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query mpt from cache! tokenid:%u", tokenid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_seg_mpt_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_mapt_ctx_query *mpt_entry = &outbuf->mpt;
+ struct udma_segment *udma_seg = NULL;
+ struct mpt *mpt = NULL;
+
+ udma_seg = udma_seg_find(udev, inbuf->tokenid);
+ if (udma_seg == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ubcore_seg, tokenid:%u",
+ inbuf->tokenid);
+ return -EINVAL;
+ }
+
+ mpt = udma_seg->mpt;
+ memcpy_fromio(mpt_entry, mpt->vaddr, sizeof(struct ub_mapt_ctx_query));
+ udma_seg_put(udma_seg);
+ return 0;
+}
+
+static int udma_dfx_query_seg_safe_dmtt_bitmap(
+ struct udma_device *udma_dev, const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ struct ub_cmd_safe_dmtt_bitmap_outbuf *safe_dmtt_bitmap =
+ &outbuf->safe_dmtt_bitmap;
+ int ret;
+
+ (void)memset_s(safe_dmtt_bitmap,
+ sizeof(struct ub_cmd_safe_dmtt_bitmap_outbuf), 0,
+ sizeof(struct ub_cmd_safe_dmtt_bitmap_outbuf));
+
+ ret = udma_cmd_seg_query_safe_dmtt_bitmap(udma_dev, inbuf,
+ safe_dmtt_bitmap);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to query safe dmtt bitmap func_id:%u",
+ inbuf->vfid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_seg_safe_dmtt_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_cmd_safe_dmtt_ctx_outbuf *safe_dmtt_ctx =
+ &outbuf->safe_dmtt_ctx;
+ int ret;
+
+ (void)memset_s(safe_dmtt_ctx,
+ sizeof(struct ub_cmd_safe_dmtt_ctx_outbuf), 0,
+ sizeof(struct ub_cmd_safe_dmtt_ctx_outbuf));
+
+ ret = udma_cmd_seg_query_safe_dmtt_ctx(udma_dev, inbuf, safe_dmtt_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to query safe dmtt ctx func_id:%u",
+ inbuf->vfid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_dmtt(struct udma_device *udev, struct mtt *ub_mtt,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ struct mtt_seg *mtt_seg = NULL;
+ void *vaddr = NULL;
+ u32 max_mtt_entry;
+ u32 offset;
+ u32 length;
+ u32 i;
+
+ if (ub_mtt->mtt_layers == 0) {
+ udma_err(udev->dev, UDMA_M_DFX, "mtt layer is 0\n");
+ return -EINVAL;
+ }
+
+ if (inbuf->layers > ub_mtt->mtt_layers || inbuf->layers == 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "inbuf layer should be less than %u and not equal zero!\n",
+ ub_mtt->mtt_layers);
+ return -EINVAL;
+ }
+
+ length = inbuf->length;
+ offset = inbuf->offset;
+ mtt_seg = ub_mtt->mtt_seg[inbuf->layers - 1];
+
+ if (mtt_seg->order > UDMA_MTT_MAX_ORDER) {
+ udma_err(udev->dev, UDMA_M_DFX, "mtt_seg order[%u] is err\n",
+ mtt_seg->order);
+ return -EINVAL;
+ }
+
+ max_mtt_entry = 1 << mtt_seg->order;
+
+ if (length >= HINIC5_MAX_BUF_SIZE) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "length is too large, HINIC5_MAX_BUF_SIZE[%u]\n",
+ HINIC5_MAX_BUF_SIZE);
+ return -EINVAL;
+ }
+ if (offset + length > max_mtt_entry) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "offset or length is too large, max_mtt_entry[%u]\n",
+ max_mtt_entry);
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(udev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX, "Comp_priv is null\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < length; i++) {
+ vaddr = hmm_em_table_find(&comp_priv->mtt_em_table,
+ mtt_seg->offset + offset + i,
+ (dma_addr_t *)&outbuf->dmtt[i]);
+ if (vaddr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "mtt entry is not found\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_seg_dmtt(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct mtt *mtt = NULL;
+ struct udma_segment *udma_seg = NULL;
+ int ret = 0;
+
+ udma_seg = udma_seg_find(udev, inbuf->tokenid);
+ if (udma_seg == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get udma_segment, tokenid = %u",
+ inbuf->tokenid);
+ return -EINVAL;
+ }
+
+ mtt = &udma_seg->mtt;
+
+ ret = udma_dfx_query_dmtt(udev, mtt, inbuf, outbuf);
+ udma_seg_put(udma_seg);
+ return ret;
+}
+
+int udma_dfx_query_cmtt(struct udma_device *udev, struct mtt *ub_mtt,
+ union ub_query_outbuf *outbuf)
+{
+ struct hmm_comp_priv *comp_priv = NULL;
+ struct mtt_seg *mtt_seg = NULL;
+ void *vaddr = NULL;
+ int i;
+
+ if (ub_mtt->mtt_layers == 0) {
+ udma_err(udev->dev, UDMA_M_DFX, "mtt layer is 0\n");
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(udev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX, "Comp_priv is null\n");
+ return -EINVAL;
+ }
+
+ mtt_seg = ub_mtt->mtt_seg[ub_mtt->mtt_layers - 1];
+
+ if (mtt_seg->order > UDMA_MTT_MAX_ORDER) {
+ udma_err(udev->dev, UDMA_M_DFX, "mtt_seg order[%u] is err\n",
+ mtt_seg->order);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < (1 << mtt_seg->order); i++) {
+ vaddr = hmm_em_table_find(&comp_priv->mtt_em_table,
+ mtt_seg->offset + i,
+ (dma_addr_t *)&outbuf->cmtt[i]);
+ if (vaddr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "mtt entry is not found\n");
+ return -EINVAL;
+ }
+ }
+
+ udma_info(udev->dev, UDMA_M_DFX, "query mmt entry success\n");
+
+ return 0;
+}
+
+static int udma_dfx_query_jetty_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jetty_entry = &outbuf->jetty_ctx;
+ struct udma_jetty *jetty = NULL;
+ u32 jettyid = inbuf->jettyid;
+ int ret;
+
+ (void)memset_s(jetty_entry, sizeof(struct ub_ta_context_query), 0,
+ sizeof(struct ub_ta_context_query));
+
+ jetty = udma_find_jetty(udev, jettyid);
+ if (jetty == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get jetty, jettyid(%u)\n", jettyid);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udev, jettyid, &jetty->cmdq_rtt,
+ jetty_entry);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query jetty from cache! jettyid(%u)",
+ jettyid);
+ return ret;
+ }
+
+ udma_jetty_put(jetty);
+ return 0;
+}
+
+static int udma_dfx_query_jetty_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jetty_entry = &outbuf->jetty_ctx;
+ struct udma_jetty *ub_jetty = NULL;
+ u32 jettyid = inbuf->jettyid;
+
+ ub_jetty = udma_find_jetty(udev, jettyid);
+ if (ub_jetty == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jettyid(%u)", jettyid);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(jetty_entry, ub_jetty->jettyc_info->vaddr,
+ sizeof(struct ub_ta_context_query));
+ udma_jetty_put(ub_jetty);
+ return 0;
+}
+
+static int
+udma_dfx_query_jetty_group_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_jetty_grp_ctx_query *jetty_grp_entry = &outbuf->jetty_grp_ctx;
+ u32 jetty_group_id = inbuf->jetty_group_id;
+ int ret;
+
+ (void)memset_s(jetty_grp_entry, sizeof(struct ub_jetty_grp_ctx_query),
+ 0, sizeof(struct ub_jetty_grp_ctx_query));
+
+ ret = udma_cmd_jetty_grp_query_ctx(udev, jetty_group_id,
+ jetty_grp_entry);
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query jetty group from cache! jetty group id(%u)",
+ jetty_group_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_jetty_group_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_jetty_grp_ctx_query *jetty_grp_entry = &outbuf->jetty_grp_ctx;
+ struct udma_jetty_grp *ub_jetty_grp = NULL;
+ u32 jetty_grp_id = inbuf->jetty_group_id;
+
+ ub_jetty_grp = udma_find_jetty_group(udev, jetty_grp_id);
+ if (ub_jetty_grp == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ubcore_jetty_group, jetty group id(%u)",
+ jetty_grp_id);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(jetty_grp_entry, ub_jetty_grp->cqm_jetty_grp->q_ctx_vaddr,
+ sizeof(struct ub_jetty_grp_ctx_query));
+ udma_jetty_group_put(ub_jetty_grp);
+ return 0;
+}
+
+static int copy_data_from_page(struct udma_device *udev, u8 *outbuf,
+ struct ubcore_umem *umem, u32 copy_len,
+ u32 offset)
+{
+ struct scatterlist *sg = NULL;
+ u8 *outbuf_tmp = outbuf;
+ u32 page_copy_len = 0;
+ u32 has_copy_len = 0;
+ u32 page_offset = 0;
+ u32 buf_offset = 0;
+ void *va = NULL;
+ u32 i = 0;
+
+ udma_info(udev->dev, UDMA_M_DFX,
+ "copy_data_from_page va:%llx, length:%llu, offset:%u, \
+ copy_len:%u",
+ umem->va, umem->length, offset, copy_len);
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) {
+ if (buf_offset + PAGE_SIZE > offset) {
+ page_offset = offset - buf_offset;
+ buf_offset = offset;
+ va = sg_virt(sg);
+ if (va == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get va");
+ return -ENOMEM;
+ }
+
+ va += page_offset;
+ page_copy_len = ((copy_len - has_copy_len) <
+ (PAGE_SIZE - page_offset)) ?
+ (copy_len - has_copy_len) :
+ (PAGE_SIZE - page_offset);
+ udma_info(
+ udev->dev, UDMA_M_DFX,
+ "copy_data_from_page buf_offset:%u, page_offset:%u, has_copy_len:%u, \
+ page_copy_len:%u, i:%u",
+ buf_offset, page_offset, has_copy_len,
+ page_copy_len, i);
+ (void)memcpy_s(outbuf_tmp, page_copy_len, va,
+ page_copy_len);
+ outbuf_tmp += page_copy_len;
+ has_copy_len += page_copy_len;
+ if (has_copy_len >= copy_len) {
+ break;
+ }
+ } else {
+ buf_offset += PAGE_SIZE;
+ }
+ }
+ return 0;
+}
+
+static int udma_dfx_query_jetty_sqe(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ u8 *jetty_sqe = (u8 *)outbuf->sqe;
+ struct udma_jetty *ub_jetty = NULL;
+ u32 jettyid = inbuf->jettyid;
+ u32 wqe_offset;
+ u32 copy_len;
+ int ret = 0;
+
+ if (source_type != UB_QUERY_SQ) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query jetty sqe, source type should be UB_QUERY_SQ");
+ return -EINVAL;
+ }
+
+ if (inbuf->wqe_id > (UINT_MAX / UB_SQ_WRITE_WQEBB_LEN)) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "inbuf->wqe_id %u too large may cause looping",
+ inbuf->wqe_id);
+ return -EINVAL;
+ }
+
+ (void)memset_s(jetty_sqe, UB_MAX_JFS_DFX_BUF, 0x0, UB_MAX_JFS_DFX_BUF);
+ ub_jetty = udma_find_jetty(udev, jettyid);
+ if (ub_jetty == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jettyid = %u", jettyid);
+ return -EINVAL;
+ }
+
+ if (ub_jetty->ubcore_jetty.uctx == NULL) {
+ wqe_offset = inbuf->wqe_id * UB_SQ_WRITE_WQEBB_LEN %
+ ub_jetty->sq.buf_size;
+ copy_len = ((UB_MAX_JFS_DFX_BUF + wqe_offset) <
+ ub_jetty->sq.buf_size) ?
+ UB_MAX_JFS_DFX_BUF :
+ (ub_jetty->sq.buf_size - wqe_offset);
+ udma_info(udev->dev, UDMA_M_DFX,
+ "copy sq buf from kernel copy_len:%u, wqe_offset:%u",
+ copy_len, wqe_offset);
+ (void)memcpy_s(jetty_sqe, copy_len,
+ ub_jetty->sq.buf + wqe_offset, copy_len);
+ goto OUT;
+ }
+ wqe_offset =
+ inbuf->wqe_id * UB_SQ_WRITE_WQEBB_LEN % ub_jetty->umem->length;
+
+ ret = copy_data_from_page(udev, jetty_sqe, ub_jetty->umem,
+ UB_MAX_JFS_DFX_BUF, wqe_offset);
+OUT:
+ udma_jetty_put(ub_jetty);
+ return ret;
+}
+
+static int
+udma_dfx_query_rc_queue_ctx_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *rcq_ctx = &outbuf->rcq_ctx;
+ u32 rcq_id = inbuf->rcq_id;
+ int ret;
+
+ (void)memset_s(rcq_ctx, sizeof(struct ub_ta_context_query), 0,
+ sizeof(struct ub_ta_context_query));
+
+ ret = udma_query_rc_queue_ctx_from_cache(
+ udev, rcq_id, rcq_ctx, sizeof(struct ub_ta_context_query));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query rc queue context from cache! rcq_id(%u) ret(%d)",
+ rcq_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_rc_queue_ctx_from_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *rcq_ctx = &outbuf->rcq_ctx;
+ u32 rcq_id = inbuf->rcq_id;
+ int ret;
+
+ (void)memset_s(rcq_ctx, sizeof(struct ub_ta_context_query), 0,
+ sizeof(struct ub_ta_context_query));
+
+ ret = udma_query_rc_queue_ctx_from_host(
+ udev, rcq_id, rcq_ctx, sizeof(struct ub_ta_context_query));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query rc queue context from host! rcq_id(%u) ret(%d)",
+ rcq_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_rc_queue_pcqc_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_pcqc_query_rsp_s *pcqc = &outbuf->pcqc;
+ u32 rcq_id = inbuf->rcq_id;
+ int ret;
+
+ (void)memset_s(pcqc, sizeof(ub_pcqc_query_rsp_s), 0,
+ sizeof(ub_pcqc_query_rsp_s));
+
+ ret = udma_query_rc_queue_pcqc_from_cache(udev, rcq_id, pcqc,
+ sizeof(ub_pcqc_query_rsp_s));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query rc queue pcqc from cache! rcq_id(%u) ret(%d)",
+ rcq_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_rc_queue_pcqc_from_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_pcqc_query_rsp_s *pcqc = &outbuf->pcqc;
+ u32 rcq_id = inbuf->rcq_id;
+ int ret;
+
+ (void)memset_s(pcqc, sizeof(ub_pcqc_query_rsp_s), 0,
+ sizeof(ub_pcqc_query_rsp_s));
+
+ ret = udma_query_rc_queue_pcqc_from_host(udev, rcq_id, pcqc,
+ sizeof(ub_pcqc_query_rsp_s));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query rc queue pcqc from cache! rcq_id(%u) ret(%d)",
+ rcq_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_rc_queue_wqe_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_rc_queue_wqe *rcqe = &outbuf->rcqe;
+ u32 rcq_id = inbuf->rcq_id;
+ u32 ci = inbuf->wqe_id;
+ int ret;
+
+ (void)memset_s(rcqe, sizeof(struct ub_rc_queue_wqe), 0,
+ sizeof(struct ub_rc_queue_wqe));
+
+ ret = udma_query_rc_queue_wqe_from_cache(
+ udev, rcq_id, ci, rcqe, sizeof(struct ub_rc_queue_wqe));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_rc_queue_wqe_from_cache_func failed! rcq_id(%u) ci(%u) ret(%d)",
+ rcq_id, ci, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_rc_queue_wqe_from_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_rc_queue_wqe *rcqe = &outbuf->rcqe;
+ u32 rcq_id = inbuf->rcq_id;
+ u32 ci = inbuf->wqe_id;
+ int ret;
+
+ (void)memset_s(rcqe, sizeof(struct ub_rc_queue_wqe), 0,
+ sizeof(struct ub_rc_queue_wqe));
+
+ ret = udma_query_rc_queue_wqe_from_host(udev, rcq_id, ci, rcqe,
+ sizeof(struct ub_rc_queue_wqe));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_rc_queue_wqe_from_host_func failed! rcq_id(%u) ci(%u) ret(%d)",
+ rcq_id, ci, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_jfc_cmtt(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfc *udma_jfc = NULL;
+ struct mtt *ub_mtt = NULL;
+ int ret = 0;
+
+ udma_jfc = udma_find_jfc(udev, inbuf->jfcid);
+ if (udma_jfc == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX, "Failed to get jfc, jfcid = %u",
+ inbuf->jfcid);
+ return -EINVAL;
+ }
+
+ ub_mtt = (struct mtt *)&udma_jfc->ub_mtt;
+
+ ret = udma_dfx_query_cmtt(udev, ub_mtt, outbuf);
+ udma_jfc_put(udma_jfc);
+ return ret;
+}
+
+static int udma_dfx_query_jfc_cqe(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfc *udma_jfc = NULL;
+ u32 jfcid = inbuf->jfcid;
+ u8 *jfc_cqe = outbuf->cqe;
+ u32 cqe_offset;
+ int ret = 0;
+
+ if (inbuf->wqe_id > (UINT_MAX / UB_SQ_WRITE_WQEBB_LEN)) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "inbuf->wqe_id %u too large may cause looping",
+ inbuf->wqe_id);
+ return -EINVAL;
+ }
+
+ (void)memset_s(jfc_cqe, UB_MAX_JFC_DFX_BUF, 0x0, UB_MAX_JFC_DFX_BUF);
+ udma_jfc = udma_find_jfc(udev, jfcid);
+ if (udma_jfc == NULL) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfc_cqe_func: ubcore find jfc failed, jfcid(%u)",
+ jfcid);
+ return -EINVAL;
+ }
+
+ if (udma_jfc->umem == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfc_cqe_func: udma_jfc->umem is null");
+ ret = -EINVAL;
+ goto OUT;
+ }
+
+ cqe_offset =
+ inbuf->wqe_id * UB_SQ_WRITE_WQEBB_LEN % udma_jfc->umem->length;
+ ret = copy_data_from_page(udev, jfc_cqe, udma_jfc->umem,
+ UB_MAX_JFC_DFX_BUF, cqe_offset);
+ udma_be32_to_cpu(jfc_cqe, UB_MAX_JFC_DFX_BUF);
+OUT:
+ udma_jfc_put(udma_jfc);
+ return ret;
+}
+
+static int udma_dfx_query_jfr_rqe(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfr *udma_jfr = NULL;
+ u32 jfrid = inbuf->jfrid;
+ u8 *jfr_rqe = outbuf->rqe;
+ struct udma_srq *srq = NULL;
+ u32 whole_container_size; // ci corresponding to container of size
+ u32 wqe_offset;
+ u64 wqe_offset_tmp;
+ int ret = 0;
+
+ (void)memset_s(jfr_rqe, UB_MAX_JFR_DFX_BUF, 0x0, UB_MAX_JFR_DFX_BUF);
+ udma_jfr = udma_find_jfr(udev, jfrid);
+ if (udma_jfr == NULL) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfr_rqe_func: ubcore find jfr failed, jfrid(%u)",
+ jfrid);
+ return -EINVAL;
+ }
+
+ srq = &udma_jfr->srq;
+
+ if (srq->umem == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfr_rqe_func: srq->umem is null");
+ ret = -EINVAL;
+ goto OUT;
+ }
+
+ whole_container_size = (1u << srq->wqe_shift) * srq->container_size;
+ if (inbuf->wqe_id > (UINT_MAX / whole_container_size)) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "inbuf->wqe_id %u too large may cause overflow",
+ inbuf->wqe_id);
+ ret = -EINVAL;
+ goto OUT;
+ }
+ wqe_offset_tmp = (u64)inbuf->wqe_id * whole_container_size;
+ wqe_offset = (u32)(wqe_offset_tmp % srq->umem->length);
+
+ udma_info(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfr_rqe_func: whole_container_size(%u), wqe_shift(%u), container_size(%u), umem->length(%llu)",
+ whole_container_size, srq->wqe_shift, srq->container_size,
+ srq->umem->length);
+
+ ret = copy_data_from_page(udev, jfr_rqe, srq->umem, UB_MAX_JFR_DFX_BUF,
+ wqe_offset);
+OUT:
+ udma_jfr_put(udma_jfr);
+ return ret;
+}
+
+static int udma_dfx_query_idx_wqe(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfr *udma_jfr = NULL;
+ u32 jfr_id = inbuf->jfrid;
+ u8 *idx_wqe = outbuf->idx_wqe;
+ struct udma_index_queue *index_queue = NULL;
+ u32 wqe_size;
+ u32 wqe_offset;
+ u64 wqe_offset_tmp;
+ int ret = 0;
+
+ if (inbuf->wqe_id > (UINT_MAX / UB_SQ_WRITE_WQEBB_LEN)) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Invalid parameter: inbuf->wqe_id %u too large may cause looping",
+ inbuf->wqe_id);
+ return -EINVAL;
+ }
+
+ (void)memset_s(idx_wqe, UB_MAX_IDX_WQE_DFX_BUF, 0x0,
+ UB_MAX_IDX_WQE_DFX_BUF);
+ udma_jfr = udma_find_jfr(udev, jfr_id);
+ if (udma_jfr == NULL) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_idx_wqe: ubcore find jfr failed, jfr_id(%u)",
+ jfr_id);
+ return -EINVAL;
+ }
+
+ index_queue = &udma_jfr->index_queue;
+
+ if (inbuf->wqe_id > index_queue->max_depth) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Invalid parameter: inbuf->wqe_id %u, jfr depth: %u",
+ inbuf->wqe_id, index_queue->max_depth);
+ ret = -EINVAL;
+ goto OUT;
+ }
+
+ if (index_queue->umem == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_idx_wqe: index_queue->umem is null");
+ ret = -EINVAL;
+ goto OUT;
+ }
+
+ wqe_size = 1u << index_queue->wqe_shift;
+ if (inbuf->wqe_id > (UINT_MAX / wqe_size)) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Invalid parameter: inbuf->wqe_id %u too large may cause overflow",
+ inbuf->wqe_id);
+ ret = -EINVAL;
+ goto OUT;
+ }
+ wqe_offset_tmp = (u64)inbuf->wqe_id * wqe_size;
+ wqe_offset = (u32)(wqe_offset_tmp % index_queue->umem->length);
+
+ udma_info(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_idx_wqe: wqe_size(%u), wqe_shift(%u), umem->length(%llu)",
+ wqe_size, index_queue->wqe_shift, index_queue->umem->length);
+
+ ret = copy_data_from_page(udev, idx_wqe, index_queue->umem,
+ UB_MAX_IDX_WQE_DFX_BUF, wqe_offset);
+OUT:
+ udma_jfr_put(udma_jfr);
+ return ret;
+}
+
+static int udma_dfx_query_sip(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ struct ub_sip_attr sip_attr = { 0 };
+ u32 sip_index = inbuf->sipid;
+ int ret;
+
+ ret = udma_query_sip(udev, sip_index, &sip_attr);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query sip, sip_index:%u, ret:%d", sip_index,
+ ret);
+ return ret;
+ }
+ (void)memcpy_s(&outbuf->sip_attr, sizeof(sip_attr), &sip_attr,
+ sizeof(sip_attr));
+ return 0;
+}
+
+static void copy_dev_res_to_dfx(struct ub_dev_res *dev_res, u32 offset,
+ struct udma_device_ctx_res *res_val)
+{
+ u32 i;
+
+ for (i = offset; i < offset + UB_QUERY_RES_CNT; i++) {
+ if (i < res_val->seg_list.seg_cnt) {
+ (void)memcpy_s(
+ dev_res->seg_list[i - offset].eid,
+ UBCORE_EID_SIZE,
+ res_val->seg_list.seg_list[i].ubva.eid.raw,
+ UBCORE_EID_SIZE);
+ dev_res->seg_list[i - offset].va =
+ res_val->seg_list.seg_list[i].ubva.va;
+ dev_res->seg_list[i - offset].key_id =
+ res_val->seg_list.seg_list[i].token_id;
+ dev_res->seg_list[i - offset].len =
+ res_val->seg_list.seg_list[i].len;
+ }
+ if (i < res_val->jfs_list.cnt) {
+ dev_res->jfs_list[i - offset] =
+ res_val->jfs_list.list[i];
+ }
+ if (i < res_val->jfr_list.cnt) {
+ dev_res->jfr_list[i - offset] =
+ res_val->jfr_list.list[i];
+ }
+ if (i < res_val->jfc_list.cnt) {
+ dev_res->jfc_list[i - offset] =
+ res_val->jfc_list.list[i];
+ }
+ if (i < res_val->jetty_list.cnt) {
+ dev_res->jetty_list[i - offset] =
+ res_val->jetty_list.list[i];
+ }
+ if (i < res_val->jetty_group_list.cnt) {
+ dev_res->jetty_group_list[i - offset] =
+ res_val->jetty_group_list.list[i];
+ }
+ if (i < res_val->tp_list.cnt) {
+ dev_res->tp_list[i - offset] = res_val->tp_list.list[i];
+ }
+ if (i < res_val->tpg_list.cnt) {
+ dev_res->tpg_list[i - offset] =
+ res_val->tpg_list.list[i];
+ }
+ if (i < res_val->rc_list.cnt) {
+ dev_res->rc_list[i - offset] = res_val->rc_list.list[i];
+ }
+ if (i < res_val->vtp_list.cnt) {
+ dev_res->vtp_list[i - offset] =
+ res_val->vtp_list.list[i];
+ }
+ if (i < res_val->utp_list.cnt) {
+ dev_res->utp_list[i - offset] =
+ res_val->utp_list.list[i];
+ }
+ }
+}
+
+static void udma_dfx_query_dev_member_cnt(struct udma_device *udma_dev,
+ struct ub_dev_res *dev_res,
+ struct udma_device_ctx_res *res_val)
+{
+ dev_res->jfs_cnt = res_val->jfs_list.cnt;
+ dev_res->jfr_cnt = res_val->jfr_list.cnt;
+ dev_res->seg_cnt = res_val->seg_list.seg_cnt;
+ dev_res->jfc_cnt = res_val->jfc_list.cnt;
+ dev_res->jetty_cnt = res_val->jetty_list.cnt;
+ dev_res->jetty_group_cnt = res_val->jetty_group_list.cnt;
+ dev_res->tp_cnt = res_val->tp_list.cnt;
+ dev_res->tpg_cnt = res_val->tpg_list.cnt;
+ dev_res->rc_cnt = res_val->rc_list.cnt;
+ dev_res->vtp_cnt = res_val->vtp_list.cnt;
+ dev_res->utp_cnt = res_val->utp_list.cnt;
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get tp_cnt:%u\n",
+ dev_res->tp_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get jfs_cnt:%u\n",
+ dev_res->jfs_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get jfr_cnt:%u\n",
+ dev_res->jfr_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get jetty_cnt:%u\n",
+ dev_res->jetty_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get jfc_cnt:%u\n",
+ dev_res->jfc_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get seg_cnt:%u\n",
+ dev_res->seg_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get jetty_group_cnt:%u\n",
+ dev_res->jetty_group_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get tpg_cnt:%u\n",
+ dev_res->tpg_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get rc_cnt:%u\n",
+ dev_res->rc_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get vtp_cnt:%u\n",
+ dev_res->vtp_cnt);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "get utp_cnt:%u\n",
+ dev_res->utp_cnt);
+}
+
+static void udma_dfx_query_dev_status(struct udma_device *udma_dev,
+ struct ub_dev_res *ub_dev_res)
+{
+ struct ubcore_device_status status = { 0 };
+ int ret;
+ int i;
+
+ ub_dev_res->port_cnt = udma_dev->ub_cap.net_dev_cap.port_cnt;
+ ret = udma_query_device_status(&(udma_dev->ub_dev), &status);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_dev_host failed.\n");
+ return;
+ }
+ for (i = 0; i < UB_MAX_PORT_CNT; i++) {
+ ub_dev_res->port_status[i].state =
+ (ub_port_state_t)status.port_status[i].state;
+ ub_dev_res->port_status[i].active_speed =
+ (ub_speed_t)status.port_status[i].active_speed;
+ ub_dev_res->port_status[i].active_width =
+ (ub_link_width_t)status.port_status[i].active_width;
+ ub_dev_res->port_status[i].active_mtu =
+ (ub_mtu_t)status.port_status[i].active_mtu;
+ }
+}
+
+static int udma_dfx_query_dev_res(struct udma_device *udma_dev,
+ struct ub_dev_res *ub_dev_res, u32 offset)
+{
+ struct udma_device_ctx_res dev_ctx_res = { 0 };
+ int ret;
+
+ ret = udma_query_res_dev(udma_dev, &dev_ctx_res);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to query device resources, ret(%d).\n", ret);
+ return ret;
+ }
+
+ udma_dfx_query_dev_member_cnt(udma_dev, ub_dev_res, &dev_ctx_res);
+ copy_dev_res_to_dfx(ub_dev_res, offset, &dev_ctx_res);
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_dev_res success.\n");
+ udma_free_dev_ctx_res(&dev_ctx_res);
+
+ return 0;
+}
+
+static int udma_dfx_query_dev_host(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_dev_res *ub_dev_res = &outbuf->dev_res;
+ u32 offset = inbuf->offset;
+ int ret;
+
+ udma_dfx_query_dev_status(udma_dev, ub_dev_res);
+
+ ret = udma_dfx_query_dev_res(udma_dev, ub_dev_res, offset);
+
+ return ret;
+}
+
+static int udma_dfx_query_dscp(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ int ret;
+
+ if (inbuf->dscp < UDMA_DSCP_MAX_NUM && inbuf->cos <= UDMA_COS_MAX) {
+ ret = udma_config_dscp_vl(&udma_dev->ub_dev, (u8 *)&inbuf->dscp,
+ (u8 *)&inbuf->cos, 1);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "config dscp cos failed.\n");
+ return ret;
+ }
+ }
+
+ ret = udma_get_dscp_cos(udma_dev, outbuf->dscp_dev, UDMA_DSCP_MAX_NUM,
+ 1);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "query dscp dev failed.\n");
+ return ret;
+ }
+ ret = udma_get_dscp_cos(udma_dev, outbuf->dscp_port, UDMA_DSCP_MAX_NUM,
+ 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "query dscp port failed.\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int udma_dfx_query_seg_mpt(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_seg_mpt_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_seg_mpt_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int
+udma_dfx_query_jfc_ctx_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_jfc_ctx_query *jfc_ctx = &outbuf->jfc_ctx;
+ u32 jfcid = inbuf->jfcid;
+ int ret;
+
+ (void)memset_s(jfc_ctx, sizeof(struct ub_jfc_ctx_query), 0,
+ sizeof(struct ub_jfc_ctx_query));
+
+ ret = udma_cmd_jfc_query_ctx(udev, jfcid, jfc_ctx);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query jfc_ctx from cache! jfcid:(%#x)",
+ jfcid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_jfc_ctx_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_jfc_ctx_query *jfc_ctx = &outbuf->jfc_ctx;
+ struct udma_jfc *ub_jfc = NULL;
+ u32 jfcid = inbuf->jfcid;
+
+ ub_jfc = udma_find_jfc(udev, jfcid);
+ if (ub_jfc == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfc, jfcid = %u", jfcid);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(jfc_ctx, ub_jfc->cqm_jfc->q_ctx_vaddr,
+ sizeof(struct ub_jfc_ctx_query));
+ udma_jfc_put(ub_jfc);
+ return 0;
+}
+
+static int udma_dfx_query_jfc_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_jfc_ctx_from_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_jfc_ctx_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int udma_dfx_query_upi(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ ub_cmd_upi_value_attr_s upi_value = outbuf->upi_value;
+ ub_cmd_upi_key_attr_s upi_index = inbuf->upi_key;
+ int ret;
+
+ ret = udma_cmd_upi_query(udev, &upi_index, &upi_value);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX, "Failed to query upi, ret:%d",
+ ret);
+ return ret;
+ }
+ (void)memcpy_s(&outbuf->upi_value, sizeof(ub_cmd_upi_value_attr_s),
+ &upi_value, sizeof(ub_cmd_upi_value_attr_s));
+ return 0;
+}
+
+static int udma_dfx_query_jetty_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_jetty_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_jetty_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int udma_dfx_query_jetty_group_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_jetty_group_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_jetty_group_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int udma_dfx_query_dev_dip(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_dip_ctx_query dip_ctx = { 0 };
+ u32 dip_index = inbuf->dipid;
+ int ret;
+
+ ret = udma_query_utp(udma_dev, dip_index, &dip_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to query dip, dip_index:%u, ret:%d", dip_index,
+ ret);
+ return ret;
+ }
+ (void)memcpy_s(&outbuf->dip_ctx, sizeof(dip_ctx), &dip_ctx,
+ sizeof(dip_ctx));
+ return 0;
+}
+
+static void udma_dfx_query_dev_cap_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_query_dev_cap *out_cap = &outbuf->dev_cap;
+
+ out_cap->feature = udev->ub_cap.dev_cap.feature.value;
+ out_cap->max_jfc_num = udev->ub_cap.dev_cap.max_jfc;
+ out_cap->max_jfs_num = udev->ub_cap.dev_cap.max_jfs;
+ out_cap->max_jfr_num = udev->ub_cap.dev_cap.max_jfr;
+ out_cap->max_jetty_num = udev->ub_cap.dev_cap.max_jetty;
+ out_cap->max_tp_num = udev->ub_cap.dev_cap.max_tp;
+ out_cap->max_tpg_num =
+ (udev->device_type == UDMA_DEV_TYPE_HI1825_V100 &&
+ udev->ub_dev.attr.tp_maintainer) ?
+ udev->ub_cap.dev_cap.max_tpg - UB_TP_LATCH_RSV_TPG_NUM :
+ udev->ub_cap.dev_cap.max_tpg;
+ out_cap->max_jetty_group_num = udev->ub_cap.dev_cap.max_jetty_grp;
+ out_cap->max_vtp_num = udev->ub_cap.dev_cap.max_vtp;
+ out_cap->max_jfc_depth = udev->ub_cap.dev_cap.max_jfc_depth;
+ out_cap->max_jfs_depth = udev->ub_cap.dev_cap.max_jfs_depth;
+ out_cap->max_jfr_depth = udev->ub_cap.dev_cap.max_jfr_depth;
+ out_cap->max_jfs_inline_size = udev->ub_cap.dev_cap.max_jfs_inline_size;
+ out_cap->max_jfc_inline_size = udev->ub_cap.dev_cap.max_jfc_inline_size;
+ out_cap->max_jfs_sge = udev->ub_cap.dev_cap.max_jfs_sge;
+ out_cap->max_jfs_rsge = udev->ub_cap.dev_cap.max_jfs_rsge;
+ out_cap->max_jfr_sge = udev->ub_cap.dev_cap.max_jfr_sge;
+ out_cap->max_dma_msg_sz = UB_MAX_WRITE_READ_LEN;
+ out_cap->max_send_msg_sz = (u32)udev->ub_cap.dev_cap.max_msg_size;
+ out_cap->max_rc_outstd_cnt =
+ (u32)udev->ub_cap.dev_cap.max_rc_outstd_cnt;
+
+ out_cap->utp_cnt = 0;
+ out_cap->max_eid_cnt = udev->ub_cap.dev_cap.max_eid_cnt;
+ out_cap->guid = 0;
+ out_cap->max_upi_cnt = udev->ub_cap.dev_cap.max_upi_cnt;
+
+ out_cap->max_oor_cnt = udev->ub_cap.dev_cap.max_oor_cnt;
+ out_cap->max_sip_cnt_per_vf = udev->ub_cap.dev_cap.max_sip_cnt_per_vf;
+ out_cap->max_dip_cnt_per_vf = udev->ub_cap.dev_cap.max_dip_cnt_per_vf;
+ out_cap->max_seid_cnt_per_vf = udev->ub_cap.dev_cap.max_seid_cnt_per_vf;
+ out_cap->max_jetty_cnt_per_jtg =
+ udev->ub_cap.dev_cap.max_jetty_in_jetty_grp;
+ out_cap->max_tp_cnt_per_tpg = udev->ub_cap.dev_cap.max_tp_in_tpg;
+
+ out_cap->seid_idx_start = udev->ub_cap.dev_cap.seid_idx_start;
+ out_cap->max_rc_num = UB_MAX_RC_NUM;
+
+ out_cap->slice_min_size = UB_SLICE_NUM64K;
+ out_cap->slice_max_size = UB_SLICE_NUM128K;
+ out_cap->max_pi_on_chip_num = udev->ub_cap.dev_cap.max_pi_on_chip_num;
+
+ out_cap->max_jetty_dest_ub = 0;
+ out_cap->device_type = udev->device_type;
+ out_cap->fe_idx = hinic5_global_func_id(udev->hwdev);
+}
+
+static void udma_dfx_query_dev_cap_net_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_query_dev_cap *out_cap = &outbuf->dev_cap;
+
+ out_cap->port_cnt = udev->ub_cap.net_dev_cap.port_cnt;
+ out_cap->vf_cnt = udev->ub_cap.net_dev_cap.vf_cnt;
+ out_cap->max_mtu = udev->ub_cap.net_dev_cap.max_mtu;
+ out_cap->is_tpf = udev->ub_cap.net_dev_cap.is_tpf;
+}
+
+static void udma_dfx_query_dev_attr_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_query_dev_cap *out_cap = &outbuf->dev_cap;
+
+ out_cap->trans_mode = udev->ub_dev.attr.dev_cap.trans_mode;
+ out_cap->congestion_ctrl_alg =
+ UB_CC_ALGO_LDCP; /* TP congestion control algorithm, 1823 and 1825 only supports UB_CC_ALGO_LDCP */
+ out_cap->comp_vector_cnt = udev->ub_dev.attr.dev_cap.ceq_cnt;
+ out_cap->virtualization = udev->ub_dev.attr.virtualization;
+}
+
+static void udma_dfx_query_dev_cap_res_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_query_dev_cap *out_cap = &outbuf->dev_cap;
+
+ out_cap->max_rc_depth = udev->ub_cap.dev_cap_res.udma_res.ubrc_depth;
+ out_cap->rc_entry_size =
+ udev->ub_cap.dev_cap_res.udma_res.ubrc_entry_size;
+ out_cap->max_mpts = udev->ub_cap.dev_cap_res.sdk_res.max_mpts;
+ out_cap->num_ceq_vectors =
+ udev->ub_cap.dev_cap_res.udma_res.num_ceq_vectors;
+ out_cap->cqc_entry_size = udev->ub_cap.dev_cap_res.sdk_res.cqc_entry_sz;
+ out_cap->qpc_entry_size = udev->ub_cap.dev_cap_res.sdk_res.qpc_entry_sz;
+ out_cap->srqc_entry_size =
+ udev->ub_cap.dev_cap_res.sdk_res.srqc_entry_sz;
+ out_cap->direct_wqe_size =
+ udev->ub_cap.dev_cap_res.udma_res.direct_wqe_size;
+ out_cap->log_mtt = udev->ub_cap.dev_cap_res.udma_res.log_mtt;
+ out_cap->num_mtts = udev->ub_cap.dev_cap_res.udma_res.num_mtts;
+ out_cap->log_mtt_seg = udev->ub_cap.dev_cap_res.udma_res.log_mtt_seg;
+ out_cap->mtt_entry_sz = udev->ub_cap.dev_cap_res.udma_res.mtt_entry_sz;
+ out_cap->mpt_entry_sz = udev->ub_cap.dev_cap_res.sdk_res.mpt_entry_sz;
+ out_cap->dmtt_cl_start = udev->ub_cap.dev_cap_res.sdk_res.dmtt_cl_start;
+ out_cap->dmtt_cl_end = udev->ub_cap.dev_cap_res.sdk_res.dmtt_cl_end;
+ out_cap->dmtt_cl_sz = udev->ub_cap.dev_cap_res.sdk_res.dmtt_cl_sz;
+ out_cap->ubrc_entry_sz =
+ udev->ub_cap.dev_cap_res.udma_res.ubrc_entry_size;
+ out_cap->log_ubrc_seg = udev->ub_cap.dev_cap_res.udma_res.log_ubrc_seg;
+ out_cap->cmtt_cl_start = udev->ub_cap.dev_cap_res.sdk_res.cmtt_cl_start;
+ out_cap->cmtt_cl_end = udev->ub_cap.dev_cap_res.sdk_res.cmtt_cl_end;
+ out_cap->cmtt_cl_sz = udev->ub_cap.dev_cap_res.sdk_res.cmtt_cl_sz;
+ out_cap->wqe_cl_start = udev->ub_cap.dev_cap_res.sdk_res.wqe_cl_start;
+ out_cap->wqe_cl_end = udev->ub_cap.dev_cap_res.sdk_res.wqe_cl_end;
+ out_cap->wqe_cl_sz = udev->ub_cap.dev_cap_res.sdk_res.wqe_cl_sz;
+}
+
+static int udma_dfx_query_dev_cap(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ udma_dfx_query_dev_cap_func(udma_dev, inbuf, outbuf);
+ udma_dfx_query_dev_cap_net_func(udma_dev, inbuf, outbuf);
+ udma_dfx_query_dev_attr_func(udma_dev, inbuf, outbuf);
+ udma_dfx_query_dev_cap_res_func(udma_dev, inbuf, outbuf);
+
+ return 0;
+}
+
+static int
+udma_dfx_query_sec_addr_pcie_hole(struct udma_device *udev,
+ struct ub_secure_addr_info *secure_addr_info)
+{
+ struct vmsec_pcie_hole_cmd cmd = { 0 };
+ u16 out_size = sizeof(cmd);
+ int ret;
+
+ cmd.vfid = hinic5_global_func_id(udev->hwdev);
+
+ ret = hinic5_msg_to_mgmt_sync(udev->hwdev, HINIC5_MOD_MIGRATE,
+ MIG_MPU_CMD_PCIE_HOLE_QUERY, &cmd,
+ sizeof(cmd), &cmd, &out_size, 0,
+ HINIC5_CHANNEL_MIG);
+ if ((ret != 0) || (out_size == 0) || (cmd.head.status != 0)) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "query pcie hole failed, err: %d, status: 0x%x, out_size: 0x%x",
+ ret, cmd.head.status, out_size);
+ return -EFAULT;
+ }
+
+ secure_addr_info->pcie_hole.pcie_hole0_addr_hi =
+ cmd.pcie_hole.pcie_hole0_addr_hi;
+ secure_addr_info->pcie_hole.pcie_hole0_addr_lo =
+ cmd.pcie_hole.pcie_hole0_addr_lo;
+ secure_addr_info->pcie_hole.pcie_hole0_len =
+ cmd.pcie_hole.pcie_hole0_len;
+ secure_addr_info->pcie_hole.pcie_hole1_addr_hi =
+ cmd.pcie_hole.pcie_hole1_addr_hi;
+ secure_addr_info->pcie_hole.pcie_hole1_addr_lo =
+ cmd.pcie_hole.pcie_hole1_addr_lo;
+ secure_addr_info->pcie_hole.pcie_hole1_len =
+ cmd.pcie_hole.pcie_hole1_len;
+ secure_addr_info->pcie_hole.domain_id = cmd.pcie_hole.domain_id;
+
+ return 0;
+}
+
+static int
+udma_dfx_query_sec_addr_ctx_gpa(struct udma_device *udev,
+ struct ub_secure_addr_info *secure_addr_info)
+{
+ struct vmsec_ctx_gpa_cmd cmd = { 0 };
+ u16 out_size = sizeof(cmd);
+ int ret;
+
+ cmd.vfid = hinic5_global_func_id(udev->hwdev);
+
+ ret = hinic5_msg_to_mgmt_sync(udev->hwdev, HINIC5_MOD_MIGRATE,
+ MIG_MPU_CMD_CTX_GPA_QUERY, &cmd,
+ sizeof(cmd), &cmd, &out_size, 0,
+ HINIC5_CHANNEL_MIG);
+ if ((ret != 0) || (out_size == 0) || (cmd.head.status != 0)) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "query ctx gpa failed, err: %d, status: 0x%x, out_size: 0x%x",
+ ret, cmd.head.status, out_size);
+ return -EFAULT;
+ }
+
+ secure_addr_info->ctx_gpa.ctx_gpa_hi = cmd.ctx_gpa.ctx_gpa_hi;
+ secure_addr_info->ctx_gpa.ctx_gpa_lo = cmd.ctx_gpa.ctx_gpa_lo;
+ secure_addr_info->ctx_gpa.ctx_len = cmd.ctx_gpa.ctx_len;
+ secure_addr_info->ctx_gpa.ctx_gpa_mode = cmd.ctx_gpa.ctx_gpa_mode;
+
+ return 0;
+}
+
+static int udma_dfx_query_sec_addr_info(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_secure_addr_info *secure_addr_info = &outbuf->sec_addr_info;
+ int ret;
+
+ ret = (udma_dfx_query_sec_addr_ctx_gpa(udma_dev, secure_addr_info) !=
+ 0) ||
+ (udma_dfx_query_sec_addr_pcie_hole(udma_dev, secure_addr_info) !=
+ 0);
+
+ return ret;
+}
+
+static int
+udma_dfx_query_jfs_ctx_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jfs_ctx = &outbuf->jfs_ctx;
+ struct udma_jfs *jfs = NULL;
+ u32 jfsid = inbuf->jfsid;
+ int ret;
+
+ (void)memset_s(jfs_ctx, sizeof(struct ub_ta_context_query), 0,
+ sizeof(struct ub_ta_context_query));
+
+ jfs = udma_find_jfs(udev, jfsid);
+ if (jfs == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get jfs, jfsid(%u)\n", jfsid);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udev, jfsid, &jfs->cmdq_rtt, jfs_ctx);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query jfs_ctx from cache! jfsid:(%#x)",
+ jfsid);
+ return ret;
+ }
+
+ udma_jfs_put(jfs);
+ return 0;
+}
+
+static int udma_dfx_query_jfs_ctx_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jfs_ctx = &outbuf->jfs_ctx;
+ struct udma_jfs *ub_jfs = NULL;
+ u32 jfsid = inbuf->jfsid;
+
+ ub_jfs = udma_find_jfs(udev, jfsid);
+ if (ub_jfs == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfs, jfsid = %u", jfsid);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(jfs_ctx, ub_jfs->jfsc_info->vaddr,
+ sizeof(struct ub_ta_context_query));
+ udma_jfs_put(ub_jfs);
+ return 0;
+}
+
+static int udma_dfx_query_jfs_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_jfs_ctx_from_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_jfs_ctx_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int udma_dfx_query_jetty_cmtt(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jetty *ub_jetty = NULL;
+ int ret = 0;
+
+ ub_jetty = udma_find_jetty(udev, inbuf->jettyid);
+ if (ub_jetty == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get jetty, jetty_id = %u", inbuf->jettyid);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_cmtt(udev, &ub_jetty->ub_mtt, outbuf);
+ udma_jetty_put(ub_jetty);
+ return ret;
+}
+
+static int udma_dfx_query_jfs_cmtt(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfs *ub_jfs = NULL;
+ int ret = 0;
+
+ ub_jfs = udma_find_jfs(udev, inbuf->jfsid);
+ if (ub_jfs == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get jfs, jfs_id = %u", inbuf->jfsid);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_cmtt(udev, &ub_jfs->ub_mtt, outbuf);
+ udma_jfs_put(ub_jfs);
+ return ret;
+}
+
+static int udma_dfx_query_jfr_cmtt(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct udma_jfr *udma_jfr = NULL;
+ int ret = 0;
+
+ udma_jfr = udma_find_jfr(udev, inbuf->jfrid);
+ if (udma_jfr == NULL) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_jfr_cmtt_func, ubcore find jfr failed, jfr_id(%u)",
+ inbuf->jfrid);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_cmtt(udev, &udma_jfr->srq.ub_mtt, outbuf);
+ udma_jfr_put(udma_jfr);
+ return ret;
+}
+
+static int
+udma_dfx_query_jfr_ctx_from_host_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jfr_entry = &outbuf->jetty_ctx;
+ struct udma_jfr *udma_jfr = NULL;
+ u32 jfrid = inbuf->jfrid;
+
+ udma_jfr = udma_find_jfr(udev, jfrid);
+ if (udma_jfr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query jfr from host failed!, jfrid(%u)", jfrid);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(jfr_entry, udma_jfr->jfrc_info->vaddr,
+ sizeof(struct ub_ta_context_query));
+ udma_jfr_put(udma_jfr);
+ return 0;
+}
+
+static int
+udma_dfx_query_jfr_ctx_from_cache_func(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_ta_context_query *jfr_entry = &outbuf->jetty_ctx;
+ struct udma_jfr *jfr = NULL;
+ u32 jfrid = inbuf->jfrid;
+ int ret;
+
+ (void)memset_s(jfr_entry, sizeof(struct ub_ta_context_query), 0,
+ sizeof(struct ub_ta_context_query));
+
+ jfr = udma_find_jfr(udev, jfrid);
+ if (jfr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get jfr, jfrid(%u)\n", jfrid);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udev, jfrid, &jfr->cmdq_rtt, jfr_entry);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query jfr from cache failed!! jfrid(%u)", jfrid);
+ return ret;
+ }
+
+ udma_jfr_put(jfr);
+ return 0;
+}
+
+static int
+udma_dfx_query_index_queue_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args)
+{
+ if (!udma_get_index_queue_en(udma_dev)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "device type(%d) does not support the command for query index wqe.",
+ udma_dev->device_type);
+ return -EINVAL;
+ }
+
+ /* TODO: later need to consider ICSL submission for invalid xid queue query of intercept */
+ return 0;
+}
+
+static int udma_dfx_query_jfr_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_jfr_ctx_from_cache_func(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_jfr_ctx_from_host_func(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int udma_dfx_query_srq_ctx_from_host(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_cmd_srq_query_rsp_s *srq_entry = &outbuf->srq_ctx;
+ struct udma_jfr *udma_jfr = NULL;
+ u32 jfrid = inbuf->jfrid;
+
+ udma_jfr = udma_find_jfr(udev, jfrid);
+ if (udma_jfr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query srq from host failed!, jfrid(%u)", jfrid);
+ return -EINVAL;
+ }
+
+ memcpy_fromio(srq_entry, udma_jfr->srq.srqc_info->q_ctx_vaddr,
+ sizeof(ub_cmd_srq_query_rsp_s));
+ udma_jfr_put(udma_jfr);
+ return 0;
+}
+
+static int udma_dfx_query_srq_ctx_from_cache(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_cmd_srq_query_rsp_s *srq_entry = &outbuf->srq_ctx;
+ struct udma_jfr *udma_jfr = NULL;
+ u32 jfrid = inbuf->jfrid;
+ int ret;
+
+ udma_jfr = udma_find_jfr(udev, jfrid);
+ if (udma_jfr == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query jfr from host failed!, jfrid(%u)", jfrid);
+ return -EINVAL;
+ }
+
+ (void)memset_s(srq_entry, sizeof(ub_cmd_srq_query_rsp_s), 0,
+ sizeof(ub_cmd_srq_query_rsp_s));
+
+ ret = udma_cmd_srq_query_ctx(udev, udma_jfr->srq.srqn, srq_entry);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "query srq from cache failed!! jfrid(%u)", jfrid);
+ udma_jfr_put(udma_jfr);
+ return ret;
+ }
+ udma_jfr_put(udma_jfr);
+ return 0;
+}
+
+static int udma_dfx_query_srq_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_srq_ctx_from_cache(udma_dev, buf_in,
+ buf_out);
+ } else {
+ return udma_dfx_query_srq_ctx_from_host(udma_dev, buf_in,
+ buf_out);
+ }
+}
+
+static int
+udma_dfx_query_rc_queue_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args)
+{
+ u32 xid = check_args->xid;
+ bool tpf = check_args->tpf;
+ struct udma_rc_queue *rcq = NULL;
+
+ if (tpf) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Should not query rcq in TPF");
+ return -EINVAL;
+ }
+
+ rcq = udma_find_rcq(udma_dev, xid);
+ if (rcq == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get rcq, xid = %u", xid);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_rc_queue_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_rc_queue_ctx_from_cache_func(
+ udma_dev, buf_in, buf_out);
+ } else {
+ return udma_dfx_query_rc_queue_ctx_from_host_func(
+ udma_dev, buf_in, buf_out);
+ }
+}
+
+static int udma_dfx_query_rc_queue_cmtt(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ u32 rc_id = buf_in->rcq_id;
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_rc_queue *udma_rcq = NULL;
+ struct tag_cqm_qpc_mpt *rcq_ctx = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ rc_id, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "failed to get cqm object, rc_id(%u)\n", rc_id);
+ return -EINVAL;
+ }
+
+ rcq_ctx = container_of(cqm_obj, struct tag_cqm_qpc_mpt, object);
+ udma_rcq = (struct udma_rc_queue *)rcq_ctx->priv;
+ if (udma_rcq->cqm_priv_type != UDMA_JETTY_TYPE_RC) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "cqmobj is not rc, rc_id(%u), type(%u)\n", rc_id,
+ udma_rcq->cqm_priv_type);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ ret = udma_dfx_query_cmtt(udma_dev, &udma_rcq->ub_mtt, buf_out);
+
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
+
+static int udma_dfx_query_rc_queue_pcqc_ctx(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_rc_queue_pcqc_from_cache_func(
+ udma_dev, buf_in, buf_out);
+ } else {
+ return udma_dfx_query_rc_queue_pcqc_from_host_func(
+ udma_dev, buf_in, buf_out);
+ }
+}
+
+static int udma_dfx_query_jfs_sqe(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct tag_ub_sq_wqe_s *jfs_sqe = &outbuf->jfs_sqe;
+ struct udma_jfs *ub_jfs = NULL;
+ u32 jfsid = inbuf->jfsid;
+ u32 wqe_offset;
+ int ret = 0;
+
+ if (inbuf->wqe_id > (UINT_MAX / UB_SQ_WRITE_WQEBB_LEN)) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "inbuf->wqe_id %u too large may cause looping",
+ inbuf->wqe_id);
+ return -EINVAL;
+ }
+
+ ub_jfs = udma_find_jfs(udev, jfsid);
+ if (ub_jfs == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfs, jfsid = %u", jfsid);
+ return -EINVAL;
+ }
+
+ ub_jfs->sq_buf_len = (u32)ub_jfs->umem->length;
+ if (ub_jfs->sq_buf_len == 0) {
+ udma_err(udev->dev, UDMA_M_DFX, "JFS sq buf length is 0");
+ ret = -EINVAL;
+ goto OUT;
+ }
+
+ wqe_offset =
+ inbuf->wqe_id * UB_SQ_WRITE_WQEBB_LEN % ub_jfs->umem->length;
+
+ ret = copy_data_from_page(udev, (u8 *)jfs_sqe, ub_jfs->umem,
+ UB_MAX_JFS_DFX_BUF, wqe_offset);
+OUT:
+ udma_jfs_put(ub_jfs);
+ return ret;
+}
+
+static int udma_dfx_query_rc_queue_wqe(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type)
+{
+ if (source_type == UB_QUERY_FROM_CACHE) {
+ return udma_dfx_query_rc_queue_wqe_from_cache_func(
+ udma_dev, buf_in, buf_out);
+ } else {
+ return udma_dfx_query_rc_queue_wqe_from_host_func(
+ udma_dev, buf_in, buf_out);
+ }
+}
+
+static int udma_dfx_query_seid_ctx_from_cache(
+ struct udma_device *udma_dev, const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ struct ub_seid_ctx_query *seid_ctx = &outbuf->seid_ctx;
+ int ret;
+
+ ret = udma_cmd_seid_query_ctx_from_cache(
+ udma_dev, (u16)inbuf->vfid, inbuf->seid_id, seid_ctx,
+ sizeof(struct ub_seid_ctx_query));
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "query seid ctx failed, ret=%d.\n", ret);
+
+ return ret;
+}
+
+static int udma_dfx_query_cc(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ struct ub_cc_params *para = &outbuf->cc_params;
+ int ret;
+
+ para->index = (u8)inbuf->pattern_index;
+ para->ub_cc_algo = (u8)inbuf->cc_alg;
+ ret = udma_cc_query_para(udma_dev, para);
+
+ return ret;
+}
+
+static int udma_dfx_query_func_info(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_cmd_func_resp *para = &outbuf->func_info;
+ struct ub_cmd_get_cfg_info get_cfg_info = { 0 };
+ u16 resp_size = sizeof(struct ub_cmd_func_resp);
+ int ret;
+
+ get_cfg_info.func_id = (u16)inbuf->vfid;
+ para->func_id = (u16)inbuf->vfid;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_FUNC_ATTR, &get_cfg_info,
+ sizeof(get_cfg_info), para, &resp_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (get_cfg_info.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "failed to get func info, ret:%d, status:0x%x, out size:0x%x",
+ ret, get_cfg_info.head.status, resp_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_func_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args)
+{
+ bool tpf = check_args->tpf;
+
+ if (!tpf) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Should query func filter in TPF");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_func_filter_info(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_cmd_get_ub_filter_info_resp *para = &outbuf->func_filter;
+ struct ub_cmd_get_cfg_info get_cfg_info = { 0 };
+ u16 resp_size = sizeof(struct ub_cmd_get_ub_filter_info_resp);
+ int ret;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_GET_FUNC_FILTER,
+ &get_cfg_info, sizeof(get_cfg_info), para,
+ &resp_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (get_cfg_info.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "failed to get func filter info, ret:%d, status:0x%x, out size:0x%x",
+ ret, get_cfg_info.head.status, resp_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_mig_counter(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ return udma_cmd_mig_query_counter(udma_dev, inbuf->vfid,
+ &outbuf->mig_ctr);
+}
+
+static int udma_dfx_query_ta_rdma_rc(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_ta_rdma_rc_outbuf *ta_rdma_rc = &outbuf->ta_rdma_rc;
+ int ret;
+
+ ret = udma_cmd_jetty_query_rdma_rc(udma_dev, inbuf->jettyid,
+ inbuf->entry_index, ta_rdma_rc);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_ta_rdma_rc_exec failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_ta_msn_entry(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_msn_entry_outbuf *ta_msn_entry = &outbuf->msn_entry_info;
+ int ret;
+
+ ret = udma_cmd_jetty_query_ta_msn_entry(udma_dev, inbuf->xid,
+ inbuf->entry_index,
+ inbuf->msn_type, ta_msn_entry);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_ta_msn_entry failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_ta_oor_info(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_oor_ta_info *oor_ta_info = &outbuf->oor_ta_info;
+ int ret;
+
+ ret = udma_cmd_jetty_query_ta_oor_info(udma_dev, inbuf->jettyid,
+ inbuf->idx, oor_ta_info);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_ta_oor_info_exec failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+ udma_cpu_to_be32(&oor_ta_info->start_tassn,
+ sizeof(oor_ta_info->start_tassn));
+ udma_cpu_to_be32(&oor_ta_info->start_bit,
+ sizeof(oor_ta_info->start_bit));
+ udma_cpu_to_be32(&oor_ta_info->end_bit, sizeof(oor_ta_info->end_bit));
+ udma_cpu_to_be32(&oor_ta_info->total_bit_num,
+ sizeof(oor_ta_info->total_bit_num));
+ udma_cpu_to_be32(&oor_ta_info->acked_bit,
+ sizeof(oor_ta_info->acked_bit));
+ udma_cpu_to_be32(&oor_ta_info->tamsnc_pi,
+ sizeof(oor_ta_info->tamsnc_pi));
+ udma_cpu_to_be32(&oor_ta_info->tamsnc_ci,
+ sizeof(oor_ta_info->tamsnc_ci));
+ udma_cpu_to_be32(&oor_ta_info->next_ack_tassn,
+ sizeof(oor_ta_info->next_ack_tassn));
+ udma_cpu_to_be32(&oor_ta_info->next_send_tassn,
+ sizeof(oor_ta_info->next_send_tassn));
+ oor_ta_info->bitmap.rc_ext_table_size =
+ udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100 ?
+ UB_TA_RDMARC_EXT_TABLE_SIZE_HI1825 :
+ UB_TA_RDMARC_EXT_TABLE_SIZE_HI1823;
+
+ return 0;
+}
+
+static int udma_dfx_query_ta_rdma_rc_ext(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ struct ub_ta_rdma_rc_ext_outbuf *ta_rdma_rc_ext =
+ &outbuf->ta_rdma_rc_ext;
+ int ret;
+
+ ret = udma_cmd_jetty_query_rdma_rc_ext(udma_dev, inbuf->jettyid,
+ inbuf->idx, ta_rdma_rc_ext);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_ta_rdma_rc_ext_exec failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_driver_ctr(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type)
+{
+ ub_driver_comm_ctr_t *ub_driver_ctr = &outbuf->ub_driver_comm_ctr;
+ u32 cmd_type;
+ int ret = 0;
+ cmd_type = inbuf->cmd_type >> UB_QUERY_TYPE_BIT;
+
+ switch (cmd_type) {
+ case UB_QUERY_TYPE_JFS:
+ ret = udma_cmd_jfs_query_driver_ctr(udma_dev, inbuf->jfsid,
+ ub_driver_ctr);
+ break;
+ case UB_QUERY_TYPE_JETTY:
+ ret = udma_cmd_jetty_query_driver_ctr(udma_dev, inbuf->jettyid,
+ ub_driver_ctr);
+ break;
+ case UB_QUERY_TYPE_DEV:
+ ub_driver_ctr->post_send_wr_num = (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr.post_send_wr_num);
+ ub_driver_ctr->post_recv_wr_num = (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr.post_recv_wr_num);
+ ub_driver_ctr->poll_total_num = (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr.poll_total_num);
+ ub_driver_ctr->poll_sq_num = (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr.poll_sq_num);
+ ub_driver_ctr->poll_rq_num = (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr.poll_rq_num);
+ break;
+ case UB_QUERY_TYPE_JFC:
+ ret = udma_cmd_jfc_query_driver_ctr(udma_dev, inbuf->jfcid,
+ ub_driver_ctr);
+ break;
+ case UB_QUERY_TYPE_JFR:
+ ret = udma_cmd_jfr_query_driver_ctr(udma_dev, inbuf->jfrid,
+ ub_driver_ctr);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_DFX, "err cmd_type=%d!\n",
+ cmd_type);
+ return -EINVAL;
+ }
+
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_driver_ctr failed!, ret=%d\n", ret);
+ }
+
+ return ret;
+}
+
+/* TODO: later need to consider ICSL submission for invalid xid queue query of intercept */
+static struct udma_dfx_query_cmd_cb g_udma_query_cmd_funcs[] = {
+ /* query segment */
+ { UB_QUERY_TYPE_SEG, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_seg_mpt },
+ { UB_QUERY_TYPE_SEG, UB_QUERY_SUB_TYPE_MTT, NULL,
+ udma_dfx_query_seg_dmtt },
+ { UB_QUERY_TYPE_SEG, UB_QUERY_SUB_TYPE_SAFE_DMTT_BITMAP, NULL,
+ udma_dfx_query_seg_safe_dmtt_bitmap },
+ { UB_QUERY_TYPE_SEG, UB_QUERY_SUB_TYPE_SAFE_DMTT_CTX, NULL,
+ udma_dfx_query_seg_safe_dmtt_ctx },
+
+ /* query jfc */
+ { UB_QUERY_TYPE_JFC, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_jfc_ctx },
+ { UB_QUERY_TYPE_JFC, UB_QUERY_SUB_TYPE_MTT, NULL,
+ udma_dfx_query_jfc_cmtt },
+ { UB_QUERY_TYPE_JFC, UB_QUERY_SUB_TYPE_WQE, NULL,
+ udma_dfx_query_jfc_cqe },
+ { UB_QUERY_TYPE_JFC, UB_QUERY_SUB_TYPE_IO_STAT, NULL,
+ udma_dfx_query_driver_ctr },
+
+ /* query jetty */
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_jetty_ctx },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_MTT, NULL,
+ udma_dfx_query_jetty_cmtt },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_WQE, NULL,
+ udma_dfx_query_jetty_sqe },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_RDMARC, NULL,
+ udma_dfx_query_ta_rdma_rc },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_RDMARC_EXT, NULL,
+ udma_dfx_query_ta_rdma_rc_ext },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_TA_OOR_INFO, NULL,
+ udma_dfx_query_ta_oor_info },
+ { UB_QUERY_TYPE_JETTY_GROUP, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_jetty_group_ctx },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_IO_STAT, NULL,
+ udma_dfx_query_driver_ctr },
+ { UB_QUERY_TYPE_JETTY, UB_QUERY_SUB_TYPE_MSN_ENTRY, NULL,
+ udma_dfx_query_ta_msn_entry },
+
+ /* query jfs */
+ { UB_QUERY_TYPE_JFS, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_jfs_ctx },
+ { UB_QUERY_TYPE_JFS, UB_QUERY_SUB_TYPE_MTT, NULL,
+ udma_dfx_query_jfs_cmtt },
+ { UB_QUERY_TYPE_JFS, UB_QUERY_SUB_TYPE_WQE, NULL,
+ udma_dfx_query_jfs_sqe },
+ { UB_QUERY_TYPE_JFS, UB_QUERY_SUB_TYPE_IO_STAT, NULL,
+ udma_dfx_query_driver_ctr },
+ { UB_QUERY_TYPE_JFS, UB_QUERY_SUB_TYPE_MSN_ENTRY, NULL,
+ udma_dfx_query_ta_msn_entry },
+
+ /* query jfr */
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_jfr_ctx },
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_MTT, NULL,
+ udma_dfx_query_jfr_cmtt },
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_WQE, NULL,
+ udma_dfx_query_jfr_rqe },
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_SRQ, NULL,
+ udma_dfx_query_srq_ctx },
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_IDX_WQE,
+ udma_dfx_query_index_queue_check, udma_dfx_query_idx_wqe },
+ { UB_QUERY_TYPE_JFR, UB_QUERY_SUB_TYPE_IO_STAT, NULL,
+ udma_dfx_query_driver_ctr },
+
+ /* query table config */
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_dev_host },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_SIP, NULL, udma_dfx_query_sip },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_DIP, NULL,
+ udma_dfx_query_dev_dip },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_CAP, NULL,
+ udma_dfx_query_dev_cap },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_SECURE_MEM_INFO, NULL,
+ udma_dfx_query_sec_addr_info },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_DSCP, NULL,
+ udma_dfx_query_dscp },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_IO_STAT, NULL,
+ udma_dfx_query_driver_ctr },
+ { UB_QUERY_TYPE_UPI, UB_QUERY_SUB_TYPE_INFO, NULL, udma_dfx_query_upi },
+
+ /* query rc queue */
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_CTX,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_rc_queue_ctx },
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_MTT,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_rc_queue_cmtt },
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_WQE,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_rc_queue_wqe },
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_PCQC,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_rc_queue_pcqc_ctx },
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_RDMARC,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_ta_rdma_rc },
+ { UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_SUB_TYPE_RDMARC_EXT,
+ udma_dfx_query_rc_queue_check, udma_dfx_query_ta_rdma_rc_ext },
+
+ /* query misc */
+ { UB_QUERY_TYPE_SEID, UB_QUERY_SUB_TYPE_CTX, NULL,
+ udma_dfx_query_seid_ctx_from_cache },
+ { UB_QUERY_TYPE_CC, UB_QUERY_SUB_TYPE_INVALID, NULL,
+ udma_dfx_query_cc },
+ { UB_QUERY_TYPE_MIG, UB_QUERY_SUB_TYPE_FUNC_INFO, NULL,
+ udma_dfx_query_func_info },
+ { UB_QUERY_TYPE_MIG, UB_QUERY_SUB_TYPE_MIG_COUNTER_INFO, NULL,
+ udma_dfx_query_mig_counter },
+ { UB_QUERY_TYPE_DEV, UB_QUERY_SUB_TYPE_FUNC_INFO,
+ udma_dfx_query_func_check, udma_dfx_query_func_filter_info },
+
+ /* query ta latch info */
+ { UB_QUERY_TYPE_LATCH, UB_QUERY_SUB_TYPE_TA_LATCH,
+ udma_dfx_query_ta_latch_check, udma_dfx_query_ta_latch_data }
+};
+
+static inline int udma_dfx_query_args_size_check(struct udma_device *udma_dev,
+ u32 out_size)
+{
+ if (out_size < (u32)sizeof(union ub_query_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx query buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int udma_dfx_query_outbuf_clear(struct udma_device *udma_dev,
+ void *buf_out, u32 *out_size)
+{
+ int ret = 0;
+
+ ret = memset_s(buf_out, *out_size, 0,
+ (u32)sizeof(union ub_query_outbuf));
+ if (ret != EOK) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx query out buf memset error ret:%d\n", ret);
+ return -EINVAL;
+ }
+
+ *out_size = (u32)sizeof(union ub_query_outbuf);
+ return 0;
+}
+
+static inline int
+udma_dfx_query_subcmd_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ udma_check_func_t check_func)
+{
+ struct udma_dfx_check_args check_args = { 0 };
+
+ /* check: 1.xid;2.ta/tp func;3.debug/release version(to add in subcmd) */
+ check_args.xid = inbuf->xid;
+ check_args.tpf = udma_dev->ub_dev.attr.tp_maintainer;
+
+ if (check_func == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "Subcmd(%u) do not need validity-check.\n",
+ inbuf->cmd_type);
+ return 0;
+ }
+
+ if (check_func(udma_dev, inbuf, &check_args) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Check func not null and check failed.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_ta_func(struct udma_device *udma_dev,
+ const void *buf_in, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ udma_query_func_t cmd_func = NULL;
+ udma_check_func_t check_func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ /* check in buf size & out buf size, memset out buf */
+ if (udma_dfx_query_args_size_check(udma_dev, *out_size) != 0 ||
+ udma_dfx_query_outbuf_clear(udma_dev, buf_out, out_size) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query buf check or clear failed.\n");
+ return -EINVAL;
+ }
+
+ /* look for sub cmd and exec */
+ for (i = 0; i < sizeof(g_udma_query_cmd_funcs) /
+ sizeof(g_udma_query_cmd_funcs[0]);
+ i++) {
+ cmd_type = ub_dfx_get_cmd_type(
+ g_udma_query_cmd_funcs[i].cmd_type,
+ g_udma_query_cmd_funcs[i].sub_type, 0);
+ if (cmd_type ==
+ (inbuf->cmd_type & UB_DFX_QUERY_SOURCE_TYPE_SHIELD_MASK)) {
+ check_func = g_udma_query_cmd_funcs[i].check_func;
+ cmd_func = g_udma_query_cmd_funcs[i].cmd_func;
+
+ if (cmd_func == NULL) {
+ udma_warn(
+ udma_dev->dev, UDMA_M_DFX,
+ "Subcmd(%u) not support yet, check cmd_type!\n",
+ inbuf->cmd_type);
+ return -EINVAL;
+ }
+
+ if (udma_dfx_query_subcmd_check(udma_dev, inbuf,
+ check_func) != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Check func not null and check failed.\n");
+ return -EINVAL;
+ }
+ return cmd_func(udma_dev, inbuf, outbuf,
+ inbuf->cmd_type &
+ UB_DFX_QUERY_SOURCE_TYPE_BIT);
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Subcmd(%u) not found, check cmd_type!\n", inbuf->cmd_type);
+ return -EINVAL;
+}
+
+int udma_query_npu_dfx_version(struct udma_device *udma_dev, int *npu_version)
+{
+ struct comm_cmd_get_fw_version fw_npu_version;
+ u16 out_size = sizeof(fw_npu_version);
+ u16 channel = HINIC5_CHANNEL_UB;
+ int ret;
+
+ if (udma_dev == NULL || udma_dev->hwdev == NULL) {
+ return -EINVAL;
+ }
+
+ (void)memset_s(&fw_npu_version, sizeof(fw_npu_version), 0,
+ sizeof(fw_npu_version));
+ fw_npu_version.fw_type = HINIC5_FW_VER_TYPE_NPU;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_COMM,
+ COMM_MGMT_CMD_GET_FW_VERSION,
+ &fw_npu_version, sizeof(fw_npu_version),
+ &fw_npu_version, &out_size, 0, channel);
+ if ((ret != 0) || (out_size == 0) ||
+ (fw_npu_version.head.status) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "fail to query npu version, ret:%d, status:0x%x\n",
+ ret, fw_npu_version.head.status);
+ return -EIO;
+ }
+ *npu_version = fw_npu_version.fw_dfx_vld;
+ return ret;
+}
+
+int udma_verify_dfx_version(struct udma_device *udma_dev, u32 cmd)
+{
+ int npu_version = -1;
+ int ret;
+
+ ret = udma_query_npu_dfx_version(udma_dev, &npu_version);
+ if (ret < 0) {
+ udma_pr_err(UDMA_M_DFX, "UDMA fail to query version.\n");
+ return ret;
+ }
+
+ if (npu_version == 0 && (cmd == UB_DFX_PACKET || cmd == UB_DFX_ATTACK ||
+ cmd == UB_DFX_CQM_MODIFY)) {
+ udma_pr_err(
+ UDMA_M_DFX,
+ "Not support this cmd type (%u) for release version",
+ cmd);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int udma_dfx_query_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_query_inbuf *query_inbuf = NULL;
+ u32 cmd_type;
+ int ret;
+
+ // check in buf size
+ if (in_size < (u32)sizeof(struct ub_query_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx query buffer in size too small\n");
+ return -EINVAL;
+ }
+ query_inbuf = (struct ub_query_inbuf *)buf_in;
+ cmd_type = query_inbuf->cmd_type >> UB_QUERY_TYPE_BIT;
+
+ if (cmd_type == UB_QUERY_TYPE_TP || cmd_type == UB_QUERY_TYPE_TPG ||
+ cmd_type == UB_QUERY_TYPE_VTP)
+ ret = udma_dfx_query_tp_func(udma_dev, buf_in, in_size, buf_out,
+ out_size);
+ else
+ ret = udma_dfx_query_ta_func(udma_dev, buf_in, buf_out,
+ out_size);
+
+ return ret;
+}
+
+static udma_ioctl_func_t g_udma_ioctl_funcs[VM_COMPAT_TEST] = {
+ [UB_DFX_QUERY] = udma_dfx_query_func,
+ [UB_DFX_MODIFY] = udma_dfx_modify_func,
+ [UB_DFX_PACKET] = udma_dfx_packet_func,
+ [UB_DFX_PORT_STA] = udma_dfx_port_sta_func,
+ [UB_DFX_ATTACK] = udma_dfx_attack_func,
+ [UB_DFX_CQM_MODIFY] = udma_dfx_cqm_modify_func,
+ [UB_DFX_PERF_CTR] = udma_dfx_perf_ctr_func,
+ [UB_DFX_L2D_MEM] = udma_dfx_l2d_func,
+ [UB_DFX_PERF_QUERY] = udma_dfx_perf_query_func,
+};
+
+int udma_ioctl(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ struct udma_device *udma_dev = (struct udma_device *)uld_dev;
+ udma_ioctl_func_t func = NULL;
+ int ret;
+
+ /* check whether is root user */
+ if (!capable(CAP_SYS_ADMIN)) {
+ udma_pr_err(UDMA_M_DFX, "Invalid permission.");
+ return -EPERM;
+ }
+
+ /* ppf device on perform version number get */
+ if (cmd == GET_DRV_VERSION) {
+ return udma_dfx_get_drv_version(buf_in, in_size, buf_out,
+ out_size);
+ }
+
+ if (uld_dev == NULL || buf_in == NULL || buf_out == NULL ||
+ out_size == NULL) {
+ udma_pr_err(UDMA_M_DFX, "UDMA ioctl. input params is null\n");
+ return -EINVAL;
+ }
+
+ if (cmd >= VM_COMPAT_TEST) {
+ udma_pr_err(UDMA_M_DFX, "Not support this cmd type(%u)", cmd);
+ return -EINVAL;
+ }
+
+ if (!hinic5_support_ub(udma_dev->hwdev, NULL)) {
+ udma_pr_err(UDMA_M_DFX, "UDMA ioctl. Hw don't support UB\n");
+ return -EINVAL;
+ }
+
+ ret = udma_verify_dfx_version(udma_dev, cmd);
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_DFX, "UDMA dfx version verify failed.\n");
+ return ret;
+ }
+
+ func = g_udma_ioctl_funcs[cmd];
+ if (func == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Not support this cmd type(%u)", cmd);
+ return -EINVAL;
+ }
+
+ return func(udma_dev, buf_in, in_size, buf_out, out_size);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.h
new file mode 100644
index 000000000..6b9aa40bc
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx.h
@@ -0,0 +1,71 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_DFX_H
+#define UDMA_DFX_H
+
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+
+int udma_ioctl(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
+
+#define UDMA_MTT_MAX_ORDER 27
+
+#define UDMA_DFX_GET_RES_CNT(member, list_head, member_name, cnt) \
+ do { \
+ (cnt) = 0; \
+ list_for_each_entry(member, &(list_head), member_name) { \
+ (cnt)++; \
+ } \
+ } while (0)
+
+struct udma_dfx_res_dev_len {
+ void **addr;
+ u32 len;
+};
+
+struct udma_dfx_check_args {
+ u32 xid;
+ bool dfx_fw_version;
+ bool tpf;
+};
+
+typedef int (*udma_ioctl_func_t)(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size);
+
+typedef int (*udma_query_func_t)(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ union ub_query_outbuf *buf_out,
+ u32 source_type);
+
+typedef int (*udma_check_func_t)(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args);
+
+struct udma_dfx_query_cmd_cb {
+ u32 cmd_type;
+ u32 sub_type;
+ udma_check_func_t check_func;
+ udma_query_func_t cmd_func;
+};
+
+struct udma_dfx_query_cmd_func {
+ u32 cmd_type;
+ u32 sub_type;
+ u32 source_type;
+ udma_ioctl_func_t cmd_func;
+};
+
+int udma_dfx_query_prepare(struct udma_device *udma_dev, void *buf_out,
+ u32 *out_size);
+int udma_dfx_query_cmtt(struct udma_device *udev, struct mtt *ub_mtt,
+ union ub_query_outbuf *outbuf);
+int udma_dfx_check_xid(struct udma_device *udev, u32 type,
+ struct ub_query_inbuf *query_inbuf);
+int udma_query_npu_dfx_version(struct udma_device *udma_dev, int *npu_version);
+int udma_verify_dfx_version(struct udma_device *udma_dev, u32 cmd);
+int udma_dfx_obj_put(struct udma_device *udev, u32 type, void *obj, u32 xid);
+#endif //UDMA_DFX_H
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.c
new file mode 100644
index 000000000..ece91c09c
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.c
@@ -0,0 +1,831 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/highmem.h>
+
+#include "ub_pub_cmd.h"
+#include "ubcore_uapi.h"
+#include "ub_xqe_format.h"
+#include "udma_common.h"
+#include "udma_jetty.h"
+#include "udma_segment.h"
+#include "udma_cmd_com.h"
+#include "udma_base_sq.h"
+
+#include "udma_dfx_attack.h"
+
+u8 copy_data_by_mask(u8 inbyte, u8 mask, u8 byte)
+{
+ return (byte & ~mask) | (inbyte & mask);
+}
+
+static int copy_data_to_page(struct udma_device *udev, u8 *inbuf, u8 *mask,
+ struct ubcore_umem *umem, u32 copy_len, u32 offset,
+ bool use_mask)
+{
+ struct scatterlist *sg = NULL;
+ u8 *inbuf_tmp = inbuf;
+ u8 *mask_tmp = mask;
+ u32 page_copy_len = 0;
+ u32 copied_len = 0;
+ u32 page_offset = 0;
+ u64 buf_offset = 0;
+ void *va = NULL;
+ u32 i = 0;
+
+ udma_info(udev->dev, UDMA_M_DFX,
+ "copy_data_to_page va:%llx, length:%llu, offset:%u, \
+ copy_len:%u",
+ umem->va, umem->length, offset, copy_len);
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, i) {
+ if (buf_offset + PAGE_SIZE > offset) {
+ page_offset = offset - (u32)buf_offset;
+ buf_offset = offset;
+ va = sg_virt(sg);
+ if (va == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get va");
+ return -ENOMEM;
+ }
+
+ va += page_offset;
+ page_copy_len = ((copy_len - copied_len) <
+ (PAGE_SIZE - page_offset)) ?
+ (copy_len - copied_len) :
+ (PAGE_SIZE - page_offset);
+ udma_info(
+ udev->dev, UDMA_M_DFX,
+ "copy_data_from_page buf_offset:%llu, page_offset:%u, copied_len:%u, \
+ page_copy_len:%u, i:%u",
+ buf_offset, page_offset, copied_len,
+ page_copy_len, i);
+
+ if (use_mask) {
+ for (u32 j = 0; j < page_copy_len; j++) {
+ u8 inbyte = inbuf_tmp[j];
+ u8 maskbyte = mask_tmp[j];
+ u8 outbyte = ((u8 *)va)[j];
+ ((u8 *)va)[j] = copy_data_by_mask(
+ inbyte, maskbyte, outbyte);
+ }
+ mask_tmp += page_copy_len;
+ } else {
+ (void)memcpy_s(va, page_copy_len, inbuf_tmp,
+ page_copy_len);
+ }
+ inbuf_tmp += page_copy_len;
+ copied_len += page_copy_len;
+ if (copied_len >= copy_len) {
+ break;
+ }
+ } else {
+ buf_offset += PAGE_SIZE;
+ }
+ }
+ return 0;
+}
+
+static int udma_dfx_attack_db(struct udma_device *udma_dev, struct udma_db *sdb,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ union tag_ub_sq_db_u jetty_db;
+
+ jetty_db.sq_db_value = 0;
+ jetty_db.sq_db.dw0.value = inbuf->attack_value[0];
+ jetty_db.sq_db.dw1.value = inbuf->attack_value[1];
+ jetty_db.sq_db.dw0.bs.type = inbuf->srv_type;
+ jetty_db.sq_db.dw1.bs.pi = (inbuf->pi_ci >> UB_SQ_DB_SHIFT) & 0xFF;
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "type:%u, cos:%u, inbuf->pi:%u\n",
+ jetty_db.sq_db.dw0.bs.type, jetty_db.sq_db.dw0.bs.cos,
+ inbuf->pi_ci);
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "c:%u, n:%u, cntx_size:%u, xqn:%u\n", jetty_db.sq_db.dw0.bs.c,
+ jetty_db.sq_db.dw0.bs.n, jetty_db.sq_db.dw0.bs.cntx_size,
+ jetty_db.sq_db.dw0.bs.xqn);
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "queue_id:%u, rsvd0:%u, pi:%u jetty_db.sq_db_value:%llu\n",
+ jetty_db.sq_db.dw1.bs.queue_id, jetty_db.sq_db.dw1.bs.rsvd0,
+ jetty_db.sq_db.dw1.bs.pi, jetty_db.sq_db_value);
+
+ outbuf->db = jetty_db.sq_db_value;
+ if (sdb->db_record != NULL) {
+ *(sdb->db_record) = cpu_to_be32(inbuf->pi_ci);
+ }
+
+ wmb();
+ return cqm5_ring_hardware_db(udma_dev->hwdev, SERVICE_T_UB,
+ inbuf->pi_ci & 0xff, jetty_db.sq_db_value);
+}
+
+static int udma_dfx_attack_jetty_db(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jetty *ub_jetty = NULL;
+ int ret = 0;
+
+ ub_jetty = udma_find_jetty(udma_dev, inbuf->object);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jettyid(%u)\n",
+ inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_db(udma_dev, &ub_jetty->sdb, inbuf, outbuf);
+
+ udma_jetty_put(ub_jetty);
+ return ret;
+}
+
+static int udma_dfx_attack_jfs_db(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfs *ub_jfs = NULL;
+ int ret = 0;
+
+ ub_jfs = udma_find_jfs(udma_dev, inbuf->object);
+ if (ub_jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfs, jfsid(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_db(udma_dev, &ub_jfs->sdb, inbuf, outbuf);
+
+ udma_jfs_put(ub_jfs);
+ return ret;
+}
+
+static int udma_dfx_attack_jfr_db(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfr *ub_jfr = NULL;
+ int ret = 0;
+
+ ub_jfr = udma_find_jfr(udma_dev, inbuf->object);
+ if (ub_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfr, jfr id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_db(udma_dev, &ub_jfr->sdb, inbuf, outbuf);
+
+ udma_jfr_put(ub_jfr);
+ return ret;
+}
+
+static int udma_dfx_attack_wqe(struct udma_device *udma_dev,
+ struct ubcore_umem *umem,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf, bool use_mask)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ int ret = 0;
+
+ if (umem == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "umem is null\n");
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "length:%u, inbuf->offset:%u\n",
+ length, inbuf->offset);
+
+ ret = copy_data_to_page(udma_dev, (u8 *)inbuf->attack_value,
+ (u8 *)inbuf->attack_mask, umem, length,
+ inbuf->offset, use_mask);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to copy data to page, ret: %d\n", ret);
+ }
+
+ return ret;
+}
+
+int copy_data_for_mtt_pro_en(struct udma_device *udma_dev, u8 *inbuf, u8 *mask,
+ struct queue_addr_info *queue_addr, u32 len,
+ u32 offset, bool use_mask)
+{
+ void *va = queue_addr->va;
+
+ if ((offset >= queue_addr->size) ||
+ (offset + len >= queue_addr->size)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "invalid params, offset:%u, len:%u, queue size:%u",
+ offset, len, queue_addr->size);
+ return -EINVAL;
+ }
+
+ if (use_mask) {
+ u8 *dest = (u8 *)va + offset;
+ for (u32 i = 0; i < len; i++) {
+ dest[i] = copy_data_by_mask(inbuf[i], mask[i], dest[i]);
+ }
+ } else {
+ return memcpy_s((void *)((u8 *)va + offset), len, (void *)inbuf,
+ len);
+ }
+ return 0;
+}
+
+int copy_data_for_attack_tamsn(struct udma_device *udma_dev, u8 *inbuf,
+ struct ubrc *ub_rc, u32 len, u32 offset)
+{
+ void *va = ub_rc->vaddr;
+
+ if ((offset >= UB_ATTACK_TAMSN_MAX_LEN) ||
+ (offset + len >= UB_ATTACK_TAMSN_MAX_LEN)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "invalid params, offset:%u, len:%u, tamsn max size:%u",
+ offset, len, UB_ATTACK_TAMSN_MAX_LEN);
+ return -EINVAL;
+ }
+
+ return memcpy_s((void *)((u8 *)va + offset), len, (void *)inbuf, len);
+}
+
+static int udma_dfx_attack_jetty_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct udma_jetty *ub_jetty = NULL;
+ int ret = 0;
+
+ ub_jetty = udma_find_jetty(udma_dev, inbuf->object);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jetty id(%u)\n",
+ inbuf->object);
+ return -EINVAL;
+ }
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ ret = copy_data_for_mtt_pro_en(udma_dev,
+ (u8 *)inbuf->attack_value,
+ (u8 *)inbuf->attack_mask,
+ &ub_jetty->queue_addr, length,
+ inbuf->offset, true);
+ goto OUT;
+ }
+
+ ret = udma_dfx_attack_wqe(udma_dev, ub_jetty->umem, inbuf, outbuf,
+ true);
+OUT:
+ udma_jetty_put(ub_jetty);
+
+ return ret;
+}
+
+static int udma_dfx_attack_jfs_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct udma_jfs *ub_jfs = NULL;
+ int ret = 0;
+
+ ub_jfs = udma_find_jfs(udma_dev, inbuf->object);
+ if (ub_jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfs, jfs id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ ret = copy_data_for_mtt_pro_en(udma_dev,
+ (u8 *)inbuf->attack_value,
+ (u8 *)inbuf->attack_mask,
+ &ub_jfs->queue_addr, length,
+ inbuf->offset, true);
+ goto OUT;
+ }
+
+ ret = udma_dfx_attack_wqe(udma_dev, ub_jfs->umem, inbuf, outbuf, true);
+OUT:
+ udma_jfs_put(ub_jfs);
+
+ return ret;
+}
+
+static int udma_dfx_attack_jfr_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct udma_jfr *ub_jfr = NULL;
+ struct udma_srq *srq = NULL;
+ int ret = 0;
+
+ ub_jfr = udma_find_jfr(udma_dev, inbuf->object);
+ if (ub_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfr, jfr id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ srq = &ub_jfr->srq;
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ ret = copy_data_for_mtt_pro_en(udma_dev,
+ (u8 *)inbuf->attack_value,
+ (u8 *)inbuf->attack_mask,
+ &srq->queue_addr, length,
+ inbuf->offset, true);
+ goto OUT;
+ }
+
+ ret = udma_dfx_attack_wqe(udma_dev, ub_jfr->srq.umem, inbuf, outbuf,
+ true);
+OUT:
+ udma_jfr_put(ub_jfr);
+
+ return ret;
+}
+
+static int udma_dfx_attack_jfc_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct udma_jfc *ub_jfc = NULL;
+ int ret = 0;
+
+ ub_jfc = udma_find_jfc(udma_dev, inbuf->object);
+ if (ub_jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfc, jfc id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ ret = copy_data_for_mtt_pro_en(udma_dev,
+ (u8 *)inbuf->attack_value,
+ (u8 *)inbuf->attack_mask,
+ &ub_jfc->queue_addr, length,
+ inbuf->offset, true);
+ goto OUT;
+ }
+
+ ret = udma_dfx_attack_wqe(udma_dev, ub_jfc->umem, inbuf, outbuf, true);
+OUT:
+ udma_jfc_put(ub_jfc);
+
+ return ret;
+}
+
+static int udma_dfx_attack_jfr_index_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfr *ub_jfr = NULL;
+ int ret = 0;
+
+ ub_jfr = udma_find_jfr(udma_dev, inbuf->object);
+ if (ub_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfr, jfr id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_wqe(udma_dev, ub_jfr->index_queue.umem, inbuf,
+ outbuf, false);
+
+ udma_jfr_put(ub_jfr);
+
+ return ret;
+}
+
+static inline struct udma_rc_queue *
+cqmobj_to_ub_rc_queue(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *rcq_ctx = NULL;
+ rcq_ctx = container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_rc_queue *)rcq_ctx->priv;
+}
+
+static int udma_dfx_attack_jfrc_wqe(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_rc_queue *rcq = NULL;
+ u32 buf_size;
+ int ret = 0;
+
+ if (inbuf->object >= udma_dev->rc_queue_cnt) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to jfrc id(%u) over rc_queue_cnt(%d)\n",
+ inbuf->object, udma_dev->rc_queue_cnt);
+ return -EINVAL;
+ }
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ inbuf->object, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to get cqm object, jfrc id(%u)\n",
+ inbuf->object);
+ return -EINVAL;
+ }
+
+ rcq = cqmobj_to_ub_rc_queue(cqm_obj);
+ if (rcq == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfrc, jfrc id(%u)\n", inbuf->object);
+ ret = -EINVAL;
+ goto TO_UB_RC_QUEUE_ERR;
+ }
+
+ buf_size = rcq->rc_queue->q_room_buf_1.buf_size;
+ if ((inbuf->offset >= buf_size) ||
+ (inbuf->offset + length > buf_size)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "invalid params, offset:%u, len:%u, buf_size:%u",
+ inbuf->offset, length, buf_size);
+ ret = -EINVAL;
+ goto TO_UB_RC_QUEUE_ERR;
+ }
+
+ ret = memcpy_s(((u8 *)rcq->rc_queue->q_room_buf_1.direct.va) +
+ inbuf->offset,
+ length, inbuf->attack_value, length);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "memcpy_s err ret:%d\n",
+ ret);
+ }
+
+TO_UB_RC_QUEUE_ERR:
+ cqm5_object_put(cqm_obj);
+ return ret;
+}
+
+static int udma_dfx_attack_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct mtt *ub_mtt)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct hmm_comp_priv *comp_priv = NULL;
+ u64 *mtts = NULL;
+ u64 page_size;
+ int ret;
+
+ if (ub_mtt == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "ub_mtt is null\n");
+ return -EINVAL;
+ }
+
+ if (ub_mtt->mtt_vaddr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "mtt_vaddr is null, mtt_layers: %u\n",
+ ub_mtt->mtt_layers);
+ return -EINVAL;
+ }
+ page_size = 1L << ub_mtt->mtt_page_shift;
+
+ if ((length + inbuf->offset > page_size) ||
+ (inbuf->offset > page_size)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "out-of-bounds address, length:%u, offset:%u, pa:0x%llu\n",
+ length, inbuf->offset, page_size);
+ return -EINVAL;
+ }
+
+ comp_priv = get_hmm_comp_priv(udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "Comp_priv is null\n");
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "mtt_layers: %u\n",
+ ub_mtt->mtt_layers);
+
+ mtts = (u64 *)hmm_em_table_find(
+ &comp_priv->mtt_em_table,
+ ub_mtt->mtt_seg[ub_mtt->mtt_layers - 1]->offset, NULL);
+ if (mtts == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Can't find va and pa of mtt entry\n");
+ return -EINVAL;
+ }
+
+ ret = memcpy_s(((void *)mtts) + inbuf->offset, length,
+ inbuf->attack_value, length);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_DFX, "memcpy_s err ret:%d\n",
+ ret);
+
+ return ret;
+}
+
+static int udma_dfx_attack_jetty_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jetty *ub_jetty = NULL;
+ int ret = 0;
+
+ ub_jetty = udma_find_jetty(udma_dev, inbuf->object);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_mtt(udma_dev, inbuf, &ub_jetty->ub_mtt);
+
+ udma_jetty_put(ub_jetty);
+ return ret;
+}
+
+static int udma_dfx_attack_jfs_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfs *ub_jfs = NULL;
+ int ret = 0;
+
+ ub_jfs = udma_find_jfs(udma_dev, inbuf->object);
+ if (ub_jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfs, id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_mtt(udma_dev, inbuf, &ub_jfs->ub_mtt);
+
+ udma_jfs_put(ub_jfs);
+ return ret;
+}
+
+static int udma_dfx_attack_jfr_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfr *ub_jfr = NULL;
+ int ret = 0;
+
+ ub_jfr = udma_find_jfr(udma_dev, inbuf->object);
+ if (ub_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfr, id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_mtt(udma_dev, inbuf, &ub_jfr->srq.ub_mtt);
+
+ udma_jfr_put(ub_jfr);
+ return ret;
+}
+
+static int udma_dfx_attack_jfc_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfc *ub_jfc = NULL;
+ int ret = 0;
+
+ ub_jfc = udma_find_jfc(udma_dev, inbuf->object);
+ if (ub_jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfc, id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_attack_mtt(udma_dev, inbuf, &ub_jfc->ub_mtt);
+
+ udma_jfc_put(ub_jfc);
+ return ret;
+}
+
+static int udma_dfx_attack_segment_mtt(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_segment *ub_segment = NULL;
+ int ret = 0;
+
+ ub_segment = udma_seg_find(udma_dev, inbuf->object);
+ if (ub_segment == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_segment, id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+ ret = udma_dfx_attack_mtt(udma_dev, inbuf, &ub_segment->mtt);
+ udma_seg_put(ub_segment);
+ return ret;
+}
+
+static int udma_dfx_attack_jetty_pi(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jetty *ub_jetty = NULL;
+
+ ub_jetty = udma_find_jetty(udma_dev, inbuf->object);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jetty id(%u)\n",
+ inbuf->object);
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "inbuf->object:%u, inbuf->pi:%u\n",
+ inbuf->object, inbuf->pi_ci);
+
+ *((u32 *)ub_jetty->sdb.virt_addr) = cpu_to_be32(inbuf->pi_ci);
+
+ udma_jetty_put(ub_jetty);
+ return 0;
+}
+
+static int udma_dfx_attack_jfc_ci(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ struct udma_jfc *ub_jfc = NULL;
+
+ ub_jfc = udma_find_jfc(udma_dev, inbuf->object);
+ if (ub_jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jfc, jfc id(%u)\n", inbuf->object);
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "inbuf->object:%u, inbuf->ci:%u\n",
+ inbuf->object, inbuf->pi_ci);
+
+ *((u32 *)ub_jfc->db.virt_addr) =
+ cpu_to_be32(inbuf->pi_ci & UB_CQ_UPDATE_CI_MASK);
+
+ udma_jfc_put(ub_jfc);
+ return 0;
+}
+
+static int udma_dfx_attack_jetty_tamsn(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf)
+{
+ u32 length = (inbuf->length > UB_ATTACK_LEN) ? UB_ATTACK_LEN :
+ inbuf->length;
+ struct udma_jetty *ub_jetty = NULL;
+ int ret = 0;
+
+ ub_jetty = udma_find_jetty(udma_dev, inbuf->object);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Failed to get ub_jetty, jetty id(%u)\n",
+ inbuf->object);
+ return -EINVAL;
+ }
+
+ ret = copy_data_for_attack_tamsn(udma_dev, (u8 *)inbuf->attack_value,
+ &ub_jetty->ubrc, length,
+ inbuf->offset);
+
+ udma_jetty_put(ub_jetty);
+
+ return ret;
+}
+
+static struct udma_dfx_attack_cmd_func g_udma_attack_cmd_funcs[] = {
+ { UB_ATTACK_TYPE_DB, UB_ATTACK_SUB_TYPE_JETTY,
+ udma_dfx_attack_jetty_db },
+ { UB_ATTACK_TYPE_DB, UB_ATTACK_SUB_TYPE_JFS, udma_dfx_attack_jfs_db },
+ { UB_ATTACK_TYPE_DB, UB_ATTACK_SUB_TYPE_JFR,
+ udma_dfx_attack_jfr_db }, //ATTACK PCNT
+
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_JETTY,
+ udma_dfx_attack_jetty_wqe },
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_JFS, udma_dfx_attack_jfs_wqe },
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_JFR, udma_dfx_attack_jfr_wqe },
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_JFC, udma_dfx_attack_jfc_wqe },
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_JFRC,
+ udma_dfx_attack_jfrc_wqe },
+ { UB_ATTACK_TYPE_WQE, UB_ATTACK_SUB_TYPE_IDX_Q,
+ udma_dfx_attack_jfr_index_wqe },
+
+ { UB_ATTACK_TYPE_MTT, UB_ATTACK_SUB_TYPE_JETTY,
+ udma_dfx_attack_jetty_mtt },
+ { UB_ATTACK_TYPE_MTT, UB_ATTACK_SUB_TYPE_JFS, udma_dfx_attack_jfs_mtt },
+ { UB_ATTACK_TYPE_MTT, UB_ATTACK_SUB_TYPE_JFR, udma_dfx_attack_jfr_mtt },
+ { UB_ATTACK_TYPE_MTT, UB_ATTACK_SUB_TYPE_JFC, udma_dfx_attack_jfc_mtt },
+ { UB_ATTACK_TYPE_MTT, UB_ATTACK_SUB_TYPE_SEG,
+ udma_dfx_attack_segment_mtt },
+
+ { UB_ATTACK_TYPE_PICI, UB_ATTACK_SUB_TYPE_JETTY,
+ udma_dfx_attack_jetty_pi },
+ { UB_ATTACK_TYPE_PICI, UB_ATTACK_SUB_TYPE_JFC, udma_dfx_attack_jfc_ci },
+
+ { UB_ATTACK_TYPE_TAMSN, UB_ATTACK_SUB_TYPE_JETTY,
+ udma_dfx_attack_jetty_tamsn },
+};
+
+static inline int udma_dfx_attack_inbuf_outbuf_check_and_clear(
+ struct udma_device *udma_dev, void *buf_out, u32 in_size, u32 *out_size)
+{
+ int ret = 0;
+
+ if (in_size < (u32)sizeof(struct ub_attack_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx attack buffer in size too small\n");
+ return -EINVAL;
+ }
+
+ if (*out_size < (u32)sizeof(struct ub_attack_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx attack buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ ret = memset_s(buf_out, *out_size, 0,
+ (u32)sizeof(struct ub_attack_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx attack out buf memset error ret:%d\n", ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_dfx_attack_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_attack_inbuf *inbuf = (struct ub_attack_inbuf *)buf_in;
+ struct ub_attack_outbuf *outbuf = (struct ub_attack_outbuf *)buf_out;
+ udma_adm_dfx_attack_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ /* check in and out buf size */
+ if (udma_dfx_attack_inbuf_outbuf_check_and_clear(
+ udma_dev, buf_out, in_size, out_size) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx attack buf check or clear failed.\n");
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "inbuf->object:%u, inbuf->convert_endian:%u\n", inbuf->object,
+ inbuf->convert_endian);
+
+ if (inbuf->convert_endian != 0) {
+ udma_cpu_to_be32((void *)inbuf->attack_value,
+ sizeof(inbuf->attack_value));
+ udma_cpu_to_be32((void *)inbuf->attack_mask,
+ sizeof(inbuf->attack_mask));
+ }
+
+ udma_dump_dfx(udma_dev, (u64)(uintptr_t)inbuf->attack_value,
+ sizeof(inbuf->attack_value),
+ (u64)(uintptr_t)inbuf->attack_value,
+ sizeof(inbuf->attack_value));
+ udma_dump_dfx(udma_dev, (u64)(uintptr_t)inbuf->attack_mask,
+ sizeof(inbuf->attack_mask),
+ (u64)(uintptr_t)inbuf->attack_mask,
+ sizeof(inbuf->attack_mask));
+
+ for (i = 0; i < sizeof(g_udma_attack_cmd_funcs) /
+ sizeof(g_udma_attack_cmd_funcs[0]);
+ i++) {
+ cmd_type = ub_dfx_get_cmd_type(
+ g_udma_attack_cmd_funcs[i].cmd_type,
+ g_udma_attack_cmd_funcs[i].sub_type, 0);
+ if (cmd_type ==
+ (inbuf->cmd_type & UB_DFX_QUERY_SOURCE_TYPE_SHIELD_MASK)) {
+ func = g_udma_attack_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "function of attack cmd(0x%x) is not supported\n",
+ cmd_type);
+ return -EINVAL;
+ }
+
+ *out_size = (u32)sizeof(struct ub_attack_outbuf);
+
+ return func(udma_dev, inbuf, outbuf);
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_DFX, "attack cmd(0x%x) is not exist\n",
+ cmd_type);
+
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.h
new file mode 100644
index 000000000..58e7c6694
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_attack.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_ATTACK_H
+#define UDMA_DFX_ATTACK_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+typedef int (*udma_adm_dfx_attack_func_t)(struct udma_device *udma_dev,
+ const struct ub_attack_inbuf *inbuf,
+ struct ub_attack_outbuf *outbuf);
+struct udma_dfx_attack_cmd_func {
+ u32 cmd_type;
+ u32 sub_type;
+ udma_adm_dfx_attack_func_t cmd_func;
+};
+
+int udma_dfx_attack_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* UDMA_DFX_ATTACK_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.c
new file mode 100644
index 000000000..fb51f3522
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+#include <linux/etherdevice.h>
+#include <linux/if_packet.h>
+#include <linux/skbuff.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "ub_mpu_cmd.h"
+#include "udma_dfx.h"
+#include "udma_dfx_drop.h"
+#include "udma_dfx_cc_inject.h"
+#include "udma_dfx_capture.h"
+
+/*
+ * capture packet configured SML table specification is 256 * 16B
+ * 0~254 index of table entry is pa address information, for microcode write capture take to of packet count data, driver can read, by struct udma_dfx_cap_tbl indicates
+ * 255 index of table entry is configuration information, by struct udma_dfx_cap_cfg_tbl indicates
+ */
+#define CAP_CFG_ENTRY_INDEX 255 // configuration item in SML table in of index
+#define CAP_PA_TBL_ENTRY_NUM 255 // a PA address table table entry count
+#define CAP_BLOCK_SIZE 256 // a block of size (Byte)
+
+#define CAP_ADDR_COMBIN_SHIFT 32
+
+#define CLEAR_CAP_TRYING_TIMES 10
+#define CLEAR_SLEEP_TIME 2
+#define CAP_STOP_SLEEP_TIME 50
+
+static DEFINE_MUTEX(cap_mutex);
+
+/*
+ * structure as use: intomember num/2 indicates a pa address corresponding to space of block count
+ * block used to store place capture take to of packet, is fixed size, each block size by macro CAP_BLOCK_SIZE specifies
+ * a pa address corresponding space size = block count * each block of size
+ * a pa address table one total has CAP_PA_TBL_ENTRY_NUM (count word) pa, total has block count is CAP_PA_TBL_ENTRY_NUM * a pa corresponding to block count
+ * total has two pa address table, respectively is que_addr[0][1][] and que_addr[1][1][]
+ */
+static struct udma_cap_block_num_attr g_nattr[8] = {
+ { .block_num_idx = 0, .shift = 4, .num = 16 },
+ { .block_num_idx = 1, .shift = 5, .num = 32 },
+ { .block_num_idx = 2, .shift = 6, .num = 64 },
+ { .block_num_idx = 3, .shift = 7, .num = 128 },
+ { .block_num_idx = 4, .shift = 8, .num = 256 },
+ { .block_num_idx = 5, .shift = 9, .num = 512 },
+ { .block_num_idx = 6, .shift = 10, .num = 1024 },
+ { .block_num_idx = 7, .shift = 11, .num = 2048 },
+};
+
+struct udma_pkt_cap_info g_udma_cap_info = {
+ .cap_status = UDMA_CAPTURE_STOP,
+ .cap_mode = 1,
+ .poll_ci = 0,
+ .udma_dev = NULL,
+ .func_id = 0,
+ /* Configurable, currently using 4, when modifying, the size of cfg bl needs to be modified synchronously */
+ .block_num_idx = 4,
+ .mode = 0,
+ .qp_list_cnt = 0,
+ .qp_list_head = LIST_HEAD_INIT(g_udma_cap_info.qp_list_head),
+};
+
+static int udma_clear_cap_counter(struct udma_device *udma_dev, u32 *value)
+{
+ struct ub_dfx_cap_ctr_cmd clear_cap_counter = { 0 };
+ u16 out_size = (u16)sizeof(clear_cap_counter);
+ int ret;
+
+ clear_cap_counter.index = 0; // UB_DP_DFX_FLOW_CAP_NUM_CNT th 0(count word) counter
+
+ ret = hinic5_msg_to_mgmt_sync(
+ udma_dev->hwdev, HINIC5_MOD_UB, UB_MPU_CMD_DFX_CLEAR_CAP_CTR,
+ &clear_cap_counter, sizeof(clear_cap_counter),
+ &clear_cap_counter, &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || clear_cap_counter.head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "clear cap counter failed, ret:%d, status:0x%x, out size:0x%x\n",
+ ret, clear_cap_counter.head.status, out_size);
+ return -EINVAL;
+ }
+
+ *value = clear_cap_counter.value;
+
+ udma_info(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "clear success, counter before clear:%u\n",
+ clear_cap_counter.value);
+
+ return 0;
+}
+
+static void udma_stop_thread(struct sdk_thread_info *thread_info)
+{
+ if (thread_info->thread_obj) {
+ (void)kthread_stop(thread_info->thread_obj);
+ thread_info->thread_obj = NULL;
+ }
+}
+
+static int udma_set_cap_func_disable(struct udma_device *udma_dev)
+{
+ u16 glb_func_id = hinic5_global_func_id(udma_dev->hwdev);
+ int ret;
+
+ ret = hinic5_set_func_capture_en(udma_dev->hwdev, glb_func_id, 0);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "set capture disable failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_dfx_dma_free_addr(struct udma_device *udma_dev, int cap_index,
+ int que_index)
+{
+ u64 v_addr;
+ u64 p_addr;
+
+ v_addr = g_udma_cap_info.que_addr[que_index][0][cap_index];
+ p_addr = g_udma_cap_info.que_addr[que_index][1][cap_index];
+ dma_free_coherent(
+ udma_dev->dev,
+ (unsigned long)(CAP_BLOCK_SIZE *
+ ((g_nattr[g_udma_cap_info.block_num_idx].num) >>
+ 1)),
+ (void *)(uintptr_t)v_addr, (dma_addr_t)p_addr);
+ /* resource free after address clear 0 */
+ g_udma_cap_info.que_addr[que_index][0][cap_index] = 0;
+ g_udma_cap_info.que_addr[que_index][1][cap_index] = 0;
+}
+
+static void udma_dfx_free_mem_for_one_cap(struct udma_device *udma_dev,
+ int cap_index)
+{
+ udma_dfx_dma_free_addr(udma_dev, cap_index, 1);
+ udma_dfx_dma_free_addr(udma_dev, cap_index, 0);
+}
+
+static void udma_dfx_free_cap(struct udma_device *udma_dev)
+{
+ int i;
+
+ for (i = 0; i < CAP_PA_TBL_ENTRY_NUM; i++)
+ udma_dfx_free_mem_for_one_cap(udma_dev, i);
+}
+
+static int udma_clear_cap_counter_encap(struct udma_device *udma_dev)
+{
+ u32 counter = 0;
+ u32 times;
+ int ret;
+
+ for (times = 0; times < CLEAR_CAP_TRYING_TIMES; times++) {
+ if (times == CLEAR_CAP_TRYING_TIMES - 1) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "clear pi failed\n");
+ return -EFAULT;
+ }
+
+ ret = udma_clear_cap_counter(udma_dev, &counter);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "clear cap counter failed, ret:%d\n", ret);
+ return -EFAULT;
+ }
+
+ if (counter == 0)
+ break;
+
+ msleep(CLEAR_SLEEP_TIME);
+ }
+
+ return 0;
+}
+
+int udma_dfx_stop_cap_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ u32 glb_func_id = hinic5_global_func_id(udma_dev->hwdev);
+ int ret = 0;
+
+ udma_info(udma_dev->dev, UDMA_M_CAPTURE_DFX, "start to stop cap\n");
+
+ mutex_lock(&cap_mutex);
+ if (g_udma_cap_info.cap_status != UDMA_CAPTURE_START) { // 1:RUNNING
+ mutex_unlock(&cap_mutex);
+ udma_warn(
+ udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "%s: capture is not running, cap_status(%u), ret(%d)\n",
+ __func__, g_udma_cap_info.cap_status, ret);
+ return 0;
+ }
+
+ if (g_udma_cap_info.func_id != glb_func_id) {
+ mutex_unlock(&cap_mutex);
+ udma_warn(
+ udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "%s: func_id not match, capture func_id(%u), glb_func_id(%u)\n",
+ __func__, g_udma_cap_info.func_id, glb_func_id);
+ return 0;
+ }
+
+ udma_stop_thread(&(g_udma_cap_info.task));
+
+ /* stop cap */
+ ret = udma_set_cap_func_disable(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "set cap enable failed, ret:%d\n", ret);
+ ret = -EFAULT;
+ goto err;
+ }
+
+ msleep(CAP_STOP_SLEEP_TIME);
+
+ /* release lt mem resource */
+ udma_dfx_free_cap(udma_dev);
+ /* lt index_1 */
+ ret = udma_clear_cap_counter_encap(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "clear cap counter failed, ret:%d\n", ret);
+ goto err;
+ }
+
+ g_udma_cap_info.cap_status = UDMA_CAPTURE_STOP;
+ g_udma_cap_info.poll_ci = 0;
+ g_udma_cap_info.func_id = 0;
+ g_udma_cap_info.udma_dev = NULL;
+
+ udma_info(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "stop cap success, func_id:%u\n", glb_func_id);
+
+err:
+ udma_dev->capture_en = false;
+ mutex_unlock(&cap_mutex);
+ return ret;
+}
+
+static struct udma_dfx_packet_cmd_func g_udma_packet_cmd_funcs[] = {
+ /* packet drop */
+ { UB_CMD_START_DROP_CARD_PACKET, udma_dfx_start_card_drop_pkt },
+ { UB_CMD_STOP_DROP_CARD_PACKET, udma_dfx_stop_card_drop_pkt },
+ { UB_CMD_START_DROP_FUNC_PACKET, udma_dfx_start_func_drop_pkt },
+ { UB_CMD_STOP_DROP_FUNC_PACKET, udma_dfx_stop_func_drop_pkt },
+ { UB_CMD_START_DROP_TP_PACKET, udma_dfx_start_tp_drop_pkt },
+ { UB_CMD_STOP_DROP_TP_PACKET, udma_dfx_stop_tp_drop_pkt },
+ /* cc inject */
+ { UB_CMD_CC_INJECT, udma_dfx_cc_inject },
+};
+
+int udma_dfx_packet_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_packet_inbuf *inbuf = (struct ub_packet_inbuf *)buf_in;
+ union ub_packet_outbuf *outbuf = (union ub_packet_outbuf *)buf_out;
+ udma_adm_dfx_packet_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ /* check in and out buf size */
+ if (in_size < (u32)sizeof(struct ub_packet_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "udma dfx packet buffer in size too small\n");
+ return -EINVAL;
+ }
+ if (*out_size < (u32)sizeof(union ub_packet_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "udma dfx packet buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+ for (i = 0; i < sizeof(g_udma_packet_cmd_funcs) /
+ sizeof(g_udma_packet_cmd_funcs[0]);
+ i++) {
+ cmd_type = g_udma_packet_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->cmd_type) {
+ func = g_udma_packet_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "error: function of cmd:0x%x is not supported\n",
+ cmd_type);
+ return -EINVAL;
+ }
+
+ *out_size = sizeof(union ub_packet_outbuf);
+
+ return func(udma_dev, inbuf, outbuf);
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_CAPTURE_DFX,
+ "error: cmd:0x%x is not exist\n", inbuf->cmd_type);
+
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.h
new file mode 100644
index 000000000..106c299c8
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_capture.h
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_CAPTURE_H
+#define UDMA_DFX_CAPTURE_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+/* hardware side packet control header (non- transport packet actualbody data) */
+typedef union udma_cap_hdr {
+ struct {
+ u32 rsvd : 16;
+ u32 pad : 8; // rx direction pad value is 0, tx direction pad value is 2(macro ETH_TX_PKT_PADDING_LEN specifies)
+ u32 rsvd0 : 2;
+ u32 col_num : 4;
+ u32 tx_rx : 1;
+ u32 vld : 1;
+ } cap_ctrl_info;
+ u32 value;
+} udma_cap_hdr_u;
+
+typedef struct udma_dfx_cap_pa_entry {
+ u32 wr_init_pc_h32;
+ u32 wr_init_pc_l32;
+} udma_dfx_cap_pa_entry_s;
+
+typedef struct udma_dfx_cap_tbl {
+ udma_dfx_cap_pa_entry_s pa[2];
+} udma_dfx_cap_tbl_s;
+
+typedef struct udma_dfx_cap_cfg_tbl {
+ u32 ci_index;
+
+ union {
+ struct {
+ /* Driver configurate bit offset by the number of per pa block, for example, 7 means 128, 8 means 256 */
+ u8 cap_block_num_shift;
+ u8 cap_mode; /* Packet Capture mode */
+ u8 qp_mode; /* according to qp Packet Capture */
+ u8 rsvd; /* reserved */
+ } bs;
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+ u32 state : 8; /* Packet Capture rate control */
+ u32 rsvd : 8;
+ u32 cap_func : 16; /* Packet Capture function */
+ } bs;
+ u32 value;
+ } dw2;
+
+ u32 maxnum;
+} udma_dfx_cap_cfg_tbl_s;
+
+struct udma_cap_block_num_attr {
+ u32 block_num_idx;
+ u32 shift;
+ u32 num;
+};
+
+struct sdk_thread_info {
+ struct task_struct *thread_obj;
+ char *name;
+ void (*thread_fn)(void *);
+ void *thread_event;
+ void *data;
+};
+
+struct udma_pkt_cap_info {
+ struct udma_device *udma_dev;
+ u32 func_id;
+ u32 poll_ci; /* driver push to protocol stack of packet of total count */
+ u32 cap_mode; /* 0 : drop mode 1: overwrite mode */
+ u32 mode; /* 0 : func mode 1: qp mode */
+ u32 cap_status; /* 0 : stopped 1: running */
+ u32 block_num_idx;
+ u32 block_num_per_entry;
+ u32 maxnum;
+ struct sdk_thread_info task;
+ char thread_name[20];
+ u64 que_addr[2][2][256];
+ struct list_head
+ qp_list_head; /* Based on qp Packet Capture linked list */
+ u32 qp_list_cnt;
+};
+
+enum udma_dfx_capture_state {
+ UDMA_CAPTURE_START = 0,
+ UDMA_CAPTURE_STOP,
+};
+
+typedef int (*udma_adm_dfx_packet_func_t)(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+
+struct udma_dfx_packet_cmd_func {
+ u32 cmd_id;
+ udma_adm_dfx_packet_func_t cmd_func;
+};
+
+extern int hinic5_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en);
+
+int udma_dfx_packet_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int udma_dfx_stop_cap_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+
+#endif /* UDMA_DFX_CAPTURE_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.c
new file mode 100644
index 000000000..79c77d3a9
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.c
@@ -0,0 +1,40 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include "hinic5_hw.h"
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "udma_dfx.h"
+#include "udma_cmd_tp.h"
+
+int udma_dfx_cc_inject(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ struct tag_ub_cc_attr cc_attr = { 0 };
+ struct tag_cqm_object *cqm_obj = NULL;
+
+ /* make sure that the tpn is valid */
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ inbuf->tpn, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_CC_INJECT_DFX,
+ "get cqm object failed, tpn(0x%x)\n", inbuf->tpn);
+ return -EINVAL;
+ }
+ cqm5_object_put(cqm_obj);
+
+ cc_attr.tpn = inbuf->tpn;
+ cc_attr.cc_inject_mode = inbuf->cc_inject_mode;
+ cc_attr.cc_percent = inbuf->cc_percent;
+ cc_attr.cc_limit_low = inbuf->cc_limit_low;
+ cc_attr.cc_limit_high = inbuf->cc_limit_high;
+ return udma_cmd_tp_cc_modify(udma_dev, &cc_attr);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.h
new file mode 100644
index 000000000..ebe05bbf2
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cc_inject.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_CC_INJECT_H
+#define UDMA_DFX_CC_INJECT_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+typedef struct tag_ub_cc_attr {
+ u32 tpn;
+ u32 cc_inject_mode;
+ u32 cc_percent;
+ u32 cc_limit_low;
+ u32 cc_limit_high;
+} ub_cc_attr_s;
+
+int udma_dfx_cc_inject(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+
+#endif /* UDMA_DFX_CC_INJECT_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.c
new file mode 100644
index 000000000..9daba8765
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "ub_pub_cmd.h"
+#include "udma_dfx.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_srq.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_jfc.h"
+#include "udma_cmd_segment.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_jfrc.h"
+#include "udma_cmd_vtp.h"
+#include "udma_cmd_tpg.h"
+#include "udma_cmd_sip.h"
+#include "udma_dfx_cqm_modify.h"
+
+#define INVALID_VALUE ((u32)~0u)
+#define INVALID_XID INVALID_VALUE
+#define INVALID_OFFSET INVALID_VALUE
+#define INVALID_LENGTH INVALID_VALUE
+#define INVALID_VF_ID INVALID_VALUE
+#define MAX_LENGTH (INVALID_VALUE >> 1)
+
+static int udma_dfx_cqm_modify_sip_tbl(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_sip_modify(udma_dev, inbuf->xid, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "[INFO] %s: ret(%d), sip_idx(%u), offset(%u), length(%u)\n",
+ __func__, ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int
+udma_dfx_cqm_jfrc_modify_pcqc(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_jfrc_modify_pcqc(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), jfrc_id(%u), offset(%u), length(%u)\n",
+ __func__, ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int
+udma_dfx_cqm_modify_jetty_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_jetty_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), jetty_id(%u), offset(%u), length(%u)\n",
+ __func__, ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int udma_dfx_cqm_modify_tp_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_tp_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), tpn(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int
+udma_dfx_cqm_modify_jfr_srq_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_srq_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), srqn(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int udma_dfx_cqm_modify_jfc_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_jfc_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), jfc_id(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int
+udma_dfx_cqm_modify_seg_mpt_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_seg_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), seg_id(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int udma_dfx_cqm_modify_vtp_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_vtp_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), vtp_id(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int udma_dfx_cqm_modify_tpg_ctx(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+
+ ret = udma_cmd_tpg_batch_modify_ctx(udma_dev, inbuf);
+
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: ret(%d), tpg_id(%u), offset(%u), length(%u)\n", __func__,
+ ret, inbuf->xid, inbuf->offset, inbuf->length);
+
+ return ret;
+}
+
+static int
+udma_dfx_cqm_modify_clear_latch_lock(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf)
+{
+ int ret;
+ ret = udma_cmd_jetty_clear_dfx_lock_ctx(udma_dev, inbuf->xid);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: clear latch lock failed, ret(%d)\n", __func__,
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_cqm_modify_latch_check(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ // TODO: later enable send requirement when add XID validity intercept
+ if (inbuf->xid == INVALID_XID) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify xid not set\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int udma_dfx_cqm_modify_check(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ if (inbuf->xid == INVALID_XID) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify xid not set\n", __func__);
+ return -EINVAL;
+ }
+
+ if (inbuf->offset == INVALID_OFFSET) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify offset not set\n", __func__);
+ return -EINVAL;
+ }
+
+ if (inbuf->length == INVALID_LENGTH) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify length not set\n", __func__);
+ return -EINVAL;
+ }
+
+ if (inbuf->is_data_set == false) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify data not set\n", __func__);
+ return -EINVAL;
+ }
+
+ /* length is byte is unit, user input of data array of a intomember is 4bit, length:data_len = 1:2 */
+ if ((inbuf->length > MAX_LENGTH) ||
+ (inbuf->length * 2 != inbuf->data_len)) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: length(%u) not match data_len(%u)\n", __func__,
+ inbuf->length, inbuf->data_len);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_cqm_modify_vtp_check(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *inbuf)
+{
+ int ret = 0;
+
+ ret = udma_dfx_cqm_modify_check(udma_dev, inbuf);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* driver only check whether passed in, not check valid validity */
+ if (inbuf->vf_id == INVALID_VF_ID) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cqm modify vf_id not set\n", __func__);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct udma_dfx_cqm_modify_cmd_func g_udma_cqm_modify_cmd_funcs[] = {
+ { UB_CQM_MODIFY_TYPE_JETTY_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jetty_ctx },
+ { UB_CQM_MODIFY_TYPE_TP_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_tp_ctx },
+ { UB_CQM_MODIFY_TYPE_JFR_SRQ_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jfr_srq_ctx },
+ { UB_CQM_MODIFY_TYPE_JFC_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jfc_ctx },
+ { UB_CQM_MODIFY_TYPE_SEG_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_seg_mpt_ctx },
+ { UB_CQM_MODIFY_TYPE_JFS_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jetty_ctx }, // reuse jetty code
+ { UB_CQM_MODIFY_TYPE_JFR_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jetty_ctx }, // reuse jetty code
+ { UB_CQM_MODIFY_TYPE_JFRC_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_jetty_ctx }, // reuse jetty code
+ { UB_CQM_MODIFY_TYPE_VTP_CTX, udma_dfx_cqm_modify_vtp_check,
+ udma_dfx_cqm_modify_vtp_ctx },
+ { UB_CQM_MODIFY_TYPE_TPG_CTX, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_tpg_ctx },
+ { UB_CQM_MODIFY_TYPE_CLEAR_LATCH_LOCK, udma_dfx_cqm_modify_latch_check,
+ udma_dfx_cqm_modify_clear_latch_lock },
+ { UB_CQM_MODIFY_TYPE_JFRC_PCQC, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_jfrc_modify_pcqc },
+ { UB_CQM_MODIFY_TYPE_SIP_TBL, udma_dfx_cqm_modify_check,
+ udma_dfx_cqm_modify_sip_tbl },
+};
+
+static inline int
+udma_dfx_cqm_modify_check_func(struct udma_device *udma_dev,
+ const struct ub_cqm_modify_inbuf *buf_in,
+ udma_adm_dfx_cqm_check_func_t check_func)
+{
+ if (check_func == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "Cmd(%u) do not need validity-check.\n",
+ buf_in->cmd_type);
+ return 0;
+ }
+
+ if (check_func(udma_dev, buf_in) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "Check func not null and check failed.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_dfx_cqm_modify_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_cqm_modify_inbuf *inbuf =
+ (struct ub_cqm_modify_inbuf *)buf_in;
+ union ub_cqm_modify_outbuf *outbuf =
+ (union ub_cqm_modify_outbuf *)buf_out;
+ udma_adm_dfx_cqm_modify_func_t cmd_func = NULL;
+ udma_adm_dfx_cqm_check_func_t check_func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ /* check in and out buf size */
+ if (in_size < (u32)sizeof(struct ub_cqm_modify_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "udma dfx cqm modify buffer in size too small\n");
+ return -EINVAL;
+ }
+ if (*out_size < (u32)sizeof(union ub_cqm_modify_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "udma dfx cqm modify buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+ for (i = 0; i < ARRAY_SIZE(g_udma_cqm_modify_cmd_funcs); i++) {
+ cmd_type = g_udma_cqm_modify_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->cmd_type) {
+ cmd_func = g_udma_cqm_modify_cmd_funcs[i].cmd_func;
+ check_func = g_udma_cqm_modify_cmd_funcs[i].check_func;
+ if (cmd_func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: function of cmd(0x%x) is not supported\n",
+ __func__, cmd_type);
+ return -EINVAL;
+ }
+
+ if (udma_dfx_cqm_modify_check_func(udma_dev, inbuf,
+ check_func) != 0) {
+ return -EINVAL;
+ }
+ *out_size = sizeof(union ub_cqm_modify_outbuf);
+
+ return cmd_func(udma_dev, inbuf, outbuf);
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: cmd(0x%x) is not exist\n", __func__, cmd_type);
+
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.h
new file mode 100644
index 000000000..ef2d6955f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_cqm_modify.h
@@ -0,0 +1,28 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_CQM_MODIFY_H
+#define UDMA_DFX_CQM_MODIFY_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+typedef int (*udma_adm_dfx_cqm_modify_func_t)(
+ struct udma_device *udma_dev, const struct ub_cqm_modify_inbuf *inbuf,
+ union ub_cqm_modify_outbuf *outbuf);
+
+typedef int (*udma_adm_dfx_cqm_check_func_t)(
+ struct udma_device *udma_dev, const struct ub_cqm_modify_inbuf *inbuf);
+
+struct udma_dfx_cqm_modify_cmd_func {
+ u32 cmd_id;
+ udma_adm_dfx_cqm_check_func_t check_func;
+ udma_adm_dfx_cqm_modify_func_t cmd_func;
+};
+
+int udma_dfx_cqm_modify_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* UDMA_DFX_CQM_MODIFY_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.c
new file mode 100644
index 000000000..90b363ed8
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "ub_pub_cmd.h"
+#include "ub_mpu_cmd.h"
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "udma_tp.h"
+#include "udma_dfx.h"
+#include "udma_cmd_tp.h"
+#include "udma_dfx_drop.h"
+
+#define DROP_MODE_SHIFT 3 // packet drop mode occupy the 4, 5 two bit
+#define DROP_1823v200_MAX_MODE 3 // packet drop supported maximum mode
+
+static void fill_dfx_l2d_set_param(struct udma_device *udma_dev,
+ ub_l2d_mem_cfg_s *cmd_in,
+ const struct udma_l2d_tbl_dfx *l2d_tbl_dfx)
+{
+ cmd_in->func_id = hinic5_global_func_id(udma_dev->hwdev);
+ cmd_in->tbl_mod = UB_L2D_TBL_MOD_DFX;
+ cmd_in->op_type = UB_L2D_TBL_OP_SET;
+ cmd_in->tile_id = UB_L2D_DFX_TILE_ID_TILE_ALL;
+
+ memcpy_s(&cmd_in->l2d_tbl.dfx_tbl.attr, sizeof(l2d_ub_dfx_tbl_attr_s),
+ &l2d_tbl_dfx->attr, sizeof(l2d_ub_dfx_tbl_attr_s));
+ memcpy_s(&cmd_in->l2d_tbl.dfx_tbl.mask, sizeof(l2d_ub_dfx_tbl_mask_s),
+ &l2d_tbl_dfx->mask, sizeof(l2d_ub_dfx_tbl_mask_s));
+}
+
+int udma_dfx_set_l2d_tbl_filter_param(struct udma_device *udma_dev,
+ const struct udma_l2d_tbl_dfx *l2d_tbl_dfx,
+ bool set_drop_level)
+{
+ ub_l2d_mem_cfg_cmd_s cmd_in = { 0 };
+ ub_l2d_mem_cmd_rsp_s cmd_out = { 0 };
+ u16 outsize = (u16)sizeof(ub_l2d_mem_cmd_rsp_s);
+ int ret = 0;
+
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ return ret;
+ }
+
+ fill_dfx_l2d_set_param(udma_dev, &cmd_in.cfg, l2d_tbl_dfx);
+ cmd_in.cfg.l2d_tbl.dfx_tbl.mask.dw0.bs.drop_pkt_ratio &=
+ (u8)set_drop_level;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_CFG_L2D_TBL, &cmd_in,
+ sizeof(ub_l2d_mem_cfg_cmd_s), &cmd_out,
+ &outsize, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || outsize == 0 || cmd_out.msg_head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "set drop l2dmem failed, err(%d), status(0x%x), out size(0x%x)\n",
+ ret, cmd_out.msg_head.status, outsize);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "set drop l2dmem success.\n");
+
+ return 0;
+}
+
+static int udma_set_func_drop_level(struct udma_device *udma_dev, u16 func_id,
+ u32 drop_level)
+{
+ struct ub_dfx_drop_cmd drop_cmd = { { 0 } };
+ u16 out_size = sizeof(drop_cmd);
+ int ret;
+
+ drop_cmd.drop_level = drop_level;
+ drop_cmd.func_port = func_id;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_SET_DROP, &drop_cmd,
+ sizeof(drop_cmd), &drop_cmd, &out_size, 0,
+ HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || drop_cmd.head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DROP_DFX,
+ "%s: set func drop failed, ret(%d), status(0x%x), out size(0x%x)\n",
+ __func__, ret, drop_cmd.head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_set_func_drop_level(struct udma_device *udma_dev,
+ u32 drop_level)
+{
+ u16 glb_func_id = hinic5_global_func_id(udma_dev->hwdev);
+ int ret;
+
+ ret = udma_set_func_drop_level(udma_dev, glb_func_id, drop_level);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "%s: set drop level(%u) failed, ret(%d)\n", __func__,
+ drop_level, ret);
+ return ret;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DROP_DFX,
+ "%s: success, drop_level(%u), func_id(%u)\n", __func__,
+ drop_level, glb_func_id);
+
+ return 0;
+}
+
+static int udma_dfx_get_drop_pkt_ratio(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ u32 *drop_pkt_ratio)
+{
+ *drop_pkt_ratio = inbuf->data.attr.dw15.bs.drop_pkt_ratio;
+
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ return 0;
+ }
+
+ if (inbuf->data.attr.dw15.bs.drop_pkt_type > DROP_1823v200_MAX_MODE) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "%s: drop_mode(%u) exceeds the drop_max_mode(%u)\n\n",
+ __func__, inbuf->data.attr.dw15.bs.drop_pkt_type,
+ DROP_1823v200_MAX_MODE);
+ return -EINVAL;
+ }
+
+ *drop_pkt_ratio =
+ *drop_pkt_ratio +
+ (inbuf->data.attr.dw15.bs.drop_pkt_type << DROP_MODE_SHIFT);
+
+ return 0;
+}
+
+int udma_dfx_start_card_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ return udma_dfx_set_l2d_tbl_filter_param(udma_dev, &inbuf->data, true);
+}
+
+int udma_dfx_stop_card_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ struct udma_l2d_tbl_dfx data = { 0 };
+
+ data.mask.dw0.value = U32_MAX;
+
+ return udma_dfx_set_l2d_tbl_filter_param(udma_dev, &data, true);
+}
+
+int udma_dfx_start_func_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ int ret = 0;
+
+ ret = udma_dfx_set_l2d_tbl_filter_param(udma_dev, &inbuf->data, false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return udma_dfx_set_func_drop_level(
+ udma_dev, inbuf->data.attr.dw15.bs.drop_pkt_ratio);
+}
+
+int udma_dfx_stop_func_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ struct udma_l2d_tbl_dfx data = { 0 };
+ int ret = 0;
+
+ data.mask.dw0.value = U32_MAX;
+ ret = udma_dfx_set_l2d_tbl_filter_param(udma_dev, &data, false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return udma_dfx_set_func_drop_level(udma_dev, 0);
+}
+
+int udma_dfx_start_tp_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ int ret = 0;
+ u32 drop_pkt_ratio = 0;
+
+ ret = udma_dfx_get_drop_pkt_ratio(udma_dev, inbuf, &drop_pkt_ratio);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = udma_dfx_set_l2d_tbl_filter_param(udma_dev, &inbuf->data, false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return udma_cmd_tp_set_drop_level(udma_dev, inbuf->tpn, drop_pkt_ratio);
+}
+
+int udma_dfx_stop_tp_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf)
+{
+ struct udma_l2d_tbl_dfx data = { 0 };
+ int ret = 0;
+
+ data.mask.dw0.value = U32_MAX;
+ ret = udma_dfx_set_l2d_tbl_filter_param(udma_dev, &data, false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return udma_cmd_tp_set_drop_level(udma_dev, inbuf->tpn, 0);
+}
+
+void udma_stop_all_drop_pkt(struct udma_device *udma_dev)
+{
+ int ret;
+ int npu_version = -1;
+
+ ret = udma_query_npu_dfx_version(udma_dev, &npu_version);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "UDMA fail to query version, ret(%d)\n", ret);
+ return;
+ }
+ if (npu_version == 0) {
+ return;
+ }
+
+ ret = udma_dfx_stop_func_drop_pkt(udma_dev, NULL, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DROP_DFX,
+ "stop func drop pkt failed, ret(%d)\n", ret);
+ }
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.h
new file mode 100644
index 000000000..63f9cbcb2
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_drop.h
@@ -0,0 +1,34 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_DROP_H
+#define UDMA_DFX_DROP_H
+
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+int udma_dfx_start_card_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+int udma_dfx_stop_card_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+int udma_dfx_start_func_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+int udma_dfx_stop_func_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+int udma_dfx_start_tp_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+int udma_dfx_stop_tp_drop_pkt(struct udma_device *udma_dev,
+ const struct ub_packet_inbuf *inbuf,
+ union ub_packet_outbuf *outbuf);
+void udma_stop_all_drop_pkt(struct udma_device *udma_dev);
+int udma_dfx_set_l2d_tbl_filter_param(struct udma_device *udma_dev,
+ const struct udma_l2d_tbl_dfx *l2d_tbl_dfx,
+ bool set_drop_level);
+
+#endif /* UDMA_DFX_DROP_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.c
new file mode 100644
index 000000000..b23aeb3ee
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "hinic5_hw.h"
+#include "ub_mpu_cmd.h"
+#include "comm_defs.h"
+#include "udma_dfx_drop.h"
+#include "udma_dfx_l2d.h"
+
+static int udma_dfx_l2d_buf_size_check(struct udma_device *udma_dev,
+ u32 in_size, u32 *out_size)
+{
+ if (in_size < (u32)sizeof(struct ub_l2d_dfx_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma l2d dfx buffer in size %u too small\n", in_size);
+ return -EINVAL;
+ }
+
+ if (*out_size < (u32)sizeof(union ub_l2d_dfx_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma l2d dfx buffer out size %u too small\n",
+ *out_size);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int udma_dfx_l2d_check(struct udma_device *udma_dev,
+ const struct ub_l2d_dfx_inbuf *inbuf)
+{
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "l2d dfx only support tpf device.\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int udma_dfx_l2d_query_perf_data(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ ub_l2d_mem_cfg_cmd_s cmd_in = { 0 };
+ ub_l2d_mem_cmd_rsp_s cmd_out = { 0 };
+ u16 outsize = (u16)sizeof(ub_l2d_mem_cmd_rsp_s);
+ int ret = 0;
+
+ cmd_in.cfg.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ cmd_in.cfg.tbl_mod = UB_L2D_TBL_MOD_DFX;
+ cmd_in.cfg.op_type = UB_L2D_TBL_OP_GET;
+ cmd_in.cfg.tile_id =
+ ((struct ub_l2d_dfx_inbuf *)buf_in)->l2d_cfg.tile_id;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_CFG_L2D_TBL, &cmd_in,
+ sizeof(ub_l2d_mem_cfg_cmd_s), &cmd_out,
+ &outsize, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || outsize == 0 || cmd_out.msg_head.status != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma l2d dfx query l2dmem perf data fail, ret=%d.\n",
+ ret);
+ return -EFAULT;
+ }
+
+ /* from MPU obtain of data is little-endian, dump_dfx need seek input is big-endian, in this need convert one next */
+ udma_cpu_to_be32(cmd_out.data, sizeof(l2d_ub_dfx_tbl_attr_s));
+ ret = memcpy_s(
+ ((union ub_l2d_dfx_outbuf *)buf_out)->ub_l2d_dfx_data,
+ sizeof(((union ub_l2d_dfx_outbuf *)buf_out)->ub_l2d_dfx_data),
+ cmd_out.data,
+ sizeof(((union ub_l2d_dfx_outbuf *)buf_out)->ub_l2d_dfx_data));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma l2d dfx query l2dmem perf data fail, ret=%d.\n",
+ ret);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX, "set drop l2dmem success.\n");
+
+ return 0;
+}
+
+static int udma_dfx_l2d_modify_perf_data(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ struct udma_l2d_tbl_dfx inbuf = { 0 };
+ int ret = 0;
+
+ ret = memcpy_s(&inbuf.attr, sizeof(inbuf.attr),
+ &(((struct ub_l2d_dfx_inbuf *)buf_in)
+ ->l2d_cfg.l2d_tbl.dfx_tbl.attr),
+ sizeof(((struct ub_l2d_dfx_inbuf *)buf_in)
+ ->l2d_cfg.l2d_tbl.dfx_tbl.attr));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy_s for attr failed, ret=%d.\n", ret);
+ return -EFAULT;
+ }
+ ret = memcpy_s(&inbuf.mask, sizeof(inbuf.mask),
+ &(((struct ub_l2d_dfx_inbuf *)buf_in)
+ ->l2d_cfg.l2d_tbl.dfx_tbl.mask),
+ sizeof(((struct ub_l2d_dfx_inbuf *)buf_in)
+ ->l2d_cfg.l2d_tbl.dfx_tbl.mask));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy_s for mask failed, ret=%d.\n", ret);
+ return -EFAULT;
+ }
+
+ ret = udma_dfx_set_l2d_tbl_filter_param(udma_dev, &inbuf, true);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma l2d dfx modify l2dmem perf data fail, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+const static struct udma_dfx_l2d_cmd_cb g_udma_dfx_l2d_cmd_funcs[] = {
+ { UB_L2D_DFX_MODULE_DFX_TBL, UB_L2D_DFX_SUB_TYPE_SHOW,
+ udma_dfx_l2d_check, udma_dfx_l2d_query_perf_data },
+ { UB_L2D_DFX_MODULE_DFX_TBL, UB_L2D_DFX_SUB_TYPE_CONFIG,
+ udma_dfx_l2d_check, udma_dfx_l2d_modify_perf_data },
+};
+
+int udma_dfx_l2d_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_l2d_dfx_inbuf *inbuf = NULL;
+ udma_dfx_l2d_check_func_t check_func = NULL;
+ udma_ioctl_func_t cmd_func = NULL;
+ u32 cmd_type = 0;
+ int ret = 0;
+ int i = 0;
+
+ ret = udma_dfx_l2d_buf_size_check(udma_dev, in_size, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "check buffer size fail, ret=%d.\n", ret);
+ return -EINVAL;
+ }
+
+ inbuf = (struct ub_l2d_dfx_inbuf *)buf_in;
+ for (i = 0; i < sizeof(g_udma_dfx_l2d_cmd_funcs) /
+ sizeof(g_udma_dfx_l2d_cmd_funcs[0]);
+ i++) {
+ cmd_type = ub_dfx_get_cmd_type(
+ g_udma_dfx_l2d_cmd_funcs[i].type,
+ g_udma_dfx_l2d_cmd_funcs[i].sub_type, 0);
+ if (cmd_type == inbuf->cmd_type) {
+ check_func = g_udma_dfx_l2d_cmd_funcs[i].check_func;
+ cmd_func = g_udma_dfx_l2d_cmd_funcs[i].cmd_func;
+ break;
+ }
+ }
+
+ if (cmd_func == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "cmd_type %u not support.\n", cmd_type);
+ return -EINVAL;
+ }
+
+ if (check_func != NULL) {
+ ret = check_func(udma_dev, inbuf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "cmd_type:%u check func fail, ret=%d.\n",
+ cmd_type, ret);
+ return ret;
+ }
+ }
+
+ ret = cmd_func(udma_dev, buf_in, in_size, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "l2d dfx cmd_type:%u, cmd func fail, ret=%d.\n",
+ cmd_type, ret);
+ return ret;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.h
new file mode 100644
index 000000000..1b06091e7
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_l2d.h
@@ -0,0 +1,28 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_DFX_L2D_H
+#define UDMA_DFX_L2D_H
+
+#include <linux/device.h>
+
+#include "udma_common.h"
+#include "udma_dfx.h"
+#include "udma_cmd_com.h"
+#include "ub_pub_cmd.h"
+
+typedef int (*udma_dfx_l2d_check_func_t)(struct udma_device *udma_dev,
+ const struct ub_l2d_dfx_inbuf *inbuf);
+
+struct udma_dfx_l2d_cmd_cb {
+ u32 type;
+ u32 sub_type;
+ udma_dfx_l2d_check_func_t check_func;
+ udma_ioctl_func_t cmd_func;
+};
+
+int udma_dfx_l2d_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif //UDMA_DFX_L2D_H
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.c
new file mode 100644
index 000000000..ae1350118
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.c
@@ -0,0 +1,671 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "udma_dfx_latch.h"
+#include "ub_npu_jetty_cmd_defs.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_tpg.h"
+
+#define UB_TP_LATCH_TPG_NUM 4
+#define UB_TP_LATCH_START_TPGN(tpgn) ((tpgn) * (UB_TP_LATCH_TPG_NUM))
+#define UB_TP_LATCH_END_TPGN(tpgn) \
+ (((tpgn) * (UB_TP_LATCH_TPG_NUM)) + (UB_TP_LATCH_TPG_NUM))
+#define MAX_LIMITED_TIME 10000
+#define LIMIT_PRINT_TIME 3
+#define CHAR_BUF_LEN 64
+#define MAX_DATA_LEN_UB_DFX 8192
+#define DUMP_LINE_BYTE_NUM 16
+#define DUMP_LINE_BYTE_HALF_NUM (DUMP_LINE_BYTE_NUM / 4)
+
+typedef struct print_latch_limiter {
+ ulong end_time;
+ int print_count;
+} print_latch_limiter_t;
+
+static struct print_latch_limiter ta_latch_limiter = {
+ .end_time = 0,
+ .print_count = 0,
+};
+
+static struct print_latch_limiter tp_latch_limiter = {
+ .end_time = 0,
+ .print_count = 0,
+};
+
+/* =================================================LATCH COMMON======================================================= */
+static bool udma_print_info_limited(struct udma_device *udma_dev,
+ struct print_latch_limiter *limter)
+{
+ ulong curr_time = jiffies;
+ if (curr_time > limter->end_time) {
+ limter->print_count = 0;
+ limter->end_time =
+ curr_time + jiffies_to_msecs(MAX_LIMITED_TIME);
+ }
+
+ if (limter->print_count < LIMIT_PRINT_TIME) {
+ udma_info_limit(udma_dev->dev, UDMA_M_DFX,
+ "start print info count: %d\n",
+ limter->print_count);
+ limter->print_count++;
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ this function no has print limit, because is is dump information, if use ratelimit related of interface, kernel 10 second 5 time,
+ then will lose log, so here not limit, by external call add print limit, and use err level ensure in any log level all can print.
+*/
+static void udma_print_byte_no_freq_limit(struct udma_device *udma_dev,
+ const u8 *buf, u32 ilen)
+{
+ char line[CHAR_BUF_LEN] = { 0 };
+ size_t line_len = 0;
+ int ret = 0;
+ u32 i;
+
+ if ((buf == NULL) || (ilen == 0) || (ilen > MAX_DATA_LEN_UB_DFX)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "The buf is Null,len=%u is error.\n", ilen);
+ return;
+ }
+
+ for (i = 0; i < ilen; i++) {
+ if ((i != 0) && (i % DUMP_LINE_BYTE_NUM == 0)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "%08x:%s\n",
+ i - DUMP_LINE_BYTE_NUM, line);
+ line[0] = '\0';
+ } else if ((i != 0) && (i % DUMP_LINE_BYTE_HALF_NUM == 0)) {
+ line_len = strlen(line);
+ ret = sprintf_s(line + line_len,
+ CHAR_BUF_LEN - line_len, " ");
+ if (ret < 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "format dump byte string separator failed, ret:%d .\n",
+ ret);
+ return;
+ }
+ }
+
+ line_len = strlen(line);
+ ret = sprintf_s(line + line_len, CHAR_BUF_LEN - line_len,
+ "%02X", buf[i]);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "format dump byte string failed, ret:%d .\n",
+ ret);
+ return;
+ }
+ }
+
+ if (strlen(line) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "%08x:%s\n",
+ ((i + DUMP_LINE_BYTE_NUM - 1) / DUMP_LINE_BYTE_NUM) *
+ DUMP_LINE_BYTE_NUM,
+ line);
+ }
+}
+
+static void
+udma_dfx_parase_latch_common_header(struct udma_device *udma_dev,
+ union ub_latch_data_common_header *header,
+ u32 dw0)
+{
+ udma_be32_to_cpu(&dw0, sizeof(u32));
+
+ header->dw0 = dw0;
+ udma_info(
+ udma_dev->dev, UDMA_M_DFX,
+ "Latched info dw0=0x%08x, first_seq=%u, last_seq=%u, valid=%u, data_len=0x%04x.\n",
+ dw0, header->first_seq, header->last_seq, header->valid,
+ header->latch_total_len);
+ return;
+}
+
+/* =================================================TA LATCH======================================================= */
+/**
+ this part is TA lock store query,TA lock store header parse,TA lock store rate-limit print
+ */
+int udma_dfx_query_ta_latch_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args)
+{
+ bool tpf = check_args->tpf;
+
+ if (tpf) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Ta latch should be checked for non-TPF devices.");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void
+udma_dfx_parse_ta_latch_header(struct udma_device *udma_dev,
+ struct ub_ta_rdma_rc_outbuf *ta_rc_entry,
+ union ub_latch_data_common_header *header)
+{
+ u32 dw0 = *(u32 *)(ta_rc_entry->rdmarc);
+
+ udma_dfx_parase_latch_common_header(udma_dev, header, dw0);
+ return;
+}
+
+static int
+udma_dfx_get_ta_latch_header(struct udma_device *udma_dev, u32 jetty_id,
+ union ub_latch_data_common_header *header)
+{
+ int ret;
+ struct ub_ta_rdma_rc_outbuf ta_rc_entry = { 0 };
+
+ (void)memset_s(header, sizeof(union ub_latch_data_common_header), 0,
+ sizeof(union ub_latch_data_common_header));
+
+ /* 1. query entry 0 */
+ ret = udma_cmd_jetty_query_rdma_rc(udma_dev, jetty_id, 0, &ta_rc_entry);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "Cmd failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ /* 2. parse get of entry 0 in of dw0 lock store header */
+ udma_dfx_parse_ta_latch_header(udma_dev, &ta_rc_entry, header);
+ return 0;
+}
+
+static int
+udma_dfx_query_ta_latch_entry(struct udma_device *udma_dev,
+ struct ub_ta_latch_data_outbuf *ta_latch_data,
+ u32 query_entry_num, u32 jetty_id)
+{
+ int ret = 0;
+ u32 remaining_size;
+ struct ub_ta_rdma_rc_outbuf ta_rc_entry = { 0 };
+ u32 entry_size = udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_entry_size;
+
+ if (query_entry_num > UB_TA_RDMARC_MAX_SIZE) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "query_entry_num(%u) is greater than (%u)\n",
+ query_entry_num, (u32)UB_TA_RDMARC_MAX_SIZE);
+ return -EINVAL;
+ }
+
+ for (u32 i = 0; i < query_entry_num; i++) {
+ ret = udma_cmd_jetty_query_rdma_rc(udma_dev, jetty_id, i,
+ &ta_rc_entry);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Cmd failed, jetty_id=%u, entry_idx=%u, ret=%d!\n",
+ jetty_id, i, ret);
+ return ret;
+ }
+ remaining_size = UB_TA_LATCH_DATA_MAX_SIZE -
+ ta_latch_data->ta_latch_size;
+ if (entry_size > remaining_size) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Buffer overflow: entry_size(%u) > remaining_size(%u)\n",
+ entry_size, remaining_size);
+ return -EINVAL;
+ }
+ ret = memcpy_s((void *)(ta_latch_data->ta_latch +
+ ta_latch_data->ta_latch_size),
+ remaining_size, (void *)(&ta_rc_entry),
+ entry_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memcpy_s failed, ret=%d!\n", ret);
+ return -EFAULT;
+ }
+
+ ta_latch_data->ta_latch_size += entry_size;
+ }
+ return ret;
+}
+
+int udma_dfx_query_ta_latch_data_exe(
+ struct udma_device *udma_dev, u32 jetty_id,
+ struct ub_ta_latch_data_outbuf *ta_latch_data)
+{
+ union ub_latch_data_common_header latch_header = { 0 };
+ union ub_latch_data_common_header record_latch_header = { 0 };
+ u32 query_entry_num = 0;
+ u32 entry_size = udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_entry_size;
+ int ret;
+
+ ret = memset_s(ta_latch_data, sizeof(struct ub_ta_latch_data_outbuf), 0,
+ sizeof(struct ub_ta_latch_data_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "memset_s failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ /* 1. get lock store of common header */
+ ret = udma_dfx_get_ta_latch_header(udma_dev, jetty_id, &latch_header);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Get latch header fail, ret=%d!\n", ret);
+ return ret;
+ }
+
+ /* 2. according to header information do check */
+ if (latch_header.valid == 0 ||
+ latch_header.first_seq != latch_header.last_seq) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Latched info is invalid, dw0=0x%08x, first_seq=%u, last_seq=%u, valid=%u, data_len=%u.\n",
+ latch_header.dw0, latch_header.first_seq,
+ latch_header.last_seq, latch_header.valid,
+ latch_header.latch_total_len);
+ return 0;
+ }
+
+ /* 3. record the one query of header information */
+ record_latch_header.first_seq = latch_header.first_seq;
+ record_latch_header.last_seq = latch_header.last_seq;
+
+ /* 4. according to header calculate need query of entry count */
+ query_entry_num =
+ (latch_header.latch_total_len + entry_size - 1) / entry_size;
+ ret = udma_dfx_query_ta_latch_entry(udma_dev, ta_latch_data,
+ query_entry_num, jetty_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Query latch entry data failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ /* 4. again query once header, determine data valid validity */
+ ret = udma_dfx_get_ta_latch_header(udma_dev, jetty_id, &latch_header);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Get latch header fail, ret=%d!\n", ret);
+ return ret;
+ }
+
+ if (record_latch_header.first_seq != latch_header.first_seq ||
+ record_latch_header.last_seq != latch_header.last_seq) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Second query latch header seq not equal, record(%u, %u), (%u, %u).\n",
+ record_latch_header.first_seq,
+ record_latch_header.last_seq, latch_header.first_seq,
+ latch_header.last_seq);
+ ta_latch_data->ta_latch_size = 0;
+ }
+
+ return 0;
+}
+
+int udma_dfx_query_ta_latch_data(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf, u32 source_type)
+{
+ int ret;
+
+ /* TPF no has TA lock store */
+ if (udma_dev->ub_dev.attr.tp_maintainer) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "%s: TA latch info only non-TPF.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_ta_latch_data_exe(udma_dev, inbuf->jettyid,
+ &outbuf->ta_latch_data);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Get ta latch data fail, ret=%d!\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static void udma_dfx_query_ta_latch_print(struct udma_device *udma_dev, int xid)
+{
+ int ret;
+ struct ub_ta_latch_data_outbuf *ta_latch_data =
+ (struct ub_ta_latch_data_outbuf *)devm_kzalloc(
+ udma_dev->dev, sizeof(struct ub_ta_latch_data_outbuf),
+ GFP_KERNEL);
+
+ if (ta_latch_data == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "devm_kzalloc failed for ta_latch_data\n");
+ return;
+ }
+
+ (void)memset_s(ta_latch_data, sizeof(struct ub_ta_latch_data_outbuf), 0,
+ sizeof(struct ub_ta_latch_data_outbuf));
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "Query xid(%d) ta latch info print.\n", xid);
+ ret = udma_dfx_query_ta_latch_data_exe(udma_dev, (u32)xid,
+ ta_latch_data);
+ if (ret != 0) {
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "Query xid=%u ta latch data fail, ret=%d.", xid, ret);
+ devm_kfree(udma_dev->dev, ta_latch_data);
+ return;
+ }
+ udma_print_byte_no_freq_limit(udma_dev, (u8 *)(ta_latch_data->ta_latch),
+ ta_latch_data->ta_latch_size);
+
+ devm_kfree(udma_dev->dev, ta_latch_data);
+ return;
+}
+
+void udma_dump_ta_latch_info(struct udma_device *udma_dev)
+{
+ if (udma_dev->ub_dev.attr.tp_maintainer) {
+ return;
+ }
+
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ if (udma_print_info_limited(
+ udma_dev, &ta_latch_limiter)) { /* 10s 3 time of frequency */
+ udma_dfx_query_ta_latch_print(
+ udma_dev, 0); /* 1823 only for for xid 0 do (done) lock store information */
+ }
+ return;
+ }
+
+ if (udma_print_info_limited(udma_dev,
+ &ta_latch_limiter)) { /* 10s 3 time of frequency */
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "=========TA Start Freq(%d)=========\n",
+ ta_latch_limiter.print_count);
+ /* log level is INFO and above next: print first occurrence and non- first occurrence xid 0 ~ 3 */
+ if (!udma_kernel_log_level_prior(UDMA_LOG_LEVEL_DEBUG)) {
+ for (int i = 0; i <= LATCH_LOCK_MAX_XID; i++) {
+ udma_dfx_query_ta_latch_print(udma_dev, i);
+ }
+ return;
+ }
+
+ /* log level is INFO and above on: print first occurrence xid 0, 2 */
+ udma_dfx_query_ta_latch_print(udma_dev, 0);
+ udma_dfx_query_ta_latch_print(udma_dev, 2); /* 2: xid */
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "=========TA End Freq(%d)=========",
+ ta_latch_limiter.print_count);
+ }
+ return;
+}
+
+/* =================================================TP LATCH======================================================= */
+/**
+ this part is TP lock store query,TP lock store header parse,TP lock store rate-limit print
+ */
+static void
+udma_dfx_parse_tp_latch_header(struct udma_device *udma_dev,
+ struct ub_tpg_ctx_query *tpg_ctx,
+ union ub_latch_data_common_header *header)
+{
+ u32 dw0 = *(u32 *)(tpg_ctx->ctx_req);
+ udma_dfx_parase_latch_common_header(udma_dev, header, dw0);
+ return;
+}
+
+static int udma_dfx_query_tp_latch_tpg_ctx(struct udma_device *udma_dev,
+ u32 tpgn,
+ struct ub_tpg_ctx_query *tpg_ctx)
+{
+ int ret = 0;
+ (void)memset_s(tpg_ctx, sizeof(struct ub_tpg_ctx_query), 0,
+ sizeof(struct ub_tpg_ctx_query));
+
+ ret = udma_cmd_tpg_query_ctx_from_cache(
+ udma_dev, tpgn, tpg_ctx, sizeof(struct ub_tpg_ctx_query));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Query tpgn(%u) context failed, ret=%d.\n", tpgn, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int udma_dfx_query_check_tp_latch_header(
+ struct udma_device *udma_dev, struct ub_tpg_ctx_query *tpg_ctx,
+ u32 tpgn, union ub_latch_data_common_header *latch_header)
+{
+ int ret;
+
+ ret = udma_dfx_query_tp_latch_tpg_ctx(udma_dev, tpgn, tpg_ctx);
+ if (ret != 0) {
+ return ret;
+ }
+
+ udma_dfx_parse_tp_latch_header(udma_dev, tpg_ctx, latch_header);
+ return 0;
+}
+
+static int
+udma_dfx_query_tp_latch_data_exe(struct udma_device *udma_dev, u32 xid,
+ struct ub_tp_latch_data_outbuf *tp_latch_data)
+{
+ union ub_latch_data_common_header latch_header = { 0 };
+ union ub_latch_data_common_header record_header = { 0 };
+ struct ub_tpg_ctx_query tpg_ctx = { 0 };
+ u32 start_tpgn = UB_TP_LATCH_START_TPGN(
+ xid); /* a TP lock store occupy 4 TPG CTX, so need mapping 0:0~3 1:4~7 2:8~11 3:12~15 */
+ u32 end_tpgn = UB_TP_LATCH_END_TPGN(xid);
+ int ret;
+
+ /* non- TPF no has TP lock store */
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "%s: TP latch info only TPF.\n", __func__);
+ return -EINVAL;
+ }
+
+ (void)memset_s(tp_latch_data, sizeof(struct ub_tp_latch_data_outbuf), 0,
+ sizeof(struct ub_tp_latch_data_outbuf));
+
+ /* 1. get lock store of common header, and determine valid validity */
+ ret = udma_dfx_query_check_tp_latch_header(udma_dev, &tpg_ctx,
+ start_tpgn, &latch_header);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "%s:First get tp latch header faild, ret=%d.\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (latch_header.valid == 0 ||
+ latch_header.first_seq != latch_header.last_seq) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Latched tp info is invalid, valid=%u, first_seq=%u, last_seq=%u.\n",
+ latch_header.valid, latch_header.first_seq,
+ latch_header.last_seq);
+ return 0;
+ }
+ record_header.first_seq = latch_header.first_seq;
+ record_header.last_seq = latch_header.last_seq;
+
+ /* 2. save the a TPG CTX */
+ (void)memcpy_s((void *)(tp_latch_data->tp_latch +
+ tp_latch_data->tp_latch_size),
+ sizeof(struct ub_tpg_ctx_query), (void *)(&tpg_ctx),
+ sizeof(struct ub_tpg_ctx_query));
+ tp_latch_data->tp_latch_size += sizeof(struct ub_tpg_ctx_query);
+
+ /* 3. query its remaining剩 next 3 TPG CTX */
+ for (u32 i = start_tpgn + 1; i < end_tpgn; i++) {
+ ret = udma_dfx_query_tp_latch_tpg_ctx(udma_dev, i, &tpg_ctx);
+ if (ret != 0) {
+ return ret;
+ }
+ (void)memcpy_s((void *)(tp_latch_data->tp_latch +
+ tp_latch_data->tp_latch_size),
+ sizeof(struct ub_tpg_ctx_query),
+ (void *)(&tpg_ctx),
+ sizeof(struct ub_tpg_ctx_query));
+ tp_latch_data->tp_latch_size += sizeof(struct ub_tpg_ctx_query);
+ }
+
+ /* 4. again query once header, determine data valid validity */
+ ret = udma_dfx_query_check_tp_latch_header(udma_dev, &tpg_ctx,
+ start_tpgn, &latch_header);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "%s:Second get tp latch header faild, ret=%d.\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (record_header.first_seq != latch_header.first_seq ||
+ record_header.last_seq != latch_header.last_seq) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Second query tp latch header seq not equal, record(%u, %u), cur(%u, %u).\n",
+ record_header.first_seq, record_header.last_seq,
+ latch_header.first_seq, latch_header.last_seq);
+ tp_latch_data->tp_latch_size = 0;
+ }
+
+ return 0;
+}
+
+int udma_dfx_query_tp_latch_data(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_tp_latch_data_exe(udma_dev, inbuf->tpg_id,
+ &outbuf->tp_latch_data);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "Get tp latch data fail, ret=%d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_dfx_query_tp_latch_print(struct udma_device *udma_dev, u32 xid)
+{
+ int ret;
+
+ struct ub_tp_latch_data_outbuf *tp_latch_data =
+ (struct ub_tp_latch_data_outbuf *)devm_kzalloc(
+ udma_dev->dev, sizeof(struct ub_tp_latch_data_outbuf),
+ GFP_KERNEL);
+
+ if (tp_latch_data == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "devm_kzalloc failed for tp_latch_data\n");
+ return;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "Query xid(%u) tp latch info print.\n", xid);
+ ret = udma_dfx_query_tp_latch_data_exe(udma_dev, xid, tp_latch_data);
+ if (ret != 0) {
+ udma_info(udma_dev->dev, UDMA_M_DFX,
+ "Query xid=%u tp latch data fail, ret=%d.", xid, ret);
+ devm_kfree(udma_dev->dev, tp_latch_data);
+ return;
+ }
+ udma_print_byte_no_freq_limit(udma_dev, (u8 *)(tp_latch_data->tp_latch),
+ tp_latch_data->tp_latch_size);
+ devm_kfree(udma_dev->dev, tp_latch_data);
+ return;
+}
+
+void udma_dump_tp_latch_info(struct udma_device *udma_dev)
+{
+ if (!udma_dev->ub_dev.attr.tp_maintainer ||
+ udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ return;
+ }
+
+ if (udma_print_info_limited(udma_dev,
+ &tp_latch_limiter)) { /* 10s 3 time of frequency */
+ /* log level is INFO and above next: print first occurrence and non- first occurrence xid 0 ~ 3 i.e.: TPG 0 ~ 15 */
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "=========TP Start Freq(%d)=========",
+ tp_latch_limiter.print_count);
+ if (!udma_kernel_log_level_prior(UDMA_LOG_LEVEL_DEBUG)) {
+ for (u32 i = 0; i <= LATCH_LOCK_MAX_XID; i++) {
+ udma_dfx_query_tp_latch_print(udma_dev, i);
+ }
+ return;
+ }
+
+ /* log level is INFO and above on: print first occurrence xid 0, 2 */
+ udma_dfx_query_tp_latch_print(udma_dev, 0);
+ udma_dfx_query_tp_latch_print(udma_dev, 2); /* 2: xid */
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "=========TP End Freq(%d)=========",
+ tp_latch_limiter.print_count);
+ }
+}
+
+/* =================================================CLEAR LATCH====================================================== */
+/**
+ this part is TA/TP lock store clear
+ */
+int udma_dfx_ub_modify_clear_ta_latch_lock(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ int ret;
+
+ /* TA lock store only has non- TPF device */
+ if (udma_dev->ub_dev.attr.tp_maintainer) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: TA latch clear only non-TPF.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_clear_dfx_lock_ctx(
+ udma_dev, 0); /* one clear all of TA lock store, default jetty_id fill 0 */
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: clear ta latch lock failed, ret(%d)\n", __func__,
+ ret);
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: TA latch clear Successful.\n", __func__);
+ return 0;
+}
+
+int udma_dfx_ub_modify_clear_tp_latch_lock(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ int ret;
+
+ /* TP lock store only has TPF device */
+ if (!udma_dev->ub_dev.attr.tp_maintainer ||
+ udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: TP latch clear only HI1825 TPF.\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_clear_tp_latch_lock(
+ udma_dev, 0); /* one clear all of TP lock store, default xid fill 0 */
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: clear latch lock failed, ret(%d)\n", __func__,
+ ret);
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_CQM_MOD_DFX,
+ "%s: TP latch clear Successful.\n", __func__);
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.h
new file mode 100644
index 000000000..9b3066df2
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_latch.h
@@ -0,0 +1,34 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_DFX_LATCH_H
+#define UDMA_DFX_LATCH_H
+
+#include <linux/device.h>
+
+#include "udma_common.h"
+#include "udma_dfx.h"
+#include "udma_cmd_com.h"
+
+#define LATCH_LOCK_MAX_XID 3
+
+int udma_dfx_query_ta_latch_check(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args);
+int udma_dfx_query_ta_latch_data(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf,
+ u32 source_type);
+int udma_dfx_query_tp_latch_data(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size);
+void udma_dump_ta_latch_info(struct udma_device *udma_dev);
+void udma_dump_tp_latch_info(struct udma_device *udma_dev);
+int udma_dfx_ub_modify_clear_ta_latch_lock(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
+int udma_dfx_ub_modify_clear_tp_latch_lock(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size);
+#endif //UDMA_DFX_LATCH_H
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.c
new file mode 100644
index 000000000..cd085a956
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.c
@@ -0,0 +1,649 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "ub_mpu_cmd.h"
+#include "udma_cmd_event.h"
+#include "udma_cmd_tpg.h"
+#include "udma_cmd_tp.h"
+#include "udma_resource.h"
+#include "udma_tp.h"
+#include "udma_jetty.h"
+#include "udma_dfx_latch.h"
+#include "udma_dfx.h"
+
+static int udma_dfx_modify_tp(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp failed.\n");
+ return ret;
+ }
+ return udma_dfx_modify_tp_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_modify_tp_q_depth(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret;
+
+ if (inbuf->q_depth == 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "q_depth cannot be 0.\n");
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp_q_depth failed, ret= %d.\n", ret);
+ return ret;
+ }
+
+ ret = udma_sysfs_set_tp_depth(&udma_dev->sysfs_res, inbuf->q_depth);
+ if (ret < 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "q_depth(%u) set failed or depth is not a power of 2, ret: %d.\n",
+ inbuf->q_depth, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_modify_tp_mtu_1k_en(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp_mtu_1k_en failed, ret= %d.\n",
+ ret);
+ return ret;
+ }
+ udma_dev->mtu_1k_en = inbuf->mtu_1k_en;
+ return ret;
+}
+
+static int udma_dfx_modify_max_jetty(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct ub_get_cfg_cap_cmd cmd = { 0 };
+ struct ub_get_cfg_cap_resp resp = { 0 };
+ u16 resp_size = sizeof(resp);
+ int ret;
+
+ if (udma_dev->ub_cap.net_dev_cap.is_tpf != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "tpf not allow modify max jetty num\n");
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_max_jetty failed, ret= %d.\n", ret);
+ return ret;
+ }
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ udma_info(udma_dev->dev, UDMA_M_DFX, "modify max jetty func_id:%u\n",
+ cmd.func_id);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_CFG_CAP, &cmd, sizeof(cmd),
+ &resp, &resp_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "Failed to get dev cap, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, resp.head.status, resp_size);
+ return -EINVAL;
+ }
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty = inbuf->max_jetty_num;
+ if (udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty <
+ resp.udma_res.max_jfrc_num) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "max_jetty_num(%u) less than max_jfrc_num(%u)\n",
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty,
+ resp.udma_res.max_jfrc_num);
+ return -EINVAL;
+ }
+ udma_dev->ub_cap.dev_cap.max_jetty =
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty -
+ resp.udma_res.max_jfrc_num;
+ udma_info(udma_dev->dev, UDMA_M_DFX, "sdk max_jetty:%u\n",
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty);
+ return ret;
+}
+
+static int udma_dfx_modify_jetty(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "The version (%d) does not support ub_modify jetty cmd.\n",
+ udma_dev->device_type);
+ return -EINVAL;
+ }
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp_mtu_1k_en failed, ret= %d.\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_modify_jetty_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_cc_set_para(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct ub_cc_params para = { 0 };
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "set cc parameters failed, fail to prepare buffers.\n");
+ return ret;
+ }
+
+ para.ub_cc_algo = inbuf->cc_params.ub_cc_algo;
+ para.init_wnd = inbuf->cc_params.init_wnd;
+ para.alpha = inbuf->cc_params.alpha;
+ para.beta = inbuf->cc_params.beta;
+ para.gamma = inbuf->cc_params.gamma;
+ para.eta = inbuf->cc_params.eta;
+
+ ret = udma_cc_set_para(udma_dev, ¶);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set cc parameters failed.\n");
+ }
+
+ return ret;
+}
+
+static int udma_dfx_modify_tp_srp_bitmap(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp_srp_bitmap failed, ret= %d.\n",
+ ret);
+ return ret;
+ }
+ ret = udma_cmd_tp_modify_tp_srp_bitmap(udma_dev, inbuf->tp_srp_index,
+ inbuf->bitmap_index,
+ inbuf->bitmap_mode);
+
+ return ret;
+}
+
+static int udma_dfx_modify_tp_srp_ctr_bitmap(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_modify_tp_srp_ctr_bitmap failed, ret= %d.\n",
+ ret);
+ return ret;
+ }
+ ret = udma_cmd_tp_modify_srp_ctr_bitmap(
+ udma_dev, inbuf->ctr_bitmap_index, inbuf->bitmap_mode);
+
+ return ret;
+}
+
+static int udma_cmd_dfx_qos_set_func_vnic_mapping(struct udma_device *udma_dev,
+ const void *buf_in,
+ u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct ub_qos_cmd qos_cmd = { 0 };
+ u16 cmd_out_size = sizeof(struct ub_qos_cmd);
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "set func vnic mapping failed, fail to prepare buffers, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ qos_cmd.func_id = (u16)inbuf->qos_params.func_id;
+ qos_cmd.vnic_id = (u16)inbuf->qos_params.vnic_id;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_QOS_FUNC_MAPPING_SET, &qos_cmd,
+ sizeof(struct ub_qos_cmd), &qos_cmd,
+ &cmd_out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_out_size == 0) || (qos_cmd.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "failed to set func vnic mapping, ret:%d, status:0x%x, outsize: %u",
+ ret, qos_cmd.head.status, cmd_out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int udma_cmd_dfx_qos_set_bps(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct ub_qos_cmd qos_cmd = { 0 };
+ u16 cmd_out_size = sizeof(struct ub_qos_cmd);
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set bps failed, fail to prepare buffers, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ qos_cmd.vnic_id = (u16)inbuf->qos_params.vnic_id;
+ qos_cmd.xir_type = (u16)inbuf->qos_params.xir_type;
+ qos_cmd.bps = (u32)inbuf->qos_params.bps;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_QOS_BPS_SET, &qos_cmd,
+ sizeof(struct ub_qos_cmd), &qos_cmd,
+ &cmd_out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_out_size == 0) || (qos_cmd.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to set bps, ret:%d, status:0x%x, outsize: %u",
+ ret, qos_cmd.head.status, cmd_out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int udma_cmd_dfx_qos_set_pps(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ struct ub_qos_cmd qos_cmd = { 0 };
+ u16 cmd_out_size = sizeof(struct ub_qos_cmd);
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set pps failed, fail to prepare buffers, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ qos_cmd.vnic_id = (u16)inbuf->qos_params.vnic_id;
+ qos_cmd.xir_type = (u16)inbuf->qos_params.xir_type;
+ qos_cmd.pps = (u32)inbuf->qos_params.pps;
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_QOS_PPS_SET, &qos_cmd,
+ sizeof(struct ub_qos_cmd), &qos_cmd,
+ &cmd_out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_out_size == 0) || (qos_cmd.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to set pps, ret:%d, status:0x%x, outsize: %u",
+ ret, qos_cmd.head.status, cmd_out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_set_multi_mode(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ ub_set_multi_mode_cmd_s para = { 0 };
+ u16 out = (u16)sizeof(para);
+ int ret;
+
+ para.multi_path_mode = inbuf->multi_path_mode;
+ para.func_id = inbuf->func_id;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_SET_MULTI_PATH_MODE, ¶,
+ (u16)sizeof(para), ¶, &out, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out == 0) || (para.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_MISC,
+ "set multi path mode failed. ret: %d, status(0x%x)\n",
+ ret, para.head.status);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static void fill_modify_func_table_attr(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ ub_dfx_modify_func_table_cmd_s *cmd)
+{
+ if (inbuf->func_table_modify_attr.dw15_flag.debug_en == 1) {
+ cmd->func_table_modify_attr.bs.debug_en =
+ inbuf->func_table_modify_attr.dw15.debug_en;
+ cmd->func_table_modify_attr.bs_flag.debug_en =
+ inbuf->func_table_modify_attr.dw15_flag.debug_en;
+ }
+ if (inbuf->func_table_modify_attr.dw15_flag.lwb_en == 1) {
+ cmd->func_table_modify_attr.bs.lwb_en =
+ inbuf->func_table_modify_attr.dw15.lwb_en;
+ cmd->func_table_modify_attr.bs_flag.lwb_en =
+ inbuf->func_table_modify_attr.dw15_flag.lwb_en;
+ }
+ if (inbuf->func_table_modify_attr.dw15_flag.traffic_en == 1) {
+ cmd->func_table_modify_attr.bs.traffic_en =
+ inbuf->func_table_modify_attr.dw15.traffic_en;
+ cmd->func_table_modify_attr.bs_flag.traffic_en =
+ inbuf->func_table_modify_attr.dw15_flag.traffic_en;
+ }
+ if ((udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) &&
+ (inbuf->func_table_modify_attr.dw15_flag.ub_link_en == 1)) {
+ cmd->func_table_modify_attr.bs.ub_link_en =
+ inbuf->func_table_modify_attr.dw15.ub_link_en;
+ cmd->func_table_modify_attr.bs_flag.ub_link_en =
+ inbuf->func_table_modify_attr.dw15_flag.ub_link_en;
+ }
+ if (inbuf->func_table_modify_attr.dw15_flag.mtt_pro_en == 1) {
+ cmd->func_table_modify_attr.bs.mtt_pro_en =
+ inbuf->func_table_modify_attr.dw15.mtt_pro_en;
+ cmd->func_table_modify_attr.bs_flag.mtt_pro_en =
+ inbuf->func_table_modify_attr.dw15_flag.mtt_pro_en;
+ cmd->func_id = (u16)inbuf->func_id;
+ }
+}
+
+static int udma_dfx_set_func_table(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ ub_dfx_modify_func_table_cmd_s cmd = { 0 };
+ u16 out = (u16)sizeof(cmd);
+ int ret;
+
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ fill_modify_func_table_attr(udma_dev, inbuf, &cmd);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_SET_FUNC_TABLE, &cmd,
+ (u16)sizeof(cmd), &cmd, &out, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out == 0) || (cmd.head.status != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set func table failed. ret: %d, status(0x%x)\n", ret,
+ cmd.head.status);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int udma_dfx_set_device(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret = 0;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set device failed, fail to prepare buffers.\n");
+ return ret;
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "slice_cfg_set:%d, slice_cfg_en:%d\n", inbuf->slice_cfg_set,
+ inbuf->slice_cfg_en);
+ if (inbuf->slice_cfg_set == 1) {
+ udma_dev->slice_cfg_en = inbuf->slice_cfg_en;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_clear_io_stat(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ int ret = 0;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX, "fail to clear.\n");
+ return ret;
+ }
+
+ atomic64_set(&udma_dev->udma_driver_device_ctr.post_send_wr_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.post_recv_wr_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_total_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_sq_num, 0);
+ atomic64_set(&udma_dev->udma_driver_device_ctr.poll_rq_num, 0);
+ return 0;
+}
+
+static int udma_dfx_set_cfg_cos_en(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "set cos enable failed, fail to prepare buffers.\n");
+ return ret;
+ }
+
+ udma_dev->default_cos.cfg_cos_en = inbuf->cfg_cos_en;
+
+ return ret;
+}
+
+static struct udma_dfx_query_cmd_func g_udma_modify_cmd_funcs[] = {
+ /* modify */
+ { UB_MODIFY_TYPE_TP, 0, 0, udma_dfx_modify_tp },
+ { UB_MODIFY_TYPE_TP, UB_MODIFY_SUB_TYPE_Q_DEPTH, 0,
+ udma_dfx_modify_tp_q_depth },
+ { UB_MODIFY_TYPE_TP, UB_MODIFY_SUB_TYPE_MTU_1K_EN, 0,
+ udma_dfx_modify_tp_mtu_1k_en },
+ { UB_MODIFY_TYPE_CC, 0, 0, udma_dfx_cc_set_para },
+ { UB_MODIFY_TYPE_TPG_MULTIPATH, 0, 0, udma_cmd_tpg_modify_multipath },
+ { UB_MODIFY_TYPE_TP_SRP, UB_MODIFY_SUB_TYPE_SRP_BITMAP, 0,
+ udma_dfx_modify_tp_srp_bitmap },
+ { UB_MODIFY_TYPE_TP_SRP, UB_MODIFY_SUB_TYPE_SRP_CTR_BITMAP, 0,
+ udma_dfx_modify_tp_srp_ctr_bitmap },
+ { UB_MODIFY_TYPE_AEQE, 0, 0, udma_cmd_dfx_aeqe_inject },
+ { UB_MODIFY_TYPE_DROP_AEQE, 0, 0, udma_cmd_dfx_aeqe_drop },
+ { UB_MODIFY_TYPE_QOS, UB_MODIFY_SUB_TYPE_FUNC_MAPPING, 0,
+ udma_cmd_dfx_qos_set_func_vnic_mapping },
+ { UB_MODIFY_TYPE_QOS, UB_MODIFY_SUB_TYPE_BPS, 0,
+ udma_cmd_dfx_qos_set_bps },
+ { UB_MODIFY_TYPE_QOS, UB_MODIFY_SUB_TYPE_PPS, 0,
+ udma_cmd_dfx_qos_set_pps },
+ { UB_MODIFY_TYPE_MUL_MODE, 0, 0, udma_dfx_set_multi_mode },
+ { UB_MODIFY_TYPE_FUNC_TABLE, 0, 0, udma_dfx_set_func_table },
+ { UB_MODIFY_TYPE_CFG_COS_EN, 0, 0, udma_dfx_set_cfg_cos_en },
+ { UB_MODIFY_TYPE_DEVICE, 0, 0, udma_dfx_set_device },
+ { UB_MODIFY_TYPE_DEVICE, UB_MODIFY_SUB_TYPE_CLEAR_IO_STAT, 0,
+ udma_dfx_clear_io_stat },
+ { UB_MODIFY_TYPE_DEVICE, UB_MODIFY_SUB_TYPE_MAX_JETTY, 0,
+ udma_dfx_modify_max_jetty },
+ { UB_MODIFY_TYPE_JETTY, 0, 0, udma_dfx_modify_jetty },
+ { UB_MODIFY_TYPE_LATCH_LOCK, UB_MODIFY_SUB_TYPE_CLEAR_TA_LATCH_LOCK, 0,
+ udma_dfx_ub_modify_clear_ta_latch_lock },
+ { UB_MODIFY_TYPE_LATCH_LOCK, UB_MODIFY_SUB_TYPE_CLEAR_TP_LATCH_LOCK, 0,
+ udma_dfx_ub_modify_clear_tp_latch_lock },
+};
+
+static bool
+udma_dfx_check_device_notmatch_for_modify(const struct udma_device *udma_dev,
+ u32 cmd_type, u32 sub_type)
+{
+ static const u32 tpf_obj_modify[] = { UB_MODIFY_TYPE_TP,
+ UB_MODIFY_TYPE_TPG_MULTIPATH,
+ UB_MODIFY_TYPE_TP_SRP };
+ bool ret = false;
+ u32 i = 0;
+ /* determine tp/tpg/utp must not be on pf device on */
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ for (i = 0; i < ARRAY_SIZE(tpf_obj_modify); i++) {
+ if (cmd_type == tpf_obj_modify[i]) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+static bool udma_modify_cmd_in_white_list(u32 in_cmd_type)
+{
+ return (in_cmd_type ==
+ ub_dfx_get_cmd_type(UB_MODIFY_TYPE_FUNC_TABLE, 0, 0) ||
+ in_cmd_type == ub_dfx_get_cmd_type(UB_MODIFY_TYPE_TP,
+ UB_MODIFY_SUB_TYPE_MTU_1K_EN,
+ 0) ||
+ in_cmd_type ==
+ ub_dfx_get_cmd_type(UB_MODIFY_TYPE_CFG_COS_EN, 0, 0) ||
+ in_cmd_type ==
+ ub_dfx_get_cmd_type(UB_MODIFY_TYPE_DEVICE, 0, 0) ||
+ in_cmd_type == ub_dfx_get_cmd_type(
+ UB_MODIFY_TYPE_LATCH_LOCK,
+ UB_MODIFY_SUB_TYPE_CLEAR_TA_LATCH_LOCK,
+ 0) ||
+ in_cmd_type == ub_dfx_get_cmd_type(
+ UB_MODIFY_TYPE_LATCH_LOCK,
+ UB_MODIFY_SUB_TYPE_CLEAR_TP_LATCH_LOCK,
+ 0));
+}
+
+int udma_verify_modify_func(struct udma_device *udma_dev, u32 in_cmd_type)
+{
+ int npu_version = -1;
+ int ret;
+
+ /* npu_version:0, means release version; npu_version:1, means debug version */
+ ret = udma_query_npu_dfx_version(udma_dev, &npu_version);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "UDMA fail to query version.\n");
+ return ret;
+ }
+
+ if (npu_version == 0 && !udma_modify_cmd_in_white_list(in_cmd_type)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "release version not support modify cmd type=%d.\n",
+ in_cmd_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_dfx_modify_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_query_inbuf *modify_inbuf = (struct ub_query_inbuf *)buf_in;
+ udma_ioctl_func_t func = NULL;
+ u32 cmd_type;
+ int ret = -EINVAL;
+ u32 i;
+
+ /* check in buf size */
+ if (in_size < (u32)sizeof(struct ub_query_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma dfx modify buffer in size too small\n");
+ return -EINVAL;
+ }
+
+ ret = udma_verify_modify_func(udma_dev, modify_inbuf->cmd_type);
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_DFX, "UDMA dfx modfiy cmd verify failed.\n");
+ return ret;
+ }
+
+ for (i = 0; i < sizeof(g_udma_modify_cmd_funcs) /
+ sizeof(g_udma_modify_cmd_funcs[0]);
+ i++) {
+ cmd_type = ub_dfx_get_cmd_type(
+ g_udma_modify_cmd_funcs[i].cmd_type,
+ g_udma_modify_cmd_funcs[i].sub_type,
+ g_udma_modify_cmd_funcs[i].source_type);
+ if (cmd_type == modify_inbuf->cmd_type) {
+ if (udma_dfx_check_device_notmatch_for_modify(
+ udma_dev,
+ g_udma_modify_cmd_funcs[i].cmd_type,
+ g_udma_modify_cmd_funcs[i].sub_type)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "call modify func, cmd type(%u), sub_type(%u) and device not match, check the device name is tpf or pf.\n",
+ g_udma_modify_cmd_funcs[i].cmd_type,
+ g_udma_modify_cmd_funcs[i].sub_type);
+ break;
+ }
+ func = g_udma_modify_cmd_funcs[i].cmd_func;
+ if (func != NULL) {
+ ret = func(udma_dev, buf_in, in_size, buf_out,
+ out_size);
+ udma_dfx_print(
+ "call modify func, cmd_type:%u, sub_type:%u, source_type:%u\n",
+ g_udma_modify_cmd_funcs[i].cmd_type,
+ g_udma_modify_cmd_funcs[i].sub_type,
+ g_udma_modify_cmd_funcs[i].source_type);
+ }
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.h
new file mode 100644
index 000000000..0a6479487
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_modify.h
@@ -0,0 +1,15 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_MODIFY_H
+#define UDMA_DFX_MODIFY_H
+
+#include <linux/types.h>
+#include "udma_common.h"
+
+int udma_dfx_modify_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int udma_verify_modify_func(struct udma_device *udma_dev, u32 in_cmd_type);
+
+#endif /* UDMA_DFX_MODIFY_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.c
new file mode 100644
index 000000000..d69fd1013
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.c
@@ -0,0 +1,108 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "ub_mpu_cmd.h"
+#include "udma_dfx.h"
+#include "udma_dfx_perf_ctr.h"
+
+static int udma_read_perf_counter(struct udma_device *udma_dev,
+ ub_dfx_perf_ctr_cmd_inbuf_s *cmd_in,
+ struct ub_perf_ctr_outbuf *cmd_ret)
+{
+ u16 out_size = (u16)sizeof(struct ub_perf_ctr_outbuf);
+ int ret;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_READ_PERF_CTR, cmd_in,
+ sizeof(ub_dfx_perf_ctr_cmd_inbuf_s),
+ cmd_ret, &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || cmd_ret->head.status != 0) {
+ udma_err(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "read perf counter failed, err(%d), status(0x%x), "
+ "out size(0x%x)\n",
+ ret, cmd_ret->head.status, out_size);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int udma_dfx_query_perf_ctr(struct udma_device *udma_dev,
+ const struct ub_perf_ctr_inbuf *inbuf,
+ struct ub_perf_ctr_outbuf *outbuf)
+
+{
+ struct ub_perf_ctr_outbuf *ctr_cur = outbuf;
+ struct ub_dfx_perf_ctr_cmd_inbuf cmd_in = { 0 };
+ int ret;
+
+ cmd_in.gap_index = inbuf->gap_index;
+ ret = udma_read_perf_counter(udma_dev, &cmd_in, ctr_cur);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query perf ctr for realtime: read counter failed, ret(%d)\n",
+ ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static struct udma_dfx_perf_ctr_cmd_func g_udma_cmd_funcs[] = {
+ { UB_PERF_CMD_TYPE, udma_dfx_query_perf_ctr },
+};
+
+int udma_dfx_perf_ctr_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_perf_ctr_inbuf *inbuf = (struct ub_perf_ctr_inbuf *)buf_in;
+ struct ub_perf_ctr_outbuf *outbuf =
+ (struct ub_perf_ctr_outbuf *)buf_out;
+ udma_dfx_perf_ctr_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ /* check in and out buf size */
+ if (in_size < (u32)sizeof(struct ub_perf_ctr_inbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "udma dfx perf ctr buffer in size too small\n");
+ return -EINVAL;
+ }
+ if (*out_size < (u32)sizeof(struct ub_perf_ctr_outbuf)) {
+ udma_err(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "udma dfx perf ctr buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+ for (i = 0; i < sizeof(g_udma_cmd_funcs) / sizeof(g_udma_cmd_funcs[0]);
+ i++) {
+ cmd_type = g_udma_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->cmd_type) {
+ func = g_udma_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "%s: function of cmd(0x%x) is not supported\n",
+ __func__, cmd_type);
+ return -EINVAL;
+ }
+
+ *out_size = sizeof(struct ub_perf_ctr_outbuf);
+
+ return func(udma_dev, inbuf, outbuf);
+ }
+ }
+
+ return -EINVAL;
+}
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.h
new file mode 100644
index 000000000..e5fc07e23
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_ctr.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_PERF_CTR_H
+#define UDMA_DFX_PERF_CTR_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+typedef int (*udma_dfx_perf_ctr_func_t)(struct udma_device *udma_dev,
+ const struct ub_perf_ctr_inbuf *inbuf,
+ struct ub_perf_ctr_outbuf *outbuf);
+
+struct udma_dfx_perf_ctr_cmd_func {
+ u32 cmd_id;
+ udma_dfx_perf_ctr_func_t cmd_func;
+};
+
+int udma_dfx_perf_ctr_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* UDMA_DFX_PERF_CTR_H */
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.c
new file mode 100644
index 000000000..0e69f69b8
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.c
@@ -0,0 +1,152 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "udma_jetty.h"
+#include "udma_segment.h"
+#include "udma_rc_table.h"
+#include "udma_tpg.h"
+#include "udma_vtp.h"
+#include "udma_tp.h"
+#include "ub_pub_cmd.h"
+#include "udma_dfx.h"
+#include "udma_dfx_perf_query.h"
+
+static int udma_check_device_ver(struct udma_device *udma_dev,
+ const struct ub_perf_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args)
+{
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "device type(%d) does not support the command for performance query.",
+ udma_dev->device_type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void udma_dfx_fill_perf_stat_outbuf(u8 clear_flag,
+ struct ub_perf_query_outbuf *buf_out,
+ struct cmdq_rtt *rtt)
+{
+ buf_out->dispatch_times = (u64)atomic64_read(&rtt->times);
+ buf_out->cmdq_rtt_sum = (u64)atomic64_read(&rtt->cmdq_rtt_sum);
+ buf_out->cmdq_npu_rtt_sum = (u64)atomic64_read(&rtt->cmdq_npu_rtt_sum);
+ if (clear_flag != 0) {
+ atomic64_set(&rtt->times, 0);
+ atomic64_set(&rtt->cmdq_rtt_sum, 0);
+ atomic64_set(&rtt->cmdq_npu_rtt_sum, 0);
+ }
+}
+
+static int udma_dfx_perf_query_stat(struct udma_device *udma_dev,
+ const struct ub_perf_query_inbuf *buf_in,
+ struct ub_perf_query_outbuf *buf_out)
+{
+ u32 offset = 0;
+ void *node = NULL;
+ switch (buf_in->cmd_type) {
+ case UB_QUERY_TYPE_JETTY:
+ node = (void *)udma_find_jetty(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_jetty, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_JFS:
+ node = (void *)udma_find_jfs(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_jfs, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_JFR:
+ node = (void *)udma_find_jfr(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_jfr, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_RC_QUEUE:
+ node = (void *)udma_find_rcq(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_rc_queue, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_SEG:
+ node = (void *)udma_seg_find(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_segment, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_TPG:
+ node = (void *)udma_get_tpg_by_id(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_tpg, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_VTP:
+ node = (void *)udma_get_vtp_by_id(udma_dev, buf_in->xid,
+ buf_in->vfid);
+ offset = offsetof(struct udma_vtp, cmdq_rtt);
+ break;
+ case UB_QUERY_TYPE_TP:
+ node = (void *)udma_find_tp(udma_dev, buf_in->xid);
+ offset = offsetof(struct udma_tp, cmdq_rtt);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_DFX, "invalid cmd type:%u\n",
+ buf_in->cmd_type);
+ return -EINVAL;
+ }
+ if (node == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "query perf stat fail, cmd_type:%u, id:%u\n",
+ buf_in->cmd_type, buf_in->xid);
+ return -EINVAL;
+ }
+ udma_dfx_fill_perf_stat_outbuf(buf_in->clear_flag, buf_out,
+ (struct cmdq_rtt *)(node + offset));
+ udma_dfx_obj_put(udma_dev, buf_in->cmd_type, node, buf_in->xid);
+ return 0;
+}
+
+static struct udma_dfx_perf_query_cmd_func g_udma_perf_query_cmd_funcs[] = {
+ { UB_QUERY_TYPE_JETTY, udma_check_device_ver,
+ udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_JFS, udma_check_device_ver, udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_JFR, udma_check_device_ver, udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_RC_QUEUE, udma_check_device_ver,
+ udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_SEG, udma_check_device_ver, udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_TPG, udma_check_device_ver, udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_VTP, udma_check_device_ver, udma_dfx_perf_query_stat },
+ { UB_QUERY_TYPE_TP, udma_check_device_ver, udma_dfx_perf_query_stat },
+};
+
+int udma_dfx_perf_query_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_perf_query_inbuf *inbuf =
+ (struct ub_perf_query_inbuf *)buf_in;
+ struct ub_perf_query_outbuf *outbuf =
+ (struct ub_perf_query_outbuf *)buf_out;
+ udma_dfx_perf_query_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+
+ *out_size = 0;
+ for (i = 0; i < sizeof(g_udma_perf_query_cmd_funcs) /
+ sizeof(g_udma_perf_query_cmd_funcs[0]);
+ i++) {
+ cmd_type = g_udma_perf_query_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->cmd_type) {
+ func = g_udma_perf_query_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "%s: function of cmd(0x%x) is not supported\n",
+ __func__, cmd_type);
+ return -EINVAL;
+ }
+
+ *out_size = sizeof(struct ub_perf_query_outbuf);
+
+ return func(udma_dev, inbuf, outbuf);
+ }
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.h
new file mode 100644
index 000000000..ec1e450eb
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_perf_query.h
@@ -0,0 +1,29 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_DFX_PERF_QUERY_H
+#define UDMA_DFX_PERF_QUERY_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+#include "udma_dfx.h"
+
+typedef int (*udma_dfx_perf_query_func_t)(
+ struct udma_device *udma_dev, const struct ub_perf_query_inbuf *inbuf,
+ struct ub_perf_query_outbuf *outbuf);
+typedef int (*udma_perf_query_check_func_t)(
+ struct udma_device *udma_dev, const struct ub_perf_query_inbuf *buf_in,
+ const struct udma_dfx_check_args *check_args);
+
+struct udma_dfx_perf_query_cmd_func {
+ u32 cmd_id;
+ udma_perf_query_check_func_t check_func;
+ udma_dfx_perf_query_func_t cmd_func;
+};
+
+int udma_dfx_perf_query_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* UDMA_DFX_PERF_QUERY_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.c
new file mode 100644
index 000000000..319d7472d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.c
@@ -0,0 +1,182 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#include "ub_mpu_cmd.h"
+#include "comm_defs.h"
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "udma_dfx.h"
+#include "udma_dfx_port_sta.h"
+
+static int udma_read_port_counter(struct udma_device *udma_dev,
+ ub_dfx_port_statistics_cmd_inbuf_s *cmd_in,
+ struct ub_dfx_port_statistics_cmd *cmd_ret)
+{
+ u16 out_size = (u16)sizeof(struct ub_dfx_port_statistics_cmd);
+ int ret;
+
+ ret = hinic5_msg_to_mgmt_sync(
+ udma_dev->hwdev, HINIC5_MOD_UB, UB_MPU_CMD_DFX_READ_PORT_STA,
+ cmd_in, sizeof(ub_dfx_port_statistics_cmd_inbuf_s), cmd_ret,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || cmd_ret->head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "read port statistics counter failed, err(%d), status(0x%x), "
+ "out size(0x%x)\n",
+ ret, cmd_ret->head.status, out_size);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "port traffic query counter success from mpu\n");
+
+ return 0;
+}
+
+static int udma_read_vf_counter(struct udma_device *udma_dev,
+ ub_dfx_vf_statistics_cmd_inbuf_s *cmd_in,
+ struct ub_dfx_port_statistics_cmd *cmd_ret)
+{
+ u16 out_size = (u16)sizeof(struct ub_dfx_port_statistics_cmd);
+ int ret;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_DFX_READ_VF_STA, cmd_in,
+ sizeof(ub_dfx_vf_statistics_cmd_inbuf_s),
+ cmd_ret, &out_size, 0, HINIC5_CHANNEL_UB);
+ if (ret != 0 || out_size == 0 || cmd_ret->head.status != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "read vf statistics counter failed, err(%d), status(0x%x), "
+ "out size(0x%x)\n",
+ ret, cmd_ret->head.status, out_size);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "vf traffic query counter success from mpu\n");
+
+ return 0;
+}
+
+int udma_dfx_query_port_sta_realtime(struct udma_device *udma_dev,
+ const struct ub_port_sta_inbuf *inbuf,
+ union ub_port_sta_outbuf *outbuf)
+{
+ struct ub_dfx_port_statistics_cmd *port_traffic = &outbuf->port_traffic;
+ ub_dfx_port_statistics_cmd_inbuf_s cmd_in = { 0 };
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query port traffic port_id(%u) cos(%u)\n", inbuf->port_id,
+ inbuf->cos);
+ cmd_in.port_id = inbuf->port_id;
+ cmd_in.cos = inbuf->cos;
+ ret = udma_read_port_counter(udma_dev, &cmd_in, port_traffic);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query port traffic for realtime: read counter failed, ret(%d)\n",
+ ret);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query port traffic for realtime success\n");
+
+ return 0;
+}
+
+int udma_dfx_query_vf_sta_realtime(struct udma_device *udma_dev,
+ const struct ub_port_sta_inbuf *inbuf,
+ union ub_port_sta_outbuf *outbuf)
+{
+ struct ub_dfx_port_statistics_cmd *port_traffic = &outbuf->port_traffic;
+ struct ub_dfx_vf_statistics_cmd_inbuf cmd_in = { 0 };
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query vf traffic vf_id(%u)\n", inbuf->vf_id);
+ cmd_in.vf_id = inbuf->vf_id;
+ ret = udma_read_vf_counter(udma_dev, &cmd_in, port_traffic);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query vf traffic for realtime: read counter failed, ret(%d)\n",
+ ret);
+ return -EFAULT;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "query vf traffic for realtime success\n");
+
+ return 0;
+}
+
+static struct udma_dfx_port_sta_cmd_func g_udma_port_cmd_funcs[] = {
+ { UB_PORT_STA_RTCB, udma_dfx_query_port_sta_realtime },
+ { UB_VF_STA_RTCB, udma_dfx_query_vf_sta_realtime },
+};
+
+int udma_dfx_port_sta_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_port_sta_inbuf *inbuf = (struct ub_port_sta_inbuf *)buf_in;
+ union ub_port_sta_outbuf *outbuf = (union ub_port_sta_outbuf *)buf_out;
+ udma_dfx_port_sta_func_t func = NULL;
+ u32 cmd_type;
+ u32 i;
+ int ret;
+
+ /* check in and out buf size */
+ if (in_size < (u32)sizeof(struct ub_port_sta_inbuf)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "udma dfx query port/vf sta realtime buffer in size too small\n");
+ return -EINVAL;
+ }
+ if (*out_size < (u32)sizeof(union ub_port_sta_outbuf)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "udma dfx query port/vf sta realtime buffer out size too small\n");
+ return -EINVAL;
+ }
+
+ *out_size = 0;
+ for (i = 0; i < sizeof(g_udma_port_cmd_funcs) /
+ sizeof(g_udma_port_cmd_funcs[0]);
+ i++) {
+ cmd_type = g_udma_port_cmd_funcs[i].cmd_id;
+ if (cmd_type == inbuf->cmd_type) {
+ func = g_udma_port_cmd_funcs[i].cmd_func;
+ if (func == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "%s: function of cmd(0x%x) is not supported\n",
+ __func__, cmd_type);
+ return -EINVAL;
+ }
+
+ ret = func(udma_dev, inbuf, outbuf);
+ if (ret != 0) {
+ *out_size = 0;
+ return ret;
+ }
+
+ *out_size = sizeof(union ub_port_sta_outbuf);
+ return 0;
+ }
+ }
+
+ udma_err(udma_dev->dev, UDMA_M_PORT_STA_DFX,
+ "%s: cmd(0x%x) is not exist\n", __func__, cmd_type);
+
+ return -EINVAL;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.h
new file mode 100644
index 000000000..d3117916a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_port_sta.h
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_PORT_STA_H
+#define UDMA_DFX_PORT_STA_H
+
+#include <linux/types.h>
+#include "ub_pub_cmd.h"
+#include "udma_common.h"
+
+typedef int (*udma_dfx_port_sta_func_t)(struct udma_device *udma_dev,
+ const struct ub_port_sta_inbuf *inbuf,
+ union ub_port_sta_outbuf *outbuf);
+
+struct udma_dfx_port_sta_cmd_func {
+ u32 cmd_id;
+ udma_dfx_port_sta_func_t cmd_func;
+};
+
+int udma_dfx_port_sta_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+
+#endif /* UDMA_DFX_PORT_STA_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.c
new file mode 100644
index 000000000..3539968aa
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.c
@@ -0,0 +1,861 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/types.h>
+#include "hinic5_hw.h"
+#include "udma_common.h"
+#include "ub_pub_cmd.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_tpg.h"
+#include "udma_cmd_vtp.h"
+#include "udma_dfx.h"
+#include "udma_tp.h"
+#include "udma_tpg.h"
+#include "udma_query.h"
+#include "udma_dfx_latch.h"
+#include "udma_dfx_query_tp.h"
+
+static int
+udma_dfx_query_tpc_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_dfx_tp_ctx_query *tpc = &outbuf->tp;
+ struct ubcore_res_key key = { 0 };
+ int ret;
+
+ (void)memset_s(tpc, sizeof(struct ub_dfx_tp_ctx_query), 0,
+ sizeof(struct ub_dfx_tp_ctx_query));
+ key.type = UBCORE_RES_KEY_TP;
+ key.key = inbuf->tpn;
+ ret = udma_query_ctx(&udev->ub_dev, &key, (void *)tpc);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to query tpc from cache, tpn=%u, ret=%d!",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tpc_from_host_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_dfx_tp_ctx_query *tpc_ctx = &outbuf->tp;
+ int ret;
+
+ ret = udma_query_tp_ctx_from_host(udev, inbuf->tpn, tpc_ctx);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get tp ctx from host, tpn=%u, ret=%d",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int udma_dfx_query_tp_mpt_from_list(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_mapt_ctx_query *tp_mpt = &outbuf->mpt;
+ int ret;
+
+ ret = udma_query_tp_mpt_from_host(udev, inbuf->tpn, tp_mpt);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get tp mpt from host, tpn=%u, ret=%d",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int udma_dfx_query_tp_pcqc_from_list(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_pcqc_query_rsp_s *pcqc = &outbuf->pcqc;
+ int ret;
+
+ ret = udma_query_tp_pcqc_from_host(udev, inbuf->tpn, pcqc);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "Failed to get tp pcqc from host, tpn=%u, ret=%d",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int
+udma_dfx_query_tp_wqe_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_tp_wqe *tpqe = &outbuf->tpqe;
+ int ret;
+
+ (void)memset_s(tpqe, sizeof(struct ub_tp_wqe), 0,
+ sizeof(struct ub_tp_wqe));
+
+ ret = udma_cmd_tp_query_wqe(udev, inbuf->tpn, inbuf->wqe_id, tpqe,
+ sizeof(struct ub_tp_wqe));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_wqe_from_cache_exec failed! tpn(%u) ci(%u) ret(%d)",
+ inbuf->tpn, inbuf->wqe_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_tp_wqe_from_host_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_tp_wqe *tpqe = &outbuf->tpqe;
+ int ret;
+
+ (void)memset_s(tpqe, sizeof(struct ub_tp_wqe), 0,
+ sizeof(struct ub_tp_wqe));
+
+ ret = udma_query_tp_wqe_from_host(udev, inbuf->tpn, inbuf->wqe_id, tpqe,
+ sizeof(struct ub_tp_wqe));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_wqe_from_host_exec failed! tpn(%u) ci(%u) ret(%d)",
+ inbuf->tpn, inbuf->wqe_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_tp_pcqc_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ ub_pcqc_query_rsp_s *pcqc = &outbuf->pcqc;
+ int ret;
+
+ ret = udma_cmd_tp_query_pcqc(udev, inbuf->tpn, pcqc,
+ sizeof(ub_pcqc_query_rsp_s));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query tp pcqc from cache, tpn = %u, ret=%d!",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tpc_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpc_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tpc_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tpc_from_host(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpc_host failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tpc_from_host_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_mpt(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_mpt failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_mpt_from_list(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_pcqc_from_host(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_pcqc failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_pcqc_from_list(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_wqe_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_wqe_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_wqe_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_wqe_from_host(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_wqe_from_host failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_wqe_from_host_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_pcqc_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_pcqc_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_pcqc_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_tp_mtt_from_list(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_tp *ub_tp = NULL;
+ struct mtt *ub_mtt = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ inbuf->tpn, false);
+ if (cqm_obj == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "failed to get cqm object, tpn = %u\n", inbuf->tpn);
+ return -EINVAL;
+ }
+ ub_tp = udma_find_tp(udev, inbuf->tpn);
+ if (ub_tp == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX, "failed to find tp, tpn = %u\n",
+ inbuf->tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ udma_tp_put(ub_tp);
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL) {
+ udma_err(udev->dev, UDMA_M_DFX,
+ "failed to get ub_tp, tpn = %u\n", inbuf->tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ ub_mtt = (struct mtt *)&ub_tp->ub_mtt;
+
+ ret = udma_dfx_query_cmtt(udev, ub_mtt, outbuf);
+
+cleanup:
+ cqm5_object_put(cqm_obj);
+ return ret;
+}
+
+static int udma_dfx_query_tp_mtt(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_mtt failed, ret=%d!\n", ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tp_mtt_from_list(udma_dev, inbuf, outbuf);
+}
+
+static int
+udma_dfx_query_tp_num_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ u32 *tp_state_num = outbuf->tp_state_num;
+ int ret;
+
+ ret = udma_cmd_tp_query_cnt(udev, tp_state_num,
+ sizeof(outbuf->tp_state_num));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_num_from_cache_exec failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tp_num_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_num_from_cache failed.\n");
+ return ret;
+ }
+
+ return udma_dfx_query_tp_num_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_oor_tp_info_from_cache(struct udma_device *udma_dev,
+ const void *buf_in,
+ u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ struct ub_oor_tp_info *oor_tp_info = &outbuf->oor_tp_info;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_oor_tp_info_from_cache failed.\n");
+ return ret;
+ }
+
+ ret = udma_cmd_tp_query_oor_info(udma_dev, inbuf->tpn, inbuf->msn,
+ oor_tp_info,
+ sizeof(struct ub_oor_tp_info));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_cmd_tp_query_oor_info failed, ret=%d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tp_msn_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ struct ub_msn_entry_outbuf *tp_msn_entry = &outbuf->msn_entry_info;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_oor_tp_info_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ ret = udma_cmd_tp_query_msn_entry(udma_dev, inbuf->tpn,
+ inbuf->entry_index, tp_msn_entry,
+ sizeof(struct ub_msn_entry_outbuf));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_cmd_tp_query_msn_entry failed, ret=%d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tp_cc_info_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out,
+
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ ub_cc_dfx_info_s *cc_info = &outbuf->cc_info;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_cc_info_from_cache failed.\n");
+ return ret;
+ }
+
+ ret = udma_cmd_tp_query_cc_info(udma_dev, inbuf->tpn, cc_info);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_cc_info_from_cache failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tp_q_depth(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_q_depth failed.\n");
+ return ret;
+ }
+
+ outbuf->q_depth = udma_sysfs_get_tp_depth(&udma_dev->sysfs_res);
+
+ return 0;
+}
+
+static int
+udma_dfx_query_tpg_ctx_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_tpg_ctx_query *tpg_ctx = &outbuf->tpg_ctx;
+ int ret;
+
+ ret = udma_cmd_tpg_query_ctx_from_cache(
+ udev, inbuf->tpg_id, tpg_ctx, sizeof(struct ub_tpg_ctx_query));
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpg_ctx_from_cache_exec failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tpg_ctx_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpg_ctx_from_cache failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tpg_ctx_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int udma_dfx_query_vtp_ctx_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ struct ub_vtp_ctx_query *vtp_ctx = &outbuf->vtp_ctx;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_vtp_ctx_from_cache failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+
+ ret = udma_cmd_query_vtp(udma_dev, inbuf->vfid, inbuf->vtp_id, vtp_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_vtp_ctx_from_cache failed, ret=%d.\n",
+ ret);
+ return ret;
+ }
+ return ret;
+}
+
+static int udma_dfx_query_tp_srp_bitmap_from_cache(struct udma_device *udma_dev,
+ const void *buf_in,
+ u32 in_size, void *buf_out,
+ u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ struct ub_cmd_tp_query_srp_bitmap_outbuf *srp_bitmap =
+ &outbuf->srp_bitmap;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_srp_bitmap_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ ret = udma_cmd_tp_query_srp_bitmap(
+ udma_dev, inbuf->tpn, srp_bitmap,
+ sizeof(struct ub_cmd_tp_query_srp_bitmap_outbuf));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma query tpn(%u) srp bitmap from_cache failed, ret=%d.\n",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_tp_srp_ctr_bitmap_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf *srp_ctr_bitmap =
+ &outbuf->srp_ctr_bitmap;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tp_srp_ctr_bitmap_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ ret = udma_cmd_tp_query_srp_ctr_bitmap(
+ udma_dev, inbuf->tpn, srp_ctr_bitmap,
+ sizeof(struct ub_cmd_tp_query_srp_ctr_bitmap_outbuf));
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma query tpn(%u) srp ctr bitmap from_cache failed, ret=%d.\n",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+udma_dfx_query_tpg_flow_from_cache_exec(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_tpg_flow *val = &outbuf->tpg_flow;
+ int ret;
+
+ val->tpgn = inbuf->tpg_id;
+ ret = udma_query_tpg_flow(udma_dev, val);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpg_flow_from_cache_exec failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tpg_flow_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "udma_dfx_query_tpg_flow_from_cache failed, ret=%d!\n",
+ ret);
+ return ret;
+ }
+
+ return udma_dfx_query_tpg_flow_from_cache_exec(udma_dev, inbuf, outbuf);
+}
+
+static int
+udma_dfx_query_tpc_ext_from_cache_exec(struct udma_device *udev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct ub_tp_ctx_ext_query *tpc_ext = &outbuf->tpc_ext;
+ struct ubcore_res_key key = { 0 };
+ int ret;
+
+ key.type = UBCORE_RES_KEY_TP;
+ key.key = inbuf->tpn;
+ memset_s(tpc_ext, sizeof(struct ub_tp_ctx_ext_query), 0,
+ sizeof(struct ub_tp_ctx_ext_query));
+
+ ret = udma_cmd_tp_query_ctx_ext(udev, &key, tpc_ext);
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_DFX,
+ "Failed to query extern tpc from cache, tpn(%u), ret(%d).",
+ inbuf->tpn, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int udma_dfx_query_tpc_ext_from_cache(struct udma_device *udma_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+ union ub_query_outbuf *outbuf = (union ub_query_outbuf *)buf_out;
+ int ret;
+
+ ret = udma_dfx_query_prepare(udma_dev, buf_out, out_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "[%s] Failed to prepare buf_out, ret(%d).\n", __func__,
+ ret);
+ return ret;
+ }
+
+ ret = udma_dfx_query_tpc_ext_from_cache_exec(udma_dev, inbuf, outbuf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "[%s] Failed to execute querying tpc ext, ret(%d).\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct udma_dfx_query_cmd_func g_udma_query_tp_cmd_funcs[] = {
+
+ /* query */
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_CTX, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tpc_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_CTX, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tpc_from_host },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_MPT, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tp_mpt },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_MTT, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tp_mtt },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_WQE, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_wqe_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_WQE, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tp_wqe_from_host },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_PCQC, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_pcqc_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_PCQC, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tp_pcqc_from_host },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_CNT, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_num_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_OOR_INFO, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_oor_tp_info_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_SRP_BITMAP, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_srp_bitmap_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_SRP_CTR_BITMAP,
+ UB_QUERY_FROM_CACHE, udma_dfx_query_tp_srp_ctr_bitmap_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_CC_INFO, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_cc_info_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_Q_DEPTH, UB_QUERY_FROM_HOST,
+ udma_dfx_query_tp_q_depth },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_CTX_EXT, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tpc_ext_from_cache },
+ { UB_QUERY_TYPE_TP, UB_QUERY_SUB_TYPE_MSN_ENTRY, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_msn_from_cache },
+
+ { UB_QUERY_TYPE_TPG, UB_QUERY_SUB_TYPE_CTX, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tpg_ctx_from_cache },
+ { UB_QUERY_TYPE_TPG, UB_QUERY_SUB_TYPE_FLOW, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tpg_flow_from_cache },
+
+ { UB_QUERY_TYPE_VTP, UB_QUERY_SUB_TYPE_CTX, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_vtp_ctx_from_cache },
+ { UB_QUERY_TYPE_TPG, UB_QUERY_SUB_TYPE_TP_LATCH, UB_QUERY_FROM_CACHE,
+ udma_dfx_query_tp_latch_data },
+};
+
+bool udma_dfx_check_device_notmatch_for_query(
+ const struct udma_device *udma_dev, u32 cmd_type, u32 sub_type)
+{
+ static const u32 tpf_obj_query[] = { UB_QUERY_TYPE_TP,
+ UB_QUERY_TYPE_TPG };
+ static const u32 pf_obj_query[] = {
+ UB_QUERY_TYPE_RC_QUEUE, UB_QUERY_TYPE_JETTY,
+ UB_QUERY_TYPE_JETTY_GROUP, UB_QUERY_TYPE_JFC,
+ UB_QUERY_TYPE_JFR, UB_QUERY_TYPE_JFS,
+ UB_QUERY_TYPE_SEG
+ };
+ bool ret = false;
+ u32 i = 0;
+ /* determine tp/tpg/utp must not be on pf device on */
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ for (i = 0; i < ARRAY_SIZE(tpf_obj_query); i++) {
+ if (cmd_type == tpf_obj_query[i]) {
+ ret = true;
+ break;
+ }
+ if (cmd_type == UB_QUERY_TYPE_DEV &&
+ (sub_type == UB_QUERY_SUB_TYPE_DIP ||
+ sub_type == UB_QUERY_SUB_TYPE_SIP)) {
+ ret = true;
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(pf_obj_query); i++) {
+ if (cmd_type == pf_obj_query[i]) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+int udma_dfx_query_tp_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct ub_query_inbuf *query_inbuf = (struct ub_query_inbuf *)buf_in;
+ udma_ioctl_func_t func = NULL;
+ u32 cmd_type;
+ int ret = -EINVAL;
+ u32 i;
+
+ for (i = 0; i < sizeof(g_udma_query_tp_cmd_funcs) /
+ sizeof(g_udma_query_tp_cmd_funcs[0]);
+ i++) {
+ cmd_type = ub_dfx_get_cmd_type(
+ g_udma_query_tp_cmd_funcs[i].cmd_type,
+ g_udma_query_tp_cmd_funcs[i].sub_type,
+ g_udma_query_tp_cmd_funcs[i].source_type);
+ if (cmd_type == query_inbuf->cmd_type) {
+ if (udma_dfx_check_device_notmatch_for_query(
+ udma_dev,
+ g_udma_query_tp_cmd_funcs[i].cmd_type,
+ g_udma_query_tp_cmd_funcs[i].sub_type)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_DFX,
+ "call query func, cmd type(%u), sub_type(%u) and device not match, check the device name is tpf or pf.\n",
+ g_udma_query_tp_cmd_funcs[i].cmd_type,
+ g_udma_query_tp_cmd_funcs[i].sub_type);
+ break;
+ }
+ /* TODO: later need to consider ICSL submission for invalid xid queue query of intercept */
+ func = g_udma_query_tp_cmd_funcs[i].cmd_func;
+ if (func != NULL) {
+ ret = func(udma_dev, buf_in, in_size, buf_out,
+ out_size);
+ udma_dfx_print(
+ "call query tp func, cmd_type:%u, sub_type:%u, source_type:%u\n",
+ g_udma_query_tp_cmd_funcs[i].cmd_type,
+ g_udma_query_tp_cmd_funcs[i].sub_type,
+ g_udma_query_tp_cmd_funcs[i]
+ .source_type);
+ }
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.h
new file mode 100644
index 000000000..417c5e53f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/dfx/udma_dfx_query_tp.h
@@ -0,0 +1,16 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_DFX_QUERY_TP_H
+#define UDMA_DFX_QUERY_TP_H
+
+#include <linux/types.h>
+#include "udma_common.h"
+
+int udma_dfx_query_tp_func(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+bool udma_dfx_check_device_notmatch_for_query(
+ const struct udma_device *udma_dev, u32 cmd_type, u32 sub_type);
+
+#endif /* UDMA_DFX_QUERY_TP_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.c b/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.c
new file mode 100644
index 000000000..60adf80ee
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.c
@@ -0,0 +1,1457 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
+
+#include "comm_defs.h"
+#include "hmm_common.h"
+#include "hmm_em_inner.h"
+#include "hinic5_crm.h"
+#include "hinic5_profile.h"
+#include "ub_mpu_cmd.h"
+#include "ub_aeqe.h"
+#include "ubcore_api.h"
+#include "udma_common.h"
+#include "udma_jetty.h"
+#include "udma_comp.h"
+#include "udma_device.h"
+#include "udma_cqm.h"
+#include "udma_cmd.h"
+#include "udma_rc_table.h"
+#include "udma_jfc.h"
+#include "udma_tp.h"
+#include "udma_vtp.h"
+#include "udma_cmd_event.h"
+#include "udma_cmd_jetty.h"
+#include "udma_misc.h"
+#include "udma_vram.h"
+#include "udma_dfx_latch.h"
+#include "udma_resource.h"
+
+#define UB_MTT_PAGE_SIZE_4K 4096
+#define UB_MTT_PAGE_SIZE_64K (64 * 1024)
+#define UB_MTT_PAGE_SIZE_2M (2 * 1024 * 1024)
+#define UB_MTT_PAGE_SIZE_4K_SHIFT 12
+#define UB_MTT_PAGE_SIZE_64K_SHIFT 16
+#define UB_MTT_PAGE_SIZE_2M_SHIFT 21
+#define UB_EM_MIN_ORDER 2 /* ub rc extend table at least 4 page */
+#define UB_DEV_STATUS_BIT_PORT_LINK 0
+#define UB_CPU_ENDIAN_MAGIC 0x12345678
+#define LATCH_DATA_LEN_MASK 0xffff
+#define VTP_SWITCH_TIME_WAIT 100 // ms
+#define VTP_ROLLBACK_TIME_WAIT 20 // ms
+#define UBRC_TABLE_DEPTH_MIN 128
+#define UBRC_TABLE_DEPTH_MAX 256
+
+u32 g_ubrc_table_depth = 0U; /* rdma_rc table depth, used for write TAMSN engine manage WQE information */
+module_param(g_ubrc_table_depth, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ g_ubrc_table_depth,
+ "128 - 256, The value is a power of 2, otherwise the value is upward. default: 128");
+
+enum {
+ UDMA_MTT_PAGE_SIZE_4K = 0,
+ UDMA_MTT_PAGE_SIZE_64K = 1,
+ UDMA_MTT_PAGE_SIZE_2M = 2
+};
+
+enum {
+ UB_CL_TYPE_CQC_SRQC =
+ 0x4, /* cl_start: 0x120, cl_end: 0x13f, cl_size: 0 */
+};
+
+void udma_cq_completion(void *svc_hd, u32 cqn, void *cq_handler)
+{
+ struct udma_jfc *jfc = NULL;
+
+ if (cq_handler == NULL) {
+ udma_pr_err(UDMA_M_RESOURCE, "Cq_handler is null\n");
+ return;
+ }
+
+ jfc = (struct udma_jfc *)cq_handler;
+
+ ++jfc->arm_sn;
+
+ if (jfc->base.jfce_handler == NULL) {
+ udma_pr_err(UDMA_M_RESOURCE, "jfce_handler is null\n");
+ return;
+ }
+ jfc->base.jfce_handler(&jfc->base);
+}
+
+u8 udma_async_event_level(void *svc_hd, u8 event_type, u8 *val)
+{
+ (void)svc_hd;
+ (void)event_type;
+ (void)val;
+ return 0;
+}
+
+static void udma_handle_jfc_async_event(struct udma_device *udma_dev,
+ u32 jfc_id, u8 event_type)
+{
+ struct udma_jfc *jfc = NULL;
+ struct tag_cqm_object *cqm_obj_queue = NULL;
+
+ cqm_obj_queue = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_RDMA_SCQ,
+ jfc_id, false);
+ if (cqm_obj_queue == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Failed to get cqm obj queue, jfc_id:%u, event_type:%u\n",
+ jfc_id, event_type);
+ return;
+ }
+ jfc = udma_find_jfc(udma_dev, jfc_id);
+ if (jfc == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "event xid(%u) is jfc, but the context not found.\n",
+ jfc_id);
+ goto out;
+ }
+ udma_jfc_put(jfc);
+
+ jfc = cqmobj_to_ub_jfc(cqm_obj_queue);
+ if (jfc != NULL) {
+ udma_jfc_async_event(udma_dev, jfc, event_type);
+ } else {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "event xid(%u) is jfc, but the context not found.\n",
+ jfc_id);
+ }
+
+out:
+ cqm5_object_put(cqm_obj_queue);
+}
+
+static void udma_handle_jetty_grp_async_event(struct udma_device *udma_dev,
+ u32 xid, u8 event_type)
+{
+ struct udma_jetty_grp *jetty_grp = NULL;
+ struct tag_cqm_object *cqm_obj = NULL;
+ u32 jetty_grp_id = xid;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_RDMA_SCQ,
+ jetty_grp_id, false);
+ if (cqm_obj == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to get cqm obj queue, jetty_grp_id:%u, event_type:%u\n",
+ jetty_grp_id, event_type);
+ return;
+ }
+ jetty_grp = udma_find_jetty_group(udma_dev, jetty_grp_id);
+ if (jetty_grp == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "event xid(%u) is jetty grp, but the context not found.\n",
+ jetty_grp_id);
+ goto out;
+ }
+ udma_jetty_group_put(jetty_grp);
+ jetty_grp = cqmobj_to_ub_jetty_grp(cqm_obj);
+ if (jetty_grp != NULL) {
+ udma_jetty_grp_async_event(udma_dev, jetty_grp, event_type);
+ } else {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "event xid(%d) is jetty_grp, but the context not found.\n",
+ xid);
+ }
+
+out:
+ cqm5_object_put(cqm_obj);
+}
+
+static bool udma_refuse_report_flag_check(struct udma_device *udma_dev,
+ struct udma_tp *tp)
+{
+ if (tp->refuse_report_flush_done == 1) {
+ udma_warn_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "do not report event to ubcore when refuse_report_flush_done flag set, tpn(%u)\n",
+ tp->tp.tpn);
+ return true;
+ }
+
+ return false;
+}
+
+static void udma_handle_tp_async_event(struct udma_device *udma_dev,
+ union ub_aeqe_t *aeqe)
+{
+ u32 drop_aeqe_en = udma_dev->sysfs_res.dfx_ctx.drop_aeqe_en;
+ u32 debug_en = udma_dev->sysfs_res.dfx_ctx.debug_en;
+ struct tag_cqm_object *cqm_obj_queue = NULL;
+ struct ubcore_event event = { NULL };
+ struct ubcore_tp *ubc_tp = NULL;
+ struct udma_tp *tp = NULL;
+
+ udma_dump_tp_latch_info(udma_dev); /* dump tp latch data */
+ if (debug_en == 1 && drop_aeqe_en == 1) {
+ udma_warn_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "drop_aeqe_en(%u), drop tp aeqe\n",
+ drop_aeqe_en);
+ return;
+ }
+
+ cqm_obj_queue = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ aeqe->xid, false);
+ if (cqm_obj_queue == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Failed to get cqm obj queue, xid:%u, sub_type:%u\n",
+ aeqe->xid, aeqe->sub_type);
+ return;
+ }
+
+ tp = cqmobj_to_ub_tp(cqm_obj_queue);
+ if (tp->cqm_priv_type != UDMA_CQM_PRIV_TYPE_TP) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "cqm obj is not a tp, xid:%u, sub_type:%u, type:%u\n",
+ aeqe->xid, aeqe->sub_type, tp->cqm_priv_type);
+ goto out;
+ }
+
+ ubc_tp = (struct ubcore_tp *)&(tp->tp);
+
+ event.ub_dev = ubc_tp->ub_dev;
+ event.element.tp = ubc_tp;
+
+ switch (aeqe->sub_type) {
+ case UB_AEQ_TYPE_TP_FATAL_ERR:
+ case UB_AEQ_TYPE_TP_RETRY_EXCEED:
+ event.event_type = UBCORE_EVENT_TP_ERR;
+ break;
+ case UB_AEQ_TYPE_TP_ERR_FLUSH_EMPTY:
+ event.event_type = UBCORE_EVENT_TP_FLUSH_DONE;
+ if (udma_refuse_report_flag_check(udma_dev, tp))
+ goto out;
+ break;
+ case UB_AEQ_TYPE_TP_SUBHEALTH:
+ event.event_type = UBCORE_EVENT_TP_SUSPEND;
+ event.element.tp->state = UBCORE_TP_STATE_SUSPENDED;
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "unknown tp asyn event(%u).\n", aeqe->sub_type);
+ goto out;
+ }
+
+ udma_info_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "tp(%u) data udp(%u) ack udp(%u) report event(%u) to ubcore .\n",
+ aeqe->xid, event.element.tp->data_udp_start,
+ event.element.tp->ack_udp_start, event.event_type);
+ ubcore_dispatch_async_event(&event);
+
+out:
+ cqm5_object_put(cqm_obj_queue);
+}
+
+static void udma_handle_device_async_event(struct udma_device *udma_dev,
+ union ub_aeqe_t *aeqe)
+{
+ u32 drop_aeqe_en = udma_dev->sysfs_res.dfx_ctx.drop_aeqe_en;
+ u32 debug_en = udma_dev->sysfs_res.dfx_ctx.debug_en;
+ struct ubcore_event event = { 0 };
+
+ if (debug_en == 1 && drop_aeqe_en == 1) {
+ udma_warn_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "debug_en&drop_aeqe_en enable, drop device err aeqe\n");
+ return;
+ }
+
+ event.ub_dev = &udma_dev->ub_dev;
+ event.event_type = UBCORE_EVENT_DEV_FATAL;
+
+ udma_info_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "aeqe xid(%u) report event(%u) to ubcore.\n", aeqe->xid,
+ (u32)event.event_type);
+ ubcore_dispatch_async_event(&event);
+}
+
+static void udma_handle_jfs_async_event(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, u8 event_type)
+{
+ udma_jfs_async_event(udma_dev, jfs, event_type);
+ return;
+}
+
+static void udma_handle_jetty_async_event(struct udma_device *udma_dev,
+ union ub_aeqe_t *aeqe)
+{
+ struct tag_cqm_object *cqm_obj_queue = NULL;
+ struct udma_jetty *jetty = NULL;
+
+ cqm_obj_queue = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ aeqe->xid, false);
+ if (cqm_obj_queue == NULL) {
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Failed to get cqm obj, queue_type:%u id:%u, sub_type:%u\n",
+ aeqe->queue_type, aeqe->xid, aeqe->sub_type);
+ return;
+ }
+
+ jetty = cqmobj_to_ub_jetty(cqm_obj_queue);
+ if (jetty == NULL) {
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Failed to get jetty from object\n");
+ goto leave;
+ }
+
+ switch (jetty->cqm_priv_type) {
+ case UDMA_JETTY_TYPE_JFR:
+ udma_jfr_async_event(udma_dev, (struct udma_jfr *)jetty,
+ aeqe->sub_type);
+ break;
+ case UDMA_JETTY_TYPE_JFS:
+ udma_handle_jfs_async_event(udma_dev, (struct udma_jfs *)jetty,
+ aeqe->sub_type);
+ break;
+ case UDMA_JETTY_TYPE_JETTY:
+ udma_jetty_async_event(udma_dev, jetty, aeqe->sub_type);
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "Unknown jetty type(%u)\n",
+ jetty->cqm_priv_type);
+ break;
+ }
+
+leave:
+ cqm5_object_put(cqm_obj_queue);
+}
+
+static void udma_handle_ta_async_event(struct udma_device *udma_dev,
+ union ub_aeqe_t *aeqe)
+{
+ u32 drop_aeqe_en = udma_dev->sysfs_res.dfx_ctx.drop_aeqe_en;
+ u32 debug_en = udma_dev->sysfs_res.dfx_ctx.debug_en;
+
+ udma_dump_ta_latch_info(udma_dev);
+ if (debug_en == 1 && drop_aeqe_en == 1) {
+ udma_warn_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "drop_aeqe_en(%u), drop ta aeqe\n",
+ drop_aeqe_en);
+ return;
+ }
+
+ switch (aeqe->queue_type) {
+ case UB_AEQE_TYPE_JFC:
+ udma_handle_jfc_async_event(udma_dev, aeqe->xid,
+ aeqe->sub_type);
+ break;
+ case UB_AEQE_TYPE_JFR:
+ case UB_AEQE_TYPE_JFS:
+ case UB_AEQE_TYPE_JETTY:
+ udma_handle_jetty_async_event(udma_dev, aeqe);
+ break;
+ case UB_AEQE_TYPE_JETTY_GROUP:
+ udma_handle_jetty_grp_async_event(udma_dev, aeqe->xid,
+ aeqe->sub_type);
+ break;
+ case UB_AEQE_TYPE_TP_DFX:
+ case UB_AEQE_TYPE_TA_DFX:
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "fatal_dfx_event,type(%u),dfx_info(0x%x),xid(0x%x)\n",
+ aeqe->queue_type, aeqe->udf_dfx, aeqe->xid);
+ break;
+ case UB_AEQE_TYPE_JFRC:
+ udma_err_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "jfrc_dfx_event,type(%u),api_type(0x%x),api_err_code(0x%x),dfx_info(0x%x),xid(0x%x)\n",
+ aeqe->queue_type, aeqe->api_type, aeqe->api_err_code,
+ aeqe->udf_dfx, aeqe->xid);
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "unknown queue type(%u), udf_dfx(%u)\n",
+ aeqe->queue_type, aeqe->udf_dfx);
+ break;
+ }
+}
+
+static void udma_handle_vtp_async_event(struct udma_device *udma_dev,
+ union ub_aeqe_t *aeqe)
+{
+ u32 drop_aeqe_en = udma_dev->sysfs_res.dfx_ctx.drop_aeqe_en;
+ u32 debug_en = udma_dev->sysfs_res.dfx_ctx.debug_en;
+ struct ubcore_event event = { 0 };
+ struct udma_vtp *ub_vtp = NULL;
+ u64 cur_time = jiffies_to_msecs(jiffies);
+
+ if (debug_en == 1 && drop_aeqe_en == 1) {
+ udma_warn_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "drop_aeqe_en(%u), drop vtp aeqe\n",
+ drop_aeqe_en);
+ return;
+ }
+
+ ub_vtp = udma_get_vtp_by_id(udma_dev, aeqe->xid, aeqe->udf_dfx);
+ if (ub_vtp == NULL) {
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "vtp not found, vtpn:%u function_id:%u.\n",
+ aeqe->xid, aeqe->udf_dfx);
+ return;
+ }
+
+ event.ub_dev = ub_vtp->base.ub_dev;
+ event.element.vtp = &ub_vtp->base;
+
+ switch (aeqe->sub_type) {
+ case UB_AEQ_TYPE_VTP_MIG_ING_ERR:
+ event.event_type = UBCORE_EVENT_MIGRATE_VTP_SWITCH;
+ if (cur_time - ub_vtp->mig_switch_time < VTP_SWITCH_TIME_WAIT) {
+ goto OUT;
+ }
+ ub_vtp->mig_switch_time = cur_time;
+ break;
+ case UB_AEQ_TYPE_VTP_MIG_BACK_ERR:
+ event.event_type = UBCORE_EVENT_MIGRATE_VTP_ROLLBACK;
+ if (cur_time - ub_vtp->mig_rollback_time <
+ VTP_ROLLBACK_TIME_WAIT) {
+ goto OUT;
+ }
+ ub_vtp->mig_rollback_time = cur_time;
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "unknown queue type(%u)\n", aeqe->sub_type);
+ goto OUT;
+ }
+
+ udma_info_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "vtp(%u) report event(%u) to ubcore .\n", aeqe->xid,
+ event.event_type);
+ ubcore_dispatch_async_event(&event);
+OUT:
+ udma_vtp_put(ub_vtp);
+}
+
+static void udma_async_event_handle(u8 event_type, u8 *val,
+ struct udma_device *udma_dev)
+{
+ union ub_aeqe_t *aeqe = (union ub_aeqe_t *)val;
+ udma_info_limit(
+ udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "event_type(%d), qtype(%d), aeqe: xid(%u), credit_vld(%u), sub_type(%u), api_type(%u), dw0(0x%x), dfx_info(0x%x) .\n",
+ event_type, aeqe->queue_type, aeqe->xid, aeqe->credit_vld,
+ aeqe->sub_type, aeqe->api_type, aeqe->dw0_value,
+ aeqe->dw1_value);
+
+ switch (event_type) {
+ case UB_CQM_AEQE_TYPE_TA_INFO:
+ case UB_CQM_AEQE_TYPE_TA_WARN:
+ case UB_CQM_AEQE_TYPE_TA_ERR:
+ udma_handle_ta_async_event(udma_dev, aeqe);
+ break;
+ case UB_CQM_AEQE_TYPE_TP_INFO:
+ case UB_CQM_AEQE_TYPE_TP_WARN:
+ case UB_CQM_AEQE_TYPE_TP_ERR:
+ udma_handle_tp_async_event(udma_dev, aeqe);
+ break;
+ case UB_CQM_AEQE_TYPE_VTP_INFO:
+ case UB_CQM_AEQE_TYPE_VTP_WARN:
+ case UB_CQM_AEQE_TYPE_VTP_ERR:
+ udma_dump_ta_latch_info(udma_dev);
+ udma_handle_vtp_async_event(udma_dev, aeqe);
+ break;
+ case UB_CQM_AEQE_TYPE_DEVICE_ERR:
+ udma_handle_device_async_event(udma_dev, aeqe);
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_ASYNC_EVENT,
+ "unknown async event type(%u)\n", event_type);
+ return;
+ }
+
+ if (aeqe->credit_vld == UB_AEQE_CREDIT_ENABLE) {
+ udma_cmd_async_event_credit_return(udma_dev, 1);
+ }
+}
+
+void udma_async_event(void *udma_dev, u8 event_type, u8 *val)
+{
+ if (udma_dev == NULL || val == NULL) {
+ udma_pr_err_limit(UDMA_M_ASYNC_EVENT,
+ "udma_dev and val both are null\n");
+ return;
+ }
+
+ udma_async_event_handle(event_type, val,
+ (struct udma_device *)udma_dev);
+}
+
+static int udma_init_ubrc_table(struct udma_device *udma_dev,
+ struct udma_comp_priv *comp_priv)
+{
+ u32 ubrc_per_channel = 0; /* ubrc num per channel 128 + 16 */
+ u32 log_ubrc_per_seg = 0; /* min num of entry, 2^log_ubrc_per_seg */
+ u32 ubrc_pow_of_two = 0;
+ u32 channel_num = 0;
+ u32 ubrc_size = 0;
+ u32 max_order = 0; /* ubrc buddy max priority num */
+ int ret = 0;
+ u32 i = 0;
+
+ channel_num = udma_dev->ub_cap.dev_cap.max_jetty +
+ udma_dev->ub_cap.dev_cap.max_tp;
+ ubrc_per_channel = roundup_pow_of_two(comp_priv->ub_cap.ubrc_depth +
+ UBRC_EXT_ENTRY);
+ log_ubrc_per_seg = comp_priv->ub_cap.log_ubrc_seg;
+ ubrc_size = comp_priv->ub_cap.ubrc_entry_sz;
+ for (i = 1; i < (u64)channel_num * ubrc_per_channel; i = (i << 1))
+ max_order++;
+
+ max_order = (max_order > log_ubrc_per_seg) ?
+ (max_order - log_ubrc_per_seg) :
+ 0;
+
+ ret = hmm_buddy_init(&comp_priv->ubrc_buddy, max_order);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Initialize ubrc's buddy failed, ret(%d)\n", -ENOMEM);
+ return -ENOMEM;
+ }
+
+ ubrc_pow_of_two =
+ (u32)(HMM_EM_ROUNDUP_POW_OF_TWO(
+ (u32)((u64)channel_num * ubrc_per_channel)) &
+ 0xffffffff);
+
+ ret = hmm_em_init_table(comp_priv->hmm_priv.dev,
+ &comp_priv->ubrc_em_table, ubrc_size,
+ ubrc_pow_of_two, 0, UB_EM_MIN_ORDER);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Initialize ubrc's em_table failed, ret(%d)\n", ret);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ hmm_buddy_cleanup(&comp_priv->ubrc_buddy);
+
+ return -ENOMEM;
+}
+
+static void udma_deinit_ubrc_table(struct udma_comp_priv *comp_priv)
+{
+ hmm_em_cleanup_table(comp_priv->hmm_priv.dev,
+ &comp_priv->ubrc_em_table);
+
+ hmm_buddy_cleanup(&comp_priv->ubrc_buddy);
+}
+
+static int udma_init_table(struct udma_device *udma_dev,
+ struct udma_comp_priv *comp_priv)
+{
+ int ret;
+
+ ret = hmm_mtt_init(&comp_priv->hmm_priv);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Initialize mtt table failed, ret(%d)\n", ret);
+ return ret;
+ }
+
+ ret = udma_init_ubrc_table(udma_dev, comp_priv);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Initialize ubrc's table failed, ret(%d)\n", ret);
+ goto err_init_ubrc_table;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE, "UB init table successful\n");
+ return 0;
+
+err_init_ubrc_table:
+ hmm_mtt_cleanup(&comp_priv->hmm_priv);
+ return ret;
+}
+
+static void udma_deinit_table(struct udma_comp_priv *comp_priv)
+{
+ udma_deinit_ubrc_table(comp_priv);
+
+ hmm_mtt_cleanup(&comp_priv->hmm_priv);
+}
+
+static void copy_value_to_comp_priv(struct udma_device *udma_dev,
+ struct udma_comp_priv *comp_priv)
+{
+ struct ub_dev_cap_udma_res *udma_res_cap =
+ &udma_dev->ub_cap.dev_cap_res.udma_res;
+ struct ub_dev_cap_sdk_res *sdk_res_cap =
+ &udma_dev->ub_cap.dev_cap_res.sdk_res;
+
+ comp_priv->hmm_priv.dev_cap.mpt_entry_sz = sdk_res_cap->mpt_entry_sz;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_start = sdk_res_cap->dmtt_cl_start;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_end = sdk_res_cap->dmtt_cl_end;
+ comp_priv->hmm_priv.dev_cap.dmtt_cl_sz = sdk_res_cap->dmtt_cl_sz;
+ comp_priv->ub_cap.cmtt_cl_start = sdk_res_cap->cmtt_cl_start;
+ comp_priv->ub_cap.cmtt_cl_end = sdk_res_cap->cmtt_cl_end;
+ comp_priv->ub_cap.cmtt_cl_sz = sdk_res_cap->cmtt_cl_sz;
+ comp_priv->ub_cap.wqe_cl_start = sdk_res_cap->wqe_cl_start;
+ comp_priv->ub_cap.wqe_cl_end = sdk_res_cap->wqe_cl_end;
+ comp_priv->ub_cap.wqe_cl_sz = sdk_res_cap->wqe_cl_sz;
+
+ comp_priv->hmm_priv.dev_cap.log_mtt = udma_res_cap->log_mtt;
+ comp_priv->hmm_priv.dev_cap.num_mtts = udma_res_cap->num_mtts;
+ comp_priv->hmm_priv.dev_cap.log_mtt_seg = udma_res_cap->log_mtt_seg;
+ comp_priv->hmm_priv.dev_cap.mtt_entry_sz = udma_res_cap->mtt_entry_sz;
+ comp_priv->ub_cap.ubrc_entry_sz = udma_res_cap->ubrc_entry_size;
+ comp_priv->ub_cap.log_ubrc_seg = udma_res_cap->log_ubrc_seg;
+ comp_priv->ub_cap.ubrc_depth = udma_res_cap->ubrc_depth; // 128
+}
+
+static int udma_init_comp_priv(struct udma_device *udma_dev)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+ int ret;
+
+ if (udma_dev->hwdev == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE, "Hwdev is null\n");
+ return -EINVAL;
+ }
+
+ comp_priv = (struct udma_comp_priv *)devm_kzalloc(
+ udma_dev->dev, sizeof(struct udma_comp_priv), GFP_KERNEL);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Alloc memory for comp_priv failed, ret(%d)\n",
+ -ENOMEM);
+ return -ENOMEM;
+ }
+
+ comp_priv->hmm_priv.hwdev = udma_dev->hwdev;
+ comp_priv->hmm_priv.dev = udma_dev->dev;
+ copy_value_to_comp_priv(udma_dev, comp_priv);
+
+ switch (g_mtt_page_size) {
+ case UDMA_MTT_PAGE_SIZE_4K:
+ comp_priv->hmm_priv.mtt_page_size = UB_MTT_PAGE_SIZE_4K;
+ comp_priv->hmm_priv.mtt_page_shift = UB_MTT_PAGE_SIZE_4K_SHIFT;
+ break;
+ case UDMA_MTT_PAGE_SIZE_64K:
+ comp_priv->hmm_priv.mtt_page_size = UB_MTT_PAGE_SIZE_64K;
+ comp_priv->hmm_priv.mtt_page_shift = UB_MTT_PAGE_SIZE_64K_SHIFT;
+ break;
+ case UDMA_MTT_PAGE_SIZE_2M:
+ comp_priv->hmm_priv.mtt_page_size = UB_MTT_PAGE_SIZE_2M;
+ comp_priv->hmm_priv.mtt_page_shift = UB_MTT_PAGE_SIZE_2M_SHIFT;
+ break;
+ default:
+ comp_priv->hmm_priv.mtt_page_size = UB_MTT_PAGE_SIZE_4K;
+ comp_priv->hmm_priv.mtt_page_shift = UB_MTT_PAGE_SIZE_4K_SHIFT;
+ break;
+ }
+ ret = udma_init_table(udma_dev, comp_priv);
+ if (ret != 0) {
+ devm_kfree(udma_dev->dev, comp_priv);
+ return ret;
+ }
+
+ ret = hinic5_register_service_adapter(udma_dev->hwdev,
+ (void *)comp_priv, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "put ub_comp_res failed, ret(%d)\n", ret);
+ udma_deinit_table(comp_priv);
+ devm_kfree(udma_dev->dev, comp_priv);
+ return ret;
+ }
+
+ comp_priv->udma_dev = udma_dev;
+ return ret;
+}
+
+static int udma_init_cqm_server(struct udma_device *udma_dev)
+{
+ service_register_template_s svc_template = { 0 };
+ struct ub_dev_cap_sdk_res *sdk_res =
+ &udma_dev->ub_cap.dev_cap_res.sdk_res;
+
+ svc_template.service_type = SERVICE_T_UB;
+ svc_template.scq_ctx_size = sdk_res->cqc_entry_sz;
+ svc_template.srq_ctx_size = sdk_res->srqc_entry_sz;
+ svc_template.service_handle = udma_dev;
+ svc_template.embedded_cq_ceq_callback = NULL;
+ svc_template.no_cq_ceq_callback = NULL;
+ svc_template.shared_cq_ceq_callback = udma_cq_completion;
+ svc_template.aeq_level_callback = udma_async_event_level;
+ svc_template.aeq_callback = udma_async_event;
+
+ return cqm5_service_register(udma_dev->hwdev, &svc_template);
+}
+
+static int udma_alloc_ceqs(struct udma_device *udma_dev)
+{
+ struct ub_dev_cap_udma_res *udma_res =
+ &udma_dev->ub_cap.dev_cap_res.udma_res;
+ int ret;
+
+ ret = hinic5_alloc_ceqs(udma_dev->hwdev, SERVICE_T_UB,
+ (int)udma_res->num_ceq_vectors, udma_dev->ceqn,
+ &udma_dev->ceq_num);
+ if (ret < 0)
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to alloc cqes, num_comp_vectors(%u) .\n",
+ udma_res->num_ceq_vectors);
+
+ return ret;
+}
+
+static void udma_free_ceqs(struct udma_device *udma_dev)
+{
+ int i;
+
+ for (i = 0; i < udma_dev->ceq_num; ++i)
+ hinic5_free_ceq(udma_dev->hwdev, SERVICE_T_UB,
+ udma_dev->ceqn[i]);
+}
+
+static int udma_get_cpu_endian(struct udma_device *udma_dev)
+{
+ int cpu_mode = 0;
+ union {
+ u32 i;
+ u8 s[4]; /* 4 occupy bit symbol */
+ } c;
+ c.i = UB_CPU_ENDIAN_MAGIC;
+
+ if (c.s[0] == 0x12) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE, "CPU is be\n");
+ cpu_mode = 1;
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE, "CPU is le\n");
+ cpu_mode = 0;
+ }
+
+ return cpu_mode;
+}
+
+static int udma_set_func_cpu_endian(struct udma_device *udma_dev)
+{
+ struct ub_cmd_func_set_cpu_endian cmd = { 0 };
+ u16 cmd_size = sizeof(cmd);
+ int ret;
+
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ cmd.cpu_endian = (u8)udma_get_cpu_endian(udma_dev);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_SET_CPU_ENDIAN, &cmd,
+ sizeof(cmd), &cmd, &cmd_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_size == 0) || (cmd.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to set cpu endian, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, cmd.head.status, cmd_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void udma_fill_dev_default_cos(struct udma_device *udma_dev,
+ const struct ub_get_cfg_cap_resp *resp)
+{
+ u32 cos_value = 0;
+ udma_dev->default_cos.cfg_cos_en = 0; // default not support user configuration cos value
+ udma_dev->default_cos.jfrc_cos = resp->dev_cap.jfrc_cos;
+ udma_dev->default_cos.vf_default_cos = resp->dev_cap.vf_default_cos;
+ udma_dev->default_cos.pf_default_cos = resp->dev_cap.pf_default_cos;
+
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ return;
+ }
+
+ udma_dev->default_cos.func_cos = (u8)resp->dev_cap.func_cos;
+
+ cos_value = udma_dev->ub_cap.dev_cap.virtualization == 1 ?
+ resp->dev_cap.func_cos :
+ resp->dev_cap.default_jetty_cos;
+ udma_dev->default_cos.pf_default_cos = (u16)cos_value;
+ udma_dev->default_cos.vf_default_cos = (u16)cos_value;
+ udma_info(
+ udma_dev->dev, UDMA_M_DEV,
+ "get dev_default_cos virtualization:%u, func_cos:%u, jetty_cos:%u\n",
+ udma_dev->ub_cap.dev_cap.virtualization, resp->dev_cap.func_cos,
+ resp->dev_cap.default_jetty_cos);
+}
+
+void udma_print_dev_cap_info(const struct udma_device *udma_dev,
+ const struct ub_service_cap *ub_cap,
+ const struct ub_get_cfg_cap_resp *resp)
+{
+ udma_info(
+ udma_dev->dev, UDMA_M_DEV,
+ "get dev cap, max_jetty:0x%x, max_tp:0x%x, max_jfc:0x%x, max_jfr:0x%x, "
+ "max_jfs:0x%x, max_jfrc_depth:0x%x\n",
+ udma_dev->ub_cap.dev_cap.max_jetty,
+ udma_dev->ub_cap.dev_cap.max_tp,
+ udma_dev->ub_cap.dev_cap.max_jfc,
+ udma_dev->ub_cap.dev_cap.max_jfr,
+ udma_dev->ub_cap.dev_cap.max_jfs,
+ udma_dev->ub_cap.dev_cap_res.udma_res.jfrc_depth);
+
+ udma_info(
+ udma_dev->dev, UDMA_M_DEV,
+ "get dev cap, slice:0x%x, virtualization:0x%x, feature 0x%x\n",
+ udma_dev->slice, resp->dev_cap.virtualization,
+ udma_dev->ub_cap.dev_cap.feature.value);
+}
+
+static u32 udma_get_ta_resp_depth(enum udma_device_type device_type,
+ u32 default_depth)
+{
+ if (device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ g_ubrc_table_depth = default_depth;
+ return default_depth;
+ }
+
+ if (g_ubrc_table_depth < UBRC_TABLE_DEPTH_MIN ||
+ g_ubrc_table_depth > UBRC_TABLE_DEPTH_MAX) {
+ g_ubrc_table_depth = default_depth;
+ return default_depth;
+ }
+
+ return (u32)roundup_pow_of_two((u64)g_ubrc_table_depth);
+}
+
+int udma_get_device_cap(struct udma_device *udma_dev,
+ struct ub_service_cap *ub_cap)
+{
+ struct ub_get_cfg_cap_cmd cmd = { 0 };
+ struct ub_get_cfg_cap_resp resp = { 0 };
+ u16 resp_size = sizeof(resp);
+ u32 is_tpf = ub_cap->net_dev_cap.is_tpf;
+ struct ub_dev_cap_res *dev_cap_res = &udma_dev->ub_cap.dev_cap_res;
+ int ret;
+
+ if (udma_vram5_get_kexec_flag() == 1) {
+ return 0;
+ }
+
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_CFG_CAP, &cmd, sizeof(cmd),
+ &resp, &resp_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to get dev cap, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, resp.head.status, resp_size);
+ return -EINVAL;
+ }
+
+ (void)memcpy_s(&udma_dev->ub_cap.dev_cap_res.sdk_res,
+ sizeof(struct ub_dev_cap_sdk_res), &ub_cap->sdk_res,
+ sizeof(struct ub_dev_cap_sdk_res));
+ (void)memcpy_s(&udma_dev->ub_cap.net_dev_cap,
+ sizeof(struct ub_net_dev_cap), &ub_cap->net_dev_cap,
+ sizeof(struct ub_net_dev_cap));
+ (void)memcpy_s(&udma_dev->ub_cap.dev_cap_res.udma_res,
+ sizeof(struct ub_dev_cap_udma_res), &resp.udma_res,
+ sizeof(struct ub_dev_cap_udma_res));
+ (void)memcpy_s(&udma_dev->ub_cap.dev_cap, sizeof(struct ub_dev_cap),
+ &resp.dev_cap, sizeof(struct ub_dev_cap));
+
+ dev_cap_res->udma_res.ubrc_depth = udma_get_ta_resp_depth(
+ udma_dev->device_type, dev_cap_res->udma_res.ubrc_depth);
+
+ if ((ub_cap->sdk_res.max_jetty < resp.udma_res.max_jfrc_num) &&
+ (is_tpf == 0)) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "max_jetty[%u] is too small!.\n",
+ ub_cap->sdk_res.max_jetty);
+ return -EINVAL;
+ }
+
+ udma_dev->ub_cap.dev_cap.max_jetty =
+ (is_tpf == 0) ?
+ ub_cap->sdk_res.max_jetty - resp.udma_res.max_jfrc_num :
+ ub_cap->sdk_res.max_jetty;
+ udma_dev->ub_cap.dev_cap.max_jetty_grp = ub_cap->sdk_res.max_jetty_grp;
+ udma_dev->ub_cap.dev_cap.max_jfc = ub_cap->sdk_res.max_jfc;
+ udma_dev->ub_cap.dev_cap.max_jfr =
+ (is_tpf == 0) ? min(udma_dev->ub_cap.dev_cap.max_jetty,
+ ub_cap->sdk_res.max_jfr) :
+ 0;
+ udma_dev->ub_cap.dev_cap.max_tp = ub_cap->sdk_res.max_tp;
+ udma_dev->ub_cap.dev_cap.max_tpg = ub_cap->sdk_res.max_tpg;
+ udma_dev->ub_cap.dev_cap.max_vtp = ub_cap->sdk_res.max_vtp;
+ udma_dev->slice = udma_dev->ub_cap.dev_cap.slice;
+ udma_dev->ub_cap.dev_cap.max_jfs =
+ (is_tpf == 0) ?
+ ub_cap->sdk_res.max_jetty - resp.udma_res.max_jfrc_num :
+ ub_cap->sdk_res.max_jetty; // jfs and jetty shared resource
+
+ udma_fill_dev_default_cos(udma_dev, &resp);
+ udma_print_dev_cap_info(udma_dev, ub_cap, &resp);
+
+ return 0;
+}
+
+int udma_get_mtt_protect_state(struct udma_device *udma_dev, u32 *mtt_pro_en)
+{
+ struct ub_get_cfg_cap_cmd cmd = { 0 };
+ struct ub_get_cfg_cap_resp resp = { 0 };
+ u16 resp_size = sizeof(resp);
+ int ret;
+
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_CFG_CAP, &cmd, sizeof(cmd),
+ &resp, &resp_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to get dev cap, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, resp.head.status, resp_size);
+ return -EIO;
+ }
+ *mtt_pro_en = resp.dev_cap.mtt_pro_en;
+
+ return 0;
+}
+
+static void udma_get_split_bdf_info(struct udma_dev_bdf_info *bdf_info, u16 bdf)
+{
+ bdf_info->bus_id = (u8)(bdf >> UB_BDF_BUS_BIT);
+ bdf_info->device_id = (bdf >> UB_BDF_DEVICE_ID_BIT) &
+ UB_BDF_DEVICE_ID_MASK;
+ bdf_info->func_id = bdf & UB_BDF_FUNC_ID_MASK;
+}
+
+static int udma_generate_bdf_info(struct udma_cmd_get_bdf_info *bdf_info_get,
+ struct udma_device *udma_dev)
+{
+ struct udma_dev_bdf_info *bdf_info = udma_dev->bdf_info;
+ u16 host_id = hinic5_pcie_itf_id(udma_dev->hwdev);
+ struct pci_dev *pdev = container_of(udma_dev->dev, struct pci_dev, dev);
+ u32 bus = pdev->bus->number + 1;
+ bool fake_bdf = false;
+ u32 vf_func_id = 0;
+ u16 bdf_id = 0;
+ u32 i = 0;
+ u32 j = 0;
+
+ fake_bdf = hinic5_is_multi_bm(udma_dev->hwdev);
+ udma_info(udma_dev->dev, UDMA_M_MAIN,
+ "generate bdf info host_id:%u, bus:%u, fake_bdf:%d", host_id,
+ bus, fake_bdf);
+ /* PF bdf info */
+ for (i = 0; i < UB_PCIE_MODE_PF_NUM; i++) {
+ if (fake_bdf &&
+ host_id != (u16)bdf_info_get->pf_bdf_info[i].itf_idx)
+ bdf_info_get->pf_bdf_info[i].bdf =
+ (u16)((bus << UB_BDF_BUS_BIT) + i);
+
+ bdf_id = bdf_info_get->pf_bdf_info[i].bdf;
+ bdf_info[i].bdf_info_vld =
+ bdf_info_get->pf_bdf_info[i].pf_bdf_info_vld;
+ bdf_info[i].host_id = bdf_info_get->pf_bdf_info[i].itf_idx;
+ udma_get_split_bdf_info(&bdf_info[i], bdf_id);
+ }
+
+ /* VF bdf info */
+ for (i = 0; i < UB_PCIE_MODE_PF_NUM; i++) {
+ for (j = 0; j < bdf_info_get->vf_bdf_info[i].max_vfs; j++) {
+ vf_func_id =
+ bdf_info_get->vf_bdf_info[i].glb_pf_vf_offset +
+ 1 + (u16)j;
+ if (vf_func_id > UB_FUNCTION_MAX_NUM) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MAIN,
+ "vf_func_id(%u) bigger than UB_FUNCTION_MAX_NUM(%d)\n",
+ vf_func_id, UB_FUNCTION_MAX_NUM);
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "i:%d, j:%d, glb_pf_vf_offset:%u \n",
+ i, j,
+ bdf_info_get->vf_bdf_info[i]
+ .glb_pf_vf_offset);
+ return -EPERM;
+ }
+
+ bdf_info[vf_func_id].bdf_info_vld =
+ bdf_info_get->pf_bdf_info[i].pf_bdf_info_vld;
+ bdf_info[vf_func_id].host_id =
+ bdf_info_get->pf_bdf_info[i].itf_idx;
+ if (bdf_info_get->vf_bdf_info[i].bus_num != 0 ||
+ fake_bdf) {
+ bdf_id =
+ (u16)(bdf_info_get->pf_bdf_info[i].bdf +
+ bdf_info_get->vf_bdf_info[i]
+ .vf_offset +
+ bdf_info_get->vf_bdf_info[i]
+ .vf_stride *
+ j);
+ } else {
+ bdf_id = 0;
+ }
+ udma_get_split_bdf_info(&bdf_info[vf_func_id], bdf_id);
+ }
+ }
+ udma_dev->bdf_cnt = vf_func_id + 1;
+ return 0;
+}
+
+int udma_get_pcie_bdf_info(struct udma_device *udma_dev)
+{
+ struct udma_cmd_get_bdf_info bdf_info_get = { 0 };
+ u16 out_size = sizeof(bdf_info_get);
+ int ret;
+
+ if (udma_dev->bdf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "bdf_info is null,maybe it's not tpf.\n");
+ return -EINVAL;
+ }
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_GET_BDF_INFO, &bdf_info_get,
+ sizeof(bdf_info_get), &bdf_info_get,
+ &out_size, 0, HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (out_size == 0) || (bdf_info_get.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_MAIN,
+ "get bdf_info failed, ret:%d, status:0x%x, out size:0x%x\n",
+ ret, bdf_info_get.head.status, out_size);
+ return -EINVAL;
+ }
+ mutex_lock(&udma_dev->bdf_mutex);
+ ret = udma_generate_bdf_info(&bdf_info_get, udma_dev);
+ udma_info(udma_dev->dev, UDMA_M_MAIN, "get pcie bdf info cnt:%u\n",
+ udma_dev->bdf_cnt);
+ mutex_unlock(&udma_dev->bdf_mutex);
+
+ return ret;
+}
+
+static int udma_get_hw_info(struct udma_device *udma_dev)
+{
+ u64 bdf_len = 0;
+ int ret = 0;
+
+ udma_dev->hw_info.config_num_ports =
+ udma_dev->ub_cap.net_dev_cap.port_cnt;
+ udma_dev->hw_info.ep_id = hinic5_ep_id(udma_dev->hwdev);
+ udma_dev->hw_info.phy_port = 1;
+ udma_dev->hw_info.is_vf =
+ (hinic5_func_type(udma_dev->hwdev) == TYPE_VF);
+ udma_dev->hw_info.cpu_endian = (u8)udma_get_cpu_endian(udma_dev);
+
+ if (udma_dev->ub_cap.net_dev_cap.is_tpf != 0 &&
+ udma_dev->dev_bus_type == HINIC5_DEVICE_T_PCI) {
+ bdf_len =
+ sizeof(struct udma_dev_bdf_info) * UB_FUNCTION_MAX_NUM;
+ udma_dev->bdf_info = (struct udma_dev_bdf_info *)devm_kzalloc(
+ udma_dev->dev, bdf_len, GFP_KERNEL);
+ if (udma_dev->bdf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "failed to allocate memory for bdf info\n");
+ return -ENOMEM;
+ }
+ mutex_init(&udma_dev->bdf_mutex);
+
+ ret = udma_get_pcie_bdf_info(udma_dev);
+ if (ret != 0) {
+ devm_kfree(udma_dev->dev, udma_dev->bdf_info);
+ udma_dev->bdf_info = NULL;
+ }
+ }
+
+ return ret;
+}
+
+int udma_cleanup_ipsu_table(struct udma_device *udma_dev)
+{
+ struct ub_cmd_ipsu_ip_entry cmd = { 0 };
+ struct ub_cmd_ipsu_ip_entry resp = { 0 };
+ u16 resp_size = sizeof(struct ub_cmd_ipsu_ip_entry);
+ int ret;
+
+ cmd.func_id = hinic5_global_func_id(udma_dev->hwdev);
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UB,
+ UB_MPU_CMD_CLEAR_IP_ENTRY, &cmd,
+ sizeof(cmd), &resp, &resp_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (resp_size == 0) || (resp.head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to get dev cap, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, resp.head.status, resp_size);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void udma_cleanup_comp_priv(struct udma_device *udma_dev)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+
+ comp_priv = (struct udma_comp_priv *)get_hmm_comp_priv(udma_dev->hwdev,
+ SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE, "Comp_priv is null\n");
+ return;
+ }
+
+ udma_deinit_table(comp_priv);
+
+ hinic5_unregister_service_adapter((void *)udma_dev->hwdev,
+ SERVICE_T_UB);
+
+ devm_kfree(udma_dev->dev, comp_priv);
+
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Ub cleanup comp_priv successful\n");
+}
+
+static int udma_set_nic_event(struct udma_device *udma_dev,
+ struct hinic5_event_info *event,
+ enum ubcore_event_type *type)
+{
+ switch (event->type) {
+ case EVENT_NIC_LINK_UP:
+ if (test_and_set_bit(
+ UB_DEV_STATUS_BIT_PORT_LINK,
+ (volatile unsigned long *)&udma_dev->status) != 0) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "device link already set up\n");
+ return -1;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Report NIC LINK_UP\n");
+ *type = UBCORE_EVENT_PORT_ACTIVE;
+ break;
+
+ case EVENT_NIC_LINK_DOWN:
+ if (test_and_clear_bit(
+ UB_DEV_STATUS_BIT_PORT_LINK,
+ (volatile unsigned long *)&udma_dev->status) == 0) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "device link already set down\n");
+ return -1;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Report NIC LINK_DOWN\n");
+ *type = UBCORE_EVENT_PORT_DOWN;
+ break;
+
+ case EVENT_NIC_DCB_STATE_CHANGE:
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "DCB state change not supported\n");
+ return -1;
+
+ default:
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Nic event unsupported, event: %d\n", event->type);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int udma_set_comm_event(struct udma_device *udma_dev,
+ struct hinic5_event_info *event,
+ enum ubcore_event_type *type)
+{
+ if (event->type == EVENT_COMM_PCIE_LINK_DOWN ||
+ event->type == EVENT_COMM_HEART_LOST) {
+ *type = UBCORE_EVENT_ELR_ERR;
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "get event: UBCORE_EVENT_ELR_ERR\n");
+ return 0;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "comm event unsupported, event: %d\n", event->type);
+
+ return -1;
+}
+
+void udma_event(struct hinic5_lld_dev *lld_dev, void *adapter,
+ struct hinic5_event_info *nic_event)
+{
+ struct udma_device *udma_dev = (struct udma_device *)adapter;
+ struct ubcore_event ubc_event = { NULL };
+ int ret = -1;
+
+ udma_pr_info(UDMA_M_RESOURCE, "udma_event UB\n");
+
+ if (adapter == NULL) {
+ udma_pr_err(UDMA_M_RC_TABLE,
+ "event, input params adapter is null\n");
+ return;
+ }
+
+ if (nic_event == NULL) {
+ udma_pr_err(UDMA_M_RESOURCE,
+ "event, input params nic_event is null\n");
+ return;
+ }
+
+ /*
+ * nic perceive to event (such as link up/down), will via sdk inform each (count word) function on of service driver, UB only disable care this function on of event,
+ * for at not belong at ub device event perform intercept handle.
+ */
+ if (!hinic5_support_ub(lld_dev->hwdev, NULL)) {
+ udma_pr_err(UDMA_M_RESOURCE,
+ "the device(func id:%u) not support UB service\n",
+ hinic5_global_func_id(lld_dev->hwdev));
+ return;
+ }
+
+ ubc_event.ub_dev = &udma_dev->ub_dev;
+ ubc_event.element.port_id = hinic5_physical_port_id(udma_dev->hwdev);
+
+ switch (nic_event->service) {
+ case EVENT_SRV_NIC:
+ ret = udma_set_nic_event(udma_dev, nic_event,
+ &ubc_event.event_type);
+ break;
+
+ case EVENT_SRV_COMM:
+ ret = udma_set_comm_event(udma_dev, nic_event,
+ &ubc_event.event_type);
+ break;
+
+ default:
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Event from svc(%u) is not supported, event(%u)\n",
+ nic_event->service, nic_event->type);
+ }
+
+ if (ret != 0)
+ return;
+
+ ubcore_dispatch_async_event(&ubc_event);
+}
+
+int udma_dev_event(struct notifier_block *netdev_nb, unsigned long event,
+ void *ptr)
+{
+ struct ubcore_event ubc_event = { NULL };
+ struct udma_device *udma_dev = NULL;
+ struct net_device *ndev = NULL;
+
+ if (netdev_nb == NULL || ptr == NULL)
+ return NOTIFY_BAD;
+
+ udma_dev = container_of(netdev_nb, struct udma_device, netdev_nb);
+ ndev = netdev_notifier_info_to_dev(
+ (const struct netdev_notifier_info *)ptr);
+ if (is_vlan_dev(ndev)) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "event: %lu, vlan dev event: %s, skip\n", event,
+ ndev->name);
+ return NOTIFY_DONE;
+ }
+
+ if (udma_dev->ndev != ndev)
+ return NOTIFY_DONE;
+
+ ubc_event.ub_dev = &udma_dev->ub_dev;
+ ubc_event.element.port_id = hinic5_physical_port_id(udma_dev->hwdev);
+
+ if (event == NETDEV_UP) {
+ if (test_and_set_bit(
+ UB_DEV_STATUS_BIT_PORT_LINK,
+ (volatile unsigned long *)&udma_dev->status) != 0) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "device link already set up\n");
+ return NOTIFY_DONE;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Report NIC LINK_UP\n");
+ ubc_event.event_type = UBCORE_EVENT_PORT_ACTIVE;
+ } else if (event == NETDEV_DOWN) {
+ if (test_and_clear_bit(
+ UB_DEV_STATUS_BIT_PORT_LINK,
+ (volatile unsigned long *)&udma_dev->status) == 0) {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "device link already set down\n");
+ return NOTIFY_DONE;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "Report NIC LINK_DOWN\n");
+ ubc_event.event_type = UBCORE_EVENT_PORT_DOWN;
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "unsupported event: %lu\n", event);
+ return NOTIFY_DONE;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "dispatch async event, event_type: %u, port_id: %u\n",
+ ubc_event.event_type, ubc_event.element.port_id);
+
+ ubcore_dispatch_async_event(&ubc_event);
+ return NOTIFY_OK;
+}
+
+int udma_alloc_fake_dma_page(struct udma_device *udma_dev,
+ struct ub_cmd_func_attr *func_attr)
+{
+ u64 fake_dma_pa = 0;
+ void *fake_dma_va = NULL;
+ if (udma_dev->ub_cap.net_dev_cap.is_tpf != 0) {
+ fake_dma_va = dma_alloc_coherent(udma_dev->dev,
+ (size_t)PAGE_SIZE_4K,
+ &fake_dma_pa, GFP_KERNEL);
+ if (fake_dma_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "failed to alloc fake dma page\n");
+ return -EFAULT;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE,
+ "udma alloc fake dma page: va 0x%p\n", fake_dma_va);
+ func_attr->attr2_mask.bs.fake_dma_pa_en = 1;
+ func_attr->fake_dma_pa = fake_dma_pa;
+ udma_dev->fake_dma_addr.pa = fake_dma_pa;
+ udma_dev->fake_dma_addr.va = fake_dma_va;
+ }
+ return 0;
+}
+
+int udma_init_res(struct udma_device *udma_dev)
+{
+ struct ub_cmd_func_attr func_attr = { 0 };
+ int ret;
+
+ ret = hinic5_stateful_init(udma_dev->hwdev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to init stateful resource\n");
+ return ret;
+ }
+
+ ret = udma_init_comp_priv(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RESOURCE,
+ "init comp_priv failed, ret(%d)\n", ret);
+ goto err_init_comp_priv;
+ }
+
+ ret = udma_init_cqm_server(udma_dev);
+ if (ret != 0)
+ goto err_init_cqm;
+
+ ret = udma_alloc_ceqs(udma_dev);
+ if (ret != 0)
+ goto err_alloc_ceqs;
+
+ ret = hinic5_alloc_db_addr(udma_dev->hwdev, &udma_dev->kernel_db_map,
+ &udma_dev->kernel_dwqe_map);
+ if (ret != 0)
+ goto err_alloc_db;
+
+ if (udma_vram5_get_kexec_flag() == 0) {
+ ret = udma_set_func_cpu_endian(udma_dev);
+ if (ret != 0)
+ goto err_set_cpu_endian;
+
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr1, func_en,
+ UDMA_FUNC_ENABLE);
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr1,
+ drv_support_mtt_pro,
+ UDMA_DRV_SUP_MTT_PRO_ENABLE);
+
+ ret = udma_alloc_fake_dma_page(udma_dev, &func_attr);
+ if (ret != 0)
+ goto err_alloc_fake_dma_page;
+
+ ret = udma_set_func_attr(udma_dev,
+ hinic5_global_func_id(udma_dev->hwdev),
+ &func_attr);
+ if (ret != 0)
+ goto err_set_func_state;
+ }
+
+ ret = udma_get_hw_info(udma_dev);
+ if (ret != 0) {
+ goto err_get_hw_info;
+ }
+ return ret;
+
+err_get_hw_info:
+err_set_func_state:
+err_alloc_fake_dma_page:
+err_set_cpu_endian:
+ hinic5_free_db_addr(udma_dev->hwdev, udma_dev->kernel_db_map,
+ udma_dev->kernel_dwqe_map);
+
+err_alloc_db:
+ udma_free_ceqs(udma_dev);
+
+err_alloc_ceqs:
+ cqm5_service_unregister(udma_dev->hwdev, SERVICE_T_UB);
+
+err_init_cqm:
+ udma_cleanup_comp_priv(udma_dev);
+
+err_init_comp_priv:
+ hinic5_stateful_deinit(udma_dev->hwdev);
+
+ return ret;
+}
+
+void udma_free_res(struct udma_device *udma_dev)
+{
+ struct ub_cmd_func_attr func_attr = { 0 };
+ u16 func_id = hinic5_global_func_id(udma_dev->hwdev);
+
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE, "udma_free_res start\n");
+
+ if (udma_dev->bdf_info != NULL) {
+ devm_kfree(udma_dev->dev, udma_dev->bdf_info);
+ udma_dev->bdf_info = NULL;
+ }
+
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr1, func_en,
+ UDMA_FUNC_DISABLE);
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr1, drv_support_mtt_pro,
+ UDMA_DRV_SUP_MTT_PRO_DISABLE);
+ udma_set_func_attr(udma_dev, func_id, &func_attr);
+ hinic5_free_db_addr(udma_dev->hwdev, udma_dev->kernel_db_map,
+ udma_dev->kernel_dwqe_map);
+ udma_free_ceqs(udma_dev);
+ cqm5_service_unregister(udma_dev->hwdev, SERVICE_T_UB);
+ udma_cleanup_ipsu_table(udma_dev);
+ udma_del_func_res(udma_dev);
+ udma_cleanup_comp_priv(udma_dev);
+ hinic5_stateful_deinit(udma_dev->hwdev);
+ udma_info(udma_dev->dev, UDMA_M_RESOURCE, "udma_free_res success\n");
+}
+
+int udma_cmd_dfx_aeqe_drop(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ const struct ub_query_inbuf *inbuf = (struct ub_query_inbuf *)buf_in;
+
+ udma_dev->sysfs_res.dfx_ctx.drop_aeqe_en =
+ (u8)(!!(inbuf->drop_aeqe_en));
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.h b/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.h
new file mode 100644
index 000000000..280f4afe4
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/event/udma_resource.h
@@ -0,0 +1,31 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_RESOURCE_H
+#define UDMA_RESOURCE_H
+
+#include "udma_common.h"
+
+enum udma_func_state { UDMA_FUNC_DISABLE = 0, UDMA_FUNC_ENABLE };
+
+enum udma_drv_mtt_pro_state {
+ UDMA_DRV_SUP_MTT_PRO_DISABLE = 0,
+ UDMA_DRV_SUP_MTT_PRO_ENABLE
+};
+
+int udma_init_res(struct udma_device *udma_dev);
+void udma_free_res(struct udma_device *udma_dev);
+int udma_get_device_cap(struct udma_device *udma_dev,
+ struct ub_service_cap *ub_cap);
+void udma_event(struct hinic5_lld_dev *lld_dev, void *adapter,
+ struct hinic5_event_info *nic_event);
+int udma_dev_event(struct notifier_block *netdev_nb, unsigned long event,
+ void *ptr);
+int udma_cleanup_ipsu_table(struct udma_device *udma_dev);
+int udma_cmd_dfx_aeqe_drop(struct udma_device *udma_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size);
+int udma_get_pcie_bdf_info(struct udma_device *udma_dev);
+int udma_get_mtt_protect_state(struct udma_device *udma_dev, u32 *mtt_pro_en);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.c b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.c
new file mode 100644
index 000000000..8f280fb38
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.c
@@ -0,0 +1,2326 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+
+#include "ubcore_uapi.h"
+#include "ub_aeqe.h"
+#include "udma_common.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_jfc.h"
+#include "udma_misc.h"
+#include "udma_ubrc_comp.h"
+#include "udma_ucontext.h"
+#include "udma_srq.h"
+#include "udma_comp.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_srq.h"
+#include "udma_abi.h"
+#include "udma_base_sq.h"
+#include "ub_xqe_format.h"
+#include "udma_jetty.h"
+
+static void udma_print_jetty_cfg(const struct ubcore_jetty_cfg *cfg,
+ const struct udma_device *udma_dev)
+{
+ if (cfg == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "ubcore jetty cfg is null.\n");
+ return;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "id:%u, priority:%u, trans_mode:%u, eid_index:%u\n", cfg->id,
+ cfg->priority, cfg->trans_mode, cfg->eid_index);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "jfr_depth:%u, jfs_depth:%u, flag.share_jfr:%u\n",
+ cfg->jfr_depth, cfg->jfs_depth, cfg->flag.bs.share_jfr);
+ udma_debug(
+ udma_dev->dev, UDMA_M_JETTY,
+ "max_send_sge:%u, max_recv_sge:%u, max_send_rsge:%u, max_inline_data:%u\n",
+ cfg->max_send_sge, cfg->max_recv_sge, cfg->max_send_rsge,
+ cfg->max_inline_data);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "rnr_retry:%u, err_timeout:%u, min_rnr_timer:%u\n",
+ cfg->rnr_retry, cfg->err_timeout, cfg->min_rnr_timer);
+ if (cfg->send_jfc == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "cfg->send_jfc is null.\n");
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "cfg->send_jfc->id:%u\n",
+ cfg->send_jfc->id);
+ }
+ if (cfg->recv_jfc == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "cfg->recv_jfc is null.\n");
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "cfg->recv_jfc->id:%u\n",
+ cfg->recv_jfc->id);
+ }
+ if (cfg->jfr == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "cfg->jfr is null.\n");
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "cfg->jfr->id:%u\n",
+ cfg->jfr->jfr_id.id);
+ }
+ if (cfg->jetty_grp == NULL) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "cfg->jetty_grp is null.\n");
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "cfg->jetty_grp->id:%u\n",
+ cfg->jetty_grp->jetty_grp_id.id);
+ }
+}
+
+static void udma_jetty_group_kref_release(struct kref *ref_cnt)
+{
+ struct udma_jetty_grp *jetty_group =
+ container_of(ref_cnt, struct udma_jetty_grp, ref_cnt);
+
+ complete(&jetty_group->comp);
+}
+
+void udma_jetty_group_put(void *obj)
+{
+ struct udma_jetty_grp *jetty_group = obj;
+
+ if (jetty_group != NULL) {
+ kref_put(&jetty_group->ref_cnt, udma_jetty_group_kref_release);
+ }
+}
+
+void udma_jetty_group_get(void *obj)
+{
+ struct udma_jetty_grp *jetty_group = obj;
+
+ if (jetty_group != NULL) {
+ kref_get(&jetty_group->ref_cnt);
+ }
+}
+
+struct udma_jetty_grp *udma_find_jetty_group(struct udma_device *udev,
+ u32 jetty_grp_id)
+{
+ struct udma_jetty_grp *udma_jetty_grp_tmp = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udev->device_res->jetty_group_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(udma_jetty_grp_tmp,
+ &udev->device_res->jetty_group_list.node, node) {
+ if (udma_jetty_grp_tmp->jetty_grp_id == jetty_grp_id) {
+ udma_jetty_group_get(udma_jetty_grp_tmp);
+ mutex_unlock(lock);
+ return udma_jetty_grp_tmp;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static void udma_jetty_kref_release(struct kref *ref_cnt)
+{
+ struct udma_jetty *jetty =
+ container_of(ref_cnt, struct udma_jetty, ref_cnt);
+
+ complete(&jetty->comp);
+}
+
+void udma_jetty_put(void *obj)
+{
+ struct udma_jetty *jetty = obj;
+
+ if (jetty != NULL) {
+ kref_put(&jetty->ref_cnt, udma_jetty_kref_release);
+ }
+}
+
+void udma_jetty_get(void *obj)
+{
+ struct udma_jetty *jetty = obj;
+
+ if (jetty != NULL) {
+ kref_get(&jetty->ref_cnt);
+ }
+}
+
+struct udma_jetty *udma_find_jetty(struct udma_device *udev, u32 jetty_id)
+{
+ struct udma_jetty *ub_jetty = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udev->device_res->jetty_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(ub_jetty, &udev->device_res->jetty_list.node,
+ node) {
+ if (ub_jetty->jetty_id == jetty_id) {
+ udma_jetty_get(ub_jetty);
+ mutex_unlock(lock);
+ return ub_jetty;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+int udma_query_res_jetty(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val)
+{
+ struct ubcore_res_jetty_val *ret_val =
+ (struct ubcore_res_jetty_val *)(uintptr_t)val->addr;
+ struct ubcore_jetty *jetty = NULL;
+ struct udma_jetty *ub_jetty = NULL;
+
+ ub_jetty = udma_find_jetty(udma_dev, key->key);
+ if (ub_jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to find jetty, id(%u)\n", key->key);
+ return -EINVAL;
+ }
+
+ jetty = &ub_jetty->ubcore_jetty;
+ ret_val->jetty_id = ub_jetty->jetty_id;
+ ret_val->jfs_depth = jetty->jetty_cfg.jfs_depth;
+
+ ret_val->priority = jetty->jetty_cfg.priority;
+ if (ub_jetty->ub_jfr == NULL) {
+ ret_val->jfr_id = U32_MAX;
+ } else {
+ ret_val->jfr_id = ub_jetty->ub_jfr->jfr_id;
+ }
+
+ if (jetty->jetty_cfg.send_jfc == NULL) {
+ ret_val->send_jfc_id = U32_MAX;
+ } else {
+ ret_val->send_jfc_id = jetty->jetty_cfg.send_jfc->id;
+ }
+
+ if ((jetty->jetty_cfg.jfr != NULL) &&
+ (jetty->jetty_cfg.jfr->jfr_cfg.jfc != NULL)) {
+ ret_val->recv_jfc_id = jetty->jetty_cfg.jfr->jfr_cfg.jfc->id;
+ } else {
+ ret_val->recv_jfc_id = U32_MAX;
+ }
+
+ ret_val->state = ub_jetty->state;
+ udma_jetty_put(ub_jetty);
+ return 0;
+}
+
+int udma_query_jetty(struct ubcore_jetty *jetty, struct ubcore_jetty_cfg *cfg,
+ struct ubcore_jetty_attr *attr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *ub_jetty = NULL;
+ struct ub_ta_context_query jetty_ctx = { 0 };
+ int ret;
+ u32 dw_value;
+
+ if (jetty == NULL || jetty->ub_dev == NULL || cfg == NULL ||
+ attr == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "query jetty invalid parameter. jetty(%d) or jetty->ub_dev or cfg(%d) or attr(%d) is null.\n",
+ !!jetty, !!cfg, !!attr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ ub_jetty = to_udma_jetty(jetty);
+ if (ub_jetty->ub_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "ub_jfr is null\n");
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udma_dev, jetty->jetty_id.id,
+ &ub_jetty->cmdq_rtt, &jetty_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "query jetty(%u) ctx cmdq failed\n",
+ jetty->jetty_id.id);
+ return -EIO;
+ }
+
+ attr->rx_threshold = ub_jetty->ub_jfr->srq.container_warn_th;
+
+ dw_value = cpu_to_be32(jetty_ctx.ctx[UDMA_JETTY_CTX_STATE_OFFSET]);
+ attr->state = (dw_value >> UDMA_STATE_IN_DW_OFFSET) &
+ UDMA_STATE_IN_DW_MASK;
+ *cfg = jetty->jetty_cfg;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "udma query jetty, rx_threshold: %u, state: %u\n",
+ attr->rx_threshold, attr->state);
+
+ return 0;
+}
+
+static u32 ub_umem_page_count(const struct ubcore_umem *umem)
+{
+ return (u32)((ALIGN(umem->va + umem->length, PAGE_SIZE) -
+ ALIGN_DOWN(umem->va, PAGE_SIZE)) /
+ PAGE_SIZE);
+}
+
+int udma_create_user_mtt(struct udma_device *udma_dev, struct ubcore_umem *umem,
+ struct mtt *ub_mtt)
+{
+ u32 npages;
+ int ret;
+
+ npages = ub_umem_page_count(umem);
+ ub_mtt->mtt_type = MTT_CMTT_TYPE;
+
+ ret = hmm_mtt_alloc(udma_dev->hwdev, npages, PAGE_SHIFT, ub_mtt,
+ SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed to alloc mtt\n");
+ return ret;
+ }
+
+ ret = udma_umem_write_mtt(udma_dev, ub_mtt, umem);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed to write mtt\n");
+ hmm_mtt_free(udma_dev->hwdev, ub_mtt, SERVICE_T_UB);
+ return ret;
+ }
+
+ return 0;
+}
+
+void udma_destroy_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt)
+{
+ hmm_mtt_free(udma_dev->hwdev, ub_mtt, SERVICE_T_UB);
+}
+
+struct ubcore_umem *udma_get_umem(struct udma_device *udma_dev, u64 buf_addr,
+ u32 buf_size)
+{
+ union ubcore_umem_flag access = { 0 };
+
+ access.bs.non_pin = 0;
+ access.bs.writable = 1;
+ return ubcore_umem_get(&udma_dev->ub_dev, buf_addr, buf_size, access);
+}
+
+void udma_put_umem(struct ubcore_umem *umem)
+{
+ ubcore_umem_release(umem);
+}
+
+static int udma_alloc_jetty_context(struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg,
+ struct ubcore_device *ub_dev)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct tag_cqm_qpc_mpt *jettyc_info = NULL;
+ u32 low_bit_mode = CQM_XID_LOW_BIT_NONE;
+ u32 xid_low = 0;
+ u32 qpn_tmp;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "to_udma_dev failed.\n");
+ return -EINVAL;
+ }
+
+ if (udma_inc_jfc_used_cnt(cfg->send_jfc) == 1) {
+ low_bit_mode =
+ (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) ?
+ CQM_XID_LOW_BIT_1_1_1 :
+ CQM_XID_LOW_BIT_0_0_1;
+ xid_low = cfg->send_jfc->id;
+ }
+ qpn_tmp = udma_get_qpn_mod(udma_dev, low_bit_mode, xid_low);
+
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return -EINVAL;
+ }
+
+ jettyc_info = udma_object_qpc_create(
+ udma_dev, UBEP_JETTY_CONTEXT_SIZE, jetty,
+ &udma_dev->jettyn_record, qpn_tmp,
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num,
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty);
+ /* stub get jetty information, call mpu interface use */
+ udma_info(
+ udma_dev->dev, UDMA_M_MISC,
+ "get qpc object, record(%u), xid(%u), start(%u), max_jetty_num(%u)\n",
+ udma_dev->jettyn_record.num, qpn_tmp,
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num,
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty);
+ if (jettyc_info == NULL) {
+ udma_dec_jfc_used_cnt(cfg->send_jfc);
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to create jettyc by cqm object\n");
+ return -ENOMEM;
+ }
+
+ if (cfg->send_jfc != NULL)
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "get jetty id(%u), jfc id(%u), jfc used cnt(%d)\n",
+ jettyc_info->xid, cfg->send_jfc->id,
+ udma_read_jfc_used_cnt(cfg->send_jfc));
+
+ jetty->jettyc_info = jettyc_info;
+
+ return 0;
+}
+
+static void udma_free_jetty_context(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ struct ubcore_jfc *jfc)
+{
+ if (jetty->jettyc_info != NULL) {
+ cqm5_object_delete(&(jetty->jettyc_info->object));
+ jetty->jettyc_info = NULL;
+ udma_dec_jfc_used_cnt(jfc);
+ }
+}
+
+static int udma_jetty_cache_out_cmd(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ u64 wb_dma = 0;
+ void *wb_va = NULL;
+ int ret;
+
+ wb_va = dma_alloc_coherent(udma_dev->dev, (size_t)sizeof(u32), &wb_dma,
+ GFP_KERNEL);
+ if (wb_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc wb_va\n");
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_jetty_cache_out_ctx(udma_dev, jetty, wb_dma);
+
+ dma_free_coherent(udma_dev->dev, sizeof(u32), wb_va, wb_dma);
+
+ return ret;
+}
+
+int udma_alloc_opt_ubrc(struct udma_device *udma_dev, u32 *rsp_depth,
+ struct ubrc *ubrc, bool is_fixed)
+{
+ u32 response_depth = (u32)roundup_pow_of_two(MAX_DEST_RM_ATOMIC);
+ int ret;
+
+ response_depth =
+ is_fixed ? response_depth :
+ udma_dev->ub_cap.dev_cap_res.udma_res.ubrc_depth;
+ if (*rsp_depth != response_depth) {
+ if (*rsp_depth > 0)
+ udma_ubrc_free(udma_dev, ubrc);
+
+ ret = udma_ubrc_alloc(udma_dev, response_depth, ubrc);
+ if (ret != 0) {
+ *rsp_depth = 0;
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc ubrc, ret(%d)\n", ret);
+ return ret;
+ }
+ }
+
+ *rsp_depth = response_depth;
+
+ return 0;
+}
+
+void udma_free_opt_ubrc(struct udma_device *udma_dev, u32 *rsp_depth,
+ struct ubrc *ubrc)
+{
+ if (*rsp_depth > 0) {
+ udma_ubrc_free(udma_dev, ubrc);
+ }
+
+ *rsp_depth = 0;
+}
+
+static int udma_update_jetty_group(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ struct ubcore_jetty_group *jetty_grp,
+ enum UB_JETTY_GRP_UPDATE_TYPE_E type)
+{
+ char *log = (type == UB_JETTY_GRP_ADD_JETTY) ? "add to" : "delete from";
+ int ret = 0;
+
+ if (jetty_grp != NULL) {
+ ret = udma_cmd_jetty_grp_update_ctx(
+ udma_dev, jetty, jetty_grp->jetty_grp_id.id, type);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "JETTY(%u) %s jetty group(%u) failed.\n",
+ jetty->jetty_id, log,
+ jetty_grp->jetty_grp_id.id);
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "JETTY(%u) %s jetty group(%u) success.\n",
+ jetty->jetty_id, log,
+ jetty_grp->jetty_grp_id.id);
+ }
+ }
+ return ret;
+}
+
+static void udma_create_jetty_kernel_set_attr(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ struct tag_cqm_queue *sq_buf_info)
+{
+ jetty->sq_info = sq_buf_info;
+ jetty->sdb.db_record = (__be32 *)(void *)(&sq_buf_info->q_header_vaddr
+ ->doorbell_record);
+ jetty->sdb.dma = sq_buf_info->q_header_paddr;
+
+ sq_buf_info->q_header_vaddr->doorbell_record = 0;
+ jetty->page_shift = UB_ILOG2(sq_buf_info->q_room_buf_1.buf_size);
+}
+
+static int udma_jetty_init_sq(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg,
+ struct tag_cqm_queue *sq_buf_info)
+{
+ u32 dev_max_inline_size = udma_dev->ub_cap.dev_cap.max_jfs_inline_size;
+ u32 depth = cfg->jfs_depth;
+ struct udma_send_queue *sq = &jetty->sq;
+ u32 wr_max_length;
+
+ spin_lock_init(&sq->lock);
+ sq->baseblk_shift = depth_align_power2(UB_JFS_WQEBB);
+ sq->buf_size = udma_get_kernel_sq_size(udma_dev, depth, &wr_max_length);
+ sq->baseblk_cnt = sq->buf_size >> sq->baseblk_shift;
+ sq->max_wr_num =
+ (sq->baseblk_cnt / (wr_max_length >> sq->baseblk_shift)) - 1;
+ sq->buf = udma_dev->ub_cap.dev_cap.mtt_pro_en == 1 ?
+ jetty->queue_addr.va :
+ sq_buf_info->q_room_buf_1.direct.va;
+ sq->buf_curr = sq->buf;
+ sq->max_inline_size = (cfg->max_inline_data > dev_max_inline_size) ?
+ dev_max_inline_size :
+ cfg->max_inline_data;
+
+ (void)memset_s(sq->buf, sq->buf_size, 0xff, sq->buf_size);
+
+ sq->pi = 0;
+ sq->head = 0;
+ sq->tail = 0;
+
+ sq->wrid_size = sq->baseblk_cnt / UB_MIN_WR_WQEBB_NUM;
+ sq->wrid = (u64 *)kzalloc(sq->wrid_size * sizeof(u64), GFP_KERNEL);
+ if (sq->wrid == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to create sq wrid.\n");
+ return -ENOMEM;
+ }
+
+ sq->is_hw_flush_done = false;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "sq->baseblk_shift:%u.\n",
+ sq->baseblk_shift);
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "sq->buf_size:%u.\n",
+ sq->buf_size);
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "sq->baseblk_cnt:%u.\n",
+ sq->baseblk_cnt);
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "sq->max_wr_num:%u.\n",
+ sq->max_wr_num);
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "sq->max_inline_size:%u.\n",
+ sq->max_inline_size);
+
+ return 0;
+}
+
+static int udma_create_jetty_context_cmd(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg,
+ struct udma_create_jfs_uinfo *uinfo)
+{
+ struct ubcore_device *ub_dev = &udma_dev->ub_dev;
+ int ret = 0;
+
+ ret = udma_alloc_jetty_context(jetty, cfg, ub_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma alloc jettyc failed.\n");
+ return ret;
+ }
+
+ jetty->jetty_id = jetty->jettyc_info->xid;
+ jetty->ubcore_jetty.jetty_id.id = jetty->jetty_id;
+
+ if (jetty->trans_mode == UBCORE_TP_RM ||
+ jetty->trans_mode == UBCORE_TP_RC) {
+ ret = udma_alloc_opt_ubrc(udma_dev, &jetty->rsp_depth,
+ &jetty->ubrc, false);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to alloc ubrc, ret(%d)\n", ret);
+ goto err_and_free_jetty_context;
+ }
+ }
+
+ ret = udma_cmd_jetty_create_ctx(udma_dev, jetty, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma create jetty(%u) failed, ret %d.\n",
+ jetty->jetty_id, ret);
+ goto err_and_free_ubrc;
+ }
+ jetty->state = UBCORE_JETTY_STATE_READY;
+
+ return 0;
+
+err_and_free_ubrc:
+ if (jetty->trans_mode == UBCORE_TP_RM ||
+ jetty->trans_mode == UBCORE_TP_RC)
+ udma_free_opt_ubrc(udma_dev, &jetty->rsp_depth, &jetty->ubrc);
+err_and_free_jetty_context:
+ udma_free_jetty_context(udma_dev, jetty, cfg->send_jfc);
+ return ret;
+}
+
+static int udma_trans_mode_check(struct udma_device *udma_dev,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ if (cfg->trans_mode != UBCORE_TP_RC &&
+ cfg->trans_mode != UBCORE_TP_RM &&
+ cfg->trans_mode != UBCORE_TP_UM) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "invalid trans_mode:%u\n",
+ cfg->trans_mode);
+ return -EINVAL;
+ }
+
+ if (cfg->trans_mode == UBCORE_TP_RC) {
+ if (cfg->flag.bs.order_type != UBCORE_OT) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "not support trans_mode:rc, order_type:%u\n",
+ cfg->flag.bs.order_type);
+ return -EINVAL;
+ }
+
+ if (cfg->jetty_grp != NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "rs static mode does not support jetty group\n");
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int udma_cap_param_check(struct udma_device *udma_dev,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ u32 cap_max_inline = udma_dev->ub_cap.dev_cap.max_jfs_inline_size;
+ u16 cap_jfs_depth = udma_dev->ub_cap.dev_cap.max_jfs_depth;
+ u16 cap_jfs_sge = udma_dev->ub_cap.dev_cap.max_jfs_sge;
+ u32 cfg_max_inline = cfg->max_inline_data;
+ u16 cfg_jfs_sge = cfg->max_send_sge;
+ u32 cfg_jfs_depth = cfg->jfs_depth;
+
+ if ((cfg->flag.bs.share_jfr == 0) || (cfg->jfr == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "ub share jfr flag is %u, shared jfr is %s null.\n",
+ cfg->flag.bs.share_jfr,
+ (cfg->jfr == NULL) ? "" : "not");
+ return -EINVAL;
+ }
+
+ if (udma_trans_mode_check(udma_dev, cfg) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "not support trans mode.\n");
+ return -EINVAL;
+ }
+
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "tpf not support this function.\n");
+ return -EINVAL;
+ }
+
+ if (cfg_jfs_depth == 0 || cfg_jfs_depth > cap_jfs_depth ||
+ cfg_jfs_sge > cap_jfs_sge || cfg_max_inline > cap_max_inline) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "Invalid parameter: cfg_jfs_depth: %u, cap_jfs_depth: %u,"
+ "cfg_jfs_sge: %u, cap_jfs_sge: %u cfg_max_inline: %u cap_max_inline: %u.\n",
+ cfg_jfs_depth, cap_jfs_depth, cfg_jfs_sge, cap_jfs_sge,
+ cfg_max_inline, cap_max_inline);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.outorder_comp != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "error: outorder_comp: %u\n",
+ cfg->flag.bs.outorder_comp);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int init_ub_jetty_param_kernel(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ u32 wr_max_length;
+ u32 depth = cfg->jfs_depth;
+
+ jetty->sq_buf_len =
+ udma_get_kernel_sq_size(udma_dev, depth, &wr_max_length);
+ jetty->ubcore_jetty.jetty_cfg = *cfg;
+ jetty->trans_mode = cfg->trans_mode;
+ jetty->ub_mtt.mtt_type = MTT_CMTT_TYPE;
+
+ return 0;
+}
+
+int udma_alloc_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s **cqm_buf_info, void *object_priv,
+ u32 buf_len, struct queue_addr_info *queue_addr)
+{
+ u8 mtt_pro_en = udma_dev->ub_cap.dev_cap.mtt_pro_en;
+ u32 buf_size;
+ u32 queue_len;
+ int ret;
+
+ buf_size = mtt_pro_en == 1 ? PAGE_SIZE : buf_len;
+ *cqm_buf_info = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_QP, buf_size,
+ object_priv, true, CQM_INDEX_INVALID, 0, 0);
+ if (*cqm_buf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to create queue by cqm object.\n");
+ return -ENOMEM;
+ }
+
+ if (mtt_pro_en == 1) {
+ queue_len = udma_cal_page_size(buf_len);
+ ret = hinic5_dma_zalloc_coherent_align(udma_dev->dev, queue_len,
+ queue_len, GFP_KERNEL,
+ &queue_addr->mem_align);
+ if (ret != 0) {
+ cqm5_object_delete(&(*cqm_buf_info)->object);
+ *cqm_buf_info = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc dma addr, ret = %d\n", ret);
+ return -ENOMEM;
+ }
+ udma_fill_kernel_queue_addr_info(queue_len, queue_addr);
+ }
+
+ return 0;
+}
+
+int udma_fill_kernel_mtt(struct mtt *ub_mtt, dma_addr_t pa)
+{
+ ub_mtt->mtt_type = MTT_CMTT_TYPE;
+ ub_mtt->mtt_paddr = pa;
+ ub_mtt->mtt_layers = MTT_ZERO_LAYER;
+ return 0;
+}
+
+int udma_init_kernel_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ cqm_queue_s *cqm_buf_info, dma_addr_t pa)
+{
+ u32 page_shift;
+ int ret;
+
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ return udma_fill_kernel_mtt(ub_mtt, pa);
+ }
+
+ page_shift = UB_ILOG2(cqm_buf_info->q_room_buf_1.buf_size);
+ ub_mtt->mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(udma_dev->hwdev,
+ cqm_buf_info->q_room_buf_1.buf_number, page_shift,
+ ub_mtt, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed to alloc MTT.\n");
+ return ret;
+ }
+
+ ret = udma_buf_write_mtt(udma_dev, ub_mtt, &cqm_buf_info->q_room_buf_1);
+ if (ret != 0) {
+ hmm_mtt_free(udma_dev->hwdev, ub_mtt, SERVICE_T_UB);
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed to write MTT.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+void udma_uninit_kernel_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt)
+{
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ return;
+ }
+
+ if (ub_mtt->mtt_seg != NULL) {
+ udma_destroy_user_mtt(udma_dev, ub_mtt);
+ ub_mtt->mtt_seg = NULL;
+ }
+}
+
+int udma_free_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s *cqm_buf_info,
+ struct queue_addr_info *queue_addr)
+{
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ hinic5_dma_free_coherent_align(udma_dev->dev,
+ &queue_addr->mem_align);
+ }
+
+ if (cqm_buf_info != NULL) {
+ cqm5_object_delete(&cqm_buf_info->object);
+ }
+
+ return 0;
+}
+
+static int udma_jetty_init_sq_kernel(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ struct tag_cqm_queue *sq_buf_info = NULL;
+ int ret;
+
+ ret = udma_alloc_queue_resource(udma_dev, &sq_buf_info, jetty,
+ jetty->sq_buf_len, &jetty->queue_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to alloc queue resource, ret = %d.\n", ret);
+ return ret;
+ }
+
+ ret = udma_init_kernel_mtt(udma_dev, &jetty->ub_mtt, sq_buf_info,
+ jetty->queue_addr.pa);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to init kernel mtt, ret = %d.\n", ret);
+ goto err_init_kernel_mtt;
+ }
+
+ ret = udma_jetty_init_sq(udma_dev, jetty, cfg, sq_buf_info);
+ if (ret != 0) {
+ goto err_jetty_init_sq;
+ }
+
+ udma_create_jetty_kernel_set_attr(udma_dev, jetty, sq_buf_info);
+
+ return 0;
+
+err_jetty_init_sq:
+ udma_uninit_kernel_mtt(udma_dev, &jetty->ub_mtt);
+err_init_kernel_mtt:
+ udma_free_queue_resource(udma_dev, sq_buf_info, &jetty->queue_addr);
+ jetty->sq_info = NULL;
+
+ return ret;
+}
+
+static void udma_jetty_deinit_sq_kernel(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ if (jetty->sq.wrid != NULL) {
+ kfree(jetty->sq.wrid);
+ jetty->sq.wrid = NULL;
+ }
+
+ udma_uninit_kernel_mtt(udma_dev, &jetty->ub_mtt);
+ udma_free_queue_resource(udma_dev, jetty->sq_info, &jetty->queue_addr);
+ jetty->sq_info = NULL;
+}
+
+static int udma_create_jetty_kernel(struct ubcore_device *ub_dev,
+ struct udma_jetty *jetty,
+ const struct ubcore_jetty_cfg *cfg)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ int ret;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return -EINVAL;
+ }
+
+ ret = init_ub_jetty_param_kernel(udma_dev, jetty, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "init jetty param failed\n");
+ return ret;
+ }
+
+ jetty->ub_jfr = to_udma_jfr(cfg->jfr);
+
+ ret = udma_jetty_init_sq_kernel(udma_dev, jetty, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "init jetty sq failed\n");
+ return ret;
+ }
+
+ ret = udma_create_jetty_context_cmd(udma_dev, jetty, cfg, NULL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "create jetty cmd failed\n");
+ goto err_jetty_cmd;
+ }
+
+ return 0;
+
+err_jetty_cmd:
+ udma_jetty_deinit_sq_kernel(udma_dev, jetty);
+
+ return ret;
+}
+
+static void udma_jetty_init(struct udma_device *udma_dev,
+ const struct ubcore_jetty_cfg *cfg,
+ struct ub_create_jetty_ucmd *ucmd,
+ struct udma_jetty *jetty)
+{
+ jetty->ubcore_jetty.jetty_cfg = *cfg;
+ jetty->trans_mode = cfg->trans_mode;
+ jetty->rq_buf_len = ucmd->index_q_buf_size;
+
+ jetty->sq_buf_len = ucmd->buf_size;
+ jetty->sq.baseblk_cnt = ucmd->sq_wqebb_cnt;
+
+ if (udma_dev == NULL || udma_dev->dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid parameter: ub_dev(%d).\n",
+ !!udma_dev);
+ return;
+ }
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JETTY,
+ "index_q_buf_addr: %llu, index_q_buf_size: %u, sq_buf_len: %u, baseblk_cnt: %d.\n",
+ ucmd->index_q_buf_addr, ucmd->index_q_buf_size,
+ jetty->sq_buf_len, jetty->sq.baseblk_cnt);
+
+ jetty->ub_jfr = to_udma_jfr(cfg->jfr);
+}
+
+static int udma_get_dma_addr(struct udma_device *udma_dev, uint64_t uva_addr,
+ dma_addr_t *dma_addr)
+{
+ struct udma_queue_buffer_info *queue_info = NULL;
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma = NULL;
+ int ret = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+ mmap_read_lock(mm);
+#else
+ down_read(&mm->mmap_sem);
+#endif
+
+ vma = find_vma(mm, uva_addr);
+ if (vma == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "find vma failed.\n");
+ ret = -ENOMEM;
+ goto err_find_vma;
+ }
+
+ queue_info = (struct udma_queue_buffer_info *)vma->vm_private_data;
+ *dma_addr = queue_info->dma_addr;
+
+err_find_vma:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+ mmap_read_unlock(mm);
+#else
+ up_read(&mm->mmap_sem);
+#endif
+ return ret;
+}
+
+int udma_fill_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ u64 buf_addr)
+{
+ dma_addr_t dma_addr;
+ int ret;
+
+ ret = udma_get_dma_addr(udma_dev, buf_addr, &dma_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma get phys addr failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ ub_mtt->mtt_type = MTT_CMTT_TYPE;
+ ub_mtt->mtt_paddr = dma_addr;
+ ub_mtt->mtt_layers = MTT_ZERO_LAYER;
+ return 0;
+}
+
+int udma_init_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ struct ubcore_umem **umem, u64 buf_addr, u32 buf_size)
+{
+ int ret;
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY, "mtt_pro_en = %d.\n",
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ return udma_fill_user_mtt(udma_dev, ub_mtt, buf_addr);
+ }
+
+ *umem = udma_get_umem(udma_dev, buf_addr, buf_size);
+ if (IS_ERR_OR_NULL(*umem)) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to get umem, ret = %d.\n",
+ PTR_ERR_OR_ZERO(*umem));
+ return -ENOMEM;
+ }
+
+ ret = udma_create_user_mtt(udma_dev, *umem, ub_mtt);
+ if (ret != 0) {
+ ubcore_umem_release(*umem);
+ *umem = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma create user mtt failed, ret = %d.\n", ret);
+ }
+
+ return ret;
+}
+
+void udma_uninit_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ struct ubcore_umem *umem)
+{
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ return;
+ }
+ udma_destroy_user_mtt(udma_dev, ub_mtt);
+ ub_mtt->mtt_seg = NULL;
+ ubcore_umem_release(umem);
+}
+
+/* store queue info, just for jetty/jfr dfx function */
+void udma_fill_queue_addr_info(struct queue_addr_info *queue_addr,
+ dma_addr_t queue_pa, u32 len, u8 mtt_pro_en)
+{
+ if (mtt_pro_en == 1) {
+ queue_addr->pa = queue_pa;
+ queue_addr->va = phys_to_virt(queue_pa);
+ queue_addr->size = len;
+ }
+}
+
+static int udma_jetty_init_sq_user(struct udma_device *udma_dev,
+ const struct ubcore_jetty_cfg *cfg,
+ struct udma_create_jfs_uinfo *uinfo,
+ struct udma_jetty *jetty)
+{
+ struct ub_create_jetty_ucmd *ucmd = uinfo->ucmd;
+ struct udma_context *udma_ctx = uinfo->udma_ctx;
+ int ret;
+
+ ret = udma_init_user_mtt(udma_dev, &jetty->ub_mtt, &jetty->umem,
+ ucmd->buf_addr, ucmd->buf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma init user mtt failed, ret = %d.\n", ret);
+ return ret;
+ }
+ udma_fill_queue_addr_info(&jetty->queue_addr, jetty->ub_mtt.mtt_paddr,
+ jetty->sq_buf_len,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ ret = udma_db_map_user(udma_ctx, ucmd->sdb_addr, &jetty->sdb);
+ if (ret != 0) {
+ udma_uninit_user_mtt(udma_dev, &jetty->ub_mtt, jetty->umem);
+ jetty->umem = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "udma db map user failed.\n");
+ }
+
+ return ret;
+}
+
+static void udma_jetty_deinit_sq_user(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ struct udma_context *udma_ctx)
+{
+ udma_db_unmap_user(udma_ctx, &jetty->sdb);
+ udma_uninit_user_mtt(udma_dev, &jetty->ub_mtt, jetty->umem);
+ jetty->umem = NULL;
+}
+
+static void udma_jetty_deinit_sq(struct udma_device *udma_dev,
+ struct udma_jetty *jetty,
+ struct udma_context *udma_ctx)
+{
+ if (udma_ctx == NULL) {
+ udma_jetty_deinit_sq_kernel(udma_dev, jetty);
+ } else {
+ udma_jetty_deinit_sq_user(udma_dev, jetty, udma_ctx);
+ }
+}
+
+static int udma_create_jetty_user(struct ubcore_device *ub_dev,
+ const struct ubcore_jetty_cfg *cfg,
+ struct udma_create_jfs_uinfo *uinfo,
+ struct udma_jetty *jetty)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ int ret;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return -EINVAL;
+ }
+
+ udma_jetty_init(udma_dev, cfg, uinfo->ucmd, jetty);
+
+ ret = udma_jetty_init_sq_user(udma_dev, cfg, uinfo, jetty);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "init jetty sq failed\n");
+ return ret;
+ }
+
+ ret = udma_create_jetty_context_cmd(udma_dev, jetty, cfg, uinfo);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "create jetty cmd failed\n");
+ goto err_jetty_cmd;
+ }
+
+ return ret;
+
+err_jetty_cmd:
+ udma_jetty_deinit_sq_user(udma_dev, jetty, uinfo->udma_ctx);
+
+ return ret;
+}
+
+static int udma_destroy_jetty_one(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ struct udma_context *udma_ctx = to_udma_ctx(jetty->ubcore_jetty.uctx);
+ struct ubcore_jetty_group *jetty_grp =
+ jetty->ubcore_jetty.jetty_cfg.jetty_grp;
+ int ret;
+
+ ret = udma_update_jetty_group(udma_dev, jetty, jetty_grp,
+ UB_JETTY_GRP_DEL_JETTY);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "delete jetty from jetty_grp failed");
+ return ret;
+ }
+
+ ret = udma_cmd_jetty_delete_ctx(udma_dev, jetty);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to delete jetty(0x%06x).\n", jetty->jetty_id);
+ return ret;
+ }
+
+ ret = udma_jetty_cache_out_cmd(udma_dev, jetty);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "jetty:0x%06x cache invalid.\n", jetty->jetty_id);
+ return ret;
+ }
+ udma_delete_list(udma_dev, &jetty->node,
+ &udma_dev->device_res->jetty_list);
+ udma_jetty_put(jetty);
+ wait_for_completion(&jetty->comp);
+ if (jetty->trans_mode == UBCORE_TP_RM ||
+ jetty->trans_mode == UBCORE_TP_RC)
+ udma_free_opt_ubrc(udma_dev, &jetty->rsp_depth, &jetty->ubrc);
+
+ udma_free_jetty_context(udma_dev, jetty,
+ jetty->ubcore_jetty.jetty_cfg.send_jfc);
+
+ udma_jetty_deinit_sq(udma_dev, jetty, udma_ctx);
+
+ jetty->state = UBCORE_JETTY_STATE_RESET;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "JETTY destroyed successfully, id: %u.\n", jetty->jetty_id);
+
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_JETTY, jetty->jetty_id,
+ &jetty->cmdq_rtt);
+ kfree(jetty);
+
+ return 0;
+}
+
+static struct udma_jetty *
+udma_create_jetty_one(struct ubcore_device *ub_dev,
+ const struct ubcore_jetty_cfg *cfg,
+ struct udma_create_jfs_uinfo *uinfo, u8 *cos)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct udma_jetty *jetty = NULL;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return NULL;
+ }
+
+ if (udma_get_dcb_cfg_cos(udma_dev, NULL, cfg->priority, cos, 1) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to get cos from dcb info, pri:%u\n",
+ cfg->priority);
+ return NULL;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "Get cos from dcb info successful, cos:%u\n", *cos);
+
+ jetty = (struct udma_jetty *)kzalloc(sizeof(struct udma_jetty),
+ GFP_KERNEL);
+ if (jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "alloc JETTY failed.\n");
+ return NULL;
+ }
+
+ jetty->cqm_priv_type = UDMA_JETTY_TYPE_JETTY;
+ jetty->cos = *cos;
+ udma_cmdq_rtt_statistic_init(&jetty->cmdq_rtt);
+ if (uinfo->udma_ctx == NULL) {
+ if (udma_create_jetty_kernel(ub_dev, jetty, cfg) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "create kernel jetty failed\n");
+ goto err_alloc_jetty;
+ }
+ } else {
+ if (udma_create_jetty_user(ub_dev, cfg, uinfo, jetty) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "create user jetty failed\n");
+ goto err_alloc_jetty;
+ }
+ }
+ kref_init(&jetty->ref_cnt);
+ init_completion(&jetty->comp);
+ udma_store_list(udma_dev, &jetty->node,
+ &udma_dev->device_res->jetty_list);
+
+ if (udma_update_jetty_group(udma_dev, jetty, cfg->jetty_grp,
+ UB_JETTY_GRP_ADD_JETTY) != 0) {
+ if (uinfo->udma_ctx == NULL) {
+ jetty->ubcore_jetty.uctx = NULL;
+ } else {
+ jetty->ubcore_jetty.uctx = &uinfo->udma_ctx->base;
+ }
+ jetty->ubcore_jetty.ub_dev = &udma_dev->ub_dev;
+ jetty->ubcore_jetty.jetty_cfg.jetty_grp = NULL;
+ udma_destroy_jetty_one(udma_dev, jetty);
+ return NULL;
+ }
+
+ return jetty;
+
+err_alloc_jetty:
+ kfree(jetty);
+
+ return NULL;
+}
+
+int udma_clear_pi_on_chip(struct udma_device *udma_dev, u32 id, u8 cos)
+{
+ union tag_ub_sq_db_u jetty_db;
+ int ret;
+ u8 sq_pi_on_chip = 0;
+
+ if (udma_dev->ub_cap.dev_cap.feature.bs.pi_on_chip_en != 0)
+ sq_pi_on_chip =
+ (u8)(id < udma_dev->ub_cap.dev_cap.max_pi_on_chip_num);
+
+ if (sq_pi_on_chip == 0)
+ return 0;
+
+ udma_base_construct_sq_db(&jetty_db, id, 0, cos);
+ wmb();
+ ret = cqm5_ring_hardware_db(udma_dev->hwdev, SERVICE_T_UB, 0,
+ jetty_db.sq_db_value);
+
+ wmb();
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "xid:0x%x, jetty_db.sq_db_value:0x%llx, ret %d\n", id,
+ jetty_db.sq_db_value, ret);
+ return ret;
+}
+
+struct ubcore_jetty *udma_create_jetty(struct ubcore_device *ub_dev,
+ struct ubcore_jetty_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct udma_create_jfs_uinfo uinfo = { 0 };
+ struct udma_jetty *jetty = NULL;
+ int ret;
+ u8 cos;
+
+ if (udma_dev == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "create jetty invalid parameter. udma_dev(%d), cfg(%d).\n",
+ !!udma_dev, !!cfg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_print_jetty_cfg(cfg, udma_dev);
+
+ if (udma_cap_param_check(udma_dev, cfg) != 0) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "jetty cfg invalid parameter.\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ ret = udma_create_jfs_uinfo_init(udma_dev, udata, &uinfo);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "init uinfo failed\n");
+ return ERR_PTR(ret);
+ }
+
+ jetty = udma_create_jetty_one(ub_dev, cfg, &uinfo, &cos);
+ if (jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Create jetty faild\n");
+ goto err_and_deinit_uinfo;
+ }
+
+ if (udma_create_jfs_uinfo_deinit(udma_dev, &uinfo, cos, jetty->round,
+ 1) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to copy to user driver\n");
+ goto err_and_free_jetty;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "JETTY create successfully, id:%u, mode:%d.\n",
+ jetty->ubcore_jetty.jetty_id.id,
+ jetty->ubcore_jetty.jetty_cfg.trans_mode);
+
+ (void)udma_clear_pi_on_chip(udma_dev, jetty->jetty_id, jetty->cos);
+
+ return &jetty->ubcore_jetty;
+
+err_and_free_jetty:
+ jetty->ubcore_jetty.uctx = udma_get_uctx(udata);
+ udma_destroy_jetty_one(udma_dev, jetty);
+err_and_deinit_uinfo:
+ udma_create_jfs_uinfo_deinit(udma_dev, &uinfo, cos, 0, 0);
+
+ return ERR_PTR(-EFAULT);
+}
+
+int udma_destroy_jetty(struct ubcore_jetty *jetty)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+
+ if (jetty == NULL || jetty->ub_dev == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "destroy jetty invalid parameter. jetty(%d) or jetty->ub_dev is null.\n",
+ !!jetty);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ udma_jetty = to_udma_jetty(jetty);
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "Destroy jetty, jetty_id: %u\n",
+ udma_jetty->jetty_id);
+
+ return udma_destroy_jetty_one(udma_dev, udma_jetty);
+}
+
+int udma_modify_jetty_parse_udata(struct udma_device *udma_dev,
+ struct udma_send_queue *sq,
+ struct ubcore_udata *udata)
+{
+ u32 ucmd_len = sizeof(struct ub_modify_jetty_uinfo);
+ struct ub_modify_jetty_uinfo *uinfo = NULL;
+ int ret = -EFAULT;
+
+ if ((udata == NULL) || (udata->uctx == NULL) ||
+ (udata->udrv_data == NULL))
+ return 0;
+
+ if (udata->udrv_data->in_len != ucmd_len) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "in_len(%u) != ucmd_len(%u)\n",
+ udata->udrv_data->in_len, ucmd_len);
+ return -EINVAL;
+ }
+
+ if ((uinfo = kzalloc(ucmd_len, GFP_KERNEL)) == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Zalloc ucmd failed: %u\n", ucmd_len);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(uinfo, (void *)(uintptr_t)udata->udrv_data->in_addr,
+ ucmd_len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Copy from user failed\n");
+ goto leave;
+ }
+
+ sq->pi = uinfo->sq_pi;
+ ret = 0;
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "Update sq pi(%u)\n", sq->pi);
+
+leave:
+ if (uinfo != NULL)
+ kfree(uinfo);
+
+ return ret;
+}
+
+int udma_modify_jetty(struct ubcore_jetty *jetty,
+ struct ubcore_jetty_attr *attr,
+ struct ubcore_udata *udata)
+{
+ struct udma_jetty *udma_jetty = NULL;
+ struct udma_device *udma_dev = NULL;
+ int ret;
+
+ if (jetty == NULL || jetty->ub_dev == NULL || attr == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "modify jetty invalid parameter. jetty(%d) or jetty->ub_dev or attr(%d) is null\n",
+ !!jetty, !!attr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ udma_jetty = to_udma_jetty(jetty);
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "Modify jetty, mask:0x%08x, rx_threshold: %u, state: %d\n",
+ attr->mask, attr->rx_threshold, attr->state);
+
+ if ((attr->mask & UBCORE_JETTY_RX_THRESHOLD) != 0 ||
+ (attr->mask & UBCORE_JETTY_STATE) == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Wrong mask: 0x%08x\n",
+ attr->mask);
+ return -EINVAL;
+ }
+
+ if (attr->state < UBCORE_JETTY_STATE_RESET ||
+ attr->state > UBCORE_JETTY_STATE_ERROR) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Invalid jetty state: %d\n", attr->state);
+ return -EINVAL;
+ }
+
+ if (udma_modify_jetty_parse_udata(udma_dev, &udma_jetty->sq, udata) !=
+ 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed parse udata\n");
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_modify_ctx(udma_dev, udma_jetty, attr->state,
+ udata);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to modify jetty(%u)\n", udma_jetty->jetty_id);
+ return ret;
+ }
+
+ udma_jetty->state = attr->state;
+ udma_jetty->sq.is_hw_flush_done = false;
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY, "Modify jetty %u, ret %d\n",
+ udma_jetty->jetty_id, ret);
+
+ return ret;
+}
+
+struct ubcore_tjetty *udma_import_jetty(struct ubcore_device *ub_dev,
+ struct ubcore_tjetty_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct ubcore_tjetty *tjetty = NULL;
+
+ if (udma_dev == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "import jetty invalid parameter. udma_dev(%d), cfg(%d).\n",
+ !!udma_dev, !!cfg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->type != UBCORE_JETTY) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "remote jetty type(%d) invalid \n", cfg->type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->flag.bs.token_policy > UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "remote jetty token_policy=%u dont support\n",
+ cfg->flag.bs.token_policy);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->tp_type == UBCORE_CTP) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "remote jetty tp_type %d invalid\n", cfg->tp_type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->trans_mode == UBCORE_TP_RC) {
+ if (cfg->flag.bs.order_type != UBCORE_OT) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "not support trans_mode:rc, order_type:%u\n",
+ cfg->flag.bs.order_type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->flag.bs.share_tp == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "rs static mode must support share_tp\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ tjetty = (struct ubcore_tjetty *)kcalloc(
+ 1, sizeof(struct ubcore_tjetty), GFP_KERNEL);
+ if (tjetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "alloc tjetty failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return tjetty;
+}
+
+int udma_unimport_jetty(struct ubcore_tjetty *tjetty)
+{
+ if (tjetty == NULL) {
+ udma_pr_err(UDMA_M_JETTY,
+ "unimport jetty invalid parameter. tjetty(%d).\n",
+ !!tjetty);
+ return -EINVAL;
+ }
+ kfree(tjetty);
+
+ return 0;
+}
+
+int udma_bind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+ int ret;
+
+ if (jetty == NULL || tjetty == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "bind jetty invalid parameter. jetty(%d), tjetty(%d).\n",
+ !!jetty, !!tjetty);
+ return -EINVAL;
+ }
+
+ if (jetty->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "Invalid ub_dev\n");
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "udma bind jetty, jetty id:%u, remote jetty id:%u\n",
+ jetty->jetty_id.id, tjetty->cfg.id.id);
+
+ if (jetty->jetty_cfg.trans_mode != UBCORE_TP_RC ||
+ tjetty->cfg.trans_mode != UBCORE_TP_RC) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "Invalid jetty type, jetty mode is %u, remote jetty mode is %u.\n",
+ (u32)jetty->jetty_cfg.trans_mode,
+ (u32)tjetty->cfg.trans_mode);
+ return -EINVAL;
+ }
+
+ if (jetty->jetty_cfg.flag.bs.order_type !=
+ tjetty->cfg.flag.bs.order_type ||
+ tjetty->cfg.flag.bs.share_tp != 1) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "order_type is different or share_tp is NOT 1, local jetty flag:%u, remote jetty flag:%u.\n",
+ jetty->jetty_cfg.flag.bs.order_type,
+ tjetty->cfg.flag.bs.order_type);
+ return -EINVAL;
+ }
+
+ if (jetty->remote_jetty == tjetty) {
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "reentry bind jetty(%u) with remote jetty(%u).\n",
+ jetty->jetty_id.id, tjetty->cfg.id.id);
+ return 0;
+ }
+
+ if (jetty->remote_jetty != NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "The jetty has already bind a remote jetty.\n");
+ return -EEXIST;
+ }
+
+ udma_jetty = to_udma_jetty(jetty);
+ ret = udma_cmd_jetty_bind_ctx(udma_dev, udma_jetty, tjetty->cfg.id.id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to bind jetty(%u) with remote jetty(%u).\n",
+ jetty->jetty_id.id, tjetty->cfg.id.id);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_unbind_jetty(struct ubcore_jetty *jetty)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+ int ret;
+
+ if (jetty == NULL || jetty->ub_dev == NULL ||
+ jetty->remote_jetty == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "unbind jetty invalid parameter. jetty(%d) or ub_dev, remote_jetty is null.\n",
+ !!jetty);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ if (jetty->jetty_cfg.trans_mode != UBCORE_TP_RC) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Invalid jetty type(%u).\n",
+ (u32)jetty->jetty_cfg.trans_mode);
+ return -EINVAL;
+ }
+
+ udma_jetty = to_udma_jetty(jetty);
+ ret = udma_cmd_jetty_unbind_ctx(udma_dev, udma_jetty);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to unbind jetty(%u) with remote jetty(%u).\n",
+ jetty->jetty_id.id, jetty->remote_jetty->cfg.id.id);
+ return ret;
+ }
+
+ udma_info(
+ udma_dev->dev, UDMA_M_JETTY,
+ "udma unbind jetty success, jetty id:%u, remote jetty id:%u\n",
+ jetty->jetty_id.id, jetty->remote_jetty->cfg.id.id);
+
+ return 0;
+}
+
+void udma_jetty_async_event(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u8 type)
+{
+ struct ubcore_jetty *ubcore_jetty = &jetty->ubcore_jetty;
+ struct ubcore_event event = { 0 };
+
+ if (ubcore_jetty->jfae_handler != NULL) {
+ event.ub_dev = ubcore_jetty->ub_dev;
+ event.element.jetty = ubcore_jetty;
+ switch (type) {
+ case UB_AEQ_TYPE_JETTY_ERR:
+ event.event_type = UBCORE_EVENT_JETTY_ERR;
+ break;
+
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_JETTY,
+ "unknown jetty asyn event(%u).\n", type);
+ return;
+ }
+
+ ubcore_jetty->jfae_handler(&event, ubcore_jetty->uctx);
+ }
+}
+
+static int udma_flush_jetty_one_normal(struct udma_device *udma_dev,
+ struct udma_jetty *udma_jetty,
+ struct ubcore_cr *cr)
+{
+ struct udma_send_queue *sq = &udma_jetty->sq;
+
+ if (sq->flush_tail == sq->head)
+ return -EAGAIN;
+
+ cr->user_ctx = sq->wrid[sq->flush_tail & (sq->wrid_size - 1)];
+ ++sq->flush_tail;
+
+ cr->status = UBCORE_CR_WR_UNHANDLED;
+ cr->flag.bs.s_r = 0; // send
+ cr->flag.bs.jetty = 1; // is jetty
+ cr->completion_len = 0;
+ cr->local_id = udma_jetty->jetty_id;
+ if (udma_jetty->ubcore_jetty.remote_jetty != NULL &&
+ udma_jetty->ubcore_jetty.remote_jetty->tp != NULL)
+ cr->tpn = udma_jetty->ubcore_jetty.remote_jetty->tp->tpn;
+ cr->user_data = (uintptr_t)(&udma_jetty->ubcore_jetty);
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "success, jetty_id(%u), tail(%u), flush_tail(%u), head(%u)\n",
+ udma_jetty->jetty_id, sq->tail, sq->flush_tail, sq->head);
+
+ return 0;
+}
+
+static int udma_flush_jetty_one(struct udma_device *udma_dev,
+ struct udma_jetty *udma_jetty,
+ struct ubcore_cr *cr)
+{
+ return udma_flush_jetty_one_normal(udma_dev, udma_jetty, cr);
+}
+
+int udma_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt,
+ struct ubcore_cr *cr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+ int nflushed = 0;
+ ulong flags = 0;
+ int ret;
+
+ if (jetty == NULL || jetty->ub_dev == NULL || cr == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "invalid parameter. jetty(%d) or jetty->ub_dev or cr(%d) is null.\n",
+ !!jetty, !!cr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ udma_jetty = to_udma_jetty(jetty);
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "udma_dev is null\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&udma_jetty->sq.lock, flags);
+ if (udma_jetty->sq.is_hw_flush_done == false) {
+ spin_unlock_irqrestore(&udma_jetty->sq.lock, flags);
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "%s: hardware is not flush done, jetty_id(%u)\n",
+ __func__, udma_jetty->jetty_id);
+ return -EINVAL;
+ }
+
+ /* forge not execute of WQE of CQE */
+ for (nflushed = 0; nflushed < cr_cnt; ++nflushed) {
+ ret = udma_flush_jetty_one(udma_dev, udma_jetty, &cr[nflushed]);
+ if (ret != 0)
+ break;
+ }
+
+ if (udma_jetty->sq.flush_tail == udma_jetty->sq.head)
+ udma_jetty->sq.is_hw_flush_done = false;
+
+ spin_unlock_irqrestore(&udma_jetty->sq.lock, flags);
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "%s: success, jetty_id(%u), nflushed(%d)\n", __func__,
+ udma_jetty->jetty_id, nflushed);
+
+ return nflushed;
+}
+
+int udma_post_jetty_recv_wr(struct ubcore_jetty *jetty,
+ struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+ struct udma_srq *srq = NULL;
+ int ret = 0;
+
+ if (jetty == NULL || jetty->ub_dev == NULL || wr == NULL ||
+ bad_wr == NULL) {
+ udma_pr_err(
+ UDMA_M_JETTY,
+ "Invalid parameter. jetty(%d), wr(%d), bad_wr(%d).\n",
+ !!jetty, !!wr, !!bad_wr);
+ return -EINVAL;
+ }
+
+ udma_jetty = to_udma_jetty(jetty);
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JETTY, "udma_dev is null\n");
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "start post jetty recv, jetty id:%u, state:%d\n",
+ udma_jetty->jetty_id, udma_jetty->state);
+
+ if (udma_jetty->state != UBCORE_JETTY_STATE_READY) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "jetty state: %d, posting not supported\n",
+ udma_jetty->state);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ if ((udma_jetty->ub_jfr == NULL) ||
+ (udma_jetty->ub_jfr->state != UBCORE_JFR_STATE_READY)) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "ub_jfr is NULL or jfr state is not ready\n");
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ srq = &udma_jetty->ub_jfr->srq;
+ udma_debug(udma_dev->dev, UDMA_M_JETTY, "jfr: %u, max_sge: %u\n",
+ srq->jfr_id, srq->max_sge);
+
+ ret = udma_post_srq_wr(udma_dev, srq, wr, bad_wr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Post jetty recv failed: %d\n", ret);
+ } else {
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "Post jetty recv success, jetty id: %u\n",
+ udma_jetty->jetty_id);
+ }
+
+ return ret;
+}
+
+bool udma_is_sq_dwqe(const struct udma_send_queue *sq, const u32 wr_cnt,
+ struct udma_device *udma_dev)
+{
+ u32 wqebb_cnt = sq->wqe_size >> sq->baseblk_shift;
+ u32 dwqe_dis = udma_sysfs_get_dwqe_dis(&udma_dev->sysfs_res);
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "wr_cnt 0x%x, head 0x%x, tail 0x%x, dwqe_dis 0x%x\n", wr_cnt,
+ sq->head, sq->tail, dwqe_dis);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "wqe_size 0x%x, dwqe_size 0x%x, baseblk_shift 0x%x\n",
+ sq->wqe_size,
+ udma_dev->ub_cap.dev_cap_res.udma_res.direct_wqe_size,
+ sq->baseblk_shift);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "wqebb_cnt 0x%x, rmd_wqebb_cnt 0x%x\n", wqebb_cnt,
+ sq->rmd_wqebb_cnt);
+
+ return ((wr_cnt == 1) && (sq->head == sq->tail) && (dwqe_dis == 0) &&
+ (udma_dev->kernel_dwqe_map != NULL) &&
+ (sq->dwqe_curr != NULL) &&
+ (sq->wqe_size <=
+ udma_dev->ub_cap.dev_cap_res.udma_res.direct_wqe_size) &&
+ (wqebb_cnt <= sq->rmd_wqebb_cnt));
+}
+
+void udma_dwqe_copy(u64 *dst, u64 *src, u32 bytecnt)
+{
+#define BYTE_MASK 255
+
+ u64 *src_tmp = src;
+ u32 bytecnt_tmp = bytecnt;
+ u64 *dst_tmp =
+ (u64 *)(void *)((u8 *)dst + (u32)((bytecnt_tmp & BYTE_MASK)
+ << 2)); // 2 is addr offset
+
+ while ((int)bytecnt_tmp > 0) {
+ *dst_tmp++ = *src_tmp++;
+ bytecnt_tmp -= (u32)sizeof(u64);
+ }
+}
+
+void udma_post_send_jetty_dwqe(struct udma_device *udma_dev,
+ struct udma_jetty *jetty)
+{
+ ulong flags = 0;
+ ub_sq_wqe_s *wqe = (ub_sq_wqe_s *)jetty->sq.dwqe_curr;
+
+ union tag_ub_sq_db_u dwqe_db;
+ dwqe_db.sq_db_value = 0;
+ dwqe_db.sq_db.dw0.bs.xqn = jetty->jetty_id;
+ dwqe_db.sq_db.dw0.bs.type = UB_DIRECT_WQE_SRV_TYPE
+ << UB_DWQE_DB_TYPE_SHIFT; // high 2bit
+ dwqe_db.sq_db.dw1.bs.pi = jetty->sq.pi &
+ 0xFFFF; // complete pi, normal is pi[15:8]
+ dwqe_db.sq_db.dw0.bs.cntx_size = UB_CNTX_SIZE;
+ dwqe_db.sq_db.dw0.bs.cos = jetty->cos;
+ udma_debug(udma_dev->dev, UDMA_M_JETTY, "cos: %u, pi: %u\n", jetty->cos,
+ jetty->sq.pi);
+
+ wqe->ctrl_sec.dw2_value = cpu_to_be32(dwqe_db.sq_db_value & 0xFFFFFFFF);
+ wqe->ctrl_sec.dw3_value =
+ cpu_to_be32(dwqe_db.sq_db_value >> ADDR_H_OFFSET);
+
+ wmb();
+ *(jetty->sdb.db_record) = cpu_to_be32(jetty->sq.pi);
+ wmb();
+
+ spin_lock_irqsave(&udma_dev->dwqe_lock, flags);
+ udma_dwqe_copy((u64 *)udma_dev->kernel_dwqe_map, (u64 *)(void *)wqe,
+ (u32)jetty->sq.wqe_size);
+ spin_unlock_irqrestore(&udma_dev->dwqe_lock, flags);
+}
+
+static int udma_update_jetty_db(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u32 wr_cnt)
+{
+ union tag_ub_sq_db_u jetty_db;
+ int ret;
+
+ if (udma_is_sq_dwqe(&jetty->sq, wr_cnt, udma_dev)) {
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "the wqe is jetty dwqe\n");
+ udma_post_send_jetty_dwqe(udma_dev, jetty);
+ return 0;
+ }
+
+ wmb();
+ udma_base_construct_sq_db(&jetty_db, jetty->jetty_id, jetty->sq.pi,
+ jetty->cos);
+ udma_debug(udma_dev->dev, UDMA_M_JETTY, "cos: %u, pi: %u\n", jetty->cos,
+ jetty->sq.pi);
+ *(jetty->sdb.db_record) = cpu_to_be32(jetty->sq.pi);
+ wmb();
+ ret = cqm5_ring_hardware_db(udma_dev->hwdev, SERVICE_T_UB,
+ jetty->sq.pi & 0xff, jetty_db.sq_db_value);
+
+ wmb();
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "xid:0x%x, jetty_db.sq_db_value:0x%llx\n", jetty->jetty_id,
+ jetty_db.sq_db_value);
+ return ret;
+}
+
+bool check_k_is_fast_path(const struct ubcore_jfs_wr *wr,
+ const struct udma_send_queue *sq)
+{
+ // current wr of request is 1, switch queue is empty
+ if ((wr != NULL && wr->next == NULL) && sq->head == sq->tail) {
+ return true;
+ }
+ return false;
+}
+
+static int udma_post_jetty_send_wr_one(struct ubcore_jetty *jetty,
+ const struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+ struct udma_post_wqe post_wqe = { 0 };
+ u32 wr_cnt = 0;
+ ulong flags = 0;
+ int ret = 0;
+
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ udma_jetty = to_udma_jetty(jetty);
+ spin_lock_irqsave(&udma_jetty->sq.lock, flags);
+ post_wqe.jfc = to_udma_jfc(udma_jetty->ubcore_jetty.jetty_cfg.send_jfc);
+ post_wqe.tp_mode = udma_jetty->trans_mode;
+ post_wqe.sq = &udma_jetty->sq;
+ post_wqe.max_send_sge = jetty->jetty_cfg.max_send_sge;
+ post_wqe.is_fast_path = check_k_is_fast_path(wr, &udma_jetty->sq);
+
+ ret = udma_construct_wqe(udma_dev, wr, bad_wr, &wr_cnt, &post_wqe);
+
+ if (wr_cnt != 0) {
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "before: sq.head:%u, wr_cnt:%u\n",
+ udma_jetty->sq.head, wr_cnt);
+ udma_update_jetty_db(udma_dev, udma_jetty, wr_cnt);
+ udma_jetty->sq.head += wr_cnt;
+ atomic64_add(
+ wr_cnt,
+ &udma_jetty->sq.udma_driver_sq_ctr.post_send_wr_num);
+ atomic64_add(
+ wr_cnt,
+ &udma_dev->udma_driver_device_ctr.post_send_wr_num);
+ udma_debug(
+ udma_dev->dev, UDMA_M_JETTY,
+ "after: sq.head:%u, wr_cnt:%u, dev_post_send_wr_num:%llu, jetty_post_send_wr_num:%llu\n",
+ udma_jetty->sq.head, wr_cnt,
+ (u64)atomic64_read(&udma_dev->udma_driver_device_ctr
+ .post_send_wr_num),
+ (u64)atomic64_read(&udma_jetty->sq.udma_driver_sq_ctr
+ .post_send_wr_num));
+ }
+ spin_unlock_irqrestore(&udma_jetty->sq.lock, flags);
+
+ return ret;
+}
+
+int udma_post_jetty_send_wr(struct ubcore_jetty *jetty,
+ struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty *udma_jetty = NULL;
+
+ if ((jetty == NULL) || (jetty->ub_dev == NULL) || (wr == NULL) ||
+ (bad_wr == NULL)) {
+ udma_pr_err(
+ UDMA_M_JFC,
+ "%s Invalid parameter: jetty(%d), or jetty->ub_dev, wr(%d), *bad_wr(%d).\n",
+ __func__, !!jetty, !!wr, !!bad_wr);
+ return -EINVAL;
+ }
+
+ udma_jetty = to_udma_jetty(jetty);
+ udma_dev = to_udma_dev(jetty->ub_dev);
+ if (udma_dev == NULL || udma_jetty == NULL) {
+ udma_pr_err(UDMA_M_JFC,
+ "failed: %s to_udma_dev(%d), udma_jetty(%d).\n",
+ __func__, !!udma_dev, !!udma_jetty);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_JETTY,
+ "start post jetty send, jetty id: %u, state: %d\n",
+ udma_jetty->jetty_id, udma_jetty->state);
+
+ if (udma_jetty->state != UBCORE_JETTY_STATE_READY) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "jetty state: %d, posting not supported\n",
+ udma_jetty->state);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ if (jetty->jetty_cfg.trans_mode == UBCORE_TP_RC &&
+ jetty->remote_jetty == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JETTY,
+ "Invalid parameter, remote jetty is null, maybe it's not bind jetty.\n");
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ return udma_post_jetty_send_wr_one(jetty, wr, bad_wr);
+}
+
+#ifdef UB_SUPPORT_JETTY_GRP
+static int udma_alloc_jetty_grp_idx(struct udma_device *udma_dev,
+ struct udma_jetty_grp *jetty_grp)
+{
+ int ret = 0;
+ u32 xid_start = SCQC_JETTY_GRP_START(udma_dev);
+ u32 xid_end =
+ xid_start + udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty_grp;
+
+ jetty_grp->cqm_jetty_grp = udma_object_queue_create(
+ udma_dev, CQM_OBJECT_RDMA_SCQ, 0, jetty_grp,
+ &udma_dev->jetty_grpn_record, false,
+ CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE, CQM_XID_LOW_BIT_NONE,
+ 0),
+ xid_start, xid_end);
+ if (jetty_grp->cqm_jetty_grp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to create cqm jetty group.\n");
+ ret = -ENOMEM;
+ } else {
+ jetty_grp->jetty_grp_id = jetty_grp->cqm_jetty_grp->index;
+ jetty_grp->base.jetty_grp_id.id = jetty_grp->jetty_grp_id;
+ }
+
+ return ret;
+}
+
+static void udma_free_jetty_grp_idx(struct udma_jetty_grp *jetty_grp)
+{
+ cqm5_object_delete(&jetty_grp->cqm_jetty_grp->object);
+ jetty_grp->cqm_jetty_grp = NULL;
+}
+#endif
+
+int udma_create_jetty_grp_pre_check(const struct ubcore_device *dev,
+ const struct ubcore_jetty_grp_cfg *cfg)
+{
+ if (dev == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_JFC,
+ "create jetty grp invalid parameter. dev(%d), cfg(%d).\n",
+ !!dev, !!cfg);
+ return -EINVAL;
+ }
+
+ if (cfg->policy != UBCORE_JETTY_GRP_POLICY_RR &&
+ cfg->policy != UBCORE_JETTY_GRP_POLICY_HASH_HINT) {
+ udma_pr_err(UDMA_M_JFC,
+ "create jetty grp policy(%u) invalid.\n",
+ cfg->policy);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.token_policy != UBCORE_TOKEN_NONE &&
+ cfg->flag.bs.token_policy != UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_pr_err(UDMA_M_JFC,
+ "create jetty grp token policy(%u) invalid.\n",
+ cfg->flag.bs.token_policy);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct ubcore_jetty_group *
+udma_create_jetty_grp(struct ubcore_device *dev,
+ struct ubcore_jetty_grp_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+#ifdef UB_SUPPORT_JETTY_GRP
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty_grp *jetty_grp = NULL;
+ int ret;
+
+ ret = udma_create_jetty_grp_pre_check(dev, cfg);
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_JFC,
+ "create jetty grp invalid parameter, ret(%d).\n",
+ ret);
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(dev);
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "create jetty grp, policy: %d.\n", cfg->policy);
+
+ jetty_grp = (struct udma_jetty_grp *)kzalloc(
+ sizeof(struct udma_jetty_grp), GFP_KERNEL);
+ if (jetty_grp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "alloc jetty grp failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ jetty_grp->cqm_priv_type = UDMA_CQM_PRIV_TYPE_JETTY_GRP;
+
+ ret = udma_alloc_jetty_grp_idx(udma_dev, jetty_grp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "alloc jetty grp idx failed\n");
+ goto err_and_free_jetty_grp;
+ }
+
+ ret = udma_cmd_jetty_grp_create_ctx(udma_dev, jetty_grp, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "init jetty grp ctx failed, id: %u.\n",
+ jetty_grp->jetty_grp_id);
+ goto err_and_free_jetty_grp_idx;
+ }
+ jetty_grp->base.jetty_grp_cfg = *cfg;
+
+ kref_init(&jetty_grp->ref_cnt);
+ init_completion(&jetty_grp->comp);
+
+ udma_store_list(udma_dev, &jetty_grp->node,
+ &udma_dev->device_res->jetty_group_list);
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "jetty grp created successfully, id: %u.\n",
+ jetty_grp->jetty_grp_id);
+ return &jetty_grp->base;
+
+err_and_free_jetty_grp_idx:
+ udma_free_jetty_grp_idx(jetty_grp);
+err_and_free_jetty_grp:
+ kfree(jetty_grp);
+
+ return ERR_PTR(-EFAULT);
+#else
+ udma_pr_err(UDMA_M_JFC,
+ "create jetty grp is not currently supported.\n");
+ return ERR_PTR(-EPERM);
+#endif
+}
+
+int udma_destroy_jetty_grp(struct ubcore_jetty_group *jetty_grp)
+{
+#ifdef UB_SUPPORT_JETTY_GRP
+ struct udma_device *udma_dev = NULL;
+ struct udma_jetty_grp *udma_jetty_grp = NULL;
+ int ret;
+
+ if (jetty_grp == NULL || jetty_grp->ub_dev == NULL) {
+ udma_pr_err(
+ UDMA_M_JFC,
+ "destroy jetty grp invalid parameter. jetty_grp or(%d) jetty_grp->ub_dev is null\n",
+ !!jetty_grp);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jetty_grp->ub_dev);
+ udma_jetty_grp = to_udma_jetty_grp(jetty_grp);
+
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "start to destroy jetty grp, id: %u.\n",
+ jetty_grp->jetty_grp_id.id);
+
+ ret = udma_cmd_jetty_grp_delete_ctx(udma_dev, udma_jetty_grp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "failed to free jetty grp ctx, id: %u, ret: %d.\n",
+ jetty_grp->jetty_grp_id.id, ret);
+ return -EFAULT;
+ }
+
+ udma_delete_list(udma_dev, &udma_jetty_grp->node,
+ &udma_dev->device_res->jetty_group_list);
+ udma_jetty_group_put(udma_jetty_grp);
+ wait_for_completion(&udma_jetty_grp->comp);
+ udma_free_jetty_grp_idx(udma_jetty_grp);
+ udma_info(udma_dev->dev, UDMA_M_JETTY,
+ "jetty grp destroyed successfully, id: %u.\n",
+ jetty_grp->jetty_grp_id.id);
+
+ kfree(udma_jetty_grp);
+ return 0;
+#else
+ udma_pr_err(UDMA_M_JFC,
+ "destroy jetty grp is not currently supported.\n");
+ return -EPERM;
+#endif
+}
+
+int udma_query_res_jetty_group(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_jetty_group_val *ret_val =
+ (struct ubcore_res_jetty_group_val *)(uintptr_t)val->addr;
+ ub_jetty_grp_ctx_info_s jetty_grp_ctx;
+ struct udma_jetty_grp *ub_jetty_grp = NULL;
+ u32 jetty_num_max;
+ u32 index;
+ u32 val_index;
+
+ (void)memset_s(&jetty_grp_ctx, sizeof(ub_jetty_grp_ctx_info_s), 0,
+ sizeof(ub_jetty_grp_ctx_info_s));
+
+ ub_jetty_grp = udma_find_jetty_group(udma_dev, key->key);
+ if (ub_jetty_grp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to get ubcore_jetty_group, jetty group id(%u)",
+ key->key);
+ return -EINVAL;
+ }
+
+ (void)memcpy_s((u8 *)&jetty_grp_ctx, sizeof(ub_jetty_grp_ctx_info_s),
+ ub_jetty_grp->cqm_jetty_grp->q_ctx_vaddr,
+ sizeof(ub_jetty_grp_ctx_info_s));
+ udma_jetty_group_put(ub_jetty_grp);
+
+ jetty_num_max = (u32)ARRAY_SIZE(jetty_grp_ctx.jetty);
+ ret_val->jetty_cnt = 0;
+ for (index = 0, val_index = 0; index < jetty_num_max; index++) {
+ jetty_grp_ctx.jetty[index].value =
+ be32_to_cpu(jetty_grp_ctx.jetty[index].value);
+ if (jetty_grp_ctx.jetty[index].vld != 0) {
+ ret_val->jetty_cnt++;
+ val_index++;
+ }
+ }
+
+ if (ret_val->jetty_cnt == 0) {
+ ret_val->jetty_list = NULL;
+ return 0;
+ }
+
+ ret_val->jetty_list = (u32 *)vmalloc(sizeof(u32) * ret_val->jetty_cnt);
+ if (ret_val->jetty_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "jetty_list vmalloc failed, jetty_cnt(%u)\n",
+ ret_val->jetty_cnt);
+ return -ENOMEM;
+ }
+
+ for (index = 0, val_index = 0; index < jetty_num_max; index++) {
+ jetty_grp_ctx.jetty[index].value =
+ be32_to_cpu(jetty_grp_ctx.jetty[index].value);
+ if (jetty_grp_ctx.jetty[index].vld != 0) {
+ ret_val->jetty_list[val_index] =
+ jetty_grp_ctx.jetty[index].jetty_id;
+ val_index++;
+ }
+ }
+
+ return 0;
+}
+
+void udma_jetty_grp_async_event(struct udma_device *udma_dev,
+ struct udma_jetty_grp *udma_jetty_grp, u8 type)
+{
+ struct ubcore_jetty_group *ubcore_jetty_group = &udma_jetty_grp->base;
+ struct ubcore_event event = { 0 };
+
+ if (ubcore_jetty_group->jfae_handler != NULL) {
+ event.ub_dev = ubcore_jetty_group->ub_dev;
+ event.element.jetty_grp = ubcore_jetty_group;
+ switch (type) {
+ case UB_AEQ_TYPE_JETTY_GROUP_ERR:
+ event.event_type = UBCORE_EVENT_JETTY_GRP_ERR;
+ break;
+
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_JETTY,
+ "unknown jetty group asyn event(%u).\n",
+ type);
+ return;
+ }
+
+ ubcore_jetty_group->jfae_handler(&event,
+ ubcore_jetty_group->uctx);
+ }
+}
+
+u32 udma_cal_page_size(u64 buf_size)
+{
+ u32 page_size = PAGE_SIZE_4K;
+
+ if (buf_size <= PAGE_SIZE_4K) {
+ page_size = PAGE_SIZE_4K;
+ } else if (buf_size > PAGE_SIZE_4K && buf_size <= PAGE_SIZE_64K) {
+ page_size = PAGE_SIZE_64K;
+ } else if (buf_size > PAGE_SIZE_64K && buf_size <= PAGE_SIZE_2M) {
+ page_size = PAGE_SIZE_2M;
+ }
+
+ page_size = (u32)ub_size_align((u64)page_size, PAGE_SIZE);
+
+ return page_size;
+}
+
+int udma_dfx_modify_jetty_exec(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct udma_jetty *jetty = NULL;
+ int ret = 0;
+
+ jetty = udma_find_jetty(udma_dev, inbuf->jettyid);
+ if (jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to get jetty, jetty_id = %u", inbuf->jettyid);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_modify_dfx(udma_dev, jetty, &inbuf->jetty_attr);
+
+ udma_jetty_put(jetty);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.h b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.h
new file mode 100644
index 000000000..18adcb910
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jetty.h
@@ -0,0 +1,551 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_JETTY_H
+#define UDMA_JETTY_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include "ubcore_api.h"
+#include "hinic5_cqm.h"
+#include "ub_npu_srq_cmd_defs.h"
+#include "udma_common.h"
+#include "udma_comp.h"
+#include "udma_srq.h"
+#include "udma_db.h"
+#include "udma_jfc.h"
+#include "ub_npu_jetty_cmd_defs.h"
+
+#define UBEP_JETTY_CONTEXT_SIZE 512
+
+#define UB_DEV_MAX_TASK_JFS_NUM (8 * 1024)
+
+#define UB_MODIFY_JETTY_TIMEOUT 10
+
+#define JETTY_WQE_SHIFT 6
+#define UB_JETTY_WQEBB_SIZE_SHIFT 4
+#define UB_JETTY_WQEBB_SIZE_MASK 0x7
+#define UB_JETTY_PAGE_SIZE_MASK 0xf
+#define UB_JETTY_SIZE_MASK 0x1f
+#define UB_RC_TABLE_SIZE_128B 0x7
+#define UB_RC_EXT_ORDER_SHIFT 3
+
+#define UB_ILOG2(n) ilog2(n)
+
+#define UB_JFS_WQEBB 64
+
+#define UB_DESTROY_FLOW_TIMEOUT 10
+
+#define UB_SGE_SHIFT 4
+#define UB_WQE_CTRL_SEC_LENGTH 2
+#define UB_WQE_VA_TYPE_VIRTUAL 1
+#define UB_DEID_LENGTH 4
+#define UB_DEID_ONE_OFFSET 8
+#define UB_DEID_TWO_OFFSET 16
+#define UB_DEID_THREE_OFFSET 24
+#define UB_WQE_CMP_TASK_LEN_SHIFT 28
+#define UB_WQE_CMP_TASK_LEN1 1u
+#define UB_TASK_SEG_ALIGN 8
+#define ADDR_H_OFFSET 32
+#define UB_JFS_WRITE_WQE_TSK_LEN 64
+#define UBCORE_ODR_BITMASK 0x7
+#define UB_DIRECT_WQE_SRV_TYPE 2
+#define UB_DWQE_DB_TYPE_SHIFT 3
+#define UB_JFS_SEND_WQE_TSK_LEN 64
+#define UB_DEID_BYTE_LENGTH 16
+#define UB_SEID_BYTE_LENGTH 16
+#define UB_WR_RD_TKV_DEID_LENGTH 80
+#define UB_SEND_TKV_DEID_LENGTH 80
+#define UB_INLINE_BYTE_LENGTH 4
+#define UB_JFS_WRITE_IMM_WQE_TSK_LEN 96
+#define UB_WRITE_IMME_TKV_DEID_LENGTH 112
+#define UB_SLICE_LEN_SHIFT 15
+#define UB_SLICE_LEN (1 << UB_SLICE_LEN_SHIFT) /* 32k */
+#define UB_SLICE_LEN_64K_SHIFT 16
+#define UB_SLICE_LEN_64K (1 << UB_SLICE_LEN_64K_SHIFT)
+#define UB_SLICE_LEN_2G_SHIFT 31
+#define UB_SLICE_LEN_2G (1 << UB_SLICE_LEN_2G_SHIFT)
+#define UB_MIN_WR_WQEBB_NUM 2
+#define UB_ATOMIC_LENGTH 8
+#define UB_MAX_WRITE_READ_LEN (2 * 1024 * 1024 * 1024L)
+
+#define UB_ERROR_SUSPEND 1
+
+#define SET_DEID(x, tjetty) \
+ cpu_to_be32( \
+ ((tjetty)->cfg.id.eid.raw[(x)*4] << UB_DEID_THREE_OFFSET) | \
+ ((tjetty)->cfg.id.eid.raw[(x)*4 + 1] << UB_DEID_TWO_OFFSET) | \
+ ((tjetty)->cfg.id.eid.raw[(x)*4 + 2] << UB_DEID_ONE_OFFSET) | \
+ ((tjetty)->cfg.id.eid.raw[(x)*4 + 3]))
+
+typedef struct ub_rseg {
+ struct ubcore_target_seg base;
+ union ubcore_import_seg_flag flag;
+ u32 token;
+} ub_rseg_t;
+
+#pragma pack(push, 1)
+typedef struct ub_cmd_sge {
+ u64 va;
+ u32 length;
+ union {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u32 L : 1;
+ u32 token_id : 31;
+#else
+ u32 token_id : 31;
+ u32 L : 1;
+#endif
+ } bs;
+ u32 dw3_value;
+ } dw3;
+} ub_cmd_sge_t;
+#pragma pack(pop)
+
+struct udma_sge_info {
+ u32 sge_num;
+ u32 max_inline_size;
+};
+
+typedef struct udma_driver_sq_ctr {
+ atomic64_t post_send_wr_num;
+} udma_driver_sq_ctr_t;
+
+typedef struct udma_send_queue {
+ spinlock_t lock;
+ u64 *wrid;
+ void *buf;
+ void *buf_curr;
+ void *dwqe_curr;
+ u32 wrid_size;
+ u32 buf_size;
+ u32 tpn;
+ u32 head;
+ u32 tail;
+ u32 wqe_size;
+ u32 rmd_wqebb_cnt;
+ u32 pi;
+ u32 max_wr_num;
+ u32 max_inline_size;
+ u32 baseblk_cnt;
+ u32 baseblk_shift;
+ u32 flush_tail;
+ u8 is_hw_flush_done; // hardware flush_done complete when set true
+ udma_driver_sq_ctr_t udma_driver_sq_ctr;
+} udma_send_queue_t;
+
+struct udma_jfs {
+ u32 cqm_priv_type;
+ struct ubcore_jfs ubcore_jfs;
+ struct tag_cqm_qpc_mpt *jfsc_info;
+ struct ubcore_umem *umem;
+ struct mtt ub_mtt;
+ struct udma_db sdb;
+ struct ubrc ubrc;
+ enum ubcore_transport_mode trans_mode;
+ enum ubcore_jetty_state state;
+ u32 jfs_id;
+ u32 sq_buf_len;
+ u32 rsp_depth;
+ cqm_queue_s *jfs_buf_info;
+ struct queue_addr_info queue_addr;
+ u8 cos;
+ u32 page_shift;
+ struct udma_send_queue sq; // in create jfs when perform initialize
+ struct list_head node;
+ u32 round;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+struct udma_jfr {
+ u32 cqm_priv_type;
+ struct ubcore_jfr ubcore_jfr;
+ struct tag_cqm_qpc_mpt *jfrc_info;
+ struct udma_srq srq;
+ struct udma_index_queue index_queue;
+ struct udma_db sdb;
+ enum ubcore_jfr_state state;
+ u32 idx_queue_lth; /* JFR index queue limit threshold. */
+ u32 jfr_id;
+ struct list_head node;
+ u32 round;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+struct udma_jetty {
+ u32 cqm_priv_type;
+ struct ubcore_jetty ubcore_jetty;
+ struct tag_cqm_qpc_mpt *jettyc_info;
+ struct tag_cqm_queue *sq_info;
+ struct queue_addr_info queue_addr;
+ struct ubcore_umem *umem;
+ struct udma_jfr *ub_jfr;
+ struct udma_db sdb;
+ struct mtt ub_mtt;
+ struct ubrc ubrc;
+ enum ubcore_transport_mode trans_mode;
+ enum ubcore_jetty_state state;
+ u32 jetty_id;
+ u32 sq_buf_len;
+ u32 rq_buf_len;
+ u32 rsp_depth;
+ u32 page_shift;
+ struct udma_send_queue sq;
+ u8 cos;
+ struct list_head node;
+ u32 round;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+struct udma_jetty_grp {
+ u32 cqm_priv_type;
+ struct ubcore_jetty_group base;
+ struct tag_cqm_queue *cqm_jetty_grp;
+ u32 jetty_grp_id;
+ struct list_head node;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+struct udma_post_wqe {
+ bool is_jetty;
+ bool is_fast_path;
+ union {
+ struct udma_jetty *jetty;
+ struct udma_jfs *jfs;
+ };
+ struct udma_send_queue *sq;
+ struct udma_jfc *jfc;
+ u32 tpn;
+ enum ubcore_transport_mode tp_mode;
+ u8 max_send_sge;
+};
+
+struct udma_create_jfs_uinfo {
+ u32 resp_len;
+ u32 cmd_len;
+ struct ub_create_jetty_resp *resp;
+ struct ub_create_jetty_ucmd *ucmd;
+ struct udma_context *udma_ctx;
+ struct ubcore_udata *udata;
+};
+
+struct udma_jfr_modify_cfg {
+ enum ubcore_jfr_state state;
+ u32 idx_queue_lth; /* JFR index queue limit threshold. */
+ struct {
+ u32 state : 1;
+ u32 idx_queue_lth : 1;
+ u32 rsvd : 30;
+ } mask;
+};
+
+struct udma_jetty_grp *udma_find_jetty_group(struct udma_device *udev,
+ u32 jetty_grp_id);
+struct udma_jetty *udma_find_jetty(struct udma_device *udev, u32 jetty_id);
+int udma_alloc_opt_ubrc(struct udma_device *udma_dev, u32 *rsp_depth,
+ struct ubrc *ubrc, bool is_fixed);
+void udma_free_opt_ubrc(struct udma_device *udma_dev, u32 *rsp_depth,
+ struct ubrc *ubrc);
+struct ubcore_jfs *udma_create_jfs(struct ubcore_device *ub_dev,
+ struct ubcore_jfs_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_destroy_jfs(struct ubcore_jfs *jfs);
+int udma_modify_jfs(struct ubcore_jfs *ubcore_jfs, struct ubcore_jfs_attr *attr,
+ struct ubcore_udata *udata);
+int udma_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr);
+
+struct ubcore_jfr *udma_create_jfr(struct ubcore_device *ub_dev,
+ struct ubcore_jfr_cfg *cfg,
+ struct ubcore_udata *udata);
+u32 udma_get_jfr_threshold(struct udma_device *udma_dev,
+ ub_cmd_srq_query_rsp_s *srq_entry,
+ struct ub_ta_context_query *jfr_entry);
+int udma_query_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_cfg *cfg,
+ struct ubcore_jfr_attr *attr);
+int udma_destroy_jfr(struct ubcore_jfr *jfr);
+
+int udma_query_jetty(struct ubcore_jetty *jetty, struct ubcore_jetty_cfg *cfg,
+ struct ubcore_jetty_attr *attr);
+int udma_query_res_jfr(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val);
+int udma_post_jfr_wr(struct ubcore_jfr *jfr, struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr);
+struct ubcore_jetty *udma_create_jetty(struct ubcore_device *ub_dev,
+ struct ubcore_jetty_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_destroy_jetty(struct ubcore_jetty *jetty);
+int udma_modify_jetty(struct ubcore_jetty *jetty,
+ struct ubcore_jetty_attr *attr,
+ struct ubcore_udata *udata);
+struct ubcore_tjetty *udma_import_jfr(struct ubcore_device *ub_dev,
+ struct ubcore_tjetty_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_flush_jetty(struct ubcore_jetty *jetty, int cr_cnt,
+ struct ubcore_cr *cr);
+int udma_unimport_jfr(struct ubcore_tjetty *tjfr);
+void udma_jfr_async_event(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ u8 type);
+int udma_modify_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_attr *attr,
+ struct ubcore_udata *udata);
+void udma_jetty_async_event(struct udma_device *udma_dev,
+ struct udma_jetty *jetty, u8 type);
+void udma_jfs_async_event(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ u8 type);
+void udma_jetty_grp_async_event(struct udma_device *udma_dev,
+ struct udma_jetty_grp *udma_jetty_grp, u8 type);
+struct ubcore_tjetty *udma_import_jetty(struct ubcore_device *ub_dev,
+ struct ubcore_tjetty_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_unimport_jetty(struct ubcore_tjetty *tjetty);
+int udma_bind_jetty(struct ubcore_jetty *jetty, struct ubcore_tjetty *tjetty,
+ struct ubcore_udata *udata);
+int udma_unbind_jetty(struct ubcore_jetty *jetty);
+int udma_post_jetty_recv_wr(struct ubcore_jetty *jetty,
+ struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr);
+struct ubcore_jetty_group *
+udma_create_jetty_grp(struct ubcore_device *dev,
+ struct ubcore_jetty_grp_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_destroy_jetty_grp(struct ubcore_jetty_group *jetty_grp);
+
+struct ubcore_umem *udma_get_umem(struct udma_device *udma_dev, u64 buf_addr,
+ u32 buf_size);
+
+void udma_destroy_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt);
+int udma_create_user_mtt(struct udma_device *udma_dev, struct ubcore_umem *umem,
+ struct mtt *ub_mtt);
+
+u32 udma_get_kernel_sq_size(const struct udma_device *udma_dev, u32 depth,
+ u32 *wr_max_length);
+
+int udma_query_res_jfs(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val);
+int udma_query_res_jetty(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+int udma_query_res_jetty_group(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+ub_sqwqe_optype_e ub_jfs_parse_opcode(enum ubcore_opcode opcode);
+int udma_construct_wqe(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr, u32 *wr_cnt,
+ struct udma_post_wqe *post_wqe);
+bool check_k_is_fast_path(const struct ubcore_jfs_wr *wr,
+ const struct udma_send_queue *sq);
+
+bool udma_is_sq_dwqe(const struct udma_send_queue *sq, const u32 wr_cnt,
+ struct udma_device *udma_dev);
+int udma_post_jetty_send_wr(struct ubcore_jetty *jetty,
+ struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr);
+int udma_query_jfs(struct ubcore_jfs *jfs, struct ubcore_jfs_cfg *cfg,
+ struct ubcore_jfs_attr *attr);
+int udma_post_jfs_wr(struct ubcore_jfs *ubcore_jfs, struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr);
+
+int udma_create_jfs_uinfo_init(struct udma_device *udma_dev,
+ struct ubcore_udata *udata,
+ struct udma_create_jfs_uinfo *uinfo);
+int udma_create_jfs_uinfo_deinit(struct udma_device *udma_dev,
+ struct udma_create_jfs_uinfo *uinfo, u8 cos,
+ u32 round, u8 copy);
+int udma_clear_pi_on_chip(struct udma_device *udma_dev, u32 id, u8 cos);
+
+void udma_dwqe_copy(u64 *dst, u64 *src, u32 bytecnt);
+struct udma_jfs *udma_find_jfs(struct udma_device *udev, u32 jfs_id);
+struct udma_jfr *udma_find_jfr(struct udma_device *udev, u32 jfr_id);
+
+int udma_modify_jetty_parse_udata(struct udma_device *udma_dev,
+ struct udma_send_queue *sq,
+ struct ubcore_udata *udata);
+void udma_put_umem(struct ubcore_umem *umem);
+void udma_jetty_put(void *obj);
+void udma_jetty_get(void *obj);
+void udma_jfs_put(void *obj);
+void udma_jfs_get(void *obj);
+void udma_jfr_put(void *obj);
+void udma_jfr_get(void *obj);
+void udma_jetty_group_put(void *obj);
+void udma_jetty_group_get(void *obj);
+int udma_init_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ struct ubcore_umem **umem, u64 buf_addr, u32 buf_size);
+void udma_uninit_user_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ struct ubcore_umem *umem);
+int udma_alloc_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s **cqm_buf_info, void *object_priv,
+ u32 buf_len, struct queue_addr_info *queue_addr);
+int udma_free_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s *jfs_buf_info,
+ struct queue_addr_info *queue_addr);
+int udma_init_kernel_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt,
+ cqm_queue_s *cqm_buf_info, dma_addr_t pa);
+void udma_uninit_kernel_mtt(struct udma_device *udma_dev, struct mtt *ub_mtt);
+int udma_fill_kernel_mtt(struct mtt *ub_mtt, dma_addr_t pa);
+
+u32 udma_cal_page_size(u64 buf_size);
+void udma_fill_queue_addr_info(struct queue_addr_info *queue_addr,
+ dma_addr_t queue_pa, u32 len, u8 mtt_pro_en);
+int udma_dfx_modify_jetty_exec(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf);
+u32 udma_jetty_get_qpn_mod(struct udma_device *udma_dev,
+ struct ubcore_jfc *urma_jfc);
+
+static inline struct udma_jfs *to_udma_jfs(const struct ubcore_jfs *jfs)
+{
+ return (struct udma_jfs *)udma_container_of(jfs, struct udma_jfs,
+ ubcore_jfs);
+}
+
+static inline struct udma_jfr *to_udma_jfr(const struct ubcore_jfr *jfr)
+{
+ return (struct udma_jfr *)udma_container_of(jfr, struct udma_jfr,
+ ubcore_jfr);
+}
+
+static inline struct udma_jetty *to_udma_jetty(const struct ubcore_jetty *jetty)
+{
+ return (struct udma_jetty *)udma_container_of(jetty, struct udma_jetty,
+ ubcore_jetty);
+}
+
+static inline struct udma_jetty_grp *
+to_udma_jetty_grp(const struct ubcore_jetty_group *jetty_grp)
+{
+ return (struct udma_jetty_grp *)udma_container_of(
+ jetty_grp, struct udma_jetty_grp, base);
+}
+
+// size to on take align of multiple of,align must is 2 of power time power
+static inline u64 ub_size_align(u64 size, u64 align)
+{
+ return ((size + align - 1) & (~(align - 1)));
+}
+
+static inline struct udma_jfr *
+cqmobj_to_ub_jfr(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *qpc_info = NULL;
+ qpc_info = container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_jfr *)qpc_info->priv;
+}
+
+static inline struct udma_jfs *
+cqmobj_to_ub_jfs(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *qpc_info = NULL;
+ qpc_info = container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_jfs *)qpc_info->priv;
+}
+
+static inline struct udma_jfc *
+cqmobj_to_ub_jfc(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *cqm_info = NULL;
+ cqm_info = container_of(object, struct tag_cqm_queue, object);
+ return (struct udma_jfc *)cqm_info->priv;
+}
+
+static inline struct udma_jetty *
+cqmobj_to_ub_jetty(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *qpc_info = NULL;
+ qpc_info = container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_jetty *)qpc_info->priv;
+}
+
+static inline struct udma_jetty_grp *
+cqmobj_to_ub_jetty_grp(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_queue *cqm_info = NULL;
+ cqm_info = container_of(object, struct tag_cqm_queue, object);
+ return (struct udma_jetty_grp *)cqm_info->priv;
+}
+
+static inline u32 depth_align_power2(u32 value)
+{
+ u32 shift;
+
+ for (shift = 0; (1U << shift) < value; shift++) {
+ ; // do nothing
+ }
+
+ return shift;
+}
+
+static inline u32 to_ubcore_jfr_state(enum UB_JETTY_STATE_E state)
+{
+ switch (state) {
+ case UB_JETTY_STATE_RESET:
+ return UBCORE_JFR_STATE_RESET;
+ case UB_JETTY_STATE_READY:
+ return UBCORE_JFR_STATE_READY;
+ case UB_JETTY_STATE_ERROR:
+ return UBCORE_JFR_STATE_ERROR;
+ default:
+ udma_pr_err(UDMA_M_JETTY,
+ "to ubcore jfr state failed! state = %d\n", state);
+ return UBCORE_JFR_STATE_ERROR + 1;
+ }
+}
+
+static inline int udma_inc_jfc_used_cnt(struct ubcore_jfc *urma_jfc)
+{
+ struct udma_jfc *jfc = to_udma_jfc(urma_jfc);
+
+ if (jfc == NULL)
+ return -EINVAL;
+
+ return atomic_inc_return(&jfc->used_by_jfs);
+}
+
+static inline void udma_dec_jfc_used_cnt(const struct ubcore_jfc *urma_jfc)
+{
+ struct udma_jfc *jfc = to_udma_jfc(urma_jfc);
+
+ if (jfc != NULL)
+ atomic_dec(&jfc->used_by_jfs);
+}
+
+static inline int udma_read_jfc_used_cnt(struct ubcore_jfc *urma_jfc)
+{
+ struct udma_jfc *jfc = to_udma_jfc(urma_jfc);
+
+ return (jfc == NULL) ? -1 : (int)atomic_read(&jfc->used_by_jfs);
+}
+
+static inline struct tag_ub_sq_wqe_s *
+udma_get_next_wqe(struct udma_send_queue *sq, struct tag_ub_sq_wqe_s *old_wqe)
+{
+ if (((sq->pi + 1) & (sq->baseblk_cnt - 1)) == 0) {
+ return (ub_sq_wqe_s *)((uint8_t *)sq->buf -
+ (1ULL << sq->baseblk_shift));
+ }
+
+ return old_wqe;
+}
+
+#define UDMA_MAX_SLICE_SHIFT (UB_SLICE_LEN_2G_SHIFT - UB_SLICE_LEN_SHIFT)
+static inline bool udma_get_jetty_slice_en(struct udma_device *udma_dev)
+{
+ return (udma_dev->sysfs_res.dfx_ctx.debug_en == 1) ?
+ (bool)udma_dev->sysfs_res.dfx_ctx.perf.jetty_slice_en :
+ true;
+}
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.c b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.c
new file mode 100644
index 000000000..8fae4c286
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.c
@@ -0,0 +1,1358 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include "ubcore_uapi.h"
+
+#include "udma_common.h"
+#include "udma_cmd.h"
+#include "udma_jetty.h"
+#include "udma_cqm.h"
+#include "udma_mtt.h"
+#include "udma_comp.h"
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+#include "udma_abi.h"
+#include "udma_resource.h"
+#include "udma_cmd_jfc.h"
+#include "udma_jfc.h"
+
+#include "ub_xqe_format.h"
+#include "ub_aeqe.h"
+
+#define CQE_WQE_IDX_SHIFT 12
+#define CQE_WQE_IDX_MASK 0xfffUL
+#define INVALID_CR_OPCODE 0xff
+
+#define UB_RESERVED_CQE 7
+
+static void udma_jfc_kref_release(struct kref *ref_cnt)
+{
+ struct udma_jfc *jfc = container_of(ref_cnt, struct udma_jfc, ref_cnt);
+
+ complete(&jfc->comp);
+}
+
+void udma_jfc_put(void *obj)
+{
+ struct udma_jfc *jfc = obj;
+
+ if (jfc != NULL) {
+ kref_put(&jfc->ref_cnt, udma_jfc_kref_release);
+ }
+}
+
+void udma_jfc_get(void *obj)
+{
+ struct udma_jfc *jfc = obj;
+
+ kref_get(&jfc->ref_cnt);
+}
+
+struct udma_jfc *udma_find_jfc(struct udma_device *udev, u32 jfc_id)
+{
+ struct udma_jfc *jfc = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udev->device_res->jfc_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(jfc, &udev->device_res->jfc_list.node, node) {
+ if (jfc->base.id == jfc_id) {
+ udma_jfc_get(jfc);
+ mutex_unlock(lock);
+ return jfc;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static void udma_set_jfc_inline(struct udma_device *udma_dev,
+ struct udma_jfc *jfc)
+{
+ if ((jfc->base.jfc_cfg.flag.bs.jfc_inline != 0) &&
+ (udma_dev->ub_cap.dev_cap.feature.bs.jfc_inline == 0)) {
+ jfc->base.jfc_cfg.flag.bs.jfc_inline = 0;
+ udma_warn(udma_dev->dev, UDMA_M_JFC,
+ "Device does not support jfc inline\n");
+ }
+}
+
+u32 udma_get_jfc_inline(struct udma_device *udma_dev,
+ const struct ubcore_jfc *jfc)
+{
+ u32 jfc_inline = jfc->jfc_cfg.flag.bs.jfc_inline;
+ if ((jfc_inline != 0) &&
+ (udma_dev->ub_cap.dev_cap.feature.bs.jfc_inline == 0)) {
+ udma_warn(udma_dev->dev, UDMA_M_JFC,
+ "Device does not support jfc inline\n");
+ jfc_inline = 0;
+ }
+ return jfc_inline;
+}
+
+static struct tag_cqm_queue *udma_get_cqm_jfc(struct udma_device *udma_dev,
+ u32 size, void *jfc,
+ bool room_header_alloc)
+{
+ u32 xid_start = SCQC_JFC_START(udma_dev);
+ u32 xid_end = xid_start + udma_dev->ub_cap.dev_cap_res.sdk_res.max_jfc;
+ u32 qpn_tmp;
+
+ qpn_tmp = udma_get_qpn_mod(udma_dev, CQM_XID_LOW_BIT_NONE, 0);
+
+ return udma_object_queue_create(udma_dev, CQM_OBJECT_RDMA_SCQ, size,
+ jfc, &udma_dev->jfcn_record,
+ room_header_alloc, qpn_tmp, xid_start,
+ xid_end);
+}
+
+static void udma_init_user_jfc_param(struct udma_jfc *jfc,
+ const struct ubcore_jfc_cfg *cfg,
+ u8 mtt_pro_en, u32 buf_size)
+{
+ uint32_t page_size;
+
+ jfc->base.jfc_cfg = *(cfg);
+ jfc->base.jfc_cfg.depth += UB_RESERVED_CQE;
+ page_size = mtt_pro_en == 1 ?
+ udma_cal_page_size(jfc->base.jfc_cfg.depth *
+ UB_CQE_SIZE) :
+ PAGE_SIZE;
+ jfc->base.jfc_cfg.depth =
+ (jfc->base.jfc_cfg.depth < (page_size / UB_CQE_SIZE)) ?
+ (page_size / UB_CQE_SIZE) :
+ ((u32)roundup_pow_of_two(jfc->base.jfc_cfg.depth));
+ jfc->base.id = jfc->cqm_jfc->index;
+ jfc->page_shift = (u32)ilog2(page_size);
+ jfc->cq_buf_size = buf_size;
+}
+
+static int udma_create_user_jfc(struct udma_device *udma_dev,
+ const struct ubcore_jfc_cfg *cfg,
+ struct ubcore_udata *udata,
+ struct udma_jfc *jfc)
+{
+ struct udma_context *udma_ctx = to_udma_ctx(udata->uctx);
+ struct ub_create_jetty_ucmd ucmd = { 0 };
+ int ret;
+
+ ret = (int)copy_from_user(
+ &ucmd, (void *)(uintptr_t)udata->udrv_data->in_addr,
+ min(udata->udrv_data->in_len,
+ (u32)sizeof(struct ub_create_jetty_ucmd)));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Failed to copy JFC udata, ret = %d.\n", ret);
+ ret = -EFAULT;
+ goto err;
+ }
+
+ jfc->cqm_jfc = udma_get_cqm_jfc(udma_dev, 0, jfc, false);
+ if (jfc->cqm_jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Failed to create cqm jfc.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ udma_init_user_jfc_param(jfc, cfg, udma_dev->ub_cap.dev_cap.mtt_pro_en,
+ ucmd.buf_size);
+ ret = udma_init_user_mtt(udma_dev, &jfc->ub_mtt, &jfc->umem,
+ ucmd.buf_addr, ucmd.buf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "udma init user mtt failed, ret = %d.\n", ret);
+ goto err_init_user_mtt;
+ }
+
+ ret = udma_db_map_user(udma_ctx, ucmd.db_addr, &jfc->db);
+ if (ret != 0)
+ goto err_map_db;
+
+ return 0;
+
+err_map_db:
+ udma_uninit_user_mtt(udma_dev, &jfc->ub_mtt, jfc->umem);
+ jfc->umem = NULL;
+err_init_user_mtt:
+ cqm5_object_delete(&jfc->cqm_jfc->object);
+ jfc->cqm_jfc = NULL;
+
+err:
+ return ret;
+}
+
+static void udma_init_kernel_jfc_param(struct udma_jfc *jfc,
+ const struct ubcore_jfc_cfg *cfg,
+ u32 depth, u32 buf_size, u8 mtt_pro_en)
+{
+ jfc->base.jfc_cfg = *(cfg);
+ jfc->base.jfc_cfg.depth = depth;
+ jfc->base.id = jfc->cqm_jfc->index;
+ jfc->buf = &jfc->cqm_jfc->q_room_buf_1;
+
+ jfc->jfc_va = mtt_pro_en == 1 ? jfc->queue_addr.va :
+ jfc->buf->direct.va;
+ (void)memset_s(jfc->jfc_va, buf_size, 0xff, buf_size);
+ jfc->ci = 0;
+ jfc->db.db_record = (__be32 *)(void *)(&jfc->cqm_jfc->q_header_vaddr
+ ->doorbell_record);
+ *(jfc->db.db_record) = 0;
+ jfc->db.dma = jfc->cqm_jfc->q_header_paddr;
+
+ jfc->page_shift = (u32)ilog2(jfc->buf->buf_size);
+ spin_lock_init(&jfc->lock);
+}
+
+int udma_alloc_jfc_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s **cqm_buf_info, void *object_priv,
+ u32 buf_len,
+ struct queue_addr_info *queue_addr)
+{
+ u8 mtt_pro_en = udma_dev->ub_cap.dev_cap.mtt_pro_en;
+ u32 queue_len;
+ u32 buf_size;
+ int ret;
+
+ buf_size = mtt_pro_en == 1 ? PAGE_SIZE : buf_len;
+ *cqm_buf_info = udma_get_cqm_jfc(udma_dev, buf_size, object_priv, true);
+ if (*cqm_buf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC, "Create cqm jfc failed.\n");
+ return -ENOMEM;
+ }
+
+ if ((*cqm_buf_info)->current_q_room != CQM_RDMA_Q_ROOM_1) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get current_q_room failed.\n");
+ ret = -EINVAL;
+ goto err_get_qroom;
+ }
+
+ if (mtt_pro_en == 1) {
+ queue_len = udma_cal_page_size(buf_len);
+ ret = hinic5_dma_zalloc_coherent_align(udma_dev->dev, queue_len,
+ queue_len, GFP_KERNEL,
+ &queue_addr->mem_align);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to alloc dma addr, ret = %d\n", ret);
+ ret = -ENOMEM;
+ goto err_get_qroom;
+ }
+ udma_fill_kernel_queue_addr_info(queue_len, queue_addr);
+ }
+
+ return 0;
+err_get_qroom:
+ cqm5_object_delete(&(*cqm_buf_info)->object);
+ *cqm_buf_info = NULL;
+ return ret;
+}
+
+static int udma_create_kernel_jfc(struct udma_device *udma_dev,
+ const struct ubcore_jfc_cfg *cfg,
+ struct udma_jfc *jfc)
+{
+ u32 buf_size;
+ u32 page_size;
+ u32 depth;
+ u32 mtt_pro_en = 0;
+ int ret;
+
+ ret = udma_sysfs_get_mtt_pro_en(&udma_dev->sysfs_res, &mtt_pro_en);
+ if (ret != 0) {
+ return ret;
+ }
+ udma_dev->ub_cap.dev_cap.mtt_pro_en = mtt_pro_en;
+
+ depth = cfg->depth + UB_RESERVED_CQE;
+ page_size = udma_dev->ub_cap.dev_cap.mtt_pro_en == 1 ?
+ udma_cal_page_size(depth * UB_CQE_SIZE) :
+ PAGE_SIZE;
+ depth = (depth < (page_size / UB_CQE_SIZE)) ?
+ (page_size / UB_CQE_SIZE) :
+ ((u32)roundup_pow_of_two(depth));
+ buf_size = sizeof(struct tag_ub_cqe) * depth;
+
+ ret = udma_alloc_jfc_queue_resource(udma_dev, &jfc->cqm_jfc, jfc,
+ buf_size, &jfc->queue_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "alloc jfc queue resource failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ udma_init_kernel_jfc_param(jfc, cfg, depth, buf_size,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ ret = udma_init_kernel_mtt(udma_dev, &jfc->ub_mtt, jfc->cqm_jfc,
+ jfc->queue_addr.pa);
+ if (ret != 0) {
+ udma_free_queue_resource(udma_dev, jfc->cqm_jfc,
+ &jfc->queue_addr);
+ jfc->cqm_jfc = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to init kernel mtt, ret = %d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_query_res_jfc(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val)
+{
+ struct ubcore_res_jfc_val *ret_val =
+ (struct ubcore_res_jfc_val *)(uintptr_t)val->addr;
+ ub_jfc_ctx_query_info_s tmp_ctx;
+ ub_jfc_ctx_query_info_s *ctx = NULL;
+ struct ubcore_jfc *jfc = NULL;
+ struct udma_jfc *ub_jfc = NULL;
+
+ ub_jfc = udma_find_jfc(udma_dev, key->key);
+ if (ub_jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Failed to find ub_jfc, id(%u)\n", key->key);
+ return -EINVAL;
+ }
+
+ jfc = &ub_jfc->base;
+ ctx = (ub_jfc_ctx_query_info_s *)(ub_jfc->cqm_jfc->q_ctx_vaddr);
+ tmp_ctx.dw2 = be32_to_cpu(ctx->dw2);
+ ret_val->depth = jfc->jfc_cfg.depth;
+ ret_val->jfc_id = jfc->id;
+ udma_jfc_put(ub_jfc);
+ if (tmp_ctx.state == UB_CQC_STATE_HW) {
+ ret_val->state = UBCORE_JFC_STATE_VALID;
+ } else if (tmp_ctx.state == UB_CQC_STATE_SW) {
+ ret_val->state = UBCORE_JFC_STATE_INVALID;
+ } else {
+ ret_val->state = UBCORE_JFC_STATE_ERROR;
+ }
+
+ return 0;
+}
+
+static void udma_free_jfc_buf_user(struct ubcore_ucontext *uctx,
+ struct udma_jfc *jfc,
+ struct udma_device *udma_dev)
+{
+ if (uctx != NULL) {
+ udma_db_unmap_user(to_udma_ctx(uctx), &jfc->db);
+ }
+
+ udma_uninit_user_mtt(udma_dev, &jfc->ub_mtt, jfc->umem);
+ jfc->umem = NULL;
+
+ if (jfc->cqm_jfc != NULL) {
+ cqm5_object_delete(&jfc->cqm_jfc->object);
+ jfc->cqm_jfc = NULL;
+ }
+}
+
+static void udma_free_jfc_buf_kernel(struct udma_jfc *jfc,
+ struct udma_device *udma_dev)
+{
+ udma_uninit_kernel_mtt(udma_dev, &jfc->ub_mtt);
+ udma_free_queue_resource(udma_dev, jfc->cqm_jfc, &jfc->queue_addr);
+ jfc->cqm_jfc = NULL;
+}
+
+static int udma_create_jfc_check_param(struct ubcore_device *ub_dev,
+ const struct ubcore_jfc_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if ((ub_dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_JFC,
+ "Invalid parameter: ub_dev(%d), cfg(%d).\n",
+ !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "tpf not support this function.\n");
+ return -EFAULT;
+ }
+
+ if (cfg->depth == 0 ||
+ cfg->depth > udma_dev->ub_cap.dev_cap.max_jfc_depth) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "jfc cfg depth out of range, depth:%u, max_depth:%u\n",
+ cfg->depth, udma_dev->ub_cap.dev_cap.max_jfc_depth);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct ubcore_jfc *udma_create_jfc(struct ubcore_device *ub_dev,
+ struct ubcore_jfc_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfc *jfc = NULL;
+ int ret;
+
+ ret = udma_create_jfc_check_param(ub_dev, cfg);
+ if (ret != 0) {
+ return ERR_PTR(ret);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ jfc = (struct udma_jfc *)kzalloc(sizeof(struct udma_jfc), GFP_KERNEL);
+ if (jfc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC, "alloc JFC Failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+ jfc->cqm_priv_type = UDMA_CQM_PRIV_TYPE_JFC;
+ udma_cmdq_rtt_statistic_init(&jfc->cmdq_rtt);
+
+ if (udma_get_uctx(udata) != NULL)
+ ret = udma_create_user_jfc(udma_dev, cfg, udata, jfc);
+ else
+ ret = udma_create_kernel_jfc(udma_dev, cfg, jfc);
+ if (ret != 0)
+ goto err_alloc_jfc;
+
+ udma_set_jfc_inline(udma_dev, jfc);
+ ret = udma_cmd_jfc_ctx(udma_dev, jfc, NULL, UB_CMD_JFC_CREATE_CTX);
+ if (ret != 0)
+ goto err_alloc_ctx;
+
+ jfc->arm_sn = 1;
+ atomic_set(&jfc->used_by_jfs, 0);
+
+ kref_init(&jfc->ref_cnt);
+ init_completion(&jfc->comp);
+ udma_store_list(udma_dev, &jfc->node, &udma_dev->device_res->jfc_list);
+
+ udma_info(udma_dev->dev, UDMA_M_JFC,
+ "JFC created successfully, id: %u.\n", jfc->base.id);
+ return &jfc->base;
+
+err_alloc_ctx:
+ if (udma_get_uctx(udata) != NULL) {
+ udma_free_jfc_buf_user(udma_get_uctx(udata), jfc, udma_dev);
+ } else {
+ udma_free_jfc_buf_kernel(jfc, udma_dev);
+ }
+
+err_alloc_jfc:
+ kfree(jfc);
+
+err:
+ return ERR_PTR(ret);
+}
+
+static int udma_modify_jfc_check_param(struct udma_device *udma_dev,
+ struct ubcore_jfc_attr *attr)
+{
+ if ((attr->mask &
+ (UBCORE_JFC_MODERATE_COUNT | UBCORE_JFC_MODERATE_PERIOD)) == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "JFC modify mask is not set or invalid.\n");
+ return -EINVAL;
+ }
+
+ if ((attr->mask & UBCORE_JFC_MODERATE_COUNT) != 0 &&
+ (attr->moderate_count > udma_dev->ub_cap.dev_cap.max_jfc_depth)) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "modify max_cnt(%u) > max_jfc_depth(%u).\n",
+ attr->moderate_count,
+ udma_dev->ub_cap.dev_cap.max_jfc_depth);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_modify_jfc(struct ubcore_jfc *ub_jfc, struct ubcore_jfc_attr *attr,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfc *jfc = NULL;
+ int ret;
+
+ if ((ub_jfc == NULL) || (ub_jfc->ub_dev == NULL) || (attr == NULL)) {
+ udma_pr_err(UDMA_M_JFC,
+ "Invalid parameter: ub_jfc(%d), attr(%d).\n",
+ !!ub_jfc, !!attr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_jfc->ub_dev);
+ jfc = to_udma_jfc(ub_jfc);
+ udma_info(udma_dev->dev, UDMA_M_JFC, "Modify jfc started, id: %u.\n",
+ ub_jfc->id);
+
+ ret = udma_modify_jfc_check_param(udma_dev, attr);
+ if (ret != 0) {
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_JFC,
+ "modify type:%u, max_cnt:0x%x, timeout:0x%x\n", attr->mask,
+ attr->moderate_count, attr->moderate_period);
+
+ ret = udma_cmd_jfc_ctx(udma_dev, jfc, attr, UB_CMD_JFC_MODIFY_CTX);
+ if (ret != 0)
+ return -EFAULT;
+
+ udma_info(udma_dev->dev, UDMA_M_JFC, "Modify jfc finished, id: %u.\n",
+ ub_jfc->id);
+ return ret;
+}
+
+static int udma_free_jfc_ctx(struct udma_device *udma_dev, struct udma_jfc *jfc)
+{
+ int ret;
+
+ ret = udma_cmd_jfc_ctx(udma_dev, jfc, NULL, UB_CMD_JFC_DELETE_CTX);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Fail to delete jfc ctx.\n");
+ return ret;
+ }
+
+ ret = udma_cmd_jfc_ctx(udma_dev, jfc, NULL, UB_CMD_JFC_CACHE_INVLD_CTX);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Fail to cache invld jfc ctx.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_destroy_jfc(struct ubcore_jfc *ub_jfc)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfc *jfc = NULL;
+ int ret;
+
+ if ((ub_jfc == NULL) || (ub_jfc->ub_dev == NULL)) {
+ udma_pr_err(UDMA_M_JFC, "Invalid parameter: ub_jfc(%d).\n",
+ !!ub_jfc);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_jfc->ub_dev);
+ jfc = to_udma_jfc(ub_jfc);
+
+ udma_delete_list(udma_dev, &jfc->node, &udma_dev->device_res->jfc_list);
+ udma_jfc_put(jfc);
+ wait_for_completion(&jfc->comp);
+
+ ret = udma_free_jfc_ctx(udma_dev, jfc);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Failed to free jfc ctx, id: %u, ret: %d.\n",
+ ub_jfc->id, ret);
+ /* delete failed, reference count reinitialized, ensure reentrant destory interface when reference count can normal put */
+ kref_init(&jfc->ref_cnt);
+ return ret;
+ }
+
+ if (ub_jfc->uctx == NULL) {
+ udma_free_jfc_buf_kernel(jfc, udma_dev);
+ } else {
+ udma_free_jfc_buf_user(ub_jfc->uctx, jfc, udma_dev);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JFC,
+ "JFC destroyed successfully, id: %u.\n", ub_jfc->id);
+ kfree(jfc);
+ return 0;
+}
+
+void udma_jfc_async_event(struct udma_device *udma_dev, struct udma_jfc *jfc,
+ u8 type)
+{
+ struct ubcore_jfc *ub_jfc = &jfc->base;
+ struct ubcore_event event = { 0 };
+
+ if (ub_jfc->jfae_handler != NULL) {
+ event.ub_dev = ub_jfc->ub_dev;
+ event.element.jfc = ub_jfc;
+ switch (type) {
+ case UB_AEQ_TYPE_JFC_ERR:
+ event.event_type = UBCORE_EVENT_JFC_ERR;
+ break;
+
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_JFC,
+ "unknown jfc asyn event(%u).\n", type);
+ return;
+ }
+
+ ub_jfc->jfae_handler(&event, ub_jfc->uctx);
+ }
+}
+
+static void udma_print_cqe_info(struct udma_device *udma_dev,
+ const struct udma_jfc *jfc,
+ const struct tag_ub_cqe *cqe)
+{
+ u32 step = sizeof(u32);
+ u32 i;
+ u32 *k_cqe = (u32 *)cqe;
+
+ if (udma_kernel_log_level_prior(UDMA_LOG_LEVEL_INFO)) {
+ for (i = 0; i < sizeof(struct tag_ub_cqe) / step; i += step) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "%08x %08x %08x %08x\n", *(k_cqe + i),
+ *(k_cqe + i + 0x1), *(k_cqe + i + 0x2),
+ *(k_cqe + i + 0x3));
+ }
+ } else {
+ for (i = 0; i < sizeof(struct tag_ub_cqe) / step; i += step) {
+ udma_debug(udma_dev->dev, UDMA_M_JFC,
+ "%08x %08x %08x %08x\n", *(k_cqe + i),
+ *(k_cqe + i + 0x1), *(k_cqe + i + 0x2),
+ *(k_cqe + i + 0x3));
+ }
+ }
+}
+
+static void udma_dfx_print_cqe(struct udma_device *udma_dev,
+ const struct udma_jfc *jfc,
+ const struct tag_ub_cqe *cqe)
+{
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JFC, "Invalid parameter: udma_dev(%d).\n",
+ !!udma_dev);
+ return;
+ }
+
+ if (udma_kernel_log_level_prior(UDMA_LOG_LEVEL_INFO)) {
+ if (cqe->dw0.bs.status == UB_CQ_STATUS_OK) {
+ return;
+ }
+ udma_print_cqe_info(udma_dev, jfc, cqe);
+ return;
+ }
+
+ udma_print_cqe_info(udma_dev, jfc, cqe);
+}
+
+static void handle_recv_inline_cqe(struct udma_device *udma_dev,
+ struct tag_ub_cqe *cqe, struct udma_srq *srq,
+ struct ubcore_cr *cr, u32 container_idx)
+{
+ struct ub_wqe_srq_data_seg *sge_list = NULL;
+ u8 *cqe_inline_buf = NULL;
+ u32 data_len;
+ u32 wqe_idx;
+ u32 sge_idx;
+ u32 sge_len;
+ u64 data;
+ u32 size;
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFC,
+ "handle recv inline cqe, data_len = %u, cqe_inline_data = 0x%x-%x\n",
+ cqe->byte_cnt, cqe->inline_data[0], cqe->inline_data[1]);
+
+ data = htonll(((u64)(cqe->inline_data[0]) << UB_LONG_DATA_OFFSET) |
+ (u64)(cqe->inline_data[1]));
+
+ wqe_idx = (container_idx * srq->container_size) & (srq->max_depth - 1);
+ sge_list = (struct ub_wqe_srq_data_seg *)ub_srq_get_wqe(srq, wqe_idx);
+ cqe_inline_buf = (u8 *)&data;
+ data_len = cqe->byte_cnt;
+
+ for (sge_idx = 0; (sge_idx < srq->max_sge) && (data_len != 0);
+ sge_idx++) {
+ sge_len = htonl(sge_list[sge_idx].dw2.length);
+ size = (sge_len < data_len) ? sge_len : data_len;
+
+ (void)memcpy_s(
+ (void *)(uintptr_t)htonll(sge_list[sge_idx].addr),
+ sge_len, (void *)cqe_inline_buf, size);
+
+ data_len -= size;
+ cqe_inline_buf += size;
+ }
+
+ if (data_len != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "handle_recv_inl_cqe error, remain data_len = %u\n",
+ data_len);
+}
+
+static int udma_check_recv_jetty_id(struct udma_device *udma_dev,
+ const struct tag_ub_cqe *cqe, u32 id)
+{
+ if (cqe->dw3.bs.local_jfx_num != id) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFC,
+ "jetty/jfr id is incorrect, cqe_id:0x%x, real_id:0x%x\n",
+ cqe->dw3.bs.wqe_idx, id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct udma_srq *
+udma_get_srq_by_cqm_object(struct udma_device *udma_dev, struct tag_ub_cqe *cqe,
+ struct tag_cqm_object *object, struct ubcore_cr *cr)
+{
+ struct udma_jetty *jetty = NULL;
+ struct udma_jfr *jfr = NULL;
+ struct udma_srq *srq = NULL;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JFC, "Invalid parameter: udma_dev(%d).\n",
+ !!udma_dev);
+ return NULL;
+ }
+
+ jetty = cqmobj_to_ub_jetty(object);
+ if (jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get srq failed or invalid, jetty_id:0x%x\n",
+ cqe->dw3.bs.local_jfx_num);
+ return NULL;
+ }
+
+ if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) {
+ if (udma_check_recv_jetty_id(udma_dev, cqe, jetty->jetty_id) !=
+ 0)
+ return NULL;
+
+ cr->user_data = (uintptr_t)(void *)(&jetty->ubcore_jetty);
+
+ if (jetty->ub_jfr != NULL)
+ srq = &jetty->ub_jfr->srq;
+ else
+ udma_err(udma_dev->dev, UDMA_M_JFC, "ub_jfr is NULL\n");
+ } else if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JFR) {
+ jfr = cqmobj_to_ub_jfr(object);
+ if (udma_check_recv_jetty_id(udma_dev, cqe, jfr->jfr_id) != 0)
+ return NULL;
+
+ cr->user_data = (uintptr_t)(void *)(&jfr->ubcore_jfr);
+
+ srq = &jfr->srq;
+ }
+
+ if ((srq == NULL) || (srq->wrid == NULL) ||
+ (srq->container_size == 0) || (srq->max_depth == 0)) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get srq failed or invalid, jetty_id:0x%x\n",
+ cqe->dw3.bs.local_jfx_num);
+ return NULL;
+ }
+
+ cr->flag.bs.jetty = (jfr == NULL) ? 0 : 1;
+ return srq;
+}
+
+static void udma_parse_cr_status(struct udma_device *udma_dev,
+ const struct tag_ub_cqe *cqe,
+ struct ubcore_cr *cr)
+{
+ u8 status = cqe->dw0.bs.status;
+ u32 sub_status = cqe->dw2.bs.sub_status;
+
+ cr->status = UBCORE_CR_WR_UNHANDLED;
+ switch (status) {
+ case UB_CQ_STATUS_OK:
+ cr->status = UBCORE_CR_SUCCESS;
+ break;
+ case UB_CQ_STATUS_UNSUPPORTED_OPCODE:
+ cr->status = UBCORE_CR_UNSUPPORTED_OPCODE_ERR;
+ break;
+ case UB_CQ_STATUS_LOCAL_OPERATION_ERROR:
+ if (sub_status == UB_CQ_SUB_STATUS_LOCAL_LENGTH_ERROR) {
+ cr->status = UBCORE_CR_LOC_LEN_ERR;
+ } else if (sub_status == UB_CQ_SUB_STATUS_LOCAL_ACCESS_ERROR) {
+ cr->status = UBCORE_CR_LOC_ACCESS_ERR;
+ } else if (sub_status ==
+ UB_CQ_SUB_STATUS_REMOTE_RESPONSE_LENGTH_ERROR) {
+ cr->status = UBCORE_CR_REM_RESP_LEN_ERR;
+ } else {
+ cr->status = UBCORE_CR_LOC_OPERATION_ERR;
+ }
+ break;
+ case UB_CQ_STATUS_REMOTE_OPERATION_ERROR:
+ if (sub_status == UB_CQ_SUB_STATUS_REMOTE_UNSUPPORTED_REQUEST) {
+ cr->status = UBCORE_CR_REM_UNSUPPORTED_REQ_ERR;
+ } else if (sub_status == UB_CQ_SUB_STATUS_REMOTE_ACCESS_ABORT) {
+ cr->status = UBCORE_CR_REM_ACCESS_ABORT_ERR;
+ } else {
+ cr->status = UBCORE_CR_REM_OPERATION_ERR;
+ }
+ break;
+ case UB_CQ_STATUS_TRANSACTION_RETRY_COUNTER_EXCEEDED:
+ cr->status = UBCORE_CR_RNR_RETRY_CNT_EXC_ERR;
+ break;
+ case UB_CQ_STATUS_TRANSACTION_ACK_TIMEOUT:
+ cr->status = UBCORE_CR_ACK_TIMEOUT_ERR;
+ break;
+ case UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED:
+ cr->status = UBCORE_CR_FLUSH_ERR;
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Invalid cr status: 0x%x, sub_status: 0x%x.\n", status,
+ sub_status);
+ break;
+ }
+}
+
+static void udma_trans_flush_state(struct tag_ub_cqe *cqe, struct ubcore_cr *cr,
+ enum ubcore_jetty_state state)
+{
+ if (cqe->dw1.bs.fake == 0) {
+ cr->flag.bs.suspend_done =
+ (state == UBCORE_JETTY_STATE_SUSPENDED) ?
+ cqe->dw1.bs.flush_done :
+ 0;
+ cr->flag.bs.flush_err_done =
+ (state == UBCORE_JETTY_STATE_ERROR) ?
+ cqe->dw1.bs.flush_done :
+ 0;
+ return;
+ }
+
+ cr->flag.bs.suspend_done = 0;
+ cr->flag.bs.flush_err_done = 0;
+
+ if (cqe->dw0.bs.status == UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED) {
+ if (state == UBCORE_JETTY_STATE_SUSPENDED) {
+ cr->status = UBCORE_CR_WR_SUSPEND_DONE;
+ } else if (state == UBCORE_JETTY_STATE_ERROR) {
+ cr->status = UBCORE_CR_WR_FLUSH_ERR_DONE;
+ }
+ }
+}
+
+static void udma_set_drop_flag(const struct udma_device *udma_dev,
+ const struct tag_ub_cqe *cqe,
+ struct udma_jetty *jetty,
+ enum ubcore_jetty_state state, bool *drop_flag)
+{
+ if (cqe->dw1.bs.fake == 0)
+ return;
+
+ /* user not switch status is ERR, will cause fake andset flush done of CQE corresponding to cr status in expected outside (i.e. ubcore status cannot indicates cr is fake of), item before scheme is lose掉 this cr */
+ if ((state != UBCORE_JETTY_STATE_SUSPENDED) &&
+ (state != UBCORE_JETTY_STATE_ERROR)) {
+ udma_warn(
+ udma_dev->dev, UDMA_M_JFC,
+ "fake cqe but jetty_state(%u) is not SUSPEND or ERR, cqe status(%u), cr will be dropped\n",
+ state, cqe->dw0.bs.status);
+ *drop_flag = true;
+ return;
+ }
+}
+
+static int udma_update_recv_jetty_tail(struct udma_jfc *jfc,
+ struct tag_ub_cqe *cqe,
+ struct ubcore_cr *cr,
+ struct tag_cqm_object *object,
+ bool *fake_flag_recv)
+{
+ struct udma_device *udma_dev = to_udma_dev(jfc->base.ub_dev);
+ u32 wqe_idx = cqe->dw5.bs.big_rqe_idx;
+ struct udma_srq *srq = NULL;
+
+ srq = udma_get_srq_by_cqm_object(udma_dev, cqe, object, cr);
+ if (srq == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get jetty/jfr failed, jetty_id:0x%x\n",
+ cqe->dw3.bs.local_jfx_num);
+ return -EINVAL;
+ }
+
+ if (cqe->dw0.bs.status == UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED &&
+ cqe->dw1.bs.fake == 1) {
+ /* fake flag will be marked when fake flush cqe.wqe_idx == srq.head. the cqe will be skipped */
+ if (wqe_idx * srq->container_size == (u32)srq->head) {
+ udma_err(udma_dev->dev, UDMA_M_JFC, "fake cqe(%u)\n",
+ wqe_idx);
+ jfc->ci++;
+ *fake_flag_recv = true;
+ return -EINVAL;
+ }
+ if (!srq->flush_flag) {
+ srq->stop_index = (u16)wqe_idx;
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "srq flush start, wqe(%u)\n", wqe_idx);
+ } else {
+ wqe_idx = srq->stop_index;
+ }
+
+ srq->flush_flag = true;
+ }
+
+ cr->user_ctx = srq->wrid[(wqe_idx * srq->container_size) &
+ (srq->max_depth - 1)];
+ udma_free_srq_wqe(srq, wqe_idx);
+
+ if (cqe->dw1.bs.inline_flag != 0)
+ handle_recv_inline_cqe(udma_dev, cqe, srq, cr, wqe_idx);
+
+ if (cqe->dw0.bs.status == UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED &&
+ cqe->dw1.bs.fake == 1) {
+ srq->stop_index = udma_get_next_srq_wqe(srq, srq->stop_index);
+ if (srq->stop_index * srq->container_size == srq->head) {
+ srq->flush_flag = false;
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "srq flush done(%u)\n", srq->stop_index);
+ jfc->ci++;
+ }
+ }
+
+ udma_parse_cr_status(udma_dev, cqe, cr);
+
+ udma_debug(udma_dev->dev, UDMA_M_JFC,
+ "update srq tail: id:0x%x, tail:0x%x, status:0x%x-%x\n",
+ cqe->dw3.bs.local_jfx_num, srq->tail, cqe->dw0.bs.status,
+ cqe->dw2.bs.sub_status);
+ return 0;
+}
+
+static void udma_handle_send_inline_cqe(struct udma_device *udma_dev,
+ struct udma_send_queue *sq,
+ struct tag_ub_cqe *cqe)
+{
+ struct tag_ub_sq_wqe_s *wqe = NULL;
+ struct ub_cmd_sge *sge = NULL;
+ struct ub_cmd_sge tmp_sge;
+ ub_sq_wqe_task_com_s tmp;
+ u8 *cqe_inline_buf = NULL;
+ u32 pi = cqe->dw1.bs.pi;
+ u32 wqe_off;
+ u32 data_len;
+ u32 size;
+ u64 data;
+
+ wqe_off = (pi & (sq->baseblk_cnt - 1)) << sq->baseblk_shift;
+ wqe = (struct tag_ub_sq_wqe_s *)(sq->buf + wqe_off);
+ tmp.dw0_value = ntohl(wqe->tsk_sec.com.dw0_value);
+ if (tmp.op_type != UB_TX_READ) {
+ udma_warn(udma_dev->dev, UDMA_M_JFC,
+ "only read support inline_flag, op_type: %d\n",
+ tmp.op_type);
+ return;
+ }
+
+ data = ntohll(((u64)(cqe->inline_data[0]) << UB_LONG_DATA_OFFSET) |
+ (u64)(cqe->inline_data[1]));
+ cqe_inline_buf = (u8 *)&data;
+ data_len = cqe->byte_cnt;
+
+ //preventstop wrap around
+ wqe_off = ((pi + 1) & (sq->baseblk_cnt - 1)) << sq->baseblk_shift;
+ sge = (ub_cmd_sge_t *)(sq->buf + wqe_off + UB_DEID_BYTE_LENGTH);
+
+ do {
+ if ((u8 *)sge >= (u8 *)(sq->buf + sq->buf_size)) {
+ sge = (ub_cmd_sge_t *)sq->buf;
+ }
+ tmp_sge = *sge;
+ tmp_sge.dw3.dw3_value = ntohl(tmp_sge.dw3.dw3_value);
+ tmp_sge.length = ntohl(tmp_sge.length);
+ tmp_sge.va = ntohll(tmp_sge.va);
+ size = (tmp_sge.length > data_len) ? data_len : tmp_sge.length;
+ memcpy_s((void *)(uintptr_t)tmp_sge.va, tmp_sge.length,
+ (void *)cqe_inline_buf, size);
+
+ data_len -= size;
+ cqe_inline_buf += size;
+ sge++;
+ } while ((tmp_sge.dw3.bs.L == 0) && (data_len != 0));
+}
+
+static int
+udma_update_send_jetty_tail(struct udma_device *udma_dev, struct udma_jfc *jfc,
+ struct tag_ub_cqe *cqe, struct ubcore_cr *cr,
+ struct tag_cqm_object *object, bool *drop_flag)
+{
+ struct udma_send_queue *sq = NULL;
+ struct udma_jetty *jetty = NULL;
+ enum ubcore_jetty_state state;
+ struct udma_jfs *jfs = NULL;
+ u8 fake = cqe->dw1.bs.fake;
+ u16 sq_tail_overflow;
+
+ jetty = cqmobj_to_ub_jetty(object);
+ if (jetty != NULL) {
+ if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) {
+ sq = &jetty->sq;
+ state = jetty->state;
+ cr->user_data = (uintptr_t)(&jetty->ubcore_jetty);
+ } else if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JFS) {
+ jfs = cqmobj_to_ub_jfs(object);
+ sq = &jfs->sq;
+ state = jfs->state;
+ cr->user_data = (uintptr_t)&jfs->ubcore_jfs;
+ }
+ }
+
+ if ((sq == NULL) || (sq->wrid == NULL) || (sq->wrid_size == 0)) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get jetty/jfs failed, jetty_id:0x%x\n",
+ cqe->dw3.bs.local_jfx_num);
+ return -EINVAL;
+ }
+
+ if (cqe->dw1.bs.inline_flag != 0)
+ udma_handle_send_inline_cqe(udma_dev, sq, cqe);
+
+ if (fake == 0) {
+ sq_tail_overflow =
+ (cqe->dw3.bs.wqe_idx < (sq->tail & CQE_WQE_IDX_MASK)) ?
+ (1 << CQE_WQE_IDX_SHIFT) :
+ 0;
+ sq->tail = cqe->dw3.bs.wqe_idx +
+ (sq->tail & (~CQE_WQE_IDX_MASK)) + sq_tail_overflow;
+ cr->user_ctx = sq->wrid[sq->tail & (sq->wrid_size - 1)];
+ sq->tail++;
+ }
+
+ if (cqe->dw1.bs.flush_done == 1)
+ sq->flush_tail = sq->tail;
+
+ cr->flag.bs.jetty =
+ (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) ? 1 : 0;
+ udma_parse_cr_status(udma_dev, cqe, cr);
+ udma_trans_flush_state(cqe, cr, state);
+ udma_set_drop_flag(udma_dev, cqe, jetty, state, drop_flag);
+
+ sq->is_hw_flush_done = cqe->dw1.bs.flush_done;
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFC,
+ "update %s tail: id:0x%x, tail:0x%x, wqe_idx: %u, fake: %u, status:0x%x-%x\n",
+ (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) ? "send jetty" :
+ "jfs",
+ cqe->dw3.bs.local_jfx_num, sq->tail, cqe->dw3.bs.wqe_idx, fake,
+ cqe->dw0.bs.status, cqe->dw2.bs.sub_status);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFC,
+ "jetty_type(%u), state(%u), status(%u), flush_done(%u), suspend_done(%u), flush_err_done(%u)\n",
+ jetty->cqm_priv_type, state, cr->status, cqe->dw1.bs.flush_done,
+ cr->flag.bs.suspend_done, cr->flag.bs.flush_err_done);
+
+ return 0;
+}
+
+static bool udma_should_get_new_object(struct udma_device *udma_dev,
+ struct tag_cqm_object *object,
+ const struct tag_ub_cqe *cqe)
+{
+ struct udma_jetty *jetty = NULL;
+ struct udma_jfr *jfr = NULL;
+ u32 round;
+
+ if (cqe->dw0.bs.s_r == UB_SQ_CQE)
+ return false;
+
+ if (object == NULL)
+ return true;
+
+ jetty = cqmobj_to_ub_jetty(object);
+ if (jetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "get jetty/jfr from object failed\n");
+ return true;
+ }
+
+ if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) {
+ round = jetty->round;
+ } else if (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JFR) {
+ jfr = cqmobj_to_ub_jfr(object);
+ round = jfr->round;
+ } else {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "cqm obj not match jetty/jfr\n");
+ return true;
+ }
+
+ if ((u8)round == cqe->dw15.bs.jetty_round)
+ return false;
+
+ udma_debug(udma_dev->dev, UDMA_M_JFC,
+ "jetty_type(%u), jfx round(%x), cqe round(%x)\n",
+ jetty->cqm_priv_type, round, cqe->dw15.bs.jetty_round);
+
+ return (jetty->cqm_priv_type == UDMA_JETTY_TYPE_JETTY) ? true : false;
+}
+
+static int udma_update_jetty_tail(struct udma_device *udma_dev,
+ struct udma_jfc *jfc, struct tag_ub_cqe *cqe,
+ struct ubcore_cr *cr, bool *drop_flag)
+{
+ struct tag_cqm_object *object =
+ cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ cqe->dw3.bs.local_jfx_num, false);
+ int ret;
+
+ if (udma_should_get_new_object(udma_dev, object, cqe) == true) {
+ if (object != NULL) {
+ cqm5_object_put(object);
+ }
+ /* for at jetty recv cqe, and jetty not match of scenario, try use jfr report up CR */
+ object = cqm5_object_get(udma_dev->hwdev,
+ CQM_OBJECT_SERVICE_CTX,
+ cqe->dw15.bs.jfrn, false);
+
+ udma_warn(
+ udma_dev->dev, UDMA_M_JFC,
+ "get cqe info, local_jfx_num(%u), jfrn(%u), status(%u)\n",
+ cqe->dw3.bs.local_jfx_num, cqe->dw15.bs.jfrn,
+ cqe->dw0.bs.status);
+
+ if (object != NULL) {
+ cqe->dw3.bs.local_jfx_num = cqe->dw15.bs.jfrn;
+ cqe->dw0.bs.status =
+ UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED;
+ }
+ }
+
+ if (object == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "Get cqm object failed, jetty_id:0x%x\n",
+ cqe->dw3.bs.local_jfx_num);
+ return -EINVAL;
+ }
+
+ if (cqe->dw0.bs.s_r == UB_SQ_CQE) {
+ atomic64_inc(&jfc->udma_driver_jfc_ctr.poll_sq_num);
+ atomic64_inc(&udma_dev->udma_driver_device_ctr.poll_sq_num);
+ ret = udma_update_send_jetty_tail(udma_dev, jfc, cqe, cr,
+ object, drop_flag);
+ } else {
+ atomic64_inc(&jfc->udma_driver_jfc_ctr.poll_rq_num);
+ atomic64_inc(&udma_dev->udma_driver_device_ctr.poll_rq_num);
+ ret = udma_update_recv_jetty_tail(jfc, cqe, cr, object,
+ drop_flag);
+ }
+
+ cqm5_object_put(object);
+ return ret;
+}
+
+static void udma_fill_recv_cr(struct udma_device *udma_dev,
+ struct tag_ub_cqe *cqe, struct ubcore_cr *cr)
+{
+ udma_debug(udma_dev->dev, UDMA_M_JFC, "recv_cqe.optype(0x%x)\n",
+ cqe->dw1.bs.op_type);
+ cr->remote_id.id = cqe->dw2.bs.rmt_jfx_num;
+ (void)memcpy_s(&cr->remote_id.eid, sizeof(cr->remote_id.eid),
+ cqe->remote_eid, sizeof(cqe->remote_eid));
+ cr->flag.bs.s_r = 1; //recv
+ switch (cqe->dw1.bs.op_type) {
+ case UB_CQE_RQ_OPTYPE_WRITE_IMMEDIATE:
+ cr->opcode = UBCORE_CR_OPC_WRITE_WITH_IMM;
+ cr->imm_data =
+ ((u64)(cqe->imme_data[0]) << UB_LONG_DATA_OFFSET) |
+ (u64)(cqe->imme_data[1]);
+ break;
+
+ case UB_CQE_RQ_OPTYPE_SEND:
+ cr->opcode = UBCORE_CR_OPC_SEND;
+ break;
+
+ case UB_CQE_RQ_OPTYPE_SEND_IMMEDIATE:
+ cr->opcode = UBCORE_CR_OPC_SEND_WITH_IMM;
+ cr->imm_data =
+ ((u64)(cqe->imme_data[0]) << UB_LONG_DATA_OFFSET) |
+ (u64)(cqe->imme_data[1]);
+ break;
+
+ case UB_CQE_RQ_OPTYPE_SEND_INVALIDATE:
+ cr->opcode = UBCORE_CR_OPC_SEND_WITH_INV;
+ cr->imm_data =
+ ((u64)(cqe->imme_data[0]) << UB_LONG_DATA_OFFSET) |
+ (u64)(cqe->imme_data[1]);
+ break;
+
+ default:
+ udma_err(udma_dev->dev, UDMA_M_JFC, "invalid cqe optype:%x\n",
+ cqe->dw1.bs.op_type);
+ break;
+ }
+}
+
+static void udma_fill_cr(struct udma_device *udma_dev, struct tag_ub_cqe *cqe,
+ struct ubcore_cr *cr)
+{
+ cr->local_id = cqe->dw3.bs.local_jfx_num;
+ cr->completion_len = cqe->byte_cnt;
+ cr->tpn = cqe->dw0.bs.tpn;
+
+ cr->flag.bs.s_r = 0; //send
+ cr->opcode = (enum ubcore_cr_opcode)INVALID_CR_OPCODE;
+
+ if (cqe->dw0.bs.s_r == UB_RQ_CQE)
+ udma_fill_recv_cr(udma_dev, cqe, cr);
+}
+
+static int udma_poll_jfc_one(struct udma_jfc *jfc, struct ubcore_cr *cr,
+ bool *drop_flag)
+{
+ struct udma_device *udma_dev = to_udma_dev(jfc->base.ub_dev);
+ u32 idx = jfc->ci & (jfc->base.jfc_cfg.depth - 1);
+ struct tag_ub_cqe *cqe = NULL;
+ u32 valid_owner;
+ int ret;
+ if (jfc->base.ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JFC, "Invalid parameter: ub_dev(%d).\n",
+ !!jfc->base.ub_dev);
+ return -EINVAL;
+ }
+
+ valid_owner = (((jfc->ci >> ilog2(jfc->base.jfc_cfg.depth)) & 1) == 0) ?
+ 1 :
+ 0;
+ cqe = (struct tag_ub_cqe *)((u8 *)jfc->jfc_va +
+ idx * sizeof(struct tag_ub_cqe));
+ if (cqe->dw0.bs.o == valid_owner)
+ return -EAGAIN;
+
+ rmb();
+
+ udma_dfx_print_cqe(udma_dev, jfc, cqe);
+
+ /* fake flush cqe is a flag to flush jfr wr, can't move to next cqe until flush done */
+ if (!(cqe->dw0.bs.s_r == UB_RQ_CQE && cqe->dw1.bs.fake == 1 &&
+ cqe->dw0.bs.status == UB_CQ_STATUS_JETTY_WORK_REQUEST_FLUSHED)) {
+ jfc->ci++;
+ }
+
+ ret = udma_update_jetty_tail(udma_dev, jfc, cqe, cr, drop_flag);
+ if (*drop_flag == true)
+ return 0;
+ if (ret != 0)
+ return ret;
+
+ udma_fill_cr(udma_dev, cqe, cr);
+ return 0;
+}
+
+int udma_poll_jfc(struct ubcore_jfc *ub_jfc, int cr_cnt, struct ubcore_cr *cr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfc *jfc = NULL;
+ bool drop_flag = false;
+ ulong flags = 0;
+ int npolled;
+ int ret = 0;
+
+ if ((ub_jfc == NULL) || (ub_jfc->ub_dev == NULL) || (cr == NULL)) {
+ udma_pr_err(UDMA_M_JFC,
+ "%s Invalid parameter: ub_jfc(%d), cr(%d).\n",
+ __func__, !!ub_jfc, !!cr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_jfc->ub_dev);
+ jfc = to_udma_jfc(ub_jfc);
+ spin_lock_irqsave(&jfc->lock, flags);
+
+ for (npolled = 0; npolled < cr_cnt; ++npolled) {
+ ret = udma_poll_jfc_one(jfc, cr + npolled, &drop_flag);
+ if (ret != 0)
+ break;
+ if (drop_flag) {
+ drop_flag = false;
+ --npolled;
+ udma_info(udma_dev->dev, UDMA_M_JFC,
+ "drop flag is set, drop cqe\n");
+ }
+ }
+
+ rmb();
+ *jfc->db.db_record = cpu_to_be32(jfc->ci & UB_CQ_UPDATE_CI_MASK);
+
+ spin_unlock_irqrestore(&jfc->lock, flags);
+
+ if (ret == 0 || ret == -EAGAIN) {
+ if (npolled > 0) {
+ atomic64_add(npolled,
+ &jfc->udma_driver_jfc_ctr.poll_total_num);
+ atomic64_add(npolled, &udma_dev->udma_driver_device_ctr
+ .poll_total_num);
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFC,
+ "jfc_id:0x%x, poll_cnt:%d, jfc_total_poll:%llu, dev_total_poll:%llu\n",
+ jfc->base.id, npolled,
+ (u64)atomic64_read(&jfc->udma_driver_jfc_ctr
+ .poll_total_num),
+ (u64)atomic64_read(
+ &udma_dev->udma_driver_device_ctr
+ .poll_total_num));
+ }
+ return npolled;
+ }
+ return ret;
+}
+
+static int udma_update_jfc_db(struct udma_device *udma_dev,
+ struct udma_jfc *jfc, u32 cmd, u32 arm_sn)
+{
+ union tag_ub_cq_db_u jfc_db;
+ int ret;
+
+ jfc_db.cq_db_value = 0;
+ jfc_db.cq_db.dw0.bs.type = CQ_DB_TYPE;
+ jfc_db.cq_db.dw0.bs.cqn = jfc->base.id;
+ jfc_db.cq_db.dw0.bs.c = 1;
+ jfc_db.cq_db.dw0.bs.n = 1;
+ jfc_db.cq_db.dw0.bs.cos = 0;
+ jfc_db.cq_db.dw0.bs.cqc_type = 0;
+ *(jfc->db.db_record) = cpu_to_be32(jfc->ci & UB_CQ_UPDATE_CI_MASK);
+
+ jfc_db.cq_db.dw1.bs.ci = jfc->ci & UB_CQ_UPDATE_CI_MASK;
+ jfc_db.cq_db.dw1.bs.cmd = cmd;
+ jfc_db.cq_db.dw1.bs.cmd_sn = arm_sn;
+
+ wmb();
+ ret = cqm5_ring_hardware_db(udma_dev->hwdev, SERVICE_T_UB,
+ jfc->ci & 0xff, jfc_db.cq_db_value);
+
+ udma_debug(udma_dev->dev, UDMA_M_JFC,
+ "xid:0x%x, jfc_db.cq_db_value:0x%llx\n", jfc->base.id,
+ jfc_db.cq_db_value);
+ return ret;
+}
+
+int udma_rearm_jfc(struct ubcore_jfc *jfc, bool solicited_only)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfc *ub_jfc = NULL;
+ u32 arm_sn;
+ u32 cmd;
+ int ret;
+
+ if ((jfc == NULL) || (jfc->ub_dev == NULL)) {
+ udma_pr_err(UDMA_M_JFC, "%s Invalid parameter: jfc(%d).\n",
+ __func__, !!jfc);
+ return -EINVAL;
+ }
+
+ ub_jfc = to_udma_jfc(jfc);
+ udma_dev = to_udma_dev(jfc->ub_dev);
+
+ cmd = (u32)((solicited_only != 0) ? UB_ARM_JFC_SOLICITED :
+ UB_ARM_JFC_UN_SOLICITED);
+ arm_sn = (u32)ub_jfc->arm_sn & (u32)UB_CQ_ARMSN_MASK;
+
+ ret = udma_update_jfc_db(udma_dev, ub_jfc, cmd, arm_sn); //update db
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFC,
+ "udma update jfc(0x%x) db failed,\n", jfc->id);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.h b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.h
new file mode 100644
index 000000000..52ee9a4fd
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfc.h
@@ -0,0 +1,77 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_JFC_H
+#define UDMA_JFC_H
+
+#include "ubcore_api.h"
+#include "udma_common.h"
+#include "udma_db.h"
+#include "hinic5_cqm.h"
+
+#define UB_CQE_SIZE 64
+#define UB_JFC_CQE_SIZE 2
+#define CQ_DB_TYPE 17
+
+#define UB_CQ_ARMSN_MASK 3
+#define UB_CQ_UPDATE_CI_MASK 0xffffff
+#define UB_LONG_DATA_OFFSET 32
+
+enum ub_arm_jfc_type { UB_ARM_JFC_SOLICITED = 1, UB_ARM_JFC_UN_SOLICITED = 2 };
+
+typedef struct udma_driver_jfc_ctr {
+ atomic64_t poll_total_num;
+ atomic64_t poll_sq_num;
+ atomic64_t poll_rq_num;
+} udma_driver_jfc_ctr_t;
+
+typedef struct udma_jfc {
+ u32 cqm_priv_type;
+ struct ubcore_jfc base;
+ struct tag_cqm_queue *cqm_jfc;
+ struct tag_cqm_buf *buf;
+ struct queue_addr_info queue_addr;
+ void *jfc_va;
+ struct udma_db db;
+ struct mtt ub_mtt;
+ struct ubcore_umem *umem;
+ spinlock_t lock;
+ u32 ci;
+ u32 page_shift;
+ u32 cq_buf_size;
+ u32 arm_sn;
+ udma_driver_jfc_ctr_t udma_driver_jfc_ctr;
+ struct list_head node;
+ atomic_t used_by_jfs;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+} udma_jfc_t;
+
+struct ubcore_jfc *udma_create_jfc(struct ubcore_device *ub_dev,
+ struct ubcore_jfc_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_modify_jfc(struct ubcore_jfc *ub_jfc, struct ubcore_jfc_attr *attr,
+ struct ubcore_udata *udata);
+int udma_destroy_jfc(struct ubcore_jfc *ub_jfc);
+int udma_poll_jfc(struct ubcore_jfc *ub_jfc, int cr_cnt, struct ubcore_cr *cr);
+void udma_jfc_async_event(struct udma_device *udma_dev, struct udma_jfc *jfc,
+ u8 type);
+int udma_rearm_jfc(struct ubcore_jfc *jfc, bool solicited_only);
+struct udma_jfc *udma_find_jfc(struct udma_device *udev, u32 jfc_id);
+int udma_query_res_jfc(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val);
+void udma_jfc_put(void *obj);
+void udma_jfc_get(void *obj);
+
+u32 udma_get_jfc_inline(struct udma_device *udma_dev,
+ const struct ubcore_jfc *jfc);
+
+static inline struct udma_jfc *to_udma_jfc(const struct ubcore_jfc *jfc)
+{
+ return (struct udma_jfc *)udma_container_of(jfc, struct udma_jfc, base);
+}
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfr.c b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfr.c
new file mode 100644
index 000000000..3d8269f56
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfr.c
@@ -0,0 +1,1042 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include "ubcore_uapi.h"
+#include "ub_aeqe.h"
+#include "udma_common.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_jetty.h"
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+#include "udma_abi.h"
+#include "udma_srq.h"
+#include "udma_cmd_srq.h"
+#include "udma_cmd_jfr.h"
+#include "udma_cmd_jetty.h"
+
+#define UB_QUERY_JFR_MASK 0x3
+
+static void udma_jfr_kref_release(struct kref *ref_cnt)
+{
+ struct udma_jfr *jfr = container_of(ref_cnt, struct udma_jfr, ref_cnt);
+
+ complete(&jfr->comp);
+}
+
+void udma_jfr_put(void *obj)
+{
+ struct udma_jfr *jfr = obj;
+
+ if (jfr != NULL) {
+ kref_put(&jfr->ref_cnt, udma_jfr_kref_release);
+ }
+}
+
+void udma_jfr_get(void *obj)
+{
+ struct udma_jfr *jfr = obj;
+
+ kref_get(&jfr->ref_cnt);
+}
+
+struct udma_jfr *udma_find_jfr(struct udma_device *udev, u32 jfr_id)
+{
+ struct udma_jfr *udma_jfr = NULL;
+ struct mutex *lock = NULL;
+
+ if (udev == NULL) {
+ udma_pr_err(UDMA_M_JFR, "Invalid parameter: udev(%d).\n",
+ !!udev);
+ return NULL;
+ }
+ lock = &udev->device_res->jfr_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(udma_jfr, &udev->device_res->jfr_list.node, node) {
+ if (udma_jfr->jfr_id == jfr_id) {
+ udma_jfr_get(udma_jfr);
+ mutex_unlock(lock);
+ return udma_jfr;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static int udma_create_jfr_check(struct ubcore_device *ub_dev,
+ const struct ubcore_jfr_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if (ub_dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_JFR,
+ "Invalid parameter, ub_dev(%d), cfg(%d)\n",
+ !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "tpf not support this function.\n");
+ return -EINVAL;
+ }
+
+ if (cfg->depth == 0 ||
+ cfg->depth > udma_dev->ub_cap.dev_cap.max_jfr_depth) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "invalid parameter: jfr depth:%u, dev_cap jfr_depth:%u\n",
+ cfg->depth, udma_dev->ub_cap.dev_cap.max_jfr_depth);
+ return -EINVAL;
+ }
+
+ if (cfg->max_sge > udma_dev->ub_cap.dev_cap.max_jfr_sge) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "invalid parameter: jfr max_sge:%u, dev_cap max_jfr_sge:%u\n",
+ cfg->max_sge, udma_dev->ub_cap.dev_cap.max_jfr_sge);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.token_policy != UBCORE_TOKEN_NONE &&
+ cfg->flag.bs.token_policy != UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "token policy(%u) only support none or plain text.\n",
+ cfg->flag.bs.token_policy);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.tag_matching != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "jfr don't support tag matching.\n");
+ return -EINVAL;
+ }
+
+ if (cfg->trans_mode != UBCORE_TP_RC &&
+ cfg->trans_mode != UBCORE_TP_RM &&
+ cfg->trans_mode != UBCORE_TP_UM) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "jfr don't support trans_mode:%u\n", cfg->trans_mode);
+ return -EINVAL;
+ }
+
+ if (cfg->trans_mode == UBCORE_TP_RC &&
+ cfg->flag.bs.order_type != UBCORE_OT) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "jfr don't support trans_mode:RC, order_type:%u.\n",
+ cfg->flag.bs.order_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_alloc_jfrc(struct udma_device *udma_dev, struct udma_jfr *jfr)
+{
+ struct tag_cqm_qpc_mpt *jfrc_info = NULL;
+ u32 qpn_tmp = udma_get_qpn_mod(udma_dev, CQM_XID_LOW_BIT_NONE, 0);
+
+ jfrc_info = udma_object_qpc_create(
+ udma_dev, UBEP_JETTY_CONTEXT_SIZE, jfr,
+ &udma_dev->jettyn_record, qpn_tmp,
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num,
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty);
+ if (jfrc_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "create jfrc by cqm object failed\n");
+ return -ENOMEM;
+ }
+
+ jfr->jfrc_info = jfrc_info;
+ jfr->jfr_id = jfrc_info->xid;
+ jfr->srq.jfr_id = jfrc_info->xid;
+ return 0;
+}
+
+static int udma_create_jfr_context_update(struct udma_device *udma_dev,
+ struct udma_jfr *jfr,
+ const struct ubcore_jfr_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ int ret = 0;
+
+ ret = udma_cmd_jfr_create_ctx(udma_dev, jfr, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "create jfr context failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ if ((udma_get_uctx(udata) != NULL)) {
+ if (udata->udrv_data->out_addr == (uint64_t)NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "out_addr is NUll\n");
+ return ret;
+ }
+
+ if ((copy_to_user((void *)(uintptr_t)udata->udrv_data->out_addr,
+ &jfr->round, sizeof(u32)) != 0)) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Failed to copy to user driver\n");
+ return -EIO;
+ }
+ }
+
+ return ret;
+}
+
+static int udma_jfr_cache_out_cmd(struct udma_device *udma_dev,
+ struct udma_jfr *udma_jfr)
+{
+ u64 wb_dma = 0;
+ void *wb_va = NULL;
+ int ret;
+
+ wb_va = dma_alloc_coherent(udma_dev->dev, (size_t)4UL, &wb_dma,
+ GFP_KERNEL);
+ if (wb_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "allocate wb_va failed\n");
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_jfr_cache_out_ctx(udma_dev, udma_jfr, wb_dma);
+
+ dma_free_coherent(udma_dev->dev, sizeof(u32), wb_va, wb_dma);
+
+ return ret;
+}
+
+static int udma_delete_jfr_context_and_cache_out(struct udma_device *udma_dev,
+ struct udma_jfr *udma_jfr)
+{
+ int ret;
+
+ ret = udma_cmd_jfr_delete_ctx(udma_dev, udma_jfr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "delete jfrc:0x%06x failed.\n", udma_jfr->jfr_id);
+ return ret;
+ }
+
+ ret = udma_jfr_cache_out_cmd(udma_dev, udma_jfr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "jfr:0x%06x cache invalid.\n", udma_jfr->jfr_id);
+ return ret;
+ }
+
+ if (udma_jfr->jfrc_info != NULL) {
+ cqm5_object_delete(&(udma_jfr->jfrc_info->object));
+ udma_jfr->jfrc_info = NULL;
+ }
+
+ return ret;
+}
+
+static void udma_jfr_user_deinit_umem(struct udma_device *udma_dev,
+ struct ubcore_umem **umem,
+ struct mtt *ub_mtt)
+{
+ if (ub_mtt->mtt_seg != NULL) {
+ udma_destroy_user_mtt(udma_dev, ub_mtt);
+ ub_mtt->mtt_seg = NULL;
+ }
+
+ if (!IS_ERR_OR_NULL(*umem)) {
+ udma_put_umem(*umem);
+ *umem = NULL;
+ }
+}
+
+static int udma_jfr_user_init_umem(struct udma_device *udma_dev,
+ struct ubcore_umem **umem,
+ struct mtt *ub_mtt, u64 buf_addr,
+ u32 buf_size)
+{
+ int ret = 0;
+ *umem = udma_get_umem(udma_dev, buf_addr, buf_size);
+ if (IS_ERR_OR_NULL(*umem)) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "get jfr umem failed.\n");
+ *umem = NULL;
+ return -ENOMEM;
+ }
+
+ ret = udma_create_user_mtt(udma_dev, *umem, ub_mtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "create user mtt failed, ret:%d\n", ret);
+ udma_put_umem(*umem);
+ *umem = NULL;
+ }
+
+ return ret;
+}
+
+static int udma_jfr_create_user(struct udma_device *udma_dev,
+ const struct ubcore_jfr_cfg *cfg,
+ struct ubcore_udata *udata,
+ struct udma_jfr *jfr)
+{
+ struct ub_create_jetty_ucmd ucmd = { 0 };
+ struct udma_context *udma_ctx = NULL;
+ u32 ucmd_len;
+ int ret = 0;
+
+ udma_ctx = to_udma_ctx(udata->uctx);
+ ucmd_len = min(udata->udrv_data->in_len, (u32)sizeof(ucmd));
+ if (copy_from_user(&ucmd, (void *)(uintptr_t)udata->udrv_data->in_addr,
+ ucmd_len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "copy JFR udata failed, ret:%d.\n", ret);
+ return -EFAULT;
+ }
+ jfr->srq.buf_size = ucmd.buf_size;
+
+ ret = udma_init_user_mtt(udma_dev, &jfr->srq.ub_mtt, &jfr->srq.umem,
+ ucmd.buf_addr, ucmd.buf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "udma init user mtt failed, ret = %d.\n", ret);
+ return ret;
+ }
+ udma_fill_queue_addr_info(&jfr->srq.queue_addr,
+ jfr->srq.ub_mtt.mtt_paddr, jfr->srq.buf_size,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ if (jfr->srq.index_queue_en) {
+ ret = udma_jfr_user_init_umem(udma_dev, &jfr->index_queue.umem,
+ &jfr->index_queue.ub_mtt,
+ ucmd.index_q_buf_addr,
+ ucmd.index_q_buf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "init jfr index queue umem failed, ret:%d\n",
+ ret);
+ goto err_init_index_queue_umem;
+ }
+ }
+
+ ret = udma_db_map_user(udma_ctx, ucmd.sdb_addr, &jfr->sdb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "map user db failed, ret:%d\n", ret);
+ goto err_map_db;
+ }
+
+ ret = udma_create_srqc_update(udma_dev, &jfr->srq, &jfr->sdb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "create srqc failed, ret:%d\n", ret);
+ goto err_create_srqc;
+ }
+ return ret;
+
+err_create_srqc:
+ udma_db_unmap_user(udma_ctx, &jfr->sdb);
+err_map_db:
+ udma_uninit_user_mtt(udma_dev, &jfr->srq.ub_mtt, jfr->srq.umem);
+ jfr->srq.umem = NULL;
+ if (jfr->srq.index_queue_en) {
+ udma_jfr_user_deinit_umem(udma_dev, &jfr->index_queue.umem,
+ &jfr->index_queue.ub_mtt);
+ }
+err_init_index_queue_umem:
+ udma_jfr_user_deinit_umem(udma_dev, &jfr->srq.umem, &jfr->srq.ub_mtt);
+ return ret;
+}
+
+int udma_alloc_srq_resource(struct udma_device *udma_dev,
+ cqm_queue_s **cqm_buf_info, struct udma_jfr *jfr,
+ u32 buf_len, struct queue_addr_info *queue_addr)
+{
+ u8 mtt_pro_en = udma_dev->ub_cap.dev_cap.mtt_pro_en;
+ u32 xid_start = 0;
+ u32 xid_end = xid_start + udma_dev->ub_cap.dev_cap_res.sdk_res.max_jfr;
+ u32 queue_len;
+ u32 buf_size;
+ int ret;
+
+ buf_size = mtt_pro_en == 1 ? PAGE_SIZE : buf_len;
+ *cqm_buf_info = udma_object_queue_create(
+ udma_dev, CQM_OBJECT_RDMA_SRQ, buf_size, (void *)jfr,
+ &udma_dev->srqn_record, true,
+ CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE, CQM_XID_LOW_BIT_0_0_1,
+ jfr->jfr_id),
+ xid_start, xid_end);
+ if (*cqm_buf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to create queue by cqm object.\n");
+ return -ENOMEM;
+ }
+
+ if (mtt_pro_en == 1) {
+ queue_len = udma_cal_page_size(buf_len);
+ ret = hinic5_dma_zalloc_coherent_align(udma_dev->dev, queue_len,
+ queue_len, GFP_KERNEL,
+ &queue_addr->mem_align);
+ if (ret != 0) {
+ cqm5_object_delete(&(*cqm_buf_info)->object);
+ *cqm_buf_info = NULL;
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Failed to alloc dma addr, ret = %d\n", ret);
+ return -ENOMEM;
+ }
+ udma_fill_kernel_queue_addr_info(queue_len, queue_addr);
+ }
+
+ return 0;
+}
+
+static int udma_jfr_create_kernel(struct udma_device *udma_dev,
+ const struct ubcore_jfr_cfg *cfg,
+ struct udma_jfr *jfr)
+{
+ struct tag_cqm_queue *srq_buf_info = NULL;
+ struct udma_srq *srq = &jfr->srq;
+ int ret = 0;
+
+ ret = udma_alloc_srq_resource(udma_dev, &srq_buf_info, jfr,
+ srq->buf_size, &jfr->srq.queue_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY,
+ "Failed to create srq queue, ret = %d.\n", ret);
+ return -ENOMEM;
+ }
+
+ ret = udma_init_kernel_mtt(udma_dev, &jfr->srq.ub_mtt, srq_buf_info,
+ jfr->srq.queue_addr.pa);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to init kernel mtt, ret = %d.\n", ret);
+ goto err_init_kernel_mtt;
+ }
+
+ ret = udma_srq_init_res(udma_dev, srq, srq_buf_info);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "init srq buf failed, ret:%d\n", ret);
+ goto err_and_free_queue_mtt;
+ }
+
+ srq->wrid = (u64 *)kzalloc((size_t)((u32)srq->max_depth * sizeof(u64)),
+ GFP_KERNEL);
+
+ if (srq->wrid == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "alloc srq wrid fail, ret:%d\n", ret);
+ ret = -ENOMEM;
+ goto err_and_free_queue_mtt;
+ }
+
+ ret = udma_cmd_srq_create_ctx(udma_dev, srq, &srq->db);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "enable srq context failed, ret:%d\n", ret);
+ goto err_and_free_queue_res;
+ }
+
+ return 0;
+
+err_and_free_queue_res:
+ kfree(srq->wrid);
+ srq->wrid = NULL;
+err_and_free_queue_mtt:
+ udma_uninit_kernel_mtt(udma_dev, &jfr->srq.ub_mtt);
+err_init_kernel_mtt:
+ udma_free_queue_resource(udma_dev, srq_buf_info, &jfr->srq.queue_addr);
+ jfr->srq.srqc_info = NULL;
+ return ret;
+}
+
+static int udma_jfr_delete_kernel(struct udma_device *udma_dev,
+ struct udma_jfr *jfr)
+{
+ struct udma_srq *srq = &jfr->srq;
+ int ret;
+
+ ret = udma_cmd_srq_delete_ctx(udma_dev, srq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "srqc delete and cache out failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ if (srq->wrid != NULL) {
+ kfree(srq->wrid);
+ srq->wrid = NULL;
+ }
+
+ udma_uninit_kernel_mtt(udma_dev, &srq->ub_mtt);
+ udma_free_queue_resource(udma_dev, srq->srqc_info, &srq->queue_addr);
+ srq->srqc_info = NULL;
+
+ return 0;
+}
+
+static int udma_jfr_delete_user(struct udma_device *udma_dev,
+ struct udma_context *udma_ctx,
+ struct udma_jfr *udma_jfr)
+{
+ int ret;
+
+ if (udma_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "jfr is null\n");
+ return -EINVAL;
+ }
+
+ ret = udma_delete_srqc_and_cache_out(udma_dev, &udma_jfr->srq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "delete srqc:0x%06x failed, ret:%d\n",
+ udma_jfr->srq.srqn, ret);
+ return ret;
+ }
+
+ udma_db_unmap_user(udma_ctx, &udma_jfr->sdb);
+
+ if (udma_jfr->srq.index_queue_en) {
+ udma_jfr_user_deinit_umem(udma_dev, &udma_jfr->index_queue.umem,
+ &udma_jfr->index_queue.ub_mtt);
+ }
+
+ udma_uninit_user_mtt(udma_dev, &udma_jfr->srq.ub_mtt,
+ udma_jfr->srq.umem);
+ udma_jfr->srq.umem = NULL;
+
+ return ret;
+}
+
+/* 1825v100 modify jfr index queue limit threshold: idx_wqe_cnt_lth */
+static int udma_modify_jfr_idx_queue_lth(struct udma_device *udma_dev,
+ struct udma_jfr *udma_jfr,
+ u16 idx_queue_lth)
+{
+ struct udma_jfr_modify_cfg cfg = { 0 };
+
+ cfg.mask.idx_queue_lth = 1;
+ cfg.idx_queue_lth = idx_queue_lth;
+
+ if (udma_cmd_jfr_modify_ctx(udma_dev, udma_jfr, &cfg) != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "modify jfr index queue limit threshold cmd failed, jfrid:%u, old_lth:%u, new_lth:%u\n",
+ udma_jfr->jfr_id, udma_jfr->idx_queue_lth,
+ idx_queue_lth);
+ return -EFAULT;
+ }
+ udma_jfr->idx_queue_lth = idx_queue_lth;
+ udma_info(
+ udma_dev->dev, UDMA_M_JFR,
+ "modify jfr index queue limit threshold successfully, jfrid:%u\n",
+ udma_jfr->jfr_id);
+ return 0;
+}
+
+static int udma_modify_jfr_threshold(struct udma_device *udma_dev,
+ struct udma_jfr *jfr, u32 threshold)
+{
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ return udma_modify_jfr_idx_queue_lth(udma_dev, jfr,
+ (u16)threshold);
+ }
+ return udma_modify_srq_threshold(udma_dev, &jfr->srq, (u8)threshold);
+}
+
+static int udma_modify_jfr_state(struct udma_device *udma_dev,
+ struct udma_jfr *udma_jfr,
+ enum ubcore_jfr_state state,
+ struct ubcore_udata *udata)
+{
+ struct udma_db *sdb = &udma_jfr->sdb;
+ struct udma_srq *srq = &udma_jfr->srq;
+ struct udma_jfr_modify_cfg cfg = { 0 };
+
+ cfg.mask.state = 1;
+ cfg.state = state;
+
+ if (udma_cmd_jfr_modify_ctx(udma_dev, udma_jfr, &cfg) != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "modify jfr state cmd failed, jfrid:%u, old_state:%u, new_state:%u\n",
+ udma_jfr->jfr_id, udma_jfr->state, state);
+ return -EFAULT;
+ }
+
+ if (udma_jfr->state == UBCORE_JFR_STATE_RESET &&
+ state == UBCORE_JFR_STATE_READY) {
+ if (udma_get_uctx(udata) == NULL) {
+ (void)memset_s(srq->wrid,
+ srq->max_depth * sizeof(*(srq->wrid)), 0,
+ srq->max_depth * sizeof(*(srq->wrid)));
+ srq->container_warn_th = 0;
+ udma_srq_init_res(udma_dev, srq, srq->srqc_info);
+ sdb = &srq->db;
+ }
+
+ if (udma_cmd_srq_create_ctx(udma_dev, srq, sdb) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "RESET: Enable srq context failed.\n");
+ return -EFAULT;
+ }
+ }
+ udma_jfr->state = state;
+ udma_info(udma_dev->dev, UDMA_M_JFR,
+ "modify jfr state successfully, jfrid:%u\n",
+ udma_jfr->jfr_id);
+ return 0;
+}
+
+struct ubcore_jfr *udma_create_jfr(struct ubcore_device *ub_dev,
+ struct ubcore_jfr_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfr *jfr = NULL;
+ int ret = 0;
+
+ if (udma_create_jfr_check(ub_dev, cfg) != 0) {
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ jfr = (struct udma_jfr *)kcalloc(1, sizeof(*jfr), GFP_KERNEL);
+ if (jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "kcalloc JFR failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ jfr->cqm_priv_type = UDMA_JETTY_TYPE_JFR;
+ udma_srq_init_attr(udma_dev, &jfr->srq, cfg->depth, cfg->max_sge);
+ if (jfr->srq.index_queue_en) {
+ udma_index_queue_init_attr(udma_dev, &jfr->index_queue,
+ cfg->depth);
+ }
+ jfr->ubcore_jfr.jfr_cfg = *cfg;
+ udma_cmdq_rtt_statistic_init(&jfr->cmdq_rtt);
+
+ if (udma_alloc_jfrc(udma_dev, jfr) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "allocate jfrc failed, ret:%d\n", ret);
+ ret = -ENOMEM;
+ goto err_init_srq;
+ }
+
+ if (udma_get_uctx(udata) == NULL)
+ ret = udma_jfr_create_kernel(udma_dev, cfg, jfr);
+ else
+ ret = udma_jfr_create_user(udma_dev, cfg, udata, jfr);
+ /* udma_jfr_create interface in has failure exception log */
+ if (ret != 0)
+ goto err_create_jfr;
+
+ ret = udma_create_jfr_context_update(udma_dev, jfr, cfg, udata);
+ /* udma_create_jfr_context_update interface in has failure exception log */
+ if (ret != 0)
+ goto err_create_jfrc;
+
+ jfr->ubcore_jfr.jfr_id.id = jfr->jfr_id;
+ kref_init(&jfr->ref_cnt);
+ init_completion(&jfr->comp);
+ udma_store_list(udma_dev, &jfr->node, &udma_dev->device_res->jfr_list);
+
+ jfr->state = UBCORE_JFR_STATE_READY;
+ udma_info(udma_dev->dev, UDMA_M_JFR,
+ "create jfr:%u, srq:%u successfully.\n", jfr->jfr_id,
+ jfr->srq.srqn);
+ return &jfr->ubcore_jfr;
+
+err_create_jfrc:
+ if (udma_get_uctx(udata) == NULL)
+ udma_jfr_delete_kernel(udma_dev, jfr);
+ else
+ udma_jfr_delete_user(udma_dev, to_udma_ctx(udata->uctx), jfr);
+err_create_jfr:
+ cqm5_object_delete(&(jfr->jfrc_info->object));
+ jfr->jfrc_info = NULL;
+err_init_srq:
+ kfree(jfr);
+ return ERR_PTR(ret);
+}
+
+int udma_destroy_jfr(struct ubcore_jfr *jfr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfr *udma_jfr = NULL;
+ int ret;
+
+ if (jfr == NULL || jfr->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JFR, "Invalid parameter, jfr(%d).\n", !!jfr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jfr->ub_dev);
+ udma_jfr = to_udma_jfr(jfr);
+ udma_jfr->state = UBCORE_JFR_STATE_RESET;
+
+ udma_delete_list(udma_dev, &udma_jfr->node,
+ &udma_dev->device_res->jfr_list);
+ udma_jfr_put(udma_jfr);
+ wait_for_completion(&udma_jfr->comp);
+
+ ret = udma_delete_jfr_context_and_cache_out(udma_dev, udma_jfr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "delete jfrc:0x%06x failed. ret:%d\n",
+ udma_jfr->jfr_id, ret);
+ /* delete failed, reference count reinitialized, ensure reentrant destory interface when reference count can normal put */
+ kref_init(&udma_jfr->ref_cnt);
+ return ret;
+ }
+
+ if (jfr->uctx == NULL)
+ ret = udma_jfr_delete_kernel(udma_dev, udma_jfr);
+ else
+ ret = udma_jfr_delete_user(udma_dev, to_udma_ctx(jfr->uctx),
+ udma_jfr);
+ if (ret != 0) {
+ /* delete failed, reference count reinitialized, ensure reentrant destory interface when reference count can normal put */
+ kref_init(&udma_jfr->ref_cnt);
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "delete jfr:0x%06x failed. ret:%d\n", udma_jfr->jfr_id,
+ ret);
+ return ret;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JFR,
+ "destroy jfr:0x%06x successfully.\n", udma_jfr->jfr_id);
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_JFR, udma_jfr->jfr_id,
+ &udma_jfr->cmdq_rtt);
+ kfree(udma_jfr);
+ return ret;
+}
+
+struct ubcore_tjetty *udma_import_jfr(struct ubcore_device *ub_dev,
+ struct ubcore_tjetty_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct ubcore_tjetty *tjetty = NULL;
+
+ if (ub_dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_JFR,
+ "Invalid parameter, ub_dev(%d), cfg(%d).\n",
+ !!ub_dev, !!cfg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (cfg->flag.bs.token_policy > UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "remote jfr token_policy:%u dont support\n",
+ cfg->flag.bs.token_policy);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (cfg->trans_mode != UBCORE_TP_RM &&
+ cfg->trans_mode != UBCORE_TP_UM) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "remote jfr trans_mode:%u dont support\n",
+ cfg->trans_mode);
+ return ERR_PTR(-EINVAL);
+ }
+
+ tjetty = (struct ubcore_tjetty *)kcalloc(
+ 1, sizeof(struct ubcore_tjetty), GFP_KERNEL);
+ if (tjetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "alloc tjfr failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return tjetty;
+}
+
+int udma_unimport_jfr(struct ubcore_tjetty *tjfr)
+{
+ if (tjfr == NULL) {
+ udma_pr_err(UDMA_M_JFR,
+ "%s: Invalid parameter, tjfr is null.\n", __func__);
+ return -EINVAL;
+ }
+
+ kfree(tjfr);
+
+ return 0;
+}
+
+void udma_jfr_async_event(struct udma_device *udma_dev, struct udma_jfr *jfr,
+ u8 type)
+{
+ struct ubcore_jfr *ubcore_jfr = &jfr->ubcore_jfr;
+ struct ubcore_event event = { 0 };
+
+ if (ubcore_jfr->jfae_handler != NULL) {
+ event.ub_dev = ubcore_jfr->ub_dev;
+ event.element.jfr = ubcore_jfr;
+ switch (type) {
+ case UB_AEQ_TYPE_JFR_ERR:
+ event.event_type = UBCORE_EVENT_JFR_ERR;
+ break;
+ case UB_AEQ_TYPE_JFR_LIMIT_REACHED:
+ event.event_type = UBCORE_EVENT_JFR_LIMIT_REACHED;
+ break;
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_JFR,
+ "unknown jfr asyn event:%u.\n", type);
+ return;
+ }
+
+ ubcore_jfr->jfae_handler(&event, ubcore_jfr->uctx);
+ }
+}
+
+int udma_query_res_jfr(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val)
+{
+ struct ubcore_res_jfr_val *ret_val =
+ (struct ubcore_res_jfr_val *)(uintptr_t)val->addr;
+ struct ub_ta_context_query *jfr_ctx = NULL; // jfr reuse jetty context
+ struct ubcore_jfr *jfr = NULL;
+ struct udma_jfr *udma_jfr = NULL;
+ u32 dw_value;
+
+ udma_jfr = udma_find_jfr(udma_dev, key->key);
+ if (udma_jfr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "ubcore find jfr failed, jfrid:%u\n", key->key);
+ return -EINVAL;
+ }
+ jfr = &udma_jfr->ubcore_jfr;
+
+ jfr_ctx = (struct ub_ta_context_query *)udma_jfr->jfrc_info->vaddr;
+
+ ret_val->depth = jfr->jfr_cfg.depth;
+ ret_val->jfc_id = jfr->jfr_cfg.jfc->id;
+ ret_val->jfr_id = jfr->jfr_id.id;
+ dw_value = be32_to_cpu(jfr_ctx->ctx[UDMA_JETTY_CTX_STATE_OFFSET]);
+ ret_val->state = (u8)to_ubcore_jfr_state(
+ (dw_value >> UDMA_STATE_IN_DW_OFFSET) & UDMA_STATE_IN_DW_MASK);
+
+ udma_jfr_put(udma_jfr);
+ udma_info(udma_dev->dev, UDMA_M_JFR,
+ "query jfr successfully, jfrid:%u\n", key->key);
+
+ return 0;
+}
+
+int udma_modify_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_attr *attr,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfr *udma_jfr = NULL;
+ int ret = 0;
+
+ if (jfr == NULL || jfr->ub_dev == NULL || attr == NULL) {
+ udma_pr_err(UDMA_M_JFR,
+ "%s: Invalid parameter, jfr(%d), attr(%d).\n",
+ __func__, !!jfr, !!attr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jfr->ub_dev);
+ udma_jfr = to_udma_jfr(jfr);
+
+ udma_info(udma_dev->dev, UDMA_M_JFR,
+ "modify jfr, mask:0x%08x, rx_threshold:%u, state:%d\n",
+ attr->mask, attr->rx_threshold, attr->state);
+
+ if ((attr->mask & (UBCORE_JFR_RX_THRESHOLD | UBCORE_JFR_STATE)) == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "JFR modify mask is not set or invalid, mask:0x%x\n",
+ attr->mask);
+ return -EINVAL;
+ }
+
+ if (attr->state < UBCORE_JFR_STATE_RESET ||
+ attr->state > UBCORE_JFR_STATE_ERROR) {
+ udma_err(udma_dev->dev, UDMA_M_JFR, "invalid jfr state:%d\n",
+ attr->state);
+ return -EINVAL;
+ }
+
+ if (udma_jfr->srq.container_size == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "invalid jfr srq container_size\n");
+ return -EINVAL;
+ }
+
+ if ((attr->mask & UBCORE_JFR_RX_THRESHOLD) != 0) {
+ if (udma_modify_jfr_threshold(udma_dev, udma_jfr,
+ (u16)(attr->rx_threshold)) != 0) {
+ ret = -EFAULT;
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "modify jfr threshold failed, jfrid:%u, limit_threshold:%u, srq_threshold:%u, dst_threshhold:%u\n",
+ udma_jfr->jfr_id, udma_jfr->idx_queue_lth,
+ udma_jfr->srq.container_warn_th,
+ attr->rx_threshold);
+ }
+ }
+
+ if ((attr->mask & UBCORE_JFR_STATE) != 0) {
+ if (udma_modify_jfr_state(udma_dev, udma_jfr, attr->state,
+ udata) != 0) {
+ ret = -EFAULT;
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "modify jfr state failed, jfrid:%u, old_state:%u, new_state:%d\n",
+ udma_jfr->jfr_id, udma_jfr->state, attr->state);
+ }
+ }
+
+ return ret;
+}
+
+int udma_post_jfr_wr(struct ubcore_jfr *jfr, struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr)
+{
+ struct udma_jfr *ub_jfr = NULL;
+ struct udma_device *udma_dev = NULL;
+ struct udma_srq *srq = NULL;
+ int ret = 0;
+
+ if (jfr == NULL || jfr->ub_dev == NULL || wr == NULL ||
+ bad_wr == NULL) {
+ udma_pr_err(
+ UDMA_M_JFR,
+ "%s: Invalid parameter, jfr(%d), wr(%d), bad_wr(%d).\n",
+ __func__, !!jfr, !!wr, !!bad_wr);
+ return -EINVAL;
+ }
+
+ ub_jfr = to_udma_jfr(jfr);
+ udma_dev = to_udma_dev(jfr->ub_dev);
+ srq = &ub_jfr->srq;
+
+ udma_debug(udma_dev->dev, UDMA_M_JFR, "start post jfr, jfr id:%u\n",
+ ub_jfr->jfr_id);
+
+ if (ub_jfr->state != UBCORE_JFR_STATE_READY) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "jfr state: %d, posting not supported\n",
+ ub_jfr->state);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ ret = udma_post_srq_wr(udma_dev, srq, wr, bad_wr);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "post jfr recv failed, ret:%d\n", ret);
+ else
+ udma_debug(udma_dev->dev, UDMA_M_JFR,
+ "post jfr recv successfully, jfr id:%u\n",
+ ub_jfr->jfr_id);
+
+ return ret;
+}
+
+/* 1825v100 of limit threshold in jfr context in, 1823v200 of srq threshold in srq context in */
+u32 udma_get_jfr_threshold(struct udma_device *udma_dev,
+ ub_cmd_srq_query_rsp_s *srq_entry,
+ struct ub_ta_context_query *jfr_entry)
+{
+ u32 warn_th;
+
+ /* 1825v100 of limit threshold in jfr context of dw4 in of high 16 bit */
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ return be32_to_cpu(jfr_entry->ctx[UDMA_JETTY_CTX_DW4]) >>
+ UDMA_IDX_QUEUE_LTH_IN_DW_OFFSET;
+ }
+
+ /* 1823v200 of threshold in srq context, 2 of warn_th time power is watermark value */
+ srq_entry->dw2.value = be32_to_cpu(srq_entry->dw2.value);
+ warn_th = srq_entry->dw2.bs_warn_th.warn_th;
+ udma_info(udma_dev->dev, UDMA_M_JFR, "warn_th:%u\n",
+ srq_entry->dw2.bs_warn_th.warn_th);
+ return (warn_th == 0) ? 0 : (1 << warn_th);
+}
+
+int udma_query_jfr(struct ubcore_jfr *jfr, struct ubcore_jfr_cfg *cfg,
+ struct ubcore_jfr_attr *attr)
+{
+ struct ub_ta_context_query *jfr_entry = NULL;
+ ub_cmd_srq_query_rsp_s *srq_entry = NULL;
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfr *ub_jfr = NULL;
+ u32 jfrid, dw_value;
+ int ret;
+
+ if (jfr == NULL || jfr->ub_dev == NULL || attr == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_JFR,
+ "%s: Invalid parameter, jfr(%d), attr(%d), cfg(%d).\n",
+ __func__, !!jfr, !!attr, !!cfg);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(jfr->ub_dev);
+ ub_jfr = to_udma_jfr(jfr);
+ jfrid = ub_jfr->jfr_id;
+
+ jfr_entry = (struct ub_ta_context_query *)kzalloc(
+ sizeof(struct ub_ta_context_query), GFP_KERNEL);
+ if (jfr_entry == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "failed to allocate memroy for ub jetty context when allocate\n");
+ return -ENOMEM;
+ }
+
+ srq_entry = (ub_cmd_srq_query_rsp_s *)kzalloc(
+ sizeof(ub_cmd_srq_query_rsp_s), GFP_KERNEL);
+ if (srq_entry == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFR,
+ "failed to allocate memroy for srq context when allocate\n");
+ kfree(jfr_entry);
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udma_dev, ub_jfr->jfr_id,
+ &ub_jfr->cmdq_rtt, jfr_entry);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "query jfr from cache failed, jfrid:%u, ret:%d\n",
+ jfrid, ret);
+ goto free_mem;
+ }
+
+ ret = udma_cmd_srq_query_ctx(udma_dev, ub_jfr->srq.srqn, srq_entry);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "query srq from cache failed, jfrid:%u, ret:%d\n",
+ jfrid, ret);
+ goto free_mem;
+ }
+
+ attr->mask = UB_QUERY_JFR_MASK;
+
+ attr->rx_threshold =
+ udma_get_jfr_threshold(udma_dev, srq_entry, jfr_entry);
+
+ dw_value = be32_to_cpu(jfr_entry->ctx[UDMA_JETTY_CTX_STATE_OFFSET]);
+ attr->state = to_ubcore_jfr_state(
+ (dw_value >> UDMA_STATE_IN_DW_OFFSET) & UDMA_STATE_IN_DW_MASK);
+ *cfg = jfr->jfr_cfg;
+
+ udma_info(
+ udma_dev->dev, UDMA_M_JFR,
+ "query jfr:%u: depth:%u, trans_mode:%u, rx_threshold:%u, state:%u\n",
+ jfrid, cfg->depth, cfg->trans_mode, attr->rx_threshold,
+ attr->state);
+
+free_mem:
+ kfree(jfr_entry);
+ kfree(srq_entry);
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfs.c b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfs.c
new file mode 100644
index 000000000..8d8101a99
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_jfs.c
@@ -0,0 +1,2107 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <asm/atomic.h>
+
+#include "ubcore_uapi.h"
+#include "ubcore_types.h"
+
+#include "udma_common.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_jfc.h"
+#include "udma_jetty.h"
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+#include "udma_abi.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_jfs.h"
+#include "udma_base_sq.h"
+
+#include "ub_aeqe.h"
+#include "ub_xqe_format.h"
+
+static void udma_jfs_kref_release(struct kref *ref_cnt)
+{
+ struct udma_jfs *jfs = container_of(ref_cnt, struct udma_jfs, ref_cnt);
+
+ complete(&jfs->comp);
+}
+
+void udma_jfs_put(void *obj)
+{
+ struct udma_jfs *jfs = obj;
+
+ if (jfs != NULL) {
+ kref_put(&jfs->ref_cnt, udma_jfs_kref_release);
+ }
+}
+
+void udma_jfs_get(void *obj)
+{
+ struct udma_jfs *jfs = obj;
+
+ kref_get(&jfs->ref_cnt);
+}
+
+struct udma_jfs *udma_find_jfs(struct udma_device *udev, u32 jfs_id)
+{
+ struct udma_jfs *jfs = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udev->device_res->jfs_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(jfs, &udev->device_res->jfs_list.node, node) {
+ if (jfs->jfs_id == jfs_id) {
+ udma_jfs_get(jfs);
+ mutex_unlock(lock);
+ return jfs;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+int udma_query_res_jfs(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key, struct ubcore_res_val *val)
+{
+ struct ubcore_res_jfs_val *ret_val =
+ (struct ubcore_res_jfs_val *)(uintptr_t)val->addr;
+ struct ubcore_jfs *jfs = NULL;
+ struct udma_jfs *udma_jfs = NULL;
+
+ udma_jfs = udma_find_jfs(udma_dev, key->key);
+ if (udma_jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to find JFS, id(%u)\n", key->key);
+ return -EINVAL;
+ }
+ jfs = &udma_jfs->ubcore_jfs;
+
+ ret_val->depth = jfs->jfs_cfg.depth;
+ ret_val->jfc_id = jfs->jfs_cfg.jfc->id;
+ ret_val->jfs_id = jfs->jfs_id.id;
+ ret_val->priority = jfs->jfs_cfg.priority;
+ ret_val->state = udma_jfs->state;
+ udma_jfs_put(udma_jfs);
+ return 0;
+}
+
+static int udma_create_jfs_cmd(struct udma_device *udma_dev,
+ struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ int ret;
+
+ if (jfs->trans_mode == UBCORE_TP_RM) {
+ ret = udma_alloc_opt_ubrc(udma_dev, &jfs->rsp_depth, &jfs->ubrc,
+ false);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to alloc ubrc, ret(%d)\n", ret);
+ return ret;
+ }
+ }
+
+ ret = udma_cmd_jfs_create_ctx(udma_dev, jfs, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to send create, jfs_id(%u), ret(%d)\n",
+ jfs->jfs_id, ret);
+ if (jfs->trans_mode == UBCORE_TP_RM)
+ udma_free_opt_ubrc(udma_dev, &jfs->rsp_depth,
+ &jfs->ubrc);
+ }
+
+ return ret;
+}
+
+static int udma_alloc_jfsc(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ struct tag_cqm_qpc_mpt *jfsc_info = NULL;
+ u32 low_bit_mode = CQM_XID_LOW_BIT_NONE;
+ u32 xid_low = 0;
+ u32 qpn_tmp;
+
+ if (udma_inc_jfc_used_cnt(cfg->jfc) == 1) {
+ low_bit_mode =
+ (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) ?
+ CQM_XID_LOW_BIT_1_1_1 :
+ CQM_XID_LOW_BIT_0_0_1;
+ xid_low = cfg->jfc->id;
+ }
+ qpn_tmp = udma_get_qpn_mod(udma_dev, low_bit_mode, xid_low);
+ jfsc_info = udma_object_qpc_create(
+ udma_dev, UBEP_JETTY_CONTEXT_SIZE, jfs,
+ &udma_dev->jettyn_record, qpn_tmp,
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num,
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_jetty);
+ if (jfsc_info == NULL) {
+ udma_dec_jfc_used_cnt(cfg->jfc);
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to create jfsc by cqm object\n");
+ return -ENOMEM;
+ }
+
+ if (cfg->jfc != NULL)
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "get jfs id(%u), jfc id(%u), jfc used cnt(%d)\n",
+ jfsc_info->xid, cfg->jfc->id,
+ udma_read_jfc_used_cnt(cfg->jfc));
+
+ jfs->jfsc_info = jfsc_info;
+
+ return 0;
+}
+
+static void udma_object_qpc_free(struct udma_device *udma_dev,
+ struct udma_jfs *jfs)
+{
+ cqm5_object_delete(&(jfs->jfsc_info->object));
+ jfs->jfsc_info = NULL;
+}
+
+static void udma_free_jfsc(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ const struct ubcore_jfc *jfc)
+{
+ udma_object_qpc_free(udma_dev, jfs);
+ udma_dec_jfc_used_cnt(jfc);
+}
+
+static int udma_init_sq_user(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg,
+ struct ub_create_jetty_ucmd *ucmd,
+ struct udma_context *udma_ctx,
+ struct udma_jfs *jfs)
+{
+ int ret;
+
+ jfs->sq_buf_len = ucmd->buf_size;
+ jfs->sq.baseblk_cnt = ucmd->sq_wqebb_cnt;
+
+ ret = udma_init_user_mtt(udma_dev, &jfs->ub_mtt, &jfs->umem,
+ ucmd->buf_addr, ucmd->buf_size);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "udma init user mtt failed, ret = %d.\n", ret);
+ return ret;
+ }
+
+ ret = udma_db_map_user(udma_ctx, ucmd->sdb_addr, &jfs->sdb);
+ if (ret != 0) {
+ udma_uninit_user_mtt(udma_dev, &jfs->ub_mtt, jfs->umem);
+ jfs->umem = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Map user DB failed.\n");
+ }
+
+ return ret;
+}
+
+static u32 udma_get_wqe_buf_size(const struct udma_device *udma_dev, u32 depth,
+ u32 wr_max_length)
+{
+ u64 align = PAGE_SIZE;
+ uint64_t size = 1L << depth_align_power2(wr_max_length * (depth + 1));
+
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ align = (u64)udma_cal_page_size(size);
+ }
+
+ return (u32)ub_size_align(size, align);
+}
+
+u32 udma_get_kernel_sq_size(const struct udma_device *udma_dev, u32 depth,
+ u32 *wr_max_length)
+{
+ u32 max_jfs_inline_size = udma_dev->ub_cap.dev_cap.max_jfs_inline_size;
+ u32 max_jfs_sge_size;
+ u32 qbuf_size;
+
+ max_jfs_sge_size = udma_dev->ub_cap.dev_cap.max_jfs_sge *
+ (u32)sizeof(struct ub_cmd_sge);
+ *wr_max_length = sizeof(struct tag_ub_sq_wqe_s);
+ *wr_max_length += max_jfs_sge_size > max_jfs_inline_size ?
+ max_jfs_sge_size :
+ max_jfs_inline_size;
+ *wr_max_length = 1L << depth_align_power2((u32)ub_size_align(
+ *wr_max_length, UB_JFS_WQEBB));
+ qbuf_size = udma_get_wqe_buf_size(udma_dev, depth, *wr_max_length);
+ return qbuf_size;
+}
+
+static void udma_create_jfs_kernel_set_attr(struct udma_jfs *jfs,
+ cqm_queue_s *jfs_buf_info,
+ u8 mtt_pro_en)
+{
+ jfs->jfs_buf_info = jfs_buf_info;
+ jfs->sdb.db_record = (__be32 *)(void *)(&jfs_buf_info->q_header_vaddr
+ ->doorbell_record);
+ jfs->sdb.dma = jfs_buf_info->q_header_paddr;
+
+ jfs_buf_info->q_header_vaddr->doorbell_record = 0;
+ jfs->page_shift = (u32)UB_ILOG2(jfs_buf_info->q_room_buf_1.buf_size);
+}
+
+static int udma_jfs_init_sq(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ u32 dev_max_inline_size = udma_dev->ub_cap.dev_cap.max_jfs_inline_size;
+ struct udma_send_queue *sq = &jfs->sq;
+ u32 wr_max_length;
+
+ spin_lock_init(&sq->lock);
+ sq->baseblk_shift = depth_align_power2(UB_JFS_WQEBB);
+ sq->buf_size =
+ udma_get_kernel_sq_size(udma_dev, cfg->depth, &wr_max_length);
+ sq->baseblk_cnt = sq->buf_size >> sq->baseblk_shift;
+ sq->max_wr_num =
+ (sq->baseblk_cnt / (wr_max_length >> sq->baseblk_shift)) - 1;
+ sq->buf = udma_dev->ub_cap.dev_cap.mtt_pro_en == 1 ?
+ jfs->queue_addr.va :
+ jfs->jfs_buf_info->q_room_buf_1.direct.va;
+ sq->buf_curr = sq->buf;
+ sq->max_inline_size = (cfg->max_inline_data > dev_max_inline_size) ?
+ dev_max_inline_size :
+ cfg->max_inline_data;
+
+ (void)memset_s(sq->buf, sq->buf_size, 0xff, sq->buf_size);
+
+ sq->wrid_size = sq->baseblk_cnt / UB_MIN_WR_WQEBB_NUM;
+ sq->wrid = (u64 *)kzalloc(sq->wrid_size * sizeof(u64), GFP_KERNEL);
+ if (sq->wrid == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to create sq wrid.\n");
+ return -ENOMEM;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq->baseblk_shift:%u.\n",
+ sq->baseblk_shift);
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq->buf_size:%u.\n",
+ sq->buf_size);
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq->baseblk_cnt:%u.\n",
+ sq->baseblk_cnt);
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq->max_wr_num:%u.\n",
+ sq->max_wr_num);
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq->max_inline_size:%u.\n",
+ sq->max_inline_size);
+
+ return 0;
+}
+
+static int udma_flush_jfs_one_normal(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, struct ubcore_cr *cr)
+{
+ struct udma_send_queue *sq = &jfs->sq;
+
+ if (sq->flush_tail == sq->head)
+ return -EAGAIN;
+
+ cr->user_ctx = sq->wrid[sq->flush_tail & (sq->wrid_size - 1)];
+ ++sq->flush_tail;
+
+ cr->status = UBCORE_CR_WR_UNHANDLED;
+ cr->flag.bs.s_r = 0; // send
+ cr->flag.bs.jetty = 0; // is jfs
+ cr->completion_len = 0;
+ cr->local_id = jfs->jfs_id;
+ cr->user_data = (uintptr_t)(&jfs->ubcore_jfs);
+
+ udma_info(
+ udma_dev->dev, UDMA_M_JFS,
+ "flush jfs one success, jfs_id(%u), tail(%u), flush_tail(%u), head(%u)\n",
+ jfs->jfs_id, sq->tail, sq->flush_tail, sq->head);
+
+ return 0;
+}
+
+static int udma_flush_jfs_one(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, struct ubcore_cr *cr)
+{
+ return udma_flush_jfs_one_normal(udma_dev, jfs, cr);
+}
+
+int udma_flush_jfs(struct ubcore_jfs *jfs, int cr_cnt, struct ubcore_cr *cr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *udma_jfs = NULL;
+ int nflushed = 0;
+ int ret;
+
+ if ((jfs == NULL) || (jfs->ub_dev == NULL) || (cr == NULL)) {
+ udma_pr_err(UDMA_M_JFS, "Invalid parameter: jfs(%d),cr(%d).\n",
+ !!jfs, !!cr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jfs->ub_dev);
+ udma_jfs = to_udma_jfs(jfs);
+ if (udma_jfs->sq.is_hw_flush_done == false) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "hardware is not flush done, jfs_id(%u)\n",
+ udma_jfs->jfs_id);
+ return -EINVAL;
+ }
+
+ /* forge not execute of WQE of CQE */
+ for (nflushed = 0; nflushed < cr_cnt; ++nflushed) {
+ ret = udma_flush_jfs_one(udma_dev, udma_jfs, &cr[nflushed]);
+ if (ret != 0)
+ break;
+ }
+
+ if (udma_jfs->sq.flush_tail == udma_jfs->sq.head) {
+ udma_jfs->sq.head = udma_jfs->sq.tail;
+ udma_jfs->sq.is_hw_flush_done = false;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "flush jfs success, jfs_id(%u), nflushed(%d)\n",
+ udma_jfs->jfs_id, nflushed);
+
+ return nflushed;
+}
+
+static void udma_deinit_sq_user(struct udma_device *udma_dev,
+ struct udma_context *udma_ctx,
+ struct udma_jfs *jfs)
+{
+ udma_db_unmap_user(udma_ctx, &jfs->sdb);
+ udma_uninit_user_mtt(udma_dev, &jfs->ub_mtt, jfs->umem);
+ jfs->umem = NULL;
+}
+
+static void udma_deinit_sq_kernel(struct udma_device *udma_dev,
+ struct udma_jfs *jfs)
+{
+ if (jfs->sq.wrid != NULL) {
+ kfree(jfs->sq.wrid);
+ jfs->sq.wrid = NULL;
+ }
+ udma_uninit_kernel_mtt(udma_dev, &jfs->ub_mtt);
+ udma_free_queue_resource(udma_dev, jfs->jfs_buf_info, &jfs->queue_addr);
+ jfs->jfs_buf_info = NULL;
+}
+
+static void udma_deinit_sq(struct udma_device *udma_dev,
+ struct udma_context *udma_ctx, struct udma_jfs *jfs)
+{
+ if (udma_ctx == NULL)
+ udma_deinit_sq_kernel(udma_dev, jfs);
+ else
+ udma_deinit_sq_user(udma_dev, udma_ctx, jfs);
+}
+
+static int udma_init_sq_kernel(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg,
+ struct udma_jfs *jfs)
+{
+ cqm_queue_s *jfs_buf_info = NULL;
+ u32 wr_max_length;
+ int ret;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JFS, "to_udma_dev failed.\n");
+ return -EINVAL;
+ }
+
+ jfs->sq_buf_len =
+ udma_get_kernel_sq_size(udma_dev, cfg->depth, &wr_max_length);
+ ret = udma_alloc_queue_resource(udma_dev, &jfs_buf_info, jfs,
+ jfs->sq_buf_len, &jfs->queue_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to alloc queue resource, ret = %d.\n", ret);
+ return ret;
+ }
+
+ udma_create_jfs_kernel_set_attr(jfs, jfs_buf_info,
+ udma_dev->ub_cap.dev_cap.mtt_pro_en);
+
+ ret = udma_init_kernel_mtt(udma_dev, &jfs->ub_mtt, jfs_buf_info,
+ jfs->queue_addr.pa);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to init kernel mtt, ret = %d.\n", ret);
+ goto err_init_kernel_mtt;
+ }
+
+ ret = udma_jfs_init_sq(udma_dev, jfs, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Failed to init jfs sq.\n");
+ goto err_jfs_init_sq;
+ }
+
+ return 0;
+
+err_jfs_init_sq:
+ udma_uninit_kernel_mtt(udma_dev, &jfs->ub_mtt);
+err_init_kernel_mtt:
+ udma_free_queue_resource(udma_dev, jfs_buf_info, &jfs->queue_addr);
+ jfs->jfs_buf_info = NULL;
+ return ret;
+}
+
+static int udma_init_sq(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg,
+ struct ub_create_jetty_ucmd *ucmd,
+ struct udma_context *udma_ctx, struct udma_jfs *jfs)
+{
+ if (udma_ctx == NULL)
+ return udma_init_sq_kernel(udma_dev, cfg, jfs);
+ else
+ return udma_init_sq_user(udma_dev, cfg, ucmd, udma_ctx, jfs);
+}
+
+static int udma_init_jfs(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg, struct udma_jfs *jfs,
+ struct udma_create_jfs_uinfo *uinfo)
+{
+ jfs->cqm_priv_type = UDMA_JETTY_TYPE_JFS;
+ jfs->ubcore_jfs.jfs_cfg = *cfg;
+ jfs->trans_mode = cfg->trans_mode;
+
+ if (uinfo == NULL) {
+ udma_pr_err(UDMA_M_JFS, "Invalid parameter: uinfo(%d).\n",
+ !!uinfo);
+ return -EINVAL;
+ }
+
+ if (udma_init_sq(udma_dev, cfg, uinfo->ucmd, uinfo->udma_ctx, jfs) !=
+ 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "init sq user failed,\n");
+ return -EINVAL;
+ }
+
+ if (udma_alloc_jfsc(udma_dev, jfs, cfg) != 0)
+ goto err_and_deinit_sq;
+
+ jfs->jfs_id = jfs->jfsc_info->xid;
+ jfs->ubcore_jfs.jfs_id.id = jfs->jfs_id;
+
+ if (udma_create_jfs_cmd(udma_dev, jfs, cfg) != 0)
+ goto err_and_delete_obj;
+
+ return 0;
+
+err_and_delete_obj:
+ udma_free_jfsc(udma_dev, jfs, cfg->jfc);
+err_and_deinit_sq:
+ udma_deinit_sq(udma_dev, uinfo->udma_ctx, jfs);
+
+ return -EPERM;
+}
+
+static struct udma_jfs *udma_create_jfs_one(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg,
+ struct udma_create_jfs_uinfo *uinfo,
+ u8 cos)
+{
+ struct udma_jfs *jfs = NULL;
+ struct udma_context *udma_ctx = uinfo->udma_ctx;
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "start to create jfs, from user: %d\n",
+ (udma_ctx == NULL) ? 0 : 1);
+
+ jfs = (struct udma_jfs *)kzalloc(sizeof(struct udma_jfs), GFP_KERNEL);
+ if (jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Alloc JFS failed.\n");
+ return NULL;
+ }
+
+ jfs->cos = cos;
+ udma_cmdq_rtt_statistic_init(&jfs->cmdq_rtt);
+ if (udma_init_jfs(udma_dev, cfg, jfs, uinfo) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "init jfs failed.\n");
+ goto err_and_free_jfs;
+ }
+
+ jfs->state = UBCORE_JETTY_STATE_READY;
+
+ kref_init(&jfs->ref_cnt);
+ init_completion(&jfs->comp);
+
+ udma_store_list(udma_dev, &jfs->node, &udma_dev->device_res->jfs_list);
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "Create JFS successfully, id: %u.\n",
+ jfs->ubcore_jfs.jfs_id.id);
+
+ (void)udma_clear_pi_on_chip(udma_dev, jfs->jfs_id, jfs->cos);
+
+ return jfs;
+
+err_and_free_jfs:
+ kfree(jfs);
+
+ return NULL;
+}
+
+static int udma_jfs_cache_out_cmd(struct udma_device *udma_dev,
+ struct udma_jfs *jfs)
+{
+ u64 wb_dma = 0;
+ void *wb_va = NULL;
+ int ret;
+
+ wb_va = dma_alloc_coherent(udma_dev->dev, (size_t)4UL, &wb_dma,
+ GFP_KERNEL);
+ if (wb_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Failed to alloc wb_va\n");
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_jfs_cache_out_ctx(udma_dev, jfs, wb_dma);
+
+ dma_free_coherent(udma_dev->dev, sizeof(u32), wb_va, wb_dma);
+
+ return ret;
+}
+
+static int udma_destroy_jfs_one(struct udma_device *udma_dev,
+ struct udma_jfs *jfs)
+{
+ struct udma_context *udma_ctx = to_udma_ctx(jfs->ubcore_jfs.uctx);
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_JFS, "start to destroy jfs: %u\n",
+ jfs->jfs_id);
+
+ ret = udma_cmd_jfs_delete_ctx(udma_dev, jfs);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to delete JFS(0x%06x).\n", jfs->jfs_id);
+ return ret;
+ }
+
+ ret = udma_jfs_cache_out_cmd(udma_dev, jfs);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Cache out JFS:0x%06x failed.\n", jfs->jfs_id);
+ return ret;
+ }
+ udma_jfs_put(jfs);
+ wait_for_completion(&jfs->comp);
+ udma_deinit_sq(udma_dev, udma_ctx, jfs);
+ udma_free_opt_ubrc(udma_dev, &jfs->rsp_depth, &jfs->ubrc);
+ udma_free_jfsc(udma_dev, jfs, jfs->ubcore_jfs.jfs_cfg.jfc);
+ jfs->state = UBCORE_JETTY_STATE_RESET;
+
+ udma_delete_list(udma_dev, &jfs->node, &udma_dev->device_res->jfs_list);
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "Destroyed JFS successfully, id: %u.\n", jfs->jfs_id);
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_JFS, jfs->jfs_id,
+ &jfs->cmdq_rtt);
+ kfree(jfs);
+
+ return ret;
+}
+
+static int udma_jfs_cfg_check(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg)
+{
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "tpf not support this function.\n");
+ return -EINVAL;
+ }
+
+ if ((cfg->trans_mode != UBCORE_TP_RM) &&
+ (cfg->trans_mode != UBCORE_TP_UM)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter: jfs tp_mode: %d.\n",
+ cfg->trans_mode);
+ return -EINVAL;
+ }
+
+ if (udma_dev->jfs_current_cnt >= udma_dev->ub_cap.dev_cap.max_jfs) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter: jfs current cnt(0x%x) is over max jfs cnt(0x%x).\n",
+ udma_dev->jfs_current_cnt,
+ udma_dev->ub_cap.dev_cap.max_jfs);
+ return -EINVAL;
+ }
+
+ if ((cfg->depth == 0) ||
+ (cfg->depth > udma_dev->ub_cap.dev_cap.max_jfs_depth) ||
+ (cfg->max_sge > udma_dev->ub_cap.dev_cap.max_jfs_sge) ||
+ cfg->max_inline_data >
+ udma_dev->ub_cap.dev_cap.max_jfs_inline_size) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter: jfs depth: %u max_depth:%u sge: %u max_sge: %u inline_size: %u max_inline_size:%u\n",
+ cfg->depth, udma_dev->ub_cap.dev_cap.max_jfs_depth,
+ cfg->max_sge, udma_dev->ub_cap.dev_cap.max_jfs_sge,
+ cfg->max_inline_data,
+ udma_dev->ub_cap.dev_cap.max_jfs_inline_size);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.outorder_comp != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "outorder_comp: %u\n",
+ cfg->flag.bs.outorder_comp);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_jfs_get_cos(struct udma_device *udma_dev,
+ const struct ubcore_jfs_cfg *cfg,
+ struct ubcore_udata *udata, u8 *cos)
+{
+ int ret;
+
+ ret = udma_get_dcb_cfg_cos(udma_dev, NULL, cfg->priority, cos, 1);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to get cos from dcb info, ret:%d, pri:%u\n",
+ ret, cfg->priority);
+ return ret;
+ }
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "Get cos from dcb info successful, cos:%u\n", *cos);
+
+ return 0;
+}
+
+int udma_create_jfs_uinfo_init(struct udma_device *udma_dev,
+ struct ubcore_udata *udata,
+ struct udma_create_jfs_uinfo *uinfo)
+{
+ if ((udata == NULL) || (udata->uctx == NULL) ||
+ (udata->udrv_data == NULL))
+ return 0;
+
+ uinfo->cmd_len = sizeof(struct ub_create_jetty_ucmd);
+ uinfo->resp_len = sizeof(struct ub_create_jetty_resp);
+
+ if (udata->udrv_data->in_len < uinfo->cmd_len) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "in_len(%u) < cmd_len(%u)\n", udata->udrv_data->in_len,
+ uinfo->cmd_len);
+ return -EINVAL;
+ }
+
+ if (udata->udrv_data->out_len < uinfo->resp_len) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "out_len(%u) < resp_len(%u)\n",
+ udata->udrv_data->out_len, uinfo->resp_len);
+ return -EINVAL;
+ }
+
+ uinfo->udata = udata;
+ uinfo->udma_ctx = to_udma_ctx(udma_get_uctx(udata));
+ if ((uinfo->ucmd = kzalloc(uinfo->cmd_len, GFP_KERNEL)) == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "zalloc cmd buf failed: %u\n", uinfo->cmd_len);
+ return -ENOMEM;
+ }
+
+ if ((uinfo->resp = kzalloc(uinfo->resp_len, GFP_KERNEL)) == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "zalloc resp buf failed: %u\n", uinfo->resp_len);
+ goto err_alloc_resp;
+ }
+
+ if (copy_from_user(uinfo->ucmd,
+ (void *)(uintptr_t)udata->udrv_data->in_addr,
+ uinfo->cmd_len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "copy from user failed: %u\n", uinfo->cmd_len);
+ goto err_and_free_all;
+ }
+
+ return 0;
+
+err_and_free_all:
+ kfree(uinfo->resp);
+ uinfo->resp = NULL;
+err_alloc_resp:
+ kfree(uinfo->ucmd);
+ uinfo->ucmd = NULL;
+
+ return -EINVAL;
+}
+
+int udma_create_jfs_uinfo_deinit(struct udma_device *udma_dev,
+ struct udma_create_jfs_uinfo *uinfo, u8 cos,
+ u32 round, u8 copy)
+{
+ if (uinfo->udma_ctx == NULL)
+ return 0;
+
+ if (copy != 0) {
+ uinfo->resp->cos = cos;
+ uinfo->resp->slice = udma_get_jetty_slice_en(udma_dev) ?
+ udma_dev->slice :
+ UDMA_MAX_SLICE_SHIFT;
+ uinfo->resp->pattern = udma_dev->ub_dev.cfg.pattern;
+ uinfo->resp->jetty_round = round;
+
+ if (copy_to_user((void *)(uintptr_t)
+ uinfo->udata->udrv_data->out_addr,
+ uinfo->resp, uinfo->resp_len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to copy to user driver\n");
+ return -EINVAL;
+ }
+ }
+
+ if (uinfo->ucmd) {
+ kfree(uinfo->ucmd);
+ uinfo->ucmd = NULL;
+ }
+
+ if (uinfo->resp) {
+ kfree(uinfo->resp);
+ uinfo->resp = NULL;
+ }
+
+ return 0;
+}
+
+struct ubcore_jfs *udma_create_jfs(struct ubcore_device *ub_dev,
+ struct ubcore_jfs_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_create_jfs_uinfo uinfo = { 0 };
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *jfs = NULL;
+ int ret;
+ u8 cos;
+
+ if (ub_dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_JFS, "ub_dev(%d), cfg(%d) is NULL", !!ub_dev,
+ !!cfg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "start create jfs, depth: %u, eid_index: %u\n", cfg->depth,
+ cfg->eid_index);
+
+ if (udma_jfs_cfg_check(udma_dev, cfg) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "check cfg failed\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ ret = udma_create_jfs_uinfo_init(udma_dev, udata, &uinfo);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "init uinfo failed\n");
+ return ERR_PTR(ret);
+ }
+
+ if (udma_jfs_get_cos(udma_dev, cfg, udata, &cos) != 0)
+ goto err_and_deinit_uinfo;
+
+ jfs = udma_create_jfs_one(udma_dev, cfg, &uinfo, cos);
+ if (jfs == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "create master jfs failed\n");
+ goto err_and_deinit_uinfo;
+ }
+
+ if (udma_create_jfs_uinfo_deinit(udma_dev, &uinfo, cos, jfs->round,
+ 1) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Failed to copy to user driver\n");
+ goto err_and_free_jfs;
+ }
+
+ return &jfs->ubcore_jfs;
+
+err_and_free_jfs:
+ jfs->ubcore_jfs.uctx = udma_get_uctx(udata);
+ udma_destroy_jfs_one(udma_dev, jfs);
+err_and_deinit_uinfo:
+ udma_create_jfs_uinfo_deinit(udma_dev, &uinfo, cos, 0, 0);
+
+ return ERR_PTR(-EFAULT);
+}
+
+int udma_query_jfs(struct ubcore_jfs *jfs, struct ubcore_jfs_cfg *cfg,
+ struct ubcore_jfs_attr *attr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *ub_jfs = NULL;
+ struct ub_ta_context_query jfs_ctx = { 0 };
+ int ret;
+ u32 dw_value;
+
+ if (jfs == NULL || jfs->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JFS, "jfs(%d), or jfs->ub_dev is NULL\n",
+ !!jfs);
+ return -EINVAL;
+ }
+
+ ub_jfs = to_udma_jfs(jfs);
+ udma_dev = to_udma_dev(jfs->ub_dev);
+ if (cfg == NULL || attr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "cfg(%d), attr(%d) is NULL\n", !!cfg, !!attr);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jetty_query_ctx(udma_dev, jfs->jfs_id.id,
+ &ub_jfs->cmdq_rtt, &jfs_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "query jfs ctx cmdq failed\n");
+ return -EIO;
+ }
+
+ dw_value = cpu_to_be32(jfs_ctx.ctx[UDMA_JETTY_CTX_STATE_OFFSET]);
+ attr->state = (dw_value >> UDMA_STATE_IN_DW_OFFSET) &
+ UDMA_STATE_IN_DW_MASK;
+ *cfg = jfs->jfs_cfg;
+
+ udma_info(udma_dev->dev, UDMA_M_JFS,
+ "JFS state: %d, depth: %u, trans_mode: %d\n", attr->state,
+ cfg->depth, cfg->trans_mode);
+ return 0;
+}
+
+int udma_destroy_jfs(struct ubcore_jfs *jfs)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *udma_jfs = NULL;
+
+ if (jfs == NULL || jfs->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JFS, "jfs(%d), or jfs->ub_dev is NULL\n",
+ !!jfs);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(jfs->ub_dev);
+ udma_jfs = to_udma_jfs(jfs);
+
+ udma_info(udma_dev->dev, UDMA_M_JFS, "destroy jfs, id(%u), depth(%u)\n",
+ jfs->jfs_id.id, jfs->jfs_cfg.depth);
+
+ return udma_destroy_jfs_one(udma_dev, udma_jfs);
+}
+
+void udma_jfs_async_event(struct udma_device *udma_dev, struct udma_jfs *jfs,
+ u8 type)
+{
+ struct ubcore_jfs *ubcore_jfs = &jfs->ubcore_jfs;
+ struct ubcore_event event = { 0 };
+
+ if (ubcore_jfs->jfae_handler != NULL) {
+ event.ub_dev = ubcore_jfs->ub_dev;
+ event.element.jfs = ubcore_jfs;
+ switch (type) {
+ case UB_AEQ_TYPE_JFS_ERR:
+ event.event_type = UBCORE_EVENT_JFS_ERR;
+ break;
+
+ default:
+ udma_err_limit(udma_dev->dev, UDMA_M_JFS,
+ "unknown jfs asyn event(%u).\n", type);
+ return;
+ }
+
+ ubcore_jfs->jfae_handler(&event, ubcore_jfs->uctx);
+ }
+}
+
+static void udma_fill_sge(struct ub_cmd_sge *sge, struct ubcore_sge *sgl,
+ u32 *len)
+{
+ sge->dw3.dw3_value = 0;
+ sge->length = cpu_to_be32(sgl->len);
+ *len += sgl->len;
+ sge->va = cpu_to_be64(sgl->addr);
+ sge->dw3.bs.token_id = sgl->tseg->seg.token_id;
+ sge->dw3.dw3_value = cpu_to_be32(sge->dw3.dw3_value);
+}
+
+ub_sqwqe_optype_e ub_jfs_parse_opcode(enum ubcore_opcode opcode)
+{
+ switch (opcode) {
+ case UBCORE_OPC_READ:
+ return UB_TX_READ;
+ case UBCORE_OPC_WRITE:
+ return UB_TX_WRITE;
+ case UBCORE_OPC_WRITE_IMM:
+ return UB_TX_WRITE_IMMEDIATE;
+ case UBCORE_OPC_SEND:
+ return UB_TX_SEND;
+ case UBCORE_OPC_SEND_IMM:
+ return UB_TX_SEND_IMMEDIATE;
+ case UBCORE_OPC_SEND_INVALIDATE:
+ return UB_TX_SEND_INVALIDATE;
+ case UBCORE_OPC_CAS:
+ return UB_TX_ATOMIC_COMPARE_SWAP;
+ case UBCORE_OPC_FADD:
+ return UB_TX_ATOMIC_FETCH_ADD;
+ default:
+ return UB_ERR_TYPE;
+ }
+}
+
+static u32 udma_get_inline_sg_len(struct udma_device *udma_dev,
+ const struct ubcore_sg *sg)
+{
+ struct ubcore_sge *tmp_sge = NULL;
+ u32 total_len = 0;
+ u32 i;
+
+ tmp_sge = sg->sge;
+ for (i = 0; i < sg->num_sge; i++) {
+ if (tmp_sge == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. Sge Is NULL\n");
+ return 0;
+ }
+
+ if (total_len > UINT_MAX - tmp_sge->len) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. sge len is error!\n");
+ return 0;
+ }
+
+ total_len += tmp_sge->len;
+ tmp_sge++;
+ }
+
+ return total_len;
+}
+
+static u32 udma_wqebb_cnt(struct udma_device *udma_dev,
+ struct udma_send_queue *sq,
+ enum UB_SQWQE_OPTYPE_E opcode,
+ const struct ubcore_jfs_wr *wr)
+{
+ u32 wqe_size = (u32)(sizeof(struct tag_ub_wqe_ctrl_sec) +
+ sizeof(struct tag_ub_sq_wqe_com_task));
+
+ switch (opcode) {
+ case UB_TX_READ:
+ wqe_size += (u32)(wr->rw.dst.num_sge << UB_SGE_SHIFT);
+ wqe_size += (u32)sizeof(struct tag_ub_sq_wqe_task_read) -
+ UB_SEID_BYTE_LENGTH - UB_INLINE_BYTE_LENGTH;
+ break;
+ case UB_TX_WRITE:
+ if (wr->flag.bs.inline_flag == 0) {
+ wqe_size += (u32)(wr->rw.src.num_sge << UB_SGE_SHIFT);
+ }
+ wqe_size += (u32)sizeof(struct tag_ub_sq_wqe_task_read) -
+ UB_SEID_BYTE_LENGTH - UB_INLINE_BYTE_LENGTH;
+ if (wr->flag.bs.inline_flag != 0) {
+ wqe_size +=
+ udma_get_inline_sg_len(udma_dev, &wr->rw.src);
+ }
+ break;
+ case UB_TX_WRITE_IMMEDIATE:
+ if (wr->flag.bs.inline_flag == 0) {
+ wqe_size += (u32)(wr->rw.src.num_sge << UB_SGE_SHIFT);
+ }
+ wqe_size += (u32)sizeof(struct tag_ub_sq_wqe_task_write) -
+ UB_SEID_BYTE_LENGTH;
+ if (wr->flag.bs.inline_flag != 0) {
+ wqe_size +=
+ udma_get_inline_sg_len(udma_dev, &wr->rw.src);
+ }
+ break;
+ case UB_TX_SEND:
+ case UB_TX_SEND_IMMEDIATE:
+ case UB_TX_SEND_INVALIDATE:
+ if (wr->flag.bs.inline_flag == 0) {
+ wqe_size += (u32)(wr->send.src.num_sge << UB_SGE_SHIFT);
+ }
+ wqe_size += (u32)sizeof(struct tag_ub_sq_wqe_task_send) -
+ UB_SEID_BYTE_LENGTH;
+ if (wr->flag.bs.inline_flag != 0) {
+ wqe_size +=
+ udma_get_inline_sg_len(udma_dev, &wr->rw.src);
+ }
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Unsupported ubcore opcode:%u\n", (u32)wr->opcode);
+ break;
+ }
+
+ wqe_size = (u32)ub_size_align(wqe_size, 1ULL << sq->baseblk_shift);
+ sq->wqe_size = wqe_size;
+
+ return wqe_size >> sq->baseblk_shift;
+}
+
+static void udma_fill_ctrl_and_task_com(struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_post_wqe *post_wqe,
+ enum UB_SQWQE_OPTYPE_E opcode,
+ u8 pattern)
+{
+ wqe->ctrl_sec.dw0_value = 0;
+ wqe->ctrl_sec.dw1_value = 0;
+ wqe->ctrl_sec.cr = wr->flag.bs.complete_enable;
+ wqe->ctrl_sec.va = UB_WQE_VA_TYPE_VIRTUAL;
+ wqe->ctrl_sec.ctrlsl = UB_WQE_CTRL_SEC_LENGTH;
+ /* fill wqe ctrl head section:cl bit */
+ wqe->ctrl_sec.dw1_value = UB_WQE_CMP_TASK_LEN1
+ << UB_WQE_CMP_TASK_LEN_SHIFT;
+ // fast path indicate
+ wqe->ctrl_sec.fast_dwqe_en = post_wqe->is_fast_path & wqe->ctrl_sec.cr;
+
+ wqe->tsk_sec.com.dw0_value = 0;
+ wqe->tsk_sec.com.dw2_value = 0;
+ wqe->tsk_sec.com.dw3_value = 0;
+ wqe->tsk_sec.com.dw4_value = 0;
+ wqe->tsk_sec.com.data_len = 0;
+ wqe->tsk_sec.com.f = wr->flag.bs.fence;
+ wqe->tsk_sec.com.op_type = (u8)opcode;
+ wqe->tsk_sec.com.se = wr->flag.bs.solicited_enable;
+ wqe->tsk_sec.com.c = wqe->ctrl_sec.cr;
+ wqe->tsk_sec.com.vtpn = post_wqe->tpn;
+ wqe->tsk_sec.com.odr = wr->flag.value & UBCORE_ODR_BITMASK;
+ wqe->tsk_sec.com.upi = pattern;
+ if (wr->tjetty->cfg.flag.bs.token_policy == UBCORE_TOKEN_NONE) {
+ wqe->tsk_sec.com.token_vld = 0;
+ } else if (wr->tjetty->cfg.flag.bs.token_policy ==
+ UBCORE_TOKEN_PLAIN_TEXT) {
+ wqe->tsk_sec.com.token_vld = 1;
+ } else {
+ udma_pr_err(UDMA_M_JFS,
+ "Bug : Invalid token_policy=%u, please check!\n",
+ wr->tjetty->cfg.flag.bs.token_policy);
+ }
+}
+
+static void udma_fill_inline_wqe(struct udma_send_queue *sq,
+ struct tag_ub_sq_wqe_s *wqe, u8 *sge_addr,
+ struct ubcore_sge *sgl,
+ const struct udma_sge_info *sge_info)
+{
+ u32 curr_ofst = 0;
+ u32 total_len = 0;
+ u32 sq_rmd_size;
+ u32 rmd_size;
+ u32 i;
+
+ for (i = 0; i < sge_info->sge_num; i++) {
+ sq_rmd_size =
+ (u32)((sq->buf + sq->buf_size) - (void *)sge_addr) -
+ curr_ofst;
+ if (sq_rmd_size < sgl[i].len) {
+ rmd_size = sgl[i].len - sq_rmd_size;
+ (void)memcpy_s((void *)(sge_addr + curr_ofst),
+ sq_rmd_size,
+ (void *)(uintptr_t)sgl[i].addr,
+ sq_rmd_size);
+ sge_addr = sq->buf;
+ curr_ofst = 0;
+ (void)memcpy_s(
+ (void *)(sge_addr + curr_ofst), rmd_size,
+ (void *)(uintptr_t)(sgl[i].addr + sq_rmd_size),
+ rmd_size);
+ total_len += sgl[i].len;
+ curr_ofst += rmd_size;
+ } else {
+ (void)memcpy_s((void *)(sge_addr + curr_ofst),
+ sgl[i].len,
+ (void *)(uintptr_t)sgl[i].addr,
+ sgl[i].len);
+ total_len += sgl[i].len;
+ curr_ofst += sgl[i].len;
+ }
+ }
+
+ wqe->ctrl_sec.df = 0x1;
+ wqe->ctrl_sec.bdsl = (u32)align_size(total_len, UB_TASK_SEG_ALIGN) /
+ UB_TASK_SEG_ALIGN;
+ wqe->tsk_sec.com.data_len = cpu_to_be32(total_len);
+ if (wqe->tsk_sec.com.op_type == UB_TX_WRITE) {
+ wqe->tsk_sec.wr_rd.length = cpu_to_be32(total_len);
+ } else if (wqe->tsk_sec.com.op_type == UB_TX_WRITE_IMMEDIATE) {
+ wqe->tsk_sec.write_immt.length = cpu_to_be32(total_len);
+ /* total_data_len is in second wqebb, need to handle wrap-around logic */
+ wqe = udma_get_next_wqe(sq, wqe);
+ wqe->tsk_sec.write_immt.total_data_len = cpu_to_be32(total_len);
+ }
+}
+
+static void udma_fill_token_vld(ub_sq_wqe_s *wqe, const struct ubcore_sge *sge)
+{
+ if (sge->tseg->seg.attr.bs.token_policy == UBCORE_TOKEN_NONE) {
+ wqe->tsk_sec.com.token_vld = 0;
+ } else if (sge->tseg->seg.attr.bs.token_policy ==
+ UBCORE_TOKEN_PLAIN_TEXT) {
+ wqe->tsk_sec.com.token_vld = 1;
+ } else {
+ udma_pr_err(UDMA_M_JFS,
+ "Bug : Invalid token_policy=%u, please check!\n",
+ sge->tseg->seg.attr.bs.token_policy);
+ }
+}
+
+static void udma_fill_rw_task_sec(struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq, u8 **sge_addr,
+ ub_sqwqe_optype_e opcode)
+{
+ struct ubcore_sge *sge = NULL;
+ struct ub_rseg *rseg = NULL;
+
+ sge = (opcode == UB_TX_READ) ? wr->rw.src.sge : wr->rw.dst.sge;
+
+ rseg = container_of(sge->tseg, ub_rseg_t, base);
+ wqe->ctrl_sec.tsl = UB_JFS_WRITE_WQE_TSK_LEN / UB_TASK_SEG_ALIGN;
+ wqe->ctrl_sec.bdsl =
+ wr->rw.src.num_sge * (sizeof(ub_cmd_sge_t) / UB_TASK_SEG_ALIGN);
+ wqe->tsk_sec.wr_rd.upi = 0;
+ wqe->tsk_sec.wr_rd.remote_token_value = cpu_to_be32(rseg->token);
+ wqe->tsk_sec.wr_rd.remote_va_l32 = cpu_to_be32(sge->addr & 0xFFFFFFFF);
+ wqe->tsk_sec.wr_rd.remote_va_h32 =
+ cpu_to_be32(sge->addr >> ADDR_H_OFFSET);
+ wqe->tsk_sec.wr_rd.remote_token_id =
+ cpu_to_be32(sge->tseg->seg.token_id);
+ udma_fill_token_vld(wqe, sge);
+
+ /* write flow in wqe fill to deid before exactly fill complete a wqebb, need re new determine next a wqebb of place */
+ wqe = udma_get_next_wqe(sq, wqe);
+ memcpy_s(wqe->tsk_sec.wr_rd.deid, sizeof(wqe->tsk_sec.wr_rd.deid),
+ wr->tjetty->cfg.id.eid.raw,
+ sizeof(wr->tjetty->cfg.id.eid.raw));
+ *sge_addr = (u8 *)wqe + UB_WR_RD_TKV_DEID_LENGTH;
+}
+
+static void udma_fill_rw_imme_task_sec(struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq,
+ u8 **sge_addr)
+{
+ struct ub_rseg *rseg =
+ container_of(wr->rw.dst.sge->tseg, ub_rseg_t, base);
+
+ wqe->ctrl_sec.tsl = UB_JFS_WRITE_IMM_WQE_TSK_LEN / UB_TASK_SEG_ALIGN;
+ wqe->ctrl_sec.bdsl =
+ wr->rw.src.num_sge * (sizeof(ub_cmd_sge_t) / UB_TASK_SEG_ALIGN);
+
+ wqe->tsk_sec.write_immt.remote_va_l32 =
+ cpu_to_be32(wr->rw.dst.sge->addr & 0xFFFFFFFF);
+ wqe->tsk_sec.write_immt.remote_va_h32 =
+ cpu_to_be32(wr->rw.dst.sge->addr >> ADDR_H_OFFSET);
+ wqe->tsk_sec.write_immt.remote_token_id =
+ cpu_to_be32(wr->rw.dst.sge->tseg->seg.token_id);
+
+ wqe->tsk_sec.write_immt.imme_data_l =
+ cpu_to_be32(wr->rw.notify_data & 0xFFFFFFFF);
+ wqe->tsk_sec.write_immt.imme_data_h =
+ cpu_to_be32(wr->rw.notify_data >> ADDR_H_OFFSET);
+ udma_fill_token_vld(wqe, wr->rw.dst.sge);
+
+ // before plane of is a complete of WQEBB, next plane th second WQEBB may need wrap around
+ wqe = udma_get_next_wqe(sq, wqe);
+ wqe->tsk_sec.write_immt.total_data_len = 0;
+ wqe->tsk_sec.write_immt.upi = 0;
+ wqe->tsk_sec.write_immt.dw3_value = 0;
+ wqe->tsk_sec.write_immt.djt = wr->tjetty->cfg.type;
+ wqe->tsk_sec.write_immt.djtn = wr->tjetty->cfg.id.id;
+ wqe->tsk_sec.write_immt.dw3_value =
+ cpu_to_be32(wqe->tsk_sec.write_immt.dw3_value);
+ wqe->tsk_sec.write_immt.remote_seg_token_value =
+ cpu_to_be32(rseg->token);
+ wqe->tsk_sec.write_immt.remote_jfr_token_value =
+ cpu_to_be32(wr->tjetty->cfg.token_value.token);
+
+ memcpy_s(wqe->tsk_sec.write_immt.deid,
+ sizeof(wqe->tsk_sec.write_immt.deid),
+ wr->tjetty->cfg.id.eid.raw,
+ sizeof(wr->tjetty->cfg.id.eid.raw));
+
+ *sge_addr = (u8 *)wqe + UB_WRITE_IMME_TKV_DEID_LENGTH;
+}
+
+static void udma_fill_send_task_sec(struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq, u8 **sge_addr)
+{
+ if (wqe->tsk_sec.com.op_type == UB_TX_SEND_INVALIDATE) {
+ wqe->tsk_sec.send.imme_data_l = 0;
+ wqe->tsk_sec.send.invalid_token_id =
+ cpu_to_be32(wr->send.tseg->seg.token_id);
+ } else {
+ wqe->tsk_sec.send.imme_data_l =
+ cpu_to_be32(wr->send.imm_data & 0xFFFFFFFF);
+ wqe->tsk_sec.send.imme_data_h =
+ cpu_to_be32(wr->send.imm_data >> ADDR_H_OFFSET);
+ }
+
+ wqe->ctrl_sec.tsl = UB_JFS_SEND_WQE_TSK_LEN / UB_TASK_SEG_ALIGN;
+ wqe->ctrl_sec.bdsl = wr->send.src.num_sge *
+ (sizeof(ub_cmd_sge_t) / UB_TASK_SEG_ALIGN);
+ wqe->tsk_sec.send.upi = 0;
+ wqe->tsk_sec.send.dw2_value = 0;
+ wqe->tsk_sec.send.hint = wr->send.target_hint;
+ wqe->tsk_sec.send.djt = wr->tjetty->cfg.type;
+ wqe->tsk_sec.send.djtn = wr->tjetty->cfg.id.id;
+ wqe->tsk_sec.send.dw2_value = cpu_to_be32(wqe->tsk_sec.send.dw2_value);
+ wqe->tsk_sec.send.remote_token_value =
+ cpu_to_be32(wr->tjetty->cfg.token_value.token);
+ if (wr->tjetty->cfg.flag.bs.token_policy == UBCORE_TOKEN_NONE) {
+ wqe->tsk_sec.com.token_vld = 0;
+ } else if (wr->tjetty->cfg.flag.bs.token_policy ==
+ UBCORE_TOKEN_PLAIN_TEXT) {
+ wqe->tsk_sec.com.token_vld = 1;
+ } else {
+ udma_pr_err(UDMA_M_JFS,
+ "Bug : Invalid token_policy=%u, please check!\n",
+ wr->tjetty->cfg.flag.bs.token_policy);
+ }
+ /* send flow in wqe fill to deid before exactly fill complete a wqebb, need re new determine next a wqebb of place */
+ wqe = udma_get_next_wqe(sq, wqe);
+
+ memcpy_s(wqe->tsk_sec.send.deid, sizeof(wqe->tsk_sec.send.deid),
+ wr->tjetty->cfg.id.eid.raw,
+ sizeof(wr->tjetty->cfg.id.eid.raw));
+ *sge_addr = (u8 *)wqe + UB_SEND_TKV_DEID_LENGTH;
+}
+
+static void udma_fill_slice_bit(struct udma_device *udma_dev,
+ enum ubcore_transport_mode trans_mode,
+ struct tag_ub_sq_wqe_s *wqe)
+{
+ if (trans_mode == UBCORE_TP_RM || trans_mode == UBCORE_TP_RC) {
+ if (cpu_to_be32(wqe->tsk_sec.com.data_len) >
+ ((1 << udma_dev->slice) * UB_SLICE_LEN)) {
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "data_len is %u, over slice len\n",
+ cpu_to_be32(wqe->tsk_sec.com.data_len));
+ wqe->tsk_sec.com.s = 1;
+ }
+ }
+}
+
+static void udma_update_wqe_fast_dwqe_en(ub_sqwqe_optype_e opcode,
+ ub_sq_wqe_s *wqe)
+{
+ u32 fast_opc = (opcode == UB_TX_READ) || (opcode == UB_TX_WRITE) ||
+ (opcode == UB_TX_WRITE_IMMEDIATE) ||
+ (opcode == UB_TX_SEND);
+ u32 fast_para = (cpu_to_be32(wqe->tsk_sec.com.data_len) <=
+ UB_FAST_DATA_LEN_MAX) &&
+ (wqe->tsk_sec.com.token_vld == 0);
+ wqe->ctrl_sec.fast_dwqe_en &= (fast_opc & fast_para);
+}
+
+static void udma_fill_rw_or_send_sge(u8 *sge_addr, struct udma_send_queue *sq,
+ struct ubcore_sge *sgl,
+ const struct udma_sge_info *sge_info,
+ u32 *len)
+{
+ struct ub_cmd_sge *sge = NULL;
+ u32 sq_rmd_size;
+ u32 i;
+
+ sge = (struct ub_cmd_sge *)sge_addr;
+ for (i = 0; i < sge_info->sge_num; i++) {
+ sq_rmd_size = (u32)((sq->buf + sq->buf_size) - (void *)sge);
+ if (sq_rmd_size > sizeof(struct ub_cmd_sge)) {
+ udma_fill_sge(sge, sgl, len);
+ sge++;
+ } else if (sq_rmd_size == sizeof(struct ub_cmd_sge)) {
+ udma_fill_sge(sge, sgl, len);
+ sge = sq->buf;
+ } else {
+ sge = sq->buf;
+ udma_fill_sge(sge, sgl, len);
+ sge++;
+ }
+ sgl++;
+ }
+
+ if (sge_info->sge_num != 0) {
+ if (sge == sq->buf) {
+ sge = (struct ub_cmd_sge *)(sq->buf + sq->buf_size -
+ sizeof(struct ub_cmd_sge));
+ } else {
+ sge--;
+ }
+ sge->dw3.dw3_value = cpu_to_be32(sge->dw3.dw3_value);
+ sge->dw3.bs.L = 1;
+ sge->dw3.dw3_value = cpu_to_be32(sge->dw3.dw3_value);
+ }
+}
+
+static void udma_fill_rw_cmd(struct udma_device *udma_dev, u8 *sge_addr,
+ struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq)
+{
+ struct udma_sge_info sge_info = {};
+ struct ubcore_sge *sgl = NULL;
+ u32 len = 0;
+
+ sgl = (wr->opcode == UBCORE_OPC_READ) ? wr->rw.dst.sge : wr->rw.src.sge;
+ sge_info.sge_num = (wr->opcode == UBCORE_OPC_READ) ?
+ wr->rw.dst.num_sge :
+ wr->rw.src.num_sge;
+ sge_info.max_inline_size = sq->max_inline_size;
+
+ if (wr->flag.bs.inline_flag != 0) {
+ udma_fill_inline_wqe(sq, wqe, sge_addr, sgl, &sge_info);
+ return;
+ }
+
+ udma_fill_rw_or_send_sge(sge_addr, sq, sgl, &sge_info, &len);
+
+ wqe->tsk_sec.com.data_len = cpu_to_be32(len);
+ wqe->tsk_sec.wr_rd.length = cpu_to_be32(len);
+ if (wqe->tsk_sec.com.op_type == UB_TX_WRITE_IMMEDIATE) {
+ /* total_data_len is in second wqebb, need to handle wrap-around logic */
+ wqe = udma_get_next_wqe(sq, wqe);
+ wqe->tsk_sec.write_immt.total_data_len = cpu_to_be32(len);
+ }
+}
+
+static void udma_fill_send_cmd(struct udma_device *udma_dev, u8 *sge_addr,
+ struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq)
+{
+ struct udma_sge_info sge_info = {};
+ u32 len = 0;
+
+ sge_info.sge_num = wr->send.src.num_sge;
+ sge_info.max_inline_size = sq->max_inline_size;
+
+ if (wr->flag.bs.inline_flag != 0) {
+ udma_fill_inline_wqe(sq, wqe, sge_addr, wr->send.src.sge,
+ &sge_info);
+ return;
+ }
+
+ udma_fill_rw_or_send_sge(sge_addr, sq, wr->send.src.sge, &sge_info,
+ &len);
+ wqe->tsk_sec.com.data_len = cpu_to_be32(len);
+}
+
+static void udma_update_pi_and_fill_o_bit(struct tag_ub_sq_wqe_s *wqe,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_send_queue *sq,
+ u32 wqebb_cnt)
+{
+ struct tag_ub_sq_wqe_s *next_wqe = NULL;
+ u32 offset = 0;
+
+ sq->pi = sq->pi + wqebb_cnt;
+ /* fill wqe ctrl head section:mask_pi bit */
+ wqe->ctrl_sec.dw1_value |= (sq->pi & (sq->baseblk_cnt - 1)) & 0xFFFF;
+ offset = (sq->pi & (sq->baseblk_cnt - 1)) << sq->baseblk_shift;
+ sq->buf_curr = sq->buf + offset;
+ wqe->ctrl_sec.o = (((sq->pi - wqebb_cnt) & sq->baseblk_cnt) == 0) ? 0 :
+ 1;
+ wqe->ctrl_sec.dw0_value = cpu_to_be32(wqe->ctrl_sec.dw0_value);
+ wqe->ctrl_sec.dw1_value = cpu_to_be32(wqe->ctrl_sec.dw1_value);
+ wqe->tsk_sec.com.dw0_value = cpu_to_be32(wqe->tsk_sec.com.dw0_value);
+ wqe->tsk_sec.com.dw4_value = cpu_to_be32(wqe->tsk_sec.com.dw4_value);
+ // set next wqebb o bit invalid
+ next_wqe = (struct tag_ub_sq_wqe_s *)sq->buf_curr;
+ next_wqe->ctrl_sec.o = !((((sq->pi) & sq->baseblk_cnt) == 0) ? 0 : 1);
+ next_wqe->ctrl_sec.dw0_value =
+ cpu_to_be32(next_wqe->ctrl_sec.dw0_value);
+}
+
+int udma_fill_jfs_cmd(struct udma_device *udma_dev, struct tag_ub_sq_wqe_s *wqe,
+ enum UB_SQWQE_OPTYPE_E opcode,
+ const struct ubcore_jfs_wr *wr,
+ struct udma_post_wqe *post_wqe)
+{
+ struct udma_send_queue *sq = post_wqe->sq;
+ u8 *sge_addr = NULL;
+ u32 wqebb_cnt;
+
+ wqebb_cnt = udma_wqebb_cnt(udma_dev, sq, opcode, wr);
+ udma_fill_ctrl_and_task_com(wqe, wr, post_wqe, opcode,
+ udma_dev->ub_dev.cfg.pattern);
+
+ switch (opcode) {
+ case UB_TX_READ:
+ case UB_TX_WRITE:
+ udma_fill_rw_task_sec(wqe, wr, sq, &sge_addr, opcode);
+ udma_fill_rw_cmd(udma_dev, sge_addr, wqe, wr, sq);
+ break;
+ case UB_TX_WRITE_IMMEDIATE:
+ udma_fill_rw_imme_task_sec(wqe, wr, sq, &sge_addr);
+ udma_fill_rw_cmd(udma_dev, sge_addr, wqe, wr, sq);
+ break;
+ case UB_TX_SEND:
+ case UB_TX_SEND_IMMEDIATE:
+ case UB_TX_SEND_INVALIDATE:
+ udma_fill_send_task_sec(wqe, wr, sq, &sge_addr);
+ udma_fill_send_cmd(udma_dev, sge_addr, wqe, wr, sq);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Invalid opcode\n");
+ return -EINVAL;
+ }
+
+ udma_update_wqe_fast_dwqe_en(opcode, wqe);
+ wqe = sq->buf_curr;
+ udma_fill_slice_bit(udma_dev, post_wqe->tp_mode, wqe);
+ udma_update_pi_and_fill_o_bit(wqe, wr, sq, wqebb_cnt);
+
+ return 0;
+}
+
+void udma_post_send_jfs_dwqe(struct udma_device *udma_dev, struct udma_jfs *jfs)
+{
+ ulong flags = 0;
+ ub_sq_wqe_s *wqe = (ub_sq_wqe_s *)jfs->sq.dwqe_curr;
+
+ union tag_ub_sq_db_u dwqe_db;
+ dwqe_db.sq_db_value = 0;
+ dwqe_db.sq_db.dw0.bs.xqn = jfs->jfs_id;
+ dwqe_db.sq_db.dw0.bs.type = UB_DIRECT_WQE_SRV_TYPE
+ << UB_DWQE_DB_TYPE_SHIFT; // high 2bit
+ dwqe_db.sq_db.dw1.bs.pi = jfs->sq.pi &
+ 0xFFFF; // complete pi, normal is pi[15:8]
+ dwqe_db.sq_db.dw0.bs.cntx_size = UB_CNTX_SIZE;
+ dwqe_db.sq_db.dw0.bs.cos = jfs->cos;
+ udma_debug(udma_dev->dev, UDMA_M_JFS, "cos: %u, pi: %u\n", jfs->cos,
+ jfs->sq.pi);
+
+ wqe->ctrl_sec.dw2_value = cpu_to_be32(dwqe_db.sq_db_value & 0xFFFFFFFF);
+ wqe->ctrl_sec.dw3_value =
+ cpu_to_be32(dwqe_db.sq_db_value >> ADDR_H_OFFSET);
+ wmb();
+ *(jfs->sdb.db_record) = cpu_to_be32(jfs->sq.pi);
+ wmb();
+
+ spin_lock_irqsave(&udma_dev->dwqe_lock, flags);
+ udma_dwqe_copy((u64 *)udma_dev->kernel_dwqe_map, (u64 *)(uintptr_t)wqe,
+ (u32)jfs->sq.wqe_size);
+ spin_unlock_irqrestore(&udma_dev->dwqe_lock, flags);
+}
+
+static int udma_update_jfs_db(struct udma_device *udma_dev,
+ struct udma_jfs *jfs, u32 wr_cnt)
+{
+ union tag_ub_sq_db_u jfs_db;
+ int ret;
+
+ if (udma_is_sq_dwqe(&jfs->sq, wr_cnt, udma_dev)) {
+ udma_debug(udma_dev->dev, UDMA_M_JFS, "the wqe is jfs dwqe\n");
+ udma_post_send_jfs_dwqe(udma_dev, jfs);
+ return 0;
+ }
+
+ wmb();
+ udma_base_construct_sq_db(&jfs_db, jfs->jfs_id, jfs->sq.pi, jfs->cos);
+ udma_debug(udma_dev->dev, UDMA_M_JFS, "cos : %u, pi : %u\n", jfs->cos,
+ jfs->sq.pi);
+ *(jfs->sdb.db_record) = cpu_to_be32(jfs->sq.pi);
+
+ wmb();
+ ret = cqm5_ring_hardware_db(udma_dev->hwdev, SERVICE_T_UB,
+ jfs->sq.pi & 0xff, jfs_db.sq_db_value);
+ if (ret != CQM_SUCCESS) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "DB write field ret: %d.\n",
+ ret);
+ ret = -EIO;
+ }
+
+ wmb();
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "xid:0x%x, jfs_db.sq_db_value:0x%llx\n", jfs->jfs_id,
+ jfs_db.sq_db_value);
+ return ret;
+}
+
+static bool udma_get_sg_len(struct udma_device *udma_dev,
+ const struct ubcore_sg *sg, u64 *total_len)
+{
+ struct ubcore_sge *tmp_sge = NULL;
+ u32 i;
+
+ tmp_sge = sg->sge;
+ for (i = 0; i < sg->num_sge; i++) {
+ if (tmp_sge == NULL || tmp_sge->tseg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. Sge Or Tseg Is NULL\n");
+ return false;
+ }
+
+ if (*total_len > UINT_MAX - tmp_sge->len) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. sge len is error!\n");
+ return false;
+ }
+
+ *total_len += tmp_sge->len;
+
+ tmp_sge++;
+ }
+ if (*total_len == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "total_len cannot be 0.\n");
+ return false;
+ }
+ return true;
+}
+
+static int udma_wr_check_inline(struct udma_device *udma_dev,
+ const struct ubcore_sg *sg, u32 max_inline_size)
+{
+ struct ubcore_sge *tmp_sge = NULL;
+ u32 total_len = 0;
+ u32 i;
+
+ tmp_sge = sg->sge;
+ for (i = 0; i < sg->num_sge; i++) {
+ if (tmp_sge == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. Sge Or Tseg Is NULL\n");
+ return -EINVAL;
+ }
+
+ if (tmp_sge->addr == 0 && tmp_sge->len != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. Sge->add is 0 and sge->len is not 0\n");
+ return -EINVAL;
+ }
+ total_len += tmp_sge->len;
+ if (total_len > max_inline_size) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Inline src_len:%u is over max_inline_size:%u\n",
+ total_len, max_inline_size);
+ return -EINVAL;
+ }
+ tmp_sge++;
+ }
+
+ return 0;
+}
+
+static int udma_wr_check_read(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr, u8 max_send_sge)
+{
+ u64 dst_len = 0;
+
+ if (wr->flag.bs.inline_flag != 0)
+ return 0;
+
+ if (wr->rw.src.num_sge > max_send_sge) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Invalid parameter.\n");
+ return -EINVAL;
+ }
+
+ if ((wr->rw.src.sge == NULL) || (wr->rw.src.sge->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. sge or tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ if (!udma_get_sg_len(udma_dev, &wr->rw.dst, &dst_len)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. dst_sge is NULL or sge len is error\n");
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "read num_sge is %u, dst_len is %llu\n", wr->rw.src.num_sge,
+ dst_len);
+ if (dst_len > UB_MAX_WRITE_READ_LEN) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. read dst_len is %llu over 2GB\n",
+ dst_len);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_wr_check_write_common(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr,
+ u8 max_send_sge,
+ const struct udma_post_wqe *post_wqe)
+{
+ u64 src_len = 0;
+
+ if (wr->flag.bs.inline_flag != 0) {
+ return udma_wr_check_inline(udma_dev, &wr->rw.src,
+ post_wqe->sq->max_inline_size);
+ }
+
+ if (wr->rw.src.num_sge > max_send_sge) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Invalid parameter.\n");
+ return -EINVAL;
+ }
+
+ if (!udma_get_sg_len(udma_dev, &wr->rw.src, &src_len)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. src_sge is NULL or sge len is error\n");
+ return -EINVAL;
+ }
+
+ if ((wr->rw.dst.sge == NULL) || (wr->rw.dst.sge->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. dst_sge is NULL\n");
+ return -EINVAL;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "write num_sge is %u, src_len is %llu\n", wr->rw.src.num_sge,
+ src_len);
+ if (src_len > UB_MAX_WRITE_READ_LEN) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. write src_len is %llu over 2G\n",
+ src_len);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_wr_check_send(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr,
+ const struct udma_post_wqe *post_wqe)
+{
+ u64 src_len = 0;
+ bool ret = true;
+
+ if ((wr->opcode == UBCORE_OPC_SEND_INVALIDATE) &&
+ (wr->send.tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ if (wr->flag.bs.inline_flag != 0) {
+ return udma_wr_check_inline(udma_dev, &wr->rw.src,
+ post_wqe->sq->max_inline_size);
+ }
+
+ ret = udma_get_sg_len(udma_dev, &wr->send.src, &src_len);
+ if (!ret) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. src_sge is NULL or sge len is error\n");
+ return -EINVAL;
+ }
+
+ if (src_len > ((1 << udma_dev->slice) * UB_SLICE_LEN) ||
+ src_len > UB_SLICE_LEN_64K) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter. src_len %llu is over %d\n",
+ src_len, (1 << udma_dev->slice) * UB_SLICE_LEN);
+ return -EINVAL;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_JFS, "UB_SLICE_LEN: %d\n",
+ (1 << udma_dev->slice) * UB_SLICE_LEN);
+ return 0;
+}
+
+static int udma_wr_check_cas(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr)
+{
+ if ((wr->cas.dst == NULL) || (wr->cas.dst->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter, dst or tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ if ((wr->cas.src == NULL) || (wr->cas.src->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter, src or tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_wr_check_fadd(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr)
+{
+ if ((wr->faa.dst == NULL) || (wr->faa.dst->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter, dst or tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ if ((wr->faa.src == NULL) || (wr->faa.src->tseg == NULL)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter, dst or tseg is NULL\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_wr_check(const struct ubcore_jfs_wr *wr, u8 max_send_sge,
+ struct udma_device *udma_dev,
+ const struct udma_post_wqe *post_wqe)
+{
+ int ret = 0;
+
+ if (post_wqe->tp_mode == UBCORE_TP_UM &&
+ (wr->opcode != UBCORE_OPC_SEND &&
+ wr->opcode != UBCORE_OPC_SEND_IMM)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "The um operation type does not support opcode %u\n",
+ (u32)wr->opcode);
+ return -EINVAL;
+ }
+
+ if (wr->tjetty == NULL || wr->tjetty->vtpn == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "send.tjetty or send.tjetty->tp is null!\n");
+ return -EINVAL;
+ }
+
+ if (wr->tjetty->cfg.flag.bs.token_policy > UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "token_policy=%u dont support\n",
+ wr->tjetty->cfg.flag.bs.token_policy);
+ return -EINVAL;
+ }
+
+ if ((wr->flag.bs.inline_flag != 0) &&
+ (wr->opcode != UBCORE_OPC_WRITE) &&
+ (wr->opcode != UBCORE_OPC_SEND) &&
+ (wr->opcode != UBCORE_OPC_WRITE_IMM)) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter: opcode=%u dont support inline\n",
+ wr->opcode);
+ return -EINVAL;
+ }
+
+ switch (wr->opcode) {
+ case UBCORE_OPC_READ:
+ ret = udma_wr_check_read(udma_dev, wr, max_send_sge);
+ break;
+ case UBCORE_OPC_WRITE:
+ case UBCORE_OPC_WRITE_IMM:
+ ret = udma_wr_check_write_common(udma_dev, wr, max_send_sge,
+ post_wqe);
+ break;
+#ifdef UB_SUPPORT_SEND_IMM_OR_INV
+ case UBCORE_OPC_SEND_IMM:
+ case UBCORE_OPC_SEND_INVALIDATE:
+#endif
+ case UBCORE_OPC_SEND:
+ ret = udma_wr_check_send(udma_dev, wr, post_wqe);
+ break;
+ case UBCORE_OPC_CAS:
+ ret = udma_wr_check_cas(udma_dev, wr);
+ break;
+ case UBCORE_OPC_FADD:
+ ret = udma_wr_check_fadd(udma_dev, wr);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Invalid opcode :%u\n",
+ (u32)wr->opcode);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+int udma_handle_jfs_wr(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr, u32 wr_cnt,
+ struct udma_post_wqe *post_wqe)
+{
+ enum UB_SQWQE_OPTYPE_E opcode = ub_jfs_parse_opcode(wr->opcode);
+ struct tag_ub_sq_wqe_s *wqe = post_wqe->sq->buf_curr;
+ struct udma_send_queue *sq = post_wqe->sq;
+ u32 wqe_len;
+ int ret = 0;
+
+ if (opcode >= UB_ERR_TYPE) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Invalid opcode :%u\n",
+ (u32)wr->opcode);
+ return -EINVAL;
+ }
+
+ post_wqe->sq->dwqe_curr = post_wqe->sq->buf_curr;
+ sq->wrid[(sq->head + wr_cnt) & (sq->wrid_size - 1)] = wr->user_ctx;
+
+ ret = udma_fill_jfs_cmd(udma_dev, wqe, opcode, wr, post_wqe);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (opcode == UB_TX_ATOMIC_COMPARE_SWAP ||
+ opcode == UB_TX_ATOMIC_FETCH_ADD) {
+ wqe_len = sizeof(struct tag_ub_sq_wqe_s) +
+ sizeof(struct ubcore_sge);
+ } else if (wr->flag.bs.inline_flag == 0) {
+ wqe_len = sizeof(struct tag_ub_sq_wqe_s) +
+ sizeof(struct ubcore_sge) * wr->rw.src.num_sge;
+ } else {
+ wqe_len = sizeof(struct tag_ub_sq_wqe_s) +
+ be32_to_cpu(wqe->tsk_sec.com.data_len);
+ }
+ udma_dump_dfx(udma_dev, (u64)(uintptr_t)wqe, wqe_len,
+ (u64)(uintptr_t)sq->buf, sq->buf_size);
+
+ return 0;
+}
+
+int udma_sq_overflow(struct udma_send_queue *sq, u32 wr_num,
+ struct udma_jfc *jfc)
+{
+ ulong flags = 0;
+
+ u32 cur = sq->head - sq->tail;
+ if ((cur + wr_num) < sq->max_wr_num) {
+ return 0;
+ }
+ if (jfc == NULL) {
+ udma_pr_err(UDMA_M_JFS, "Invalid parameter: jfc(%d).\n", !!jfc);
+ return -EINVAL;
+ }
+
+ if (jfc == NULL) {
+ udma_pr_err(UDMA_M_JFS, "Invalid parameter: jfc(%d).\n", !!jfc);
+ return 0;
+ }
+
+ spin_lock_irqsave(&jfc->lock, flags);
+ cur = sq->head - sq->tail;
+ spin_unlock_irqrestore(&jfc->lock, flags);
+
+ return ((cur + wr_num) >= sq->max_wr_num);
+}
+
+int udma_construct_wqe(struct udma_device *udma_dev,
+ const struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr, u32 *wr_cnt,
+ struct udma_post_wqe *post_wqe)
+{
+ struct ubcore_jfs_wr *iter = NULL;
+ int ret = 0;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_JFS, "%s Invalid parameter: udma_dev(%d).\n",
+ __func__, !!udma_dev);
+ *bad_wr = (struct ubcore_jfs_wr *)wr;
+ return -EINVAL;
+ }
+
+ for (iter = (struct ubcore_jfs_wr *)wr; iter != NULL;
+ iter = (struct ubcore_jfs_wr *)(void *)iter->next) {
+ if (udma_sq_overflow(post_wqe->sq, *wr_cnt, post_wqe->jfc) !=
+ 0) {
+ udma_info(udma_dev->dev, UDMA_M_JFS, "sq overflow!\n");
+ *bad_wr = iter;
+ return -EAGAIN;
+ }
+
+ if (udma_wr_check(iter, post_wqe->max_send_sge, udma_dev,
+ post_wqe) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "wr check false!\n");
+ *bad_wr = iter;
+ return -EINVAL;
+ }
+
+ if (iter->tjetty == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter: iter->tjetty is null.\n");
+ *bad_wr = iter;
+ return -EINVAL;
+ }
+
+ if (post_wqe->tp_mode != iter->tjetty->cfg.trans_mode) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "Invalid parameter, local jetty trans_mode is %u, target jetty trans_mode is %u.\n",
+ post_wqe->tp_mode,
+ iter->tjetty->cfg.trans_mode);
+ *bad_wr = iter;
+ return -EINVAL;
+ }
+
+ if ((post_wqe->tp_mode != UBCORE_TP_RM) &&
+ (iter->tjetty->cfg.type == UBCORE_JETTY_GROUP)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFS,
+ "ERR: tp_mode(%d) and tjetty type(%d) not match\n",
+ post_wqe->tp_mode, iter->tjetty->cfg.type);
+ *bad_wr = iter;
+ return -EINVAL;
+ }
+
+ post_wqe->tpn = iter->tjetty->vtpn->vtpn;
+ post_wqe->sq->wqe_size = 0;
+ post_wqe->sq->rmd_wqebb_cnt =
+ post_wqe->sq->baseblk_cnt -
+ (post_wqe->sq->pi & (post_wqe->sq->baseblk_cnt - 1));
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFS,
+ "handle jfs START.trans_mode:%u,tjetty_type:%d,tpn:%u,ubcore opcode:%u\n",
+ post_wqe->tp_mode, iter->tjetty->cfg.type,
+ post_wqe->tpn, wr->opcode);
+ ret = udma_handle_jfs_wr(udma_dev, iter, *wr_cnt, post_wqe);
+ if (ret != 0) {
+ *bad_wr = (struct ubcore_jfs_wr *)iter;
+ return ret;
+ }
+ (*wr_cnt)++;
+
+ if ((*wr_cnt) > post_wqe->sq->max_wr_num) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "ERR: wr_cnt[%u] big than max_wr_num[%u]\n",
+ (*wr_cnt), post_wqe->sq->max_wr_num);
+ *bad_wr = iter;
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+int udma_post_jfs_wr_one(struct ubcore_jfs *ubcore_jfs,
+ const struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *jfs = NULL;
+ struct udma_post_wqe post_wqe = { 0 };
+ ulong flags = 0;
+ u32 wr_cnt = 0;
+ int ret = 0;
+
+ if (ubcore_jfs == NULL || ubcore_jfs->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_JFS, "Invalid parameter. ubcore_jfs(%d) .\n",
+ !!ubcore_jfs);
+ *bad_wr = (struct ubcore_jfs_wr *)wr;
+ return -EINVAL;
+ }
+
+ jfs = to_udma_jfs(ubcore_jfs);
+ udma_dev = to_udma_dev(ubcore_jfs->ub_dev);
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "Start to post jfs send wr, jfs_id:%u\n", jfs->jfs_id);
+ spin_lock_irqsave(&jfs->sq.lock, flags);
+ post_wqe.jfc = to_udma_jfc(jfs->ubcore_jfs.jfs_cfg.jfc);
+ post_wqe.tp_mode = jfs->trans_mode;
+ post_wqe.sq = &jfs->sq;
+ post_wqe.max_send_sge = jfs->ubcore_jfs.jfs_cfg.max_sge;
+ post_wqe.is_fast_path = check_k_is_fast_path(wr, post_wqe.sq);
+
+ ret = udma_construct_wqe(udma_dev, wr, bad_wr, &wr_cnt, &post_wqe);
+
+ if (wr_cnt != 0) {
+ udma_update_jfs_db(udma_dev, jfs, wr_cnt);
+ jfs->sq.head += wr_cnt;
+ atomic64_add(wr_cnt,
+ &jfs->sq.udma_driver_sq_ctr.post_send_wr_num);
+ atomic64_add(
+ wr_cnt,
+ &udma_dev->udma_driver_device_ctr.post_send_wr_num);
+ udma_debug(
+ udma_dev->dev, UDMA_M_JFS,
+ "dev_post_send_wr_num:%llu, post_jfs_wr_num:%llu\n",
+ (u64)atomic64_read(&udma_dev->udma_driver_device_ctr
+ .post_send_wr_num),
+ (u64)atomic64_read(
+ &jfs->sq.udma_driver_sq_ctr.post_send_wr_num));
+ }
+ spin_unlock_irqrestore(&jfs->sq.lock, flags);
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "Finished to post jfs send wr, wr_cnt:%u\n", wr_cnt);
+ return ret;
+}
+
+int udma_post_jfs_wr(struct ubcore_jfs *ubcore_jfs, struct ubcore_jfs_wr *wr,
+ struct ubcore_jfs_wr **bad_wr)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *jfs = NULL;
+
+ if ((ubcore_jfs == NULL) || (ubcore_jfs->ub_dev == NULL) ||
+ (wr == NULL) || (bad_wr == NULL)) {
+ udma_pr_err(
+ UDMA_M_JFC,
+ "%s Invalid parameter: ubcore_jfs(%d), wr(%d), bad_wr(%d).\n",
+ __func__, !!ubcore_jfs, !!wr, !!bad_wr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ubcore_jfs->ub_dev);
+ jfs = to_udma_jfs(ubcore_jfs);
+ udma_debug(udma_dev->dev, UDMA_M_JFS,
+ "start post jfs send, jfs id: %u, state: %d\n", jfs->jfs_id,
+ jfs->state);
+
+ if (jfs->state != UBCORE_JETTY_STATE_READY) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "jfs state: %d, posting not supported\n", jfs->state);
+ *bad_wr = wr;
+ return -EINVAL;
+ }
+
+ return udma_post_jfs_wr_one(ubcore_jfs, wr, bad_wr);
+}
+
+int udma_modify_jfs(struct ubcore_jfs *ubcore_jfs, struct ubcore_jfs_attr *attr,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_jfs *jfs = NULL;
+ int ret;
+
+ if (ubcore_jfs == NULL || ubcore_jfs->ub_dev == NULL || attr == NULL) {
+ udma_pr_err(
+ UDMA_M_JFC,
+ "ubcore_jfs(%d), attr(%d) or ubcore_jfs->ub_dev is NULL\n",
+ !!ubcore_jfs, !!attr);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ubcore_jfs->ub_dev);
+ jfs = to_udma_jfs(ubcore_jfs);
+ udma_info(udma_dev->dev, UDMA_M_JFS, "Modify jfs(%u), state(%u)\n",
+ jfs->jfs_id, attr->state);
+
+ if ((attr->mask & UBCORE_JFS_STATE) == 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "JFS modify mask is not set or invalid.\n");
+ return -EINVAL;
+ }
+
+ if (attr->state < UBCORE_JETTY_STATE_RESET ||
+ attr->state > UBCORE_JETTY_STATE_ERROR) {
+ udma_err(udma_dev->dev, UDMA_M_JFS,
+ "Invalid jfs state: 0x%08x\n", attr->state);
+ return -EINVAL;
+ }
+
+ if (udma_modify_jetty_parse_udata(udma_dev, &jfs->sq, udata) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JETTY, "Failed parse udata\n");
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_jfs_modify_ctx(udma_dev, jfs, attr->state, udata);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFS, "Failed to modify jfs\n");
+ } else {
+ jfs->state = attr->state;
+ jfs->sq.is_hw_flush_done = false;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_JFS, "Modify jfs %u, ret %d\n",
+ jfs->jfs_id, ret);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.c b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.c
new file mode 100644
index 000000000..fd71b0f56
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_cmd_srq.h"
+#include "udma_jetty.h"
+#include "ub_ta_wqe_format.h"
+#include "udma_srq.h"
+
+/* Containers are managed using a linked list, with one sentinel node added to the linked list */
+#define UDMA_CONTAINER_GUARD_NODE 1
+
+static u8 ub_get_container_sz(u32 container_mode)
+{
+ switch (container_mode) {
+ case UB_SRQ_MODE_1:
+ return UB_SRQ_CONT_NUM_MODE1;
+ case UB_SRQ_MODE_2:
+ return UB_SRQ_CONT_NUM_MODE2;
+ case UB_SRQ_MODE_3:
+ return UB_SRQ_CONT_NUM_MODE3;
+ case UB_SRQ_MODE_4:
+ return UB_SRQ_CONT_NUM_MODE4;
+ default:
+ return UB_SRQ_CONT_NUM_MODE0;
+ }
+}
+
+static void udma_set_srq_depth(struct udma_srq *srq, u32 depth)
+{
+ /* container in non- link wqe of rqe count */
+ uint32_t no_link_wqe_num = srq->container_size - 1;
+ /* get this depth at least need how many container, round up */
+ uint32_t container_num =
+ ((depth + 1) + (no_link_wqe_num - 1)) /
+ no_link_wqe_num; /* Note: this at adaptation no_link_wqe scenario and container_size equal to 2 of scenario, other scenario need analyze */
+
+ srq->max_depth = container_num * srq->container_size;
+ srq->max_depth = roundup_pow_of_two(srq->max_depth) & 0xffffffff;
+}
+
+static uint32_t udma_get_rqe_buf_size(struct udma_device *udma_dev,
+ struct udma_srq *srq, u32 wqe_size)
+{
+ uint32_t buf_size = 0;
+ uint32_t page_sz = PAGE_SIZE;
+
+ buf_size = srq->max_depth * wqe_size;
+ if (udma_dev->ub_cap.dev_cap.mtt_pro_en == 1) {
+ page_sz = udma_cal_page_size(buf_size);
+ }
+
+ if (buf_size < page_sz) {
+ buf_size = page_sz;
+ srq->max_depth = buf_size >> srq->wqe_shift;
+ }
+
+ return ALIGN(buf_size, page_sz);
+}
+
+int udma_srq_init_attr(struct udma_device *udma_dev, struct udma_srq *srq,
+ u32 depth, u8 max_sge)
+{
+ u32 wqe_size = 0;
+ u32 temp_size = 0;
+
+ spin_lock_init(&srq->lock);
+ srq->index_queue_en = udma_get_index_queue_en(udma_dev);
+ srq->container_flag = UB_SRQ_CONTAINER_EN;
+ srq->container_mode = srq->index_queue_en ? UB_SRQ_MODE_4 :
+ UB_SRQ_MODE_1;
+ srq->container_size = ub_get_container_sz(srq->container_mode);
+ srq->container_warn_th = 0;
+
+ udma_set_srq_depth(srq, depth);
+ srq->max_sge = srq->index_queue_en ? UB_SRQ_MAX_SGE :
+ SRQ_MAX_SGE(max_sge);
+ temp_size = (u32)roundup_pow_of_two(
+ (u32)sizeof(struct ub_wqe_srq_next_seg) +
+ (srq->max_sge) * (u32)sizeof(struct ub_wqe_srq_data_seg));
+ wqe_size = SRQ_WQE_SIZE(temp_size);
+ srq->wqe_shift = (u32)ilog2(wqe_size);
+ srq->buf_size = udma_get_rqe_buf_size(udma_dev, srq, wqe_size);
+
+ return 0;
+}
+
+int udma_index_queue_init_attr(struct udma_device *udma_dev,
+ struct udma_index_queue *index_queue, u32 depth)
+{
+ u32 buf_size = 0;
+
+ index_queue->wqe_shift = (u32)ilog2(sizeof(ubg_jfr_index_wqe_s));
+ index_queue->max_depth = roundup_pow_of_two(depth) & 0xffffffff;
+ buf_size = index_queue->max_depth << index_queue->wqe_shift;
+ if (buf_size < PAGE_SIZE)
+ index_queue->max_depth = PAGE_SIZE >>
+ (u16)index_queue->wqe_shift;
+ index_queue->buf_size = ALIGN(buf_size, PAGE_SIZE);
+
+ return 0;
+}
+
+int udma_create_srqc_update(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct udma_db *sdb)
+{
+ struct tag_cqm_queue *srqc_info = NULL;
+ int ret = 0;
+
+ u32 xid_start = 0;
+ u32 xid_end = xid_start + udma_dev->ub_cap.dev_cap_res.sdk_res.max_jfr;
+ u32 qpn_tmp =
+ udma_get_qpn_mod(udma_dev, CQM_XID_LOW_BIT_1_1_1, srq->jfr_id);
+
+ srq->cqm_priv_type = UDMA_CQM_PRIV_TYPE_SRQ;
+ srqc_info = udma_object_queue_create(udma_dev, CQM_OBJECT_RDMA_SRQ, 0,
+ srq, &udma_dev->srqn_record, false,
+ qpn_tmp, xid_start, xid_end);
+ if (srqc_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Create srqc by cqm object failed.\n");
+ return -ENOMEM;
+ }
+
+ srq->srqc_info = srqc_info;
+ srq->srqn = srq->srqc_info->index;
+
+ ret = udma_cmd_srq_create_ctx(udma_dev, srq, sdb);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "Enable srq context failed. ret: %d\n", ret);
+ cqm5_object_delete(&(srqc_info->object));
+ srq->srqc_info = NULL;
+ return ret;
+ }
+
+ return ret;
+}
+
+int udma_delete_srqc_and_cache_out(struct udma_device *udma_dev,
+ struct udma_srq *srq)
+{
+ int ret;
+
+ ret = udma_cmd_srq_delete_ctx(udma_dev, srq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "Delete srq and cache out failed. ret: %d\n", ret);
+ return ret;
+ }
+
+ if (srq->srqc_info != NULL) {
+ cqm5_object_delete(&(srq->srqc_info->object));
+ srq->srqc_info = NULL;
+ }
+ return ret;
+}
+
+int udma_srq_init_res(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct tag_cqm_queue *buf_info)
+{
+ struct ub_wqe_srq_data_seg *sge = NULL;
+ struct ub_container_srq_wqe_head *next = NULL;
+ u32 container_cap = srq->container_size;
+ u32 wr_cnt;
+
+ srq->srqc_info = buf_info;
+ srq->srqn = buf_info->index;
+ srq->buf = &buf_info->q_room_buf_1;
+ srq->srq_va = udma_dev->ub_cap.dev_cap.mtt_pro_en == 1 ?
+ srq->queue_addr.va :
+ srq->buf->direct.va;
+
+ srq->db.db_record =
+ (__be32 *)(void *)(&buf_info->q_header_vaddr->doorbell_record);
+ srq->db.dma = buf_info->q_header_paddr;
+ *srq->db.db_record = 0;
+ srq->counter_left = 0;
+ srq->container_counter = 0;
+ if (srq->flush_flag == true) {
+ udma_err(udma_dev->dev, UDMA_M_JFR,
+ "init srq, now flush_flag is true.\n");
+ srq->flush_flag = false;
+ }
+
+ srq->head = 0;
+ srq->tail = (s32)(srq->max_depth - container_cap);
+
+ for (wr_cnt = 0; wr_cnt < srq->max_depth; ++wr_cnt) {
+ next = (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, wr_cnt);
+
+ if ((wr_cnt + 1U) % container_cap == 0) {
+ next->dw3.bs.link_flag = 1;
+ next->dw2.bs.next_idx =
+ (u16)((wr_cnt + 1) & (srq->max_depth - 1)) /
+ container_cap;
+ next->dw2.bs.cur_idx =
+ (u16)(wr_cnt & (srq->max_depth - 1)) /
+ container_cap;
+
+ next->dw4.value = (u32)htonl(next->dw4.value);
+ next->dw3.value = (u32)htonl(next->dw3.value);
+ next->dw2.value = (u32)htonl(next->dw2.value);
+ } else {
+ /* we just need to init the first sge section; */
+ sge = (struct ub_wqe_srq_data_seg *)(void *)next;
+ sge[0].dw3.lkey =
+ (u32)htonl((u32)UB_WQE_NEXT_SGE_INVALID);
+ sge[0].dw2.length = 0;
+ }
+ }
+
+ return 0;
+}
+
+void udma_free_srq_wqe(struct udma_srq *srq, u32 container_idx)
+{
+ u32 last_link_wqe_idx =
+ ((u32)container_idx + 1) * srq->container_size - 1;
+ struct ub_container_srq_wqe_head *tail_cont_link_wqe = NULL;
+ struct ub_container_srq_wqe_head *last_cont_link_wqe = NULL;
+ u32 tail_link_wqe_idx = 0;
+
+ spin_lock(&srq->lock);
+
+ last_cont_link_wqe = (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, last_link_wqe_idx);
+ last_cont_link_wqe->dw3.value =
+ (u32)ntohl(last_cont_link_wqe->dw3.value);
+ if (last_cont_link_wqe->dw3.bs.link_flag != 0) {
+ tail_link_wqe_idx = (u32)srq->tail + (srq->container_size - 1);
+
+ tail_cont_link_wqe =
+ (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, tail_link_wqe_idx);
+ tail_cont_link_wqe->dw2.value =
+ (u32)ntohl(tail_cont_link_wqe->dw2.value);
+ tail_cont_link_wqe->dw2.bs.next_idx = container_idx;
+ tail_cont_link_wqe->dw2.value =
+ (u32)htonl(tail_cont_link_wqe->dw2.value);
+
+ srq->tail = (s32)(container_idx * srq->container_size);
+ }
+ last_cont_link_wqe->dw3.value =
+ (u32)htonl(last_cont_link_wqe->dw3.value);
+
+ spin_unlock(&srq->lock);
+}
+
+u16 udma_get_next_srq_wqe(struct udma_srq *srq, u16 cur_idx)
+{
+ struct ub_container_srq_wqe_head *cur_link_wqe = NULL;
+ u16 cur_link_wqe_idx = (u16)(cur_idx * srq->container_size +
+ (srq->container_size - 1));
+ u16 next_idx;
+
+ spin_lock(&srq->lock);
+ cur_link_wqe = (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, cur_link_wqe_idx);
+ cur_link_wqe->dw2.value = (u32)ntohl(cur_link_wqe->dw2.value);
+ next_idx = cur_link_wqe->dw2.bs.next_idx;
+ cur_link_wqe->dw2.value = (u32)htonl(cur_link_wqe->dw2.value);
+ spin_unlock(&srq->lock);
+
+ return next_idx;
+}
+
+static u32 udma_srq_get_max_avail_wr(struct udma_srq *srq)
+{
+ u32 link_wqe_count = 0;
+
+ if (srq->container_flag != 0 && srq->container_size != 0) {
+ link_wqe_count = srq->max_depth / srq->container_size;
+ return (srq->max_depth - link_wqe_count) -
+ (srq->container_size - 1);
+ } else {
+ return srq->max_depth - 1;
+ }
+}
+
+int udma_modify_srq_threshold(struct udma_device *udma_dev,
+ struct udma_srq *srq, u8 container_warn_th)
+{
+ u32 max_avail_wr = 0;
+ int ret = 0;
+
+ max_avail_wr = udma_srq_get_max_avail_wr(srq);
+ if (container_warn_th > max_avail_wr) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SRQ,
+ "rx_threshold > max_wr, rx_threshold(%u), max_avail_wr(%u)\n",
+ container_warn_th, max_avail_wr);
+ return -EINVAL;
+ }
+
+ mutex_lock(&srq->mutex);
+ ret = udma_cmd_srq_modify_ctx(udma_dev, srq, container_warn_th);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "modify srq threshold cmdq failed, srqn(%u).\n",
+ srq->srqn);
+ mutex_unlock(&srq->mutex);
+ return -EFAULT;
+ }
+ mutex_unlock(&srq->mutex);
+
+ srq->container_warn_th = container_warn_th;
+ udma_info(udma_dev->dev, UDMA_M_SRQ,
+ "modify srq threshold success, srqn(%u)\n", srq->srqn);
+ return ret;
+}
+
+static int udma_sge_check_vld(struct udma_device *udma_dev,
+ const struct ubcore_sge *sge, u32 data_size,
+ u64 max_msg_sz)
+{
+ if ((data_size + sge->len > max_msg_sz) ||
+ (data_size + sge->len < data_size) ||
+ (sge->len > UB_SGE_LEN_LIMIT)) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "data_size: %u, wr sge len: %u, max_msg_sz: %llu\n",
+ data_size, sge->len, max_msg_sz);
+ return -EINVAL;
+ }
+
+ if (sge->tseg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ, "sge tseg is null\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_srq_pre_post_wqe_check(struct udma_device *udma_dev,
+ const struct udma_srq *srq,
+ const struct ubcore_jfr_wr *wr)
+{
+ u32 data_size = 0;
+ u32 sge_num = 0;
+
+ if ((u32)wr->src.num_sge > srq->max_sge) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "wr sge num(%u) > max sge(%u)\n", wr->src.num_sge,
+ srq->max_sge);
+ return -EINVAL;
+ }
+
+ if (srq->head == srq->tail) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "srq is full, head: %d, tail: %d\n", srq->head,
+ srq->tail);
+ return -EINVAL;
+ }
+
+ if (wr->src.num_sge != 0 && wr->src.sge == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "sge num is %u, wr sge is null\n", wr->src.num_sge);
+ return -EINVAL;
+ }
+
+ for (sge_num = 0, data_size = 0; sge_num < wr->src.num_sge; ++sge_num) {
+ if (udma_sge_check_vld(udma_dev, &wr->src.sge[sge_num],
+ data_size, UB_MAX_WRITE_READ_LEN) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "wr sge(%u) is invalid\n", sge_num);
+ return -EINVAL;
+ }
+ data_size += wr->src.sge[sge_num].len;
+ }
+ return 0;
+}
+
+static void udma_get_container_head(struct udma_srq *srq,
+ struct ub_container_srq_wqe_head **next)
+{
+ struct ub_container_srq_wqe_head tmp;
+
+ *next = (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, (u32)srq->head);
+ tmp.dw3.value = (u32)ntohl((*next)->dw3.value);
+ if (tmp.dw3.bs.link_flag != 0) {
+ tmp.dw2.value = (u32)ntohl((*next)->dw2.value);
+ srq->head =
+ (s32)((u32)(tmp.dw2.bs.next_idx) * srq->container_size);
+ (*next) = (struct ub_container_srq_wqe_head *)ub_srq_get_wqe(
+ srq, (u32)srq->head);
+ }
+}
+
+static int udma_init_srq_wqe_header(struct udma_device *udma_dev,
+ struct udma_srq *srq,
+ const struct ubcore_jfr_wr *wr,
+ struct ub_wqe_srq_data_seg **sge,
+ u16 wr_num)
+{
+ struct ub_container_srq_wqe_head *next = NULL;
+
+ if (srq->container_flag == 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "only support container mode\n");
+ return -EINVAL;
+ }
+
+ udma_get_container_head(srq, &next);
+ if (srq->head == srq->tail) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "srq is full, head: %d, tail: %d\n", srq->head,
+ srq->tail);
+ return -EINVAL;
+ }
+
+ *sge = (struct ub_wqe_srq_data_seg *)(void *)next;
+ srq->wrid[srq->head] = wr->user_ctx;
+ srq->head += 1;
+
+ udma_get_container_head(srq, &next);
+
+ return 0;
+}
+
+static int udma_construct_sge(struct udma_device *udma_dev,
+ const struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr,
+ struct ub_wqe_srq_data_seg *sge)
+{
+ u32 sge_num = 0;
+
+ for (sge_num = 0; sge_num < wr->src.num_sge; ++sge_num) {
+ sge[sge_num].addr = htonll(wr->src.sge[sge_num].addr);
+ sge[sge_num].dw2.length = htonl(wr->src.sge[sge_num].len);
+ sge[sge_num].dw3.lkey =
+ htonl((wr->src.sge[sge_num].tseg->seg.token_id) &
+ (~UB_WQE_NEXT_SGE_INVALID));
+ }
+
+ /*
+ * Set the last sge L bit. To avoid case sge = 0, need to judge sge number;
+ * When wr.sge_num == 0,set sge[0] L flags
+ */
+ if (wr->src.num_sge != 0) {
+ sge[sge_num - 1].dw3.lkey =
+ htonl((wr->src.sge[sge_num - 1].tseg->seg.token_id) |
+ UB_WQE_NEXT_SGE_INVALID);
+ } else {
+ sge[0].dw3.lkey = htonl(UB_WQE_NEXT_SGE_INVALID);
+ sge[0].dw2.length = 0;
+ }
+
+ return 0;
+}
+
+int udma_post_srq_wr(struct udma_device *udma_dev, struct udma_srq *srq,
+ const struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr)
+{
+ struct ub_wqe_srq_data_seg *sge = NULL;
+ u16 wr_num;
+ ulong flags = 0;
+ int ret = 0;
+
+ spin_lock_irqsave(&srq->lock, flags);
+ for (wr_num = 0; wr != NULL; ++wr_num, wr = wr->next) {
+ ret = udma_srq_pre_post_wqe_check(udma_dev, srq, wr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "check post wqe failed, wr num: %u\n", wr_num);
+ *bad_wr = (struct ubcore_jfr_wr *)wr;
+ goto out;
+ }
+
+ ret = udma_init_srq_wqe_header(udma_dev, srq, wr, &sge, wr_num);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "init srq wqe header failed, wr num: %u\n",
+ wr_num);
+ *bad_wr = (struct ubcore_jfr_wr *)wr;
+ goto out;
+ }
+
+ ret = udma_construct_sge(udma_dev, wr, bad_wr, sge);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SRQ,
+ "construct sge failed, wr num: %u\n", wr_num);
+ *bad_wr = (struct ubcore_jfr_wr *)wr;
+ goto out;
+ }
+ udma_dump_dfx(udma_dev, (u64)(uintptr_t)sge,
+ (u32)(1 << (unsigned)srq->wqe_shift),
+ (u64)(uintptr_t)srq->srq_va, srq->buf_size);
+ }
+
+out:
+ if (wr_num != 0) {
+ srq->container_counter += (u16)(srq->counter_left + wr_num) /
+ (srq->container_size - 1);
+ srq->counter_left = (u8)((srq->counter_left + wr_num) %
+ (srq->container_size - 1));
+ atomic64_add(wr_num, &srq->udma_driver_rq_ctr.post_recv_wr_num);
+ atomic64_add(
+ wr_num,
+ &udma_dev->udma_driver_device_ctr.post_recv_wr_num);
+ udma_debug(udma_dev->dev, UDMA_M_SRQ,
+ "post_jfr_wr_num:%llu, dev_post_recv_wr_num:%llu\n",
+ (u64)atomic64_read(
+ &srq->udma_driver_rq_ctr.post_recv_wr_num),
+ (u64)atomic64_read(&udma_dev->udma_driver_device_ctr
+ .post_recv_wr_num));
+ /*
+ * Make sure that descriptors are written before
+ * we write doorbell record.
+ */
+ wmb();
+
+ *(srq->db.db_record) = (u32)htonl((u32)srq->container_counter);
+ }
+ spin_unlock_irqrestore(&srq->lock, flags);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_SRQ,
+ "post srq recv, wr_num: %u, container_counter: %u, conter_left: %u\n",
+ wr_num, srq->container_counter, srq->counter_left);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.h b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.h
new file mode 100644
index 000000000..094b43160
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/jetty/udma_srq.h
@@ -0,0 +1,205 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_SRQ_H
+#define UDMA_SRQ_H
+
+#include "udma_common.h"
+#include "udma_db.h"
+#include "hinic5_cqm.h"
+
+#define UB_SRQ_MAX_SGE 15
+#define UB_SRQ_MIN_SGE 7
+#define UB_WQEBB_SIZE_MIN 128
+#define UB_SRQ_CONTAINER_EN 1
+
+#define UB_SGE_LEN_LIMIT ((u32)(1U << 31))
+#define SRQ_WQEBB_SIZE_CAL_SECTTOR \
+ 4 //(2^rq_wqebb_size)*16B => divide 16 means shift need to minus 4
+#define UB_SRQ_CONTAINER_WARTH_MASK 0xF
+
+#define UB_WQE_NEXT_SGE_INVALID (1UL << 31)
+
+#define SRQ_MAX_SGE(x) \
+ (((x) <= UB_SRQ_MIN_SGE) ? UB_SRQ_MIN_SGE : UB_SRQ_MAX_SGE)
+#define SRQ_WQE_SIZE(x) (max((u32)UB_WQEBB_SIZE_MIN, x))
+
+#ifndef htonll
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define htonll(x) \
+ ((((x)&0x00000000000000ffULL) << 56) | \
+ (((x)&0x000000000000ff00ULL) << 40) | \
+ (((x)&0x0000000000ff0000ULL) << 24) | \
+ (((x)&0x00000000ff000000ULL) << 8) | \
+ (((x)&0x000000ff00000000ULL) >> 8) | \
+ (((x)&0x0000ff0000000000ULL) >> 24) | \
+ (((x)&0x00ff000000000000ULL) >> 40) | \
+ (((x)&0xff00000000000000ULL) >> 56))
+
+#elif BYTE_ORDER == BIG_ENDIAN
+#define htonll(x) (x)
+#else
+#error BYTE_ORDER is neither LITTLE_ENDIAN nor BIG_ENDIAN
+#endif
+#endif
+
+#ifndef ntohll
+#define ntohll(x) htonll(x)
+#endif
+
+enum srq_state {
+ UB_SRQ_STATE_INVALID = 0x0,
+ UB_SRQ_STATE_ERR = 0x1,
+ UB_SRQ_STATE_VALID = 0xf,
+ UB_SRQ_STATE_MEM_INIT = 0xa
+};
+
+/**
+ * srq container_mode:
+ * mode: 0 -> Not container
+ * mode: 1 -> container_size: 2
+ * mode: 2 -> container_size: 4
+ * mode: 3 -> container_size: 8
+ * mode: 4 -> container_size: 16
+ */
+enum ub_srq_mode {
+ UB_SRQ_MODE_0 = 0,
+ UB_SRQ_MODE_1,
+ UB_SRQ_MODE_2,
+ UB_SRQ_MODE_3,
+ UB_SRQ_MODE_4
+};
+
+enum ub_srq_cont_num_mode {
+ UB_SRQ_CONT_NUM_MODE0 = 0,
+ UB_SRQ_CONT_NUM_MODE1 = 2,
+ UB_SRQ_CONT_NUM_MODE2 = 4,
+ UB_SRQ_CONT_NUM_MODE3 = 8,
+ UB_SRQ_CONT_NUM_MODE4 = 16
+};
+struct ub_wqe_srq_next_seg {
+ u16 reserved1;
+ u16 pcnt; // indicate the pi
+ u8 signature;
+ u8 reserved2;
+ u16 next_wqe_index;
+ u32 reserved3[2];
+};
+
+struct ub_container_srq_wqe_head {
+ u32 next_gpa_h;
+
+ union {
+ struct {
+ u32 rsvd : 11;
+ u32 next_gpa_vd : 1;
+ u32 next_gpa_l : 20; /* indicate the pi */
+ } bs;
+
+ u32 value;
+ } dw1;
+
+ union {
+ struct {
+ u32 next_idx : 16;
+ u32 cur_idx : 16;
+ } bs;
+ u32 value;
+ } dw2;
+
+ union {
+ struct {
+ u32 rsvd2 : 30;
+ u32 link_flag : 1;
+ u32 rsvd : 1;
+ } bs;
+ u32 value;
+ } dw3;
+
+ union {
+ struct {
+ u32 osd_next_idx : 16;
+ u32 osd_cur_idx : 16;
+ } bs;
+ u32 value;
+ } dw4;
+};
+
+typedef struct udma_driver_rq_ctr {
+ atomic64_t post_recv_wr_num;
+} udma_driver_rq_ctr_t;
+
+struct udma_srq {
+ u32 cqm_priv_type;
+ struct tag_cqm_queue *srqc_info;
+ struct queue_addr_info queue_addr;
+ struct ubcore_umem *umem;
+ struct mtt ub_mtt;
+ struct mutex mutex;
+ spinlock_t lock;
+ u32 srqn;
+ u32 jfr_id;
+ cqm_buf_s *buf;
+ void *srq_va;
+ u64 *wrid;
+ s32 head;
+ s32 tail;
+ u32 max_depth;
+ u32 max_sge;
+ u32 wqe_shift;
+ u32 buf_size;
+ struct udma_db db;
+ u8 container_flag;
+ u8 container_size;
+ u8 container_mode;
+ u8 counter_left;
+ u8 container_warn_th;
+ bool flush_flag;
+ bool index_queue_en;
+ u16 stop_index;
+ u16 container_counter;
+ udma_driver_rq_ctr_t udma_driver_rq_ctr;
+};
+
+struct udma_index_queue {
+ struct ubcore_umem *umem;
+ struct mtt ub_mtt;
+ u32 buf_size;
+ u32 max_depth;
+ u32 wqe_shift;
+};
+
+static inline void *ub_srq_buf_offset(void *va, int offset)
+{
+ return (void *)((char *)va + offset);
+}
+
+static inline void *ub_srq_get_wqe(struct udma_srq *srq, u32 n)
+{
+ return ub_srq_buf_offset(srq->srq_va,
+ (int)(n << (unsigned)srq->wqe_shift));
+}
+
+int udma_srq_init_attr(struct udma_device *udma_dev, struct udma_srq *srq,
+ u32 depth, u8 max_sge);
+int udma_index_queue_init_attr(struct udma_device *udma_dev,
+ struct udma_index_queue *index_queue, u32 depth);
+int udma_create_srqc_update(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct udma_db *sdb);
+int udma_delete_srqc_and_cache_out(struct udma_device *udma_dev,
+ struct udma_srq *srq);
+int udma_srq_init_res(struct udma_device *udma_dev, struct udma_srq *srq,
+ struct tag_cqm_queue *buf_info);
+void udma_free_srq_wqe(struct udma_srq *srq, u32 container_idx);
+int udma_modify_srq_threshold(struct udma_device *udma_dev,
+ struct udma_srq *srq, u8 container_warn_th);
+int udma_post_srq_wr(struct udma_device *udma_dev, struct udma_srq *srq,
+ const struct ubcore_jfr_wr *wr,
+ struct ubcore_jfr_wr **bad_wr);
+u16 udma_get_next_srq_wqe(struct udma_srq *srq, u16 cur_idx);
+
+int udma_srq_pre_post_wqe_check(struct udma_device *udma_dev,
+ const struct udma_srq *srq,
+ const struct ubcore_jfr_wr *wr);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.c b/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.c
new file mode 100644
index 000000000..d9ababf90
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.c
@@ -0,0 +1,1049 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <asm/io.h>
+#include <linux/vmalloc.h>
+
+#include "ubcore_types.h"
+#include "hinic5_cqm.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_mtt.h"
+#include "udma_jetty.h"
+#include "udma_cmd_com.h"
+#include "udma_cmd_jfrc.h"
+#include "udma_xid_cfg.h"
+#include "udma_resource.h"
+#include "udma_fast_msg.h"
+#include "udma_tpg.h"
+#include "udma_vtp.h"
+#include "udma_rc_table.h"
+
+#define UB_DMA_JETTY 0 //reserved xid 0
+#define UB_RC_QUEUE_CONTEXT_SIZE (512)
+
+//current temporarily not support dynamic configuration
+#define UB_MIN_RC_NUM 16
+#define UB_MID_RC_NUM 32
+#define MIN_SLICE_SIZE (32 * 1024)
+#define SLICE_EN_FAIL 0
+#define SLICE_EN_OK 1
+
+#define UB_MAX_CNT_SIZE_SHIFT 10 //1k granularity align
+
+/* compatible A5 use of urma tag */
+union udma_device_cfg_feature {
+ struct {
+ uint32_t taack_flush : 1; /* enable sending TAACK after data written into memory */
+ uint32_t inline_reduce : 1; /* enable inline reduce */
+ uint32_t npu_direct_urma : 1; /* enable NPU-direct URMA */
+ uint32_t bus_multipath : 1; /* enable multipath transport in bus */
+ uint32_t reserved : 28;
+ } bs;
+ uint32_t value;
+};
+
+static void
+udma_config_device_init_attr(struct udma_device *udma_dev,
+ const struct ub_cmd_func_attr *func_attr);
+
+static int udma_create_rc_queue_ctx(struct udma_rc_queue *udma_rcq,
+ struct udma_device *udma_dev, u32 rc_cnt)
+{
+ udma_rcq->cqm_priv_type = UDMA_JETTY_TYPE_RC;
+ udma_rcq->rc_ctx = cqm5_object_qpc_mpt_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_SERVICE_CTX,
+ UB_RC_QUEUE_CONTEXT_SIZE, udma_rcq,
+ CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE, CQM_XID_LOW_BIT_NONE,
+ 0),
+ 0, rc_cnt);
+ if (udma_rcq->rc_ctx == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "rc context memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+int udma_alloc_rcq_resource(struct udma_device *udma_dev,
+ cqm_queue_s **cqm_buf_info, void *object_priv,
+ u32 buf_len, struct queue_addr_info *queue_addr)
+{
+ u32 queue_len;
+ int ret;
+
+ *cqm_buf_info = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_QP, PAGE_SIZE,
+ object_priv, true, CQM_INDEX_INVALID, 0, 0);
+ if (*cqm_buf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "Failed to create queue by cqm object.\n");
+ return -ENOMEM;
+ }
+
+ queue_len = udma_cal_page_size(buf_len);
+ ret = hinic5_dma_zalloc_coherent_align(udma_dev->dev, queue_len,
+ queue_len, GFP_KERNEL,
+ &queue_addr->mem_align);
+ if (ret != 0) {
+ cqm5_object_delete(&(*cqm_buf_info)->object);
+ *cqm_buf_info = NULL;
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "Failed to alloc dma addr, ret = %d\n", ret);
+ return -ENOMEM;
+ }
+ udma_fill_kernel_queue_addr_info(queue_len, queue_addr);
+
+ return 0;
+}
+
+static int udma_create_rc_queue_buf_info(struct udma_rc_queue *udma_rcq,
+ struct udma_device *udma_dev,
+ u32 total_depth)
+{
+ u32 page_size;
+ u32 rcqe_size;
+ int ret = 0;
+
+ rcqe_size = UB_RC_QUEUE_WQEBB_SIZE * UB_PER_RCQE_WQEBB_NUM;
+ page_size = udma_cal_page_size(total_depth * rcqe_size);
+
+ udma_rcq->total_depth = total_depth < (page_size / rcqe_size) ?
+ (page_size / rcqe_size) :
+ ((u32)roundup_pow_of_two(total_depth));
+ udma_rcq->total_size = udma_rcq->total_depth * rcqe_size;
+ ret = udma_alloc_rcq_resource(udma_dev, &udma_rcq->rc_queue, udma_rcq,
+ udma_rcq->total_size,
+ &udma_rcq->queue_addr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "alloc queue resource failed, ret = %d\n", ret);
+ return ret;
+ }
+
+ udma_rcq->rcq_va = udma_rcq->queue_addr.va;
+ return ret;
+}
+
+int udma_free_rc_queue_resource(struct udma_device *udma_dev,
+ cqm_queue_s *cqm_buf_info,
+ struct queue_addr_info *queue_addr)
+{
+ hinic5_dma_free_coherent_align(udma_dev->dev, &queue_addr->mem_align);
+ if (cqm_buf_info != NULL) {
+ cqm5_object_delete(&cqm_buf_info->object);
+ }
+
+ return 0;
+}
+
+static int udma_create_rc_queue_pcqc_info(struct udma_rc_queue *udma_rcq,
+ struct udma_device *udma_dev)
+{
+ udma_rcq->pcqc = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_SCQ, 0, udma_rcq,
+ false, udma_rcq->rc_ctx->xid, 0, 0);
+ if (udma_rcq->pcqc == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "rc pcqc memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int udma_create_jfrc_context(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq)
+{
+ int ret;
+
+ ret = udma_alloc_opt_ubrc(udma_dev, &udma_rcq->rsp_depth,
+ &udma_rcq->ubrc, true);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "failed to alloc ubrc, ret(%d)\n", ret);
+ return ret;
+ }
+
+ ret = udma_cmd_jfrc_create_ctx(udma_dev, udma_rcq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "cmd jfrc create failed, ret(%d)\n", ret);
+ udma_free_opt_ubrc(udma_dev, &udma_rcq->rsp_depth,
+ &udma_rcq->ubrc);
+ }
+
+ return ret;
+}
+
+/**
+ * input @total_depth: RC queue of total depth
+ * input @index: struct udma_device in rc_queue member address of index
+ * input @rc_cnt: need created rc queue of count
+ */
+static int udma_create_one_rc_queue(struct udma_device *udma_dev,
+ u32 total_depth, int index, u32 rc_cnt)
+{
+ struct udma_rc_queue *udma_rcq = &udma_dev->rc_queue[index];
+ int ret;
+
+ /* udma_rcq in caller allocate memory when already ensure non- NULL, not again repeat check */
+ ret = udma_create_rc_queue_ctx(udma_rcq, udma_dev, rc_cnt);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = udma_create_rc_queue_buf_info(udma_rcq, udma_dev, total_depth);
+ if (ret != 0) {
+ goto err_queue_create;
+ }
+
+ (void)memset_s(udma_rcq->rcq_va,
+ (size_t)((unsigned)udma_rcq->total_size), 0,
+ (size_t)((unsigned)udma_rcq->total_size));
+ udma_rcq->rc_queue->q_header_vaddr->doorbell_record = 0;
+ udma_cmdq_rtt_statistic_init(&udma_rcq->cmdq_rtt);
+
+ ret = udma_fill_kernel_mtt(&udma_rcq->ub_mtt, udma_rcq->queue_addr.pa);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "Failed to init kernel mtt, ret = %d.\n", ret);
+ goto err_init_kernel_mtt;
+ }
+
+ ret = udma_create_rc_queue_pcqc_info(udma_rcq, udma_dev);
+ if (ret != 0) {
+ goto err_init_kernel_mtt;
+ }
+
+ ret = udma_create_jfrc_context(udma_dev, udma_rcq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "udma jfrc create failed, ret(%d)\n", ret);
+ goto err_create_cmdq;
+ }
+
+ udma_store_list(udma_dev, &udma_rcq->node,
+ &udma_dev->device_res->rc_list);
+ udma_info(udma_dev->dev, UDMA_M_JFRC,
+ "index(%d) depth(%u) rc_id(%u) pcqc_id(%u) success\n", index,
+ udma_rcq->total_depth, udma_rcq->rc_ctx->xid,
+ udma_rcq->pcqc->index);
+
+ return ret;
+
+err_create_cmdq:
+ cqm5_object_delete(&udma_rcq->pcqc->object);
+err_init_kernel_mtt:
+ udma_free_rc_queue_resource(udma_dev, udma_rcq->rc_queue,
+ &udma_rcq->queue_addr);
+ udma_rcq->rc_queue = NULL;
+err_queue_create:
+ cqm5_object_delete(&udma_rcq->rc_ctx->object);
+
+ return ret;
+}
+
+struct udma_rc_queue *udma_find_rcq(struct udma_device *udma_dev, u32 rcq_id)
+{
+ struct udma_rc_queue *rcq = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udma_dev->device_res->rc_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(rcq, &udma_dev->device_res->rc_list.node, node) {
+ if (rcq->rc_ctx->xid == rcq_id) {
+ mutex_unlock(lock);
+ return rcq;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static int udma_create_rcq_pre_check(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ /* if already create RC queue, then not again repeat create */
+ if (udma_dev->is_rc_queue_configured != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "rc queue has already configured\n");
+ return -EALREADY;
+ }
+
+ if (cfg->rc_cfg.rc_cnt >
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "ubcore rc_cnt(%u) excceeds max_rc(%u)\n",
+ cfg->rc_cfg.rc_cnt,
+ udma_dev->ub_cap.dev_cap_res.udma_res.max_jfrc_num);
+ return -EINVAL;
+ }
+
+ if (cfg->rc_cfg.depth >
+ udma_dev->ub_cap.dev_cap_res.udma_res.jfrc_depth) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "ubcore rc_depth(%u) excceeds max rc depth(%u)\n",
+ cfg->rc_cfg.depth,
+ udma_dev->ub_cap.dev_cap_res.udma_res.jfrc_depth);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int udma_jfrc_queue_free(struct udma_device *udma_dev,
+ struct udma_rc_queue *udma_rcq)
+{
+ int ret;
+
+ ret = udma_cmd_jfrc_delete_ctx(udma_dev, udma_rcq);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "rc queue delete cmd failed, rcq_id(%u), ret(%d)\n",
+ udma_rcq->rc_ctx->xid, ret);
+ return ret;
+ }
+
+ ret = udma_cmd_jfrc_cache_invalidate(udma_dev, udma_rcq);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFRC,
+ "rc queue cache invalidate cmd failed, rcq_id(%u), ret(%d)\n",
+ udma_rcq->rc_ctx->xid, ret);
+ return ret;
+ }
+
+ udma_free_opt_ubrc(udma_dev, &udma_rcq->rsp_depth, &udma_rcq->ubrc);
+ cqm5_object_delete(&udma_rcq->pcqc->object);
+ udma_free_rc_queue_resource(udma_dev, udma_rcq->rc_queue,
+ &udma_rcq->queue_addr);
+ udma_rcq->rc_queue = NULL;
+ cqm5_object_delete(&udma_rcq->rc_ctx->object);
+
+ return ret;
+}
+
+/**
+ * input @index: struct udma_device in rc_queue member address of index
+*/
+static int udma_delete_one_rc_queue(struct udma_device *udma_dev, int index)
+{
+ struct udma_rc_queue *udma_rcq = &udma_dev->rc_queue[index];
+
+ udma_delete_list(udma_dev, &udma_rcq->node,
+ &udma_dev->device_res->rc_list);
+
+ return udma_jfrc_queue_free(udma_dev, udma_rcq);
+}
+
+static int udma_set_rc_cnt(struct udma_device *udma_dev)
+{
+ u16 func_id = hinic5_global_func_id(udma_dev->hwdev);
+ struct ub_cmd_func_attr func_attr = { 0 };
+
+ if (udma_dev->ub_dev.attr.tp_maintainer == 1) {
+ udma_info(udma_dev->dev, UDMA_M_JFRC,
+ "tpf not support set rc cnt\n");
+ return 0;
+ }
+
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr1, rcq_cnt,
+ (u32)ilog2(udma_dev->rc_queue_cnt));
+ udma_info(udma_dev->dev, UDMA_M_JFRC,
+ "func_id:%u mask 0x%x,rcq_cnt:%u=ilog2(%u)", func_id,
+ func_attr.attr1_mask.bs.rcq_cnt, func_attr.attr1.rcq_cnt,
+ udma_dev->rc_queue_cnt);
+ return udma_set_func_attr(udma_dev, func_id, &func_attr);
+}
+
+static u32 udma_get_rc_cnt(u32 rc_cnt)
+{
+ return UB_MAX_RC_NUM;
+}
+
+int udma_create_rc_table(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ u32 cur_idx = 0, i;
+ int ret;
+
+ /* 1.mask check 2.tpf not reserved 0 1 and create rc */
+ if (cfg->mask.bs.rc_cnt == 0 || cfg->mask.bs.rc_depth == 0 ||
+ udma_dev->ub_dev.attr.tp_maintainer ||
+ cfg->rc_cfg.rc_cnt < UB_MIN_RC_NUM) {
+ /* not create RC, normal return, not affect outside layer function */
+ udma_info(
+ udma_dev->dev, UDMA_M_JFRC,
+ "mask rc_cnt(%u) or rc_depth(%u) = 0, or is tpf(%u), or rc_cnt(%u) < 4\n",
+ cfg->mask.bs.rc_cnt, cfg->mask.bs.rc_depth,
+ udma_dev->ub_dev.attr.tp_maintainer,
+ cfg->rc_cfg.rc_cnt);
+ return 0;
+ }
+ mutex_lock(&udma_dev->dev_mutex);
+ ret = udma_create_rcq_pre_check(udma_dev, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "create rc table pre check failed\n");
+ goto end;
+ }
+
+ udma_dev->rc_queue_cnt = udma_get_rc_cnt(cfg->rc_cfg.rc_cnt);
+ udma_dev->rc_queue = (struct udma_rc_queue *)devm_kzalloc(
+ udma_dev->dev,
+ sizeof(struct udma_rc_queue) * udma_dev->rc_queue_cnt,
+ GFP_KERNEL);
+ if (udma_dev->rc_queue == NULL) {
+ ret = -ENOMEM;
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "create rc table: memory allocation failed\n");
+ goto end;
+ }
+
+ for (cur_idx = 0; cur_idx < udma_dev->rc_queue_cnt; cur_idx++) {
+ ret = udma_create_one_rc_queue(udma_dev, cfg->rc_cfg.depth,
+ (int)cur_idx,
+ udma_dev->rc_queue_cnt);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFRC,
+ "udma_create_one_rc_table iteration(%u) failed\n",
+ cur_idx);
+ goto err_udma_create_one_rc_queue;
+ }
+ }
+ ret = udma_set_rc_cnt(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC, "set rc cnt failed\n");
+ goto err_udma_create_one_rc_queue;
+ }
+ udma_dev->is_rc_queue_configured = true;
+ udma_info(udma_dev->dev, UDMA_M_JFRC, "create rc table success\n");
+ goto end;
+
+err_udma_create_one_rc_queue:
+ /* free already allocate of rc resource */
+ for (i = 0; i < cur_idx; ++i) {
+ if (udma_delete_one_rc_queue(udma_dev, (int)i) != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "delete one rc queue failed\n");
+ }
+
+ udma_dev->rc_queue_cnt = 0;
+ udma_dev->is_rc_queue_configured = false;
+
+ devm_kfree(udma_dev->dev, udma_dev->rc_queue);
+ udma_dev->rc_queue = NULL;
+
+end:
+ mutex_unlock(&udma_dev->dev_mutex);
+
+ return ret;
+}
+
+static int udma_set_suspend_para(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "cfg_suspend_period %x, cfg_suspend_cnt %x, cfg_mask %x.\n",
+ cfg->suspend_period, cfg->suspend_cnt, cfg->mask.value);
+
+ if (cfg->mask.bs.suspend_period == 0 || cfg->mask.bs.suspend_cnt == 0) {
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "mask %x, suspend_period or suspend_cnt is zero.\n",
+ cfg->mask.value);
+ return 0;
+ }
+
+ if (cfg->suspend_period == 0 || cfg->suspend_cnt == 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "suspend_period %x, suspend_cnt %x.\n",
+ cfg->suspend_period, cfg->suspend_cnt);
+ return -EINVAL;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "suspend_period %x, suspend_cnt %x.\n", cfg->suspend_period,
+ cfg->suspend_cnt);
+
+ udma_dev->suspend_period = cfg->suspend_period;
+ udma_dev->suspend_cnt = cfg->suspend_cnt;
+
+ return 0;
+}
+
+static int udma_set_plug_attach_en(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg,
+ bool res_clear)
+{
+ union ubcore_device_cfg_mask mask = cfg->mask;
+ void *hwdev = udma_dev->hwdev;
+ u8 attach_en;
+ int ret;
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_MAIN,
+ "start to set attach_en flag, func_id:%u, mask:%u, clear:%u\n",
+ adapted_ue_idx(cfg), mask.value, (u8)res_clear);
+
+ if (!hinic5_is_master_host(hwdev)) {
+ udma_debug(udma_dev->dev, UDMA_M_MAIN,
+ "no need to set attach_en flag\n");
+ return 0;
+ }
+
+ if (res_clear) {
+ attach_en = 0;
+ if (UDMA_IS_MIG_VFID(adapted_ue_idx(cfg))) {
+ udma_vf_migrate_end_proc(
+ udma_dev,
+ adapted_ue_idx(
+ cfg)); //vport delete scenario, force cleanup live migration vtp buffer
+ }
+ } else if ((mask.bs.pattern | mask.bs.virtualization |
+ mask.bs.min_jetty_cnt | mask.bs.max_jetty_cnt |
+ mask.bs.min_jfr_cnt | mask.bs.max_jfr_cnt) == 1) {
+ attach_en = 1;
+ } else {
+ udma_debug(udma_dev->dev, UDMA_M_MAIN,
+ "no need to set attach_en flag\n");
+ return 0;
+ }
+
+ ret = hisdk5_set_plug_srv_bitmap(hwdev, COMM_PLUG_SRV_UB,
+ adapted_ue_idx(cfg), attach_en);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "set plug service bitmap failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_MAIN,
+ "set plug service bitmap success, attach_en:%u\n", attach_en);
+ return 0;
+}
+
+static int udma_fill_func_attr(struct udma_device *udma_dev,
+ struct ubcore_device_cfg *cfg,
+ struct ub_cmd_func_attr *func_attr,
+ bool res_clear)
+{
+ int ret = 0;
+ u8 cos = 0;
+ u32 slice = UB_SLICE_NUM64K;
+ u32 pattern = (cfg->pattern == UBCORE_PATTERN_3) ? PATTERN_TYPE_3 :
+ PATTERN_TYPE_1;
+ u32 fast_path_timer_disable = (adapted_ue_idx(cfg) < PF_MAX_NUM) ?
+ g_udma_fast_path_timer_disable :
+ 0;
+ union udma_device_cfg_feature feature = { 0 };
+
+ if (cfg->mask.bs.slice == 1) {
+ if (udma_dev->slice_cfg_en == SLICE_EN_OK &&
+ cfg->slice == UB_SLICE_NUM128K) {
+ slice = cfg->slice;
+ }
+ slice = (u32)ilog2(slice / MIN_SLICE_SIZE);
+ if (res_clear == false) {
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr1,
+ slice, slice);
+ udma_debug(udma_dev->dev, UDMA_M_RC_TABLE,
+ "func_attr->slice:%u\n",
+ func_attr->attr1.slice);
+ }
+ }
+ if (cfg->mask.bs.virtualization == 1) {
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(
+ func_attr, attr1, virtualization, cfg->virtualization);
+ }
+ if (cfg->mask.bs.pattern == 1) {
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr1,
+ pattern_type, pattern);
+ }
+ if (cfg->mask.bs.ta2tp_sched_alg == 1) {
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(
+ func_attr, attr2, ta2tp_type, cfg->ta2tp_sched_alg);
+ }
+
+ if (cfg->mask.bs.feature == 1) {
+ feature.value = cfg->feature.value;
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr2,
+ taack_flush_en,
+ feature.bs.taack_flush);
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr2, reduce_en,
+ feature.bs.inline_reduce);
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr2,
+ bus_multi_path_en,
+ feature.bs.bus_multipath);
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr2, hbm_en,
+ feature.bs.npu_direct_urma);
+ }
+
+ if (cfg->mask.bs.dscp == 1) {
+ ret = udma_get_cos_by_pri(udma_dev, (u8)cfg->dscp, &cos);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RC_TABLE,
+ "Failed to get cos from dcb info, ret=%d, dscp:%u\n",
+ ret, cfg->dscp);
+ return ret;
+ }
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr2, func_cos,
+ cos);
+ udma_debug(udma_dev->dev, UDMA_M_RC_TABLE,
+ "func_attr->func_cos:%d\n",
+ func_attr->attr2.func_cos);
+ }
+
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK_PTR(func_attr, attr1,
+ fast_path_timer_disable,
+ fast_path_timer_disable);
+
+ return 0;
+}
+
+static int udma_set_func_table(struct udma_device *udma_dev,
+ struct ubcore_device_cfg *cfg, bool res_clear)
+{
+ struct udma_device *udma_dev_update = NULL;
+ struct ub_cmd_func_attr func_attr = { 0 };
+ int ret = 0;
+
+ ret = udma_fill_func_attr(udma_dev, cfg, &func_attr, res_clear);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "fill func attr failed\n");
+ return ret;
+ }
+
+ ret = udma_set_func_attr(udma_dev, adapted_ue_idx(cfg), &func_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "mpu set func table failed\n");
+ return ret;
+ }
+
+ udma_dev_update =
+ udma_find_dev_by_fe_idx(udma_dev, adapted_ue_idx(cfg));
+ if (udma_dev_update != NULL) {
+ /* config dev configured fe and tpf is in same a host on, update this fe dev attribute */
+ udma_config_device_init_attr(udma_dev_update, &func_attr);
+ }
+
+ return 0;
+}
+
+static int udma_check_nic_plug_attach_en(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ u8 attach_en = 0;
+ int ret;
+
+ u16 ue_idx = adapted_ue_idx(cfg);
+ if ((ue_idx < PF_MAX_NUM) || (ue_idx >= UB_VF_NUM_MAX)) {
+ udma_debug(udma_dev->dev, UDMA_M_MAIN, "func %d is not ub vf\n",
+ ue_idx);
+ return 0;
+ }
+
+ if (!hinic5_is_master_host(udma_dev->hwdev)) {
+ udma_debug(udma_dev->dev, UDMA_M_MAIN,
+ "no need to get attach_en flag\n");
+ return 0;
+ }
+
+ /* prevent呆, check nic whether be ovs enable, use nic of srv type */
+ ret = hisdk5_get_plug_srv_bitmap(udma_dev->hwdev, COMM_PLUG_SRV_NIC,
+ ue_idx, &attach_en);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "get plug srv bitmap failed, ret:%d\n", ret);
+ return ret;
+ }
+
+ if (attach_en == 0) {
+ udma_err(udma_dev->dev, UDMA_M_MAIN,
+ "attach_en: %d flag is invalid.\n", attach_en);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int udma_set_func_cfg(struct udma_device *udma_dev,
+ struct ubcore_device_cfg *cfg, bool res_clear)
+{
+ int ret = 0;
+
+ /* same step 1823 DTS2024122616167 problem single */
+ ret = udma_check_nic_plug_attach_en(udma_dev, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "get plug srv bitmap failed, ret: %d, func id:%d\n",
+ ret, adapted_ue_idx(cfg));
+ return ret;
+ }
+
+ ret = udma_set_func_table(udma_dev, cfg, res_clear);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "set func table failed\n");
+ return ret;
+ }
+
+ ret = udma_vm_glb_xid_cfg_set(udma_dev, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "vm global xid cfg set failed\n");
+ return ret;
+ }
+
+ ret = udma_set_plug_attach_en(udma_dev, cfg, res_clear);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+udma_config_device_init_attr(struct udma_device *udma_dev,
+ const struct ub_cmd_func_attr *func_attr)
+{
+ if (func_attr->attr1_mask.bs.virtualization != 0)
+ udma_dev->ub_cap.dev_cap.virtualization =
+ func_attr->attr1.virtualization;
+
+ if (func_attr->attr1_mask.bs.slice != 0) {
+ udma_dev->slice = func_attr->attr1.slice;
+ }
+
+ if (func_attr->attr1_mask.bs.pattern_type != 0) {
+ udma_dev->ub_cap.dev_cap.pattern_type =
+ func_attr->attr1.pattern_type;
+ udma_dev->ub_dev.cfg.pattern =
+ (udma_dev->ub_cap.dev_cap.pattern_type ==
+ PATTERN_TYPE_3) ?
+ UBCORE_PATTERN_3 :
+ UBCORE_PATTERN_1;
+ udma_dev->ub_dev.attr.pattern = udma_dev->ub_dev.cfg.pattern;
+ }
+
+ if (func_attr->attr2_mask.bs.func_cos != 0) {
+ udma_dev->default_cos.func_cos = func_attr->attr2.func_cos;
+ }
+
+ if (func_attr->attr2_mask.bs.bus_multi_path_en != 0) {
+ udma_dev->ub_cap.dev_cap.dcs_en =
+ func_attr->attr2.bus_multi_path_en;
+ }
+
+ if (func_attr->attr2_mask.bs.hbm_en != 0 &&
+ udma_dev->ub_cap.dev_cap.hbm_en != func_attr->attr2.hbm_en) {
+ udma_dev->ub_cap.dev_cap.hbm_en = func_attr->attr2.hbm_en;
+ udma_dev->ub_cap.dev_cap.dcs_en = func_attr->attr2.hbm_en;
+ }
+}
+
+static int udma_cfg_max_cnt_check(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg)
+{
+ /* passed in of max_jetty_cnt need is 1k of multiple data */
+ if (cfg->mask.bs.max_jetty_cnt == 1 &&
+ ((cfg->max_jetty_cnt & ((1U << UB_MAX_CNT_SIZE_SHIFT) - 1)) != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RC_TABLE,
+ "max_jetty_cnt should be a multiple of 1k. cur_value: %d.\n",
+ cfg->max_jetty_cnt);
+ return -EINVAL;
+ }
+ if (cfg->mask.bs.max_jfr_cnt == 1 &&
+ ((cfg->max_jfr_cnt & ((1U << UB_MAX_CNT_SIZE_SHIFT) - 1)) != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RC_TABLE,
+ "max_jfr_cnt should be a multiple of 1k. cur_value: %d.\n",
+ cfg->max_jfr_cnt);
+ return -EINVAL;
+ }
+ return EOK;
+}
+
+int udma_config_device(struct ubcore_device *ub_dev,
+ struct ubcore_device_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ bool res_clear = false;
+ int ret;
+
+ if (ub_dev == NULL || cfg == NULL) {
+ udma_pr_err(
+ UDMA_M_RC_TABLE,
+ "%s: parameters is incorrect, ub_dev(%d), cfg(%d).\n",
+ __func__, !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_cfg_max_cnt_check(udma_dev, cfg) != EOK) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "input cfg, max_cnt check failed!\n");
+ return -EINVAL;
+ }
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE,
+ "slice: %u virtualization:%u pattern:%u mask:%u\n",
+ cfg->slice, cfg->virtualization, cfg->pattern,
+ cfg->mask.value);
+
+ ret = udma_create_rc_table(udma_dev, cfg);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = udma_set_suspend_para(udma_dev, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "tp suspend para set failed\n");
+ goto err_xid_cfg_set;
+ }
+
+ if (udma_dev->ub_dev.attr.virtualization) {
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE,
+ "virtualization is 1, return 0\n");
+ return 0;
+ }
+
+ if (cfg->mask.bs.max_jetty_cnt == 1 && cfg->max_jetty_cnt == 0) {
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE,
+ "virtual clear filter resource\n");
+ res_clear = true;
+ }
+
+ /* inline_reduce of enable depend npu_direct_urma of enable */
+ if (cfg->feature.bs.inline_reduce == 1 &&
+ cfg->feature.bs.npu_direct_urma == 0) {
+ udma_warn(
+ udma_dev->dev, UDMA_M_RC_TABLE,
+ "inline reduce enable invalid, as npu_direct_urma disable!\n");
+ }
+
+ ret = udma_set_func_cfg(udma_dev, cfg, res_clear);
+ if (ret != 0) {
+ goto err_xid_cfg_set;
+ }
+
+ /* create reserved TP lock store of TPG */
+ ret = udma_create_tp_latch_tpg(udma_dev);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "TP latch create fail ret=%d.\n", ret);
+ }
+
+ return ret;
+
+err_xid_cfg_set:
+ if (cfg->mask.bs.rc_cnt != 0 && cfg->mask.bs.rc_depth != 0)
+ udma_delete_rc_table(udma_dev);
+
+ return ret;
+}
+
+void udma_delete_rc_table(struct udma_device *udma_dev)
+{
+ u32 i;
+
+ /* tpf did not create RC */
+ if (udma_dev->ub_dev.attr.tp_maintainer) {
+ return;
+ }
+
+ if (udma_dev->is_rc_queue_configured == 0 ||
+ udma_dev->rc_queue_cnt == 0 || udma_dev->rc_queue == NULL) {
+ udma_warn(udma_dev->dev, UDMA_M_RC_TABLE,
+ "no rc queue to delete\n");
+ return;
+ }
+
+ for (i = 0; i < udma_dev->rc_queue_cnt; ++i) {
+ if (udma_delete_one_rc_queue(udma_dev, (int)i) != 0)
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "delete one rc queue failed\n");
+ }
+
+ udma_dev->rc_queue_cnt = 0;
+ udma_dev->is_rc_queue_configured = false;
+
+ devm_kfree(udma_dev->dev, udma_dev->rc_queue);
+ udma_dev->rc_queue = NULL;
+
+ udma_info(udma_dev->dev, UDMA_M_RC_TABLE, "delete rc table success\n");
+}
+
+/**
+ * func: dfx tool from cache query target rc_id of rc queue of rc context
+ * input @rc_id: NA
+ * input @outbuf_size: NA
+ * output @outbuf: stores queried rc context content
+*/
+int udma_query_rc_queue_ctx_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf,
+ u32 outbuf_size)
+{
+ return udma_cmd_jfrc_query_qpc_ctx(udma_dev, rc_id, outbuf);
+}
+
+/**
+ * func: dfx tool from host memory query target rc_id of rc queue of rc context
+ * input @rc_id: NA
+ * input @outbuf_size: NA
+ * output @outbuf: stores queried rc context content
+*/
+int udma_query_rc_queue_ctx_from_host(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf,
+ u32 outbuf_size)
+{
+ struct tag_cqm_qpc_mpt *rcq_ctx = NULL;
+ struct tag_cqm_object *cqm_obj = NULL;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ rc_id, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "failed to get cqm object, rc_id(%u)\n", rc_id);
+ return -EINVAL;
+ }
+
+ rcq_ctx = container_of(cqm_obj, struct tag_cqm_qpc_mpt, object);
+
+ memcpy_fromio((void *)outbuf, (void *)rcq_ctx->vaddr, outbuf_size);
+
+ udma_info(udma_dev->dev, UDMA_M_JFRC, "success, rc_id(%u)\n", rc_id);
+
+ cqm5_object_put(cqm_obj);
+
+ return 0;
+}
+
+/**
+ * func: dfx tool from cache query target rc_id of rc queue of pcqc content
+ * input @rc_id: NA
+ * input @outbuf_size: NA
+ * output @outbuf: stores queried rc queue pcqc content
+*/
+int udma_query_rc_queue_pcqc_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf,
+ u32 outbuf_size)
+{
+ return udma_cmd_jfrc_query_pcqc_ctx(udma_dev, rc_id, outbuf);
+}
+
+/**
+ * func: dfx tool from host memory query target rc_id of rc queue of pcqc content
+ * input @rc_id: NA
+ * input @outbuf_size: NA
+ * output @outbuf: stores queried rc queue pcqc content
+*/
+int udma_query_rc_queue_pcqc_from_host(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf,
+ u32 outbuf_size)
+{
+ struct tag_cqm_queue *pcqc = NULL;
+ struct tag_cqm_object *cqm_obj = NULL;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_RDMA_SCQ, rc_id,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "failed to get cqm object, rc_id(%u)\n", rc_id);
+ return -EINVAL;
+ }
+
+ pcqc = container_of(cqm_obj, struct tag_cqm_queue, object);
+
+ memcpy_fromio((void *)outbuf, pcqc->q_ctx_vaddr, outbuf_size);
+
+ udma_info(udma_dev->dev, UDMA_M_JFRC, "success, rc_id(%u)\n", rc_id);
+
+ cqm5_object_put(cqm_obj);
+
+ return 0;
+}
+
+/**
+ * func: dfx tool from cache query target rc_id of rc table ci index of command content
+ * input @rc_id: NA
+ * input @ci: target consumer index
+ * input @outbuf_size: NA
+ * output @outbuf: NA
+*/
+int udma_query_rc_queue_wqe_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ u32 ci, struct ub_rc_queue_wqe *outbuf,
+ u32 outbuf_size)
+{
+ return udma_cmd_jfrc_query_wqe(udma_dev, rc_id, ci, outbuf);
+}
+
+static inline struct udma_rc_queue *
+cqmobj_to_ub_rc_queue(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *rcq_ctx = NULL;
+ rcq_ctx = container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_rc_queue *)rcq_ctx->priv;
+}
+
+/**
+ * func: dfx tool from host query target rc_id of rc table ci index of command content
+ * input @rc_id: NA
+ * input @ci: target consumer index
+ * input @outbuf_size: NA
+ * output @outbuf: NA
+*/
+int udma_query_rc_queue_wqe_from_host(struct udma_device *udma_dev, u32 rc_id,
+ u32 ci, struct ub_rc_queue_wqe *outbuf,
+ u32 outbuf_size)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_rc_queue *udma_rcq = NULL;
+ u64 rcqe_offset; // target ci of address offset
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ rc_id, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "failed to get cqm object, rc_id(%u)\n", rc_id);
+ return -EINVAL;
+ }
+
+ udma_rcq = cqmobj_to_ub_rc_queue(cqm_obj);
+ if (udma_rcq->cqm_priv_type != UDMA_JETTY_TYPE_RC) {
+ udma_err(udma_dev->dev, UDMA_M_JFRC,
+ "cqmobj is not rc, rc_id(%u), type(%u)\n", rc_id,
+ udma_rcq->cqm_priv_type);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ if (ci >= udma_rcq->total_depth) {
+ udma_err(
+ udma_dev->dev, UDMA_M_JFRC,
+ "ci exceeds the maximum depth, rc_id(%u) ci(%u) total_depth(%u)\n",
+ rc_id, ci, udma_rcq->total_depth);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ rcqe_offset = ci * outbuf_size;
+ memcpy_fromio((void *)outbuf, udma_rcq->rcq_va + rcqe_offset,
+ outbuf_size);
+
+ udma_info(udma_dev->dev, UDMA_M_JFRC, "success, rc_id(%u) ci(%u)\n",
+ rc_id, ci);
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.h b/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.h
new file mode 100644
index 000000000..9551b8d90
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/rc_table/udma_rc_table.h
@@ -0,0 +1,46 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef _UDMA_RC_TABLE_H
+#define _UDMA_RC_TABLE_H
+
+#include <linux/mutex.h>
+#include "ubcore_api.h"
+#include "ub_npu_jfrc_cmd_defs.h"
+#include "ub_npu_jetty_cmd_defs.h"
+#include "hmm_common.h"
+#include "hinic5_cqm.h"
+#include "udma_common.h"
+
+#define UB_SLICE_NUM64K 65536
+#define UB_SLICE_NUM128K 131072
+enum { PATTERN_TYPE_1 = 0x0, PATTERN_TYPE_2 = 0x1, PATTERN_TYPE_3 = 0x2 };
+
+extern u32 g_udma_fast_path_timer_disable;
+
+int udma_config_device(struct ubcore_device *ub_dev,
+ struct ubcore_device_cfg *cfg);
+int udma_create_rc_table(struct udma_device *udma_dev,
+ const struct ubcore_device_cfg *cfg);
+void udma_delete_rc_table(struct udma_device *udma_dev);
+int udma_query_rc_queue_ctx_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf,
+ u32 outbuf_size);
+int udma_query_rc_queue_ctx_from_host(struct udma_device *udma_dev, u32 rc_id,
+ struct ub_ta_context_query *outbuf,
+ u32 outbuf_size);
+int udma_query_rc_queue_pcqc_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf,
+ u32 outbuf_size);
+int udma_query_rc_queue_pcqc_from_host(struct udma_device *udma_dev, u32 rc_id,
+ ub_pcqc_query_rsp_s *outbuf,
+ u32 outbuf_size);
+int udma_query_rc_queue_wqe_from_cache(struct udma_device *udma_dev, u32 rc_id,
+ u32 ci, struct ub_rc_queue_wqe *outbuf,
+ u32 outbuf_size);
+int udma_query_rc_queue_wqe_from_host(struct udma_device *udma_dev, u32 rc_id,
+ u32 ci, struct ub_rc_queue_wqe *outbuf,
+ u32 outbuf_size);
+struct udma_rc_queue *udma_find_rcq(struct udma_device *udma_dev, u32 rcq_id);
+#endif /* _UDMA_RC_TABLE_H */
\ No newline at end of file
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.c b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.c
new file mode 100644
index 000000000..8e9b63ace
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.c
@@ -0,0 +1,73 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+#include "udma_key.h"
+
+struct ubcore_token_id *udma_alloc_key_id(struct ubcore_device *ub_dev,
+ union ubcore_token_id_flag flag,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_keyid *udma_key = NULL;
+ int ret;
+
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_KEY, "Invalid parameter: ub_dev is null.\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ udma_key = (struct udma_keyid *)kzalloc(sizeof(struct udma_keyid),
+ GFP_KERNEL);
+ if (udma_key == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_KEY,
+ "allocate key id memory failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ mutex_init(&udma_key->mpt_mutex);
+
+ ret = hmm_mpt_alloc(udma_dev->hwdev, &udma_key->mpt, SERVICE_T_UB);
+ if (ret != 0) {
+ kfree(udma_key);
+ udma_err(udma_dev->dev, UDMA_M_KEY,
+ "create key id mpt failed, ret:%d\n", ret);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ udma_key->base.ub_dev = ub_dev;
+ udma_key->base.uctx = udma_get_uctx(udata);
+ udma_key->base.token_id = udma_key->mpt.mpt_index;
+
+ udma_debug(udma_dev->dev, UDMA_M_KEY, "allocate key id:%u success.\n",
+ udma_key->base.token_id);
+
+ return &udma_key->base;
+}
+
+int udma_free_key_id(struct ubcore_token_id *token_id)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_keyid *udma_key = NULL;
+ u32 id;
+
+ if ((token_id == NULL) || (token_id->ub_dev == NULL)) {
+ udma_pr_err(UDMA_M_KEY, "Invalid parameter: token_id(%d).\n",
+ !!token_id);
+ return -EINVAL;
+ }
+
+ id = token_id->token_id;
+ udma_dev = to_udma_dev(token_id->ub_dev);
+ udma_key = to_udma_keyid(token_id);
+ mutex_lock(&udma_key->mpt_mutex);
+ hmm_mpt_free(udma_dev->hwdev, &udma_key->mpt);
+ mutex_unlock(&udma_key->mpt_mutex);
+ kfree(udma_key);
+
+ udma_info(udma_dev->dev, UDMA_M_KEY, "free key id:%u success.\n", id);
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.h b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.h
new file mode 100644
index 000000000..fcdb3cd18
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_key.h
@@ -0,0 +1,29 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_KEY_H
+#define UDMA_KEY_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+typedef struct udma_keyid {
+ struct ubcore_token_id base;
+ struct mpt mpt;
+ struct mutex mpt_mutex;
+} udma_keyid_t;
+
+struct ubcore_token_id *udma_alloc_key_id(struct ubcore_device *ub_dev,
+ union ubcore_token_id_flag flag,
+ struct ubcore_udata *udata);
+int udma_free_key_id(struct ubcore_token_id *token_id);
+
+static inline struct udma_keyid *
+to_udma_keyid(const struct ubcore_token_id *key_id)
+{
+ return (struct udma_keyid *)udma_container_of(key_id, struct udma_keyid,
+ base);
+}
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.c b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.c
new file mode 100644
index 000000000..23d7719ec
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.c
@@ -0,0 +1,788 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#include <linux/device.h>
+#include <linux/iommu.h>
+#include <linux/version.h>
+#include <linux/vmstat.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_mtt.h"
+#include "udma_key.h"
+#include "udma_misc.h"
+#include "udma_ucontext.h"
+#include "comm_defs.h"
+#include "udma_jetty.h"
+#include "udma_shm_manage.h"
+#include "udma_cmd_segment.h"
+#include "ubcnet_mpu_cmd.h"
+#include "ubcnet_mpu_cmd_defs.h"
+#include "udma_segment.h"
+
+static inline int udma_get_seg_umem(struct ubcore_device *ub_dev,
+ const struct ubcore_seg_cfg *cfg,
+ struct udma_segment *udma_seg)
+{
+ union ubcore_umem_flag umem_flag = {};
+
+ umem_flag.bs.non_pin = cfg->flag.bs.non_pin;
+ umem_flag.bs.writable = 1;
+ udma_seg->umem = ubcore_umem_get(ub_dev, cfg->va, cfg->len, umem_flag);
+
+ if (IS_ERR_OR_NULL(udma_seg->umem)) {
+ udma_pr_err(
+ UDMA_M_SEG,
+ "Failed to get umem, get umem ptr err or zero ret:%d\n",
+ (int)PTR_ERR_OR_ZERO(udma_seg->umem));
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static inline u32 udma_get_umem_page_count(const struct ubcore_umem *umem,
+ u32 os_page_size)
+{
+ return (u32)((ALIGN(umem->va + umem->length, os_page_size) -
+ ALIGN_DOWN(umem->va, os_page_size)) /
+ os_page_size);
+}
+
+static inline u32 udma_get_key_from_index(u32 mpt_index)
+{
+ return (mpt_index >> SEG_KEY_RIGHT_SHIFT_OFS) |
+ (mpt_index << SEG_KEY_LEFT_SHIFT_OFS);
+}
+
+static void udma_fill_udma_seg(struct udma_segment *udma_seg,
+ const struct ubcore_seg_cfg *cfg,
+ struct udma_keyid *udma_key)
+{
+ udma_seg->va = cfg->va;
+ udma_seg->size = cfg->len;
+ udma_seg->access = cfg->flag.bs.access;
+ udma_seg->key = udma_get_key_from_index(
+ udma_key->mpt.mpt_index); /* by mpt index convert to key */
+ udma_seg->key_type = cfg->flag.bs.token_policy;
+ udma_seg->token_value = cfg->token_value.token;
+ udma_seg->mpt = &udma_key->mpt;
+}
+
+static void udma_seg_kref_release(struct kref *ref_cnt)
+{
+ struct udma_segment *seg =
+ container_of(ref_cnt, struct udma_segment, ref_cnt);
+
+ complete(&seg->comp);
+}
+
+void udma_seg_put(void *obj)
+{
+ struct udma_segment *seg = obj;
+
+ if (seg != NULL) {
+ kref_put(&seg->ref_cnt, udma_seg_kref_release);
+ }
+}
+
+void udma_seg_get(void *obj)
+{
+ struct udma_segment *seg = obj;
+
+ kref_get(&seg->ref_cnt);
+}
+
+struct udma_segment *udma_seg_find(struct udma_device *udma_dev, u32 key_id)
+{
+ struct udma_segment *udma_seg = NULL;
+
+ mutex_lock(&udma_dev->device_res->seg_list.node_lock);
+ list_for_each_entry(udma_seg, &udma_dev->device_res->seg_list.node,
+ node) {
+ if (udma_seg->mpt->mpt_index == key_id) {
+ udma_seg_get(udma_seg);
+ mutex_unlock(&udma_dev->device_res->seg_list.node_lock);
+ return udma_seg;
+ }
+ }
+ mutex_unlock(&udma_dev->device_res->seg_list.node_lock);
+
+ return NULL;
+}
+
+int udma_alloc_david_fe(struct udma_device *udma_dev, u32 eid_d, u32 tid_d)
+{
+ ubcnet_mpu_cmd_tid_fe_op_s cmd = { 0 };
+ u16 cmd_size = sizeof(cmd);
+ int ret;
+
+ cmd.op_type = UBCNET_TBL_ADD;
+ cmd.ctrl_fe = hinic5_global_func_id(udma_dev->hwdev);
+ cmd.deid = eid_d;
+ cmd.tokenid = tid_d;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UBCNET,
+ UBCNET_MPU_CMD_RDMA_TID_FE_OP, &cmd,
+ sizeof(cmd), &cmd, &cmd_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_size == 0) || (cmd.msg_head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to alloc david fe, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, cmd.msg_head.status, cmd_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_free_david_fe(struct udma_device *udma_dev, u32 eid_d, u32 tid_d)
+{
+ ubcnet_mpu_cmd_tid_fe_op_s cmd = { 0 };
+ u16 cmd_size = sizeof(cmd);
+ int ret;
+
+ cmd.op_type = UBCNET_TBL_DEL;
+ cmd.ctrl_fe = hinic5_global_func_id(udma_dev->hwdev);
+ cmd.deid = eid_d;
+ cmd.tokenid = tid_d;
+
+ ret = hinic5_msg_to_mgmt_sync(udma_dev->hwdev, HINIC5_MOD_UBCNET,
+ UBCNET_MPU_CMD_RDMA_TID_FE_OP, &cmd,
+ sizeof(cmd), &cmd, &cmd_size, 0,
+ HINIC5_CHANNEL_UB);
+ if ((ret != 0) || (cmd_size == 0) || (cmd.msg_head.status != 0)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_RESOURCE,
+ "Failed to free david fe, err(%d), status(0x%x), out_size(0x%x) .\n",
+ ret, cmd.msg_head.status, cmd_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_david_info_init(struct udma_device *udma_dev,
+ const struct ubcore_seg_cfg *cfg,
+ struct udma_segment *udma_seg)
+{
+ struct mem_uva uva = { 0 };
+ union acquire_attr attr = { 0 };
+ int ret;
+
+ uva.va = cfg->va;
+ uva.size = cfg->len;
+ attr.bs.require_pin = 1;
+
+ //debug debug, remove later
+ if (udma_dev->sysfs_res.dfx_ctx.hbm_en == 1) {
+ udma_seg->uba.eid.eid = udma_dev->sysfs_res.dfx_ctx.eid;
+ udma_seg->uba.token_id = udma_dev->sysfs_res.dfx_ctx.tid;
+ goto david_fe_alloc;
+ }
+
+ ret = udma_ubdevshm_acquire_uba(&udma_seg->ctx, &uva, &attr, NULL,
+ &udma_seg->uba);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to acquire uba, ret:%d\n", ret);
+ return ret;
+ }
+
+david_fe_alloc:
+ ret = udma_alloc_david_fe(udma_dev, udma_seg->uba.eid.eid,
+ udma_seg->uba.token_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to alloc david fe, ret:%d\n", ret);
+ goto david_fe_alloc_fail;
+ }
+
+ udma_seg->david_hbm_en = true;
+ return 0;
+
+david_fe_alloc_fail:
+ //debug debug, remove later
+ if (udma_dev->sysfs_res.dfx_ctx.hbm_en == 1) {
+ return 0;
+ }
+
+ if (udma_ubdevshm_release_uba(&udma_seg->ctx, &udma_seg->uba) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG, "failed to release uba\n");
+ }
+
+ return ret;
+}
+
+int udma_david_info_uninit(struct udma_device *udma_dev,
+ struct udma_segment *udma_seg)
+{
+ int ret;
+
+ ret = udma_free_david_fe(udma_dev, udma_seg->uba.eid.eid,
+ udma_seg->uba.token_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to release fe, ret:%d\n", ret);
+ return ret;
+ }
+
+ //debug debug, remove later
+ if (udma_dev->sysfs_res.dfx_ctx.hbm_en == 1) {
+ return 0;
+ }
+
+ ret = udma_ubdevshm_release_uba(&udma_seg->ctx, &udma_seg->uba);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to release uba, ret:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_register_seg_user(struct ubcore_device *ub_dev,
+ const struct ubcore_seg_cfg *cfg,
+ struct udma_segment *udma_seg)
+{
+ struct udma_device *udma_dev = NULL;
+ u32 os_page_size = PAGE_SIZE;
+ u32 os_page_shift = PAGE_SHIFT;
+ u32 npages;
+ int ret;
+
+ if ((ub_dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_SEG,
+ "Invalid parameter: ub_dev(%d), cfg(%d).\n",
+ !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_SEG, "to_udma_dev failed.\n");
+ return -EINVAL;
+ }
+
+ ret = udma_get_seg_umem(ub_dev, cfg, udma_seg);
+ if (ret != 0) {
+ udma_warn(udma_dev->dev, UDMA_M_SEG,
+ "failed to get seg umem, ret:%d\n", ret);
+ return udma_david_info_init(udma_dev, cfg, udma_seg);
+ }
+
+ if (udma_sysfs_get_huge_page_en(&udma_dev->sysfs_res) == 1) {
+ os_page_size = udma_cal_page_size(udma_seg->umem->length);
+ os_page_shift = (u32)ilog2(os_page_size);
+ }
+
+ npages = udma_get_umem_page_count(udma_seg->umem, os_page_size);
+ udma_seg->mtt.mtt_type = MTT_DMTT_TYPE;
+
+ ret = hmm_mtt_alloc(udma_dev->hwdev, npages, os_page_shift,
+ &udma_seg->mtt, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to allocate mtt, ret:%d\n", ret);
+ goto err_alloc_seg_mem;
+ }
+
+ ret = udma_umem_write_mtt(udma_dev, &udma_seg->mtt, udma_seg->umem);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to write mtt, ret:%d\n", ret);
+ goto err_write_mtt;
+ }
+
+ return 0;
+
+err_write_mtt:
+ hmm_mtt_free(udma_dev->hwdev, &udma_seg->mtt, SERVICE_T_UB);
+ udma_seg->mtt.mtt_seg = NULL;
+
+err_alloc_seg_mem:
+ ubcore_umem_release(udma_seg->umem);
+ udma_seg->umem = NULL;
+
+ return ret;
+}
+
+static int udma_sg_set_pages(struct sg_table *sgt, u64 len, u64 npages,
+ void *buf, bool is_vmalloc)
+{
+ struct scatterlist *sg = NULL;
+ struct page *vm_page = NULL;
+ u64 sg_len = len;
+ size_t min;
+ u64 i;
+
+ sg = &sgt->sgl[0];
+ for (i = 0; i < npages; i++) {
+ if (is_vmalloc) {
+ min = min_t(size_t, sg_len,
+ PAGE_SIZE - offset_in_page((uintptr_t)buf));
+ vm_page = vmalloc_to_page(buf);
+ if (!vm_page) {
+ return -ENOMEM;
+ }
+
+ sg_set_page(sg, vm_page, (u32)min,
+ offset_in_page((uintptr_t)buf));
+ } else {
+ min = min_t(size_t, sg_len, PAGE_SIZE);
+ sg_set_buf(sg, buf, (u32)min);
+ }
+
+ buf += min;
+ sg_len -= min;
+ sg = sg_next(sg);
+ }
+
+ return 0;
+}
+
+static int udma_get_kmem(struct ubcore_device *ub_dev,
+ struct udma_seg_kmem *kmem,
+ const struct ubcore_seg_cfg *cfg)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct sg_table *sgt = &kmem->sgt;
+ void *buf = (void *)(uintptr_t)cfg->va;
+ u64 len = cfg->len;
+ bool is_vmalloc;
+ u64 npages;
+ int ret;
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_SEG, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return -EINVAL;
+ }
+
+ if (udma_dev == NULL || udma_dev->dev == NULL) {
+ udma_pr_err(
+ UDMA_M_SEG,
+ "Invalid parameter: ub_dev(%d), udma_dev->dev(%d).\n",
+ !!udma_dev, !!udma_dev->dev);
+ return -EINVAL;
+ }
+
+ is_vmalloc = is_vmalloc_addr(buf);
+ if (is_vmalloc) {
+ npages = DIV_ROUND_UP(len + offset_in_page((uintptr_t)buf),
+ PAGE_SIZE);
+ } else if (virt_addr_valid(buf) != 0) {
+ npages = DIV_ROUND_UP(len, PAGE_SIZE);
+ } else {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Error: the va buf is invalid\n");
+ return -EINVAL;
+ }
+
+ kmem->npages = (u32)npages;
+ ret = sg_alloc_table(sgt, (u32)npages, GFP_KERNEL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to allocate table, ret:%d\n", ret);
+ return ret;
+ }
+
+ ret = udma_sg_set_pages(sgt, len, npages, buf, is_vmalloc);
+ if (ret != 0) {
+ sg_free_table(sgt);
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to set sg pages, vm_page is NULL\n");
+ return ret;
+ }
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 90))
+ ret = dma_map_sg(ub_dev->dma_dev, sgt->sgl, sgt->nents,
+ DMA_BIDIRECTIONAL);
+#else
+ ret = dma_map_sgtable(ub_dev->dma_dev, sgt, DMA_BIDIRECTIONAL, 0);
+#endif
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to map sgtable, ret:%d\n", ret);
+ sg_free_table(sgt);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void udma_kmem_release(struct ubcore_device *ub_dev,
+ struct udma_seg_kmem *kmem)
+{
+ if (kmem->sgt.orig_nents != 0) {
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 90))
+ dma_unmap_sg(ub_dev->dma_dev, kmem->sgt.sgl, kmem->sgt.nents,
+ DMA_BIDIRECTIONAL);
+#else
+ dma_unmap_sgtable(ub_dev->dma_dev, &kmem->sgt,
+ DMA_BIDIRECTIONAL, 0);
+#endif
+ sg_free_table(&kmem->sgt);
+ kmem->sgt.orig_nents = 0;
+ kmem->sgt.nents = 0;
+ }
+
+ return;
+}
+
+int udma_register_seg_kernel(struct ubcore_device *ub_dev,
+ const struct ubcore_seg_cfg *cfg,
+ struct udma_segment *udma_seg)
+{
+ struct udma_device *udma_dev = NULL;
+ udma_seg_kmem_t *kmem = &udma_seg->kmem;
+ struct mtt *mtt = &udma_seg->mtt;
+ int ret;
+
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_SEG, "Invalid parameter. ub_dev(%d) .\n",
+ !!ub_dev);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(ub_dev);
+
+ ret = udma_get_kmem(ub_dev, kmem, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to get kmem, ret:%d\n", ret);
+ return ret;
+ }
+
+ mtt->mtt_type = MTT_DMTT_TYPE;
+ ret = hmm_mtt_alloc(udma_dev->hwdev, kmem->npages, PAGE_SHIFT, mtt,
+ SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to allocate mtt, ret:%d\n", ret);
+ goto alloc_mtt_err;
+ }
+
+ ret = udma_mem_write_mtt_update(udma_dev, mtt, kmem->sgt.sgl,
+ kmem->sgt.nents);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to write mtt, ret:%d\n", ret);
+ goto write_mtt_err;
+ }
+
+ return 0;
+
+write_mtt_err:
+ hmm_mtt_free(udma_dev->hwdev, mtt, SERVICE_T_UB);
+ mtt->mtt_seg = NULL;
+alloc_mtt_err:
+ udma_kmem_release(ub_dev, kmem);
+ return ret;
+}
+
+static int udma_check_seg_cfg_param(struct udma_device *udma_dev,
+ const struct ubcore_seg_cfg *cfg)
+{
+ u64 free_pages;
+
+ if (cfg->flag.bs.token_policy > UBCORE_TOKEN_PLAIN_TEXT) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Invalid segment token_policy:%u.\n",
+ cfg->flag.bs.token_policy);
+ return -EINVAL;
+ }
+
+ if (cfg->flag.bs.access >= UB_MAX_ACCESS_VALUE) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Invalid segment access(%u).\n", cfg->flag.bs.access);
+ return -EINVAL;
+ }
+
+ if (cfg->len > MAX_SEGMENT_LEN) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "invalid segment len:0x%llx\n", cfg->len);
+ return -EINVAL;
+ }
+
+ free_pages = global_zone_page_state(NR_FREE_PAGES);
+ if ((cfg->len >> PAGE_SHIFT) >= free_pages) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SEG,
+ "free pages are not enough, len:0x%llx, free pages:0x%llx, page_shift:0x%x\n",
+ cfg->len, free_pages, (u32)PAGE_SHIFT);
+ return -EINVAL;
+ }
+
+ if (cfg->token_id == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG, "invalid token_id\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void udma_mem_relese(struct ubcore_device *ub_dev,
+ struct udma_segment *udma_seg,
+ struct ubcore_ucontext *uctx)
+{
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_SEG, "Invalid parameter: ub_dev(%d).\n",
+ !!ub_dev);
+ return;
+ }
+
+ if (udma_seg->mtt.mtt_seg != NULL) {
+ hmm_mtt_free(udma_dev->hwdev, &udma_seg->mtt, SERVICE_T_UB);
+ udma_seg->mtt.mtt_seg = NULL;
+ }
+
+ if (uctx != NULL) {
+ /* user mode segment */
+ if (udma_seg->umem != NULL) {
+ ubcore_umem_release(udma_seg->umem);
+ udma_seg->umem = NULL;
+ }
+ } else {
+ /* kernel mode segment */
+ udma_kmem_release(ub_dev, &udma_seg->kmem);
+ }
+}
+
+static int udma_register_seg_check_param(struct ubcore_device *ub_dev,
+ struct ubcore_seg_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if ((ub_dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_SEG,
+ "Invalid parameter: ub_dev(%d), cfg(%d).\n",
+ !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (udma_dev_is_tpf(udma_dev) == 1) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "tpf not support this function.\n");
+ return -EINVAL;
+ }
+
+ return udma_check_seg_cfg_param(udma_dev, cfg);
+}
+
+struct ubcore_target_seg *udma_register_seg(struct ubcore_device *ub_dev,
+ struct ubcore_seg_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_segment *udma_seg = NULL;
+ struct udma_keyid *udma_key = NULL;
+ int ret;
+
+ ret = udma_register_seg_check_param(ub_dev, cfg);
+ if (ret != 0) {
+ return ERR_PTR(ret);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ udma_seg = udma_seg_find(udma_dev, cfg->token_id->token_id);
+ if (udma_seg != NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "Error: token id:%u has been registered\n",
+ cfg->token_id->token_id);
+ udma_seg_put(udma_seg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_seg = (struct udma_segment *)kzalloc(sizeof(struct udma_segment),
+ GFP_KERNEL);
+ if (udma_seg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to allocate segment\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ udma_key = to_udma_keyid(cfg->token_id);
+ udma_fill_udma_seg(udma_seg, cfg, udma_key);
+ udma_cmdq_rtt_statistic_init(&udma_seg->cmdq_rtt);
+
+ if (udma_get_uctx(udata) != NULL)
+ ret = udma_register_seg_user(ub_dev, cfg, udma_seg);
+ else
+ ret = udma_register_seg_kernel(ub_dev, cfg, udma_seg);
+
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to register segment, ret:%d\n", ret);
+ goto err_register_seg;
+ }
+
+ ret = udma_cmd_seg_create_ctx(udma_dev, udma_seg, udma_key);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to create mpt context, ret:%d\n", ret);
+ goto err_create_mpt_ctx;
+ }
+ udma_seg->tseg.seg.token_id = udma_seg->key;
+
+ kref_init(&udma_seg->ref_cnt);
+ init_completion(&udma_seg->comp);
+
+ udma_store_list(udma_dev, &udma_seg->node,
+ &udma_dev->device_res->seg_list);
+
+ udma_info(
+ udma_dev->dev, UDMA_M_SEG,
+ "register segment success, token_id:0x%x,tseg token_id:0x%x,len:0x%llx,va:0x%llx,mpt_index:0x%x\n",
+ udma_key->base.token_id, udma_seg->tseg.seg.token_id, cfg->len,
+ (u64)cfg->va, udma_key->mpt.mpt_index);
+
+ return &udma_seg->tseg;
+
+err_create_mpt_ctx:
+ udma_mem_relese(ub_dev, udma_seg, udma_get_uctx(udata));
+err_register_seg:
+ kfree(udma_seg);
+
+ return ERR_PTR(-EFAULT);
+}
+
+int udma_unregister_seg(struct ubcore_target_seg *tseg)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_keyid *udma_key = NULL;
+ struct udma_segment *udma_seg = NULL;
+ int ret;
+
+ if (tseg == NULL) {
+ udma_pr_err(UDMA_M_SEG, "%s Invalid parameter: tseg is null.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if ((tseg->ub_dev == NULL) || (tseg->token_id == NULL)) {
+ udma_pr_err(
+ UDMA_M_SEG,
+ "%s Invalid parameter: tseg->ub_dev(%d), tseg->token_id(%d).\n",
+ __func__, !!tseg->ub_dev, !!tseg->token_id);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(tseg->ub_dev);
+ udma_key = to_udma_keyid(tseg->token_id);
+ udma_seg = to_ub_seg(tseg);
+
+ udma_delete_list(udma_dev, &udma_seg->node,
+ &udma_dev->device_res->seg_list);
+ udma_seg_put(udma_seg);
+ wait_for_completion(&udma_seg->comp);
+
+ mutex_lock(&udma_key->mpt_mutex);
+ ret = udma_cmd_seg_delete_ctx(udma_dev, udma_key, udma_seg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to disable seg's mpt, ret:%d\n", ret);
+ mutex_unlock(&udma_key->mpt_mutex);
+ /* delete failed, reference count reinitialized, ensure reentrant destory interface when reference count can normal put */
+ kref_init(&udma_seg->ref_cnt);
+ return ret;
+ }
+
+ if (udma_seg->david_hbm_en) {
+ udma_david_info_uninit(udma_dev, udma_seg);
+ } else {
+ udma_mem_relese(tseg->ub_dev, udma_seg, tseg->uctx);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_SEG, "unregister segment:%u success\n",
+ udma_key->base.token_id);
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_SEG, udma_key->base.token_id,
+ &udma_seg->cmdq_rtt);
+ mutex_unlock(&udma_key->mpt_mutex);
+ kfree(udma_seg);
+
+ return ret;
+}
+
+struct ubcore_target_seg *udma_import_seg(struct ubcore_device *ub_dev,
+ struct ubcore_target_seg_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct ub_rseg *rseg = NULL;
+
+ if ((ub_dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_SEG,
+ "%s Invalid parameter: ub_dev(%d), cfg(%d).\n",
+ __func__, !!ub_dev, !!cfg);
+ return ERR_PTR(-EINVAL);
+ }
+
+ rseg = (struct ub_rseg *)kzalloc(sizeof(struct ub_rseg), GFP_KERNEL);
+ if (rseg == NULL) {
+ udma_err(&ub_dev->dev, UDMA_M_SEG, "failed to allocate rseg\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ rseg->token = cfg->token_value.token;
+
+ return &rseg->base;
+}
+
+int udma_unimport_seg(struct ubcore_target_seg *tseg)
+{
+ struct ub_rseg *rseg = NULL;
+
+ if (tseg == NULL) {
+ udma_pr_err(UDMA_M_JFC, "%s Invalid parameter: tseg is null.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ rseg = container_of(tseg, struct ub_rseg, base);
+ kfree(rseg);
+
+ return 0;
+}
+
+int udma_query_res_segment(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_seg_val *res_seg =
+ (struct ubcore_res_seg_val *)(uintptr_t)val->addr;
+ struct ubcore_seg_info *seg_list = NULL;
+ struct udma_segment *udma_seg = NULL;
+ int ret = 0;
+
+ udma_seg = udma_seg_find(udma_dev, key->key); //key=token_id
+ if (udma_seg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "failed to find segment, id:%u\n", key->key);
+ return -EINVAL;
+ }
+
+ res_seg->seg_cnt = TOKEN_ID_SEG_CNT;
+ seg_list = (struct ubcore_seg_info *)vmalloc(
+ sizeof(struct ubcore_seg_info)); //only supports 1(count word)
+ if (seg_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SEG,
+ "segment list vmalloc fail.\n");
+ ret = -ENOMEM;
+ goto OUT;
+ }
+
+ res_seg->seg_list = seg_list;
+ (void)memcpy_s(seg_list->ubva.eid.raw, UBCORE_EID_SIZE,
+ udma_dev->eid.raw, UBCORE_EID_SIZE);
+ seg_list->ubva.va = udma_seg->va;
+ seg_list->len = udma_seg->size;
+ seg_list->token_id = udma_seg->mpt->mpt_index;
+OUT:
+ udma_seg_put(udma_seg);
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.h b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.h
new file mode 100644
index 000000000..013113d0e
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_segment.h
@@ -0,0 +1,78 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
+
+
+#ifndef UDMA_SEGMENT_H
+#define UDMA_SEGMENT_H
+
+#include "ubdevshm.h"
+#include "udma_common.h"
+
+#define TOKEN_ID_SEG_CNT 1
+
+typedef struct udma_seg_kmem {
+ u32 npages;
+ struct sg_table sgt;
+} udma_seg_kmem_t;
+
+typedef struct udma_segment {
+ struct ubcore_target_seg tseg;
+ struct ubcore_umem *umem;
+ struct udma_seg_kmem kmem;
+ struct mtt mtt;
+ struct mpt *mpt;
+ struct access_ctx ctx;
+ struct mem_uba uba;
+ u64 va;
+ u64 size;
+ u32 key;
+ u32 access;
+ int enabled;
+ u32 block_size;
+ u32 token_value;
+ u8 key_type;
+ bool david_hbm_en;
+ struct list_head node;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+} udma_segment_t;
+
+#define UB_ACCESS_LOCAL_WRITE (0x1 << 0)
+#define UB_ACCESS_REMOTE_READ (0x1 << 1)
+#define UB_ACCESS_REMOTE_WRITE (0x1 << 2)
+#define UB_ACCESS_REMOTE_ATOMIC (0x1 << 3)
+#define UB_ACCESS_REMOTE_INVALIDATE (0x1 << 4)
+
+#define SEG_KEY_RIGHT_SHIFT_OFS 24
+#define SEG_KEY_LEFT_SHIFT_OFS 8
+#define MAX_SEGMENT_LEN 0x8000000000ULL //max support 512GB
+#define UB_MAX_ACCESS_VALUE 32
+
+struct ubcore_target_seg *udma_register_seg(struct ubcore_device *ub_dev,
+ struct ubcore_seg_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_unregister_seg(struct ubcore_target_seg *tseg);
+struct ubcore_target_seg *udma_import_seg(struct ubcore_device *ub_dev,
+ struct ubcore_target_seg_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_unimport_seg(struct ubcore_target_seg *tseg);
+int udma_query_res_segment(struct udma_device *udma_dev,
+ const struct ubcore_device *dev,
+ struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+
+struct ubcore_token_id *udma_alloc_key_id(struct ubcore_device *ub_dev,
+ union ubcore_token_id_flag flag,
+ struct ubcore_udata *udata);
+struct udma_segment *udma_seg_find(struct udma_device *udma_dev, u32 key_id);
+void udma_seg_put(void *obj);
+void udma_seg_get(void *obj);
+
+static inline struct udma_segment *
+to_ub_seg(const struct ubcore_target_seg *tseg)
+{
+ return container_of(tseg, struct udma_segment, tseg);
+}
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.c b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.c
new file mode 100644
index 000000000..aa4a6587e
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.c
@@ -0,0 +1,67 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+#include "ossl_knl.h"
+#include "udma_log.h"
+#include "udma_shm_manage.h"
+
+static ubdevshm_acquire_uba_t _udma_ubdevshm_acquire_uba = NULL;
+static ubdevshm_release_uba_t _udma_ubdevshm_release_uba = NULL;
+
+int udma_ubdevshm_acquire_uba(struct access_ctx *ctx, struct mem_uva *va,
+ union acquire_attr *attr, invalidate func,
+ struct mem_uba *uba)
+{
+ if (_udma_ubdevshm_acquire_uba != NULL) {
+ return _udma_ubdevshm_acquire_uba(ctx, va, attr, func, uba);
+ }
+
+ return -EINVAL;
+}
+
+int udma_ubdevshm_release_uba(struct access_ctx *ctx, struct mem_uba *uba)
+{
+ if (_udma_ubdevshm_release_uba != NULL) {
+ return _udma_ubdevshm_release_uba(ctx, uba);
+ }
+
+ return -EINVAL;
+}
+
+int udma_init_shm_related_symbols(void)
+{
+ _udma_ubdevshm_acquire_uba =
+ (ubdevshm_acquire_uba_t)symbol_get(ubdevshm_acquire_uba);
+ if (_udma_ubdevshm_acquire_uba == NULL) {
+ /* if find not to shm related of symbol, description shm driver not load, directly exit i.e. can, not support david passthrough */
+ udma_pr_info(UDMA_M_SHM, "ubdev_shm driver is unloaded.\n");
+ return 0;
+ }
+
+ _udma_ubdevshm_release_uba =
+ (ubdevshm_release_uba_t)symbol_get(ubdevshm_release_uba);
+ if (_udma_ubdevshm_release_uba == NULL) {
+ symbol_put(ubdevshm_acquire_uba);
+ udma_pr_info(UDMA_M_SHM, "ubdev_shm driver is unloaded.\n");
+ return 0;
+ }
+
+ return 0;
+}
+
+void udma_uninit_shm_related_symbols(void)
+{
+ if (_udma_ubdevshm_acquire_uba != NULL) {
+ symbol_put(ubdevshm_acquire_uba);
+ _udma_ubdevshm_acquire_uba = NULL;
+ }
+
+ if (_udma_ubdevshm_release_uba != NULL) {
+ symbol_put(ubdevshm_release_uba);
+ _udma_ubdevshm_release_uba = NULL;
+ }
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.h b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.h
new file mode 100644
index 000000000..d6f3daae3
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/segment/udma_shm_manage.h
@@ -0,0 +1,25 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_SHM_MANAGE_H
+#define UDMA_SHM_MANAGE_H
+
+#include "ubdevshm.h"
+
+typedef int __iomem (*ubdevshm_acquire_uba_t)(struct access_ctx *ctx,
+ struct mem_uva *va,
+ union acquire_attr *attr,
+ invalidate func,
+ struct mem_uba *uba);
+typedef int __iomem (*ubdevshm_release_uba_t)(struct access_ctx *ctx,
+ struct mem_uba *uba);
+
+int udma_ubdevshm_acquire_uba(struct access_ctx *ctx, struct mem_uva *va,
+ union acquire_attr *attr, invalidate func,
+ struct mem_uba *uba);
+int udma_ubdevshm_release_uba(struct access_ctx *ctx, struct mem_uba *uba);
+int udma_init_shm_related_symbols(void);
+void udma_uninit_shm_related_symbols(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.c b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.c
new file mode 100644
index 000000000..9a4a7621a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.c
@@ -0,0 +1,476 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved.
+
+
+#include <linux/slab.h>
+#include <linux/mm_types.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+
+#include "udma_misc.h"
+#include "udma_sysfs_common.h"
+#include "udma_sysfs_config.h"
+#include "udma_sysfs.h"
+
+/* and above on is old code, pending refactor; and above next is refactor after of code */
+void *udma_sysfs_get_child_value(void *parent, u32 offset)
+{
+ return (void *)((uintptr_t)parent + offset);
+}
+/**
+ * @brief configuration initialize check
+ * @param[in] udma_dev: device information
+ * @param[in] node: node configuration information
+ * @details used for determine this configuration whether need initialize
+ * @return
+ * - true: check success can initialize
+ * - false: check failure, cannot initialize
+ */
+static bool
+udma_sysfs_func_type_and_version_check(struct udma_device *udma_dev,
+ struct udma_sysfs_support_info *support)
+{
+ enum udma_device_type sysfs_ver = udma_dev->device_type;
+ enum udma_sysfs_func_type device_func_type =
+ (udma_dev_is_tpf(udma_dev) == 1) ? UDMA_SYSFS_TPF :
+ UDMA_SYSFS_TAF;
+
+ if ((support->func_ver & (u32)sysfs_ver) == 0) {
+ return false;
+ }
+
+ if (support->func_type != UDMA_SYSFS_ALL &&
+ support->func_type != device_func_type) {
+ return false;
+ }
+
+ return true;
+}
+
+struct udma_sysfs_node *udma_sysfs_get_node_from_child_list_by_name(
+ struct udma_sysfs_child_node_info *child_info, const char *name)
+{
+ struct udma_sysfs_node *child_list = child_info->node_list;
+ int length = child_info->length;
+ int i = 0;
+
+ for (i = 0; i < length; ++i) {
+ if (strcmp(child_list[i].attr.name, name) == 0) {
+ return &child_list[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* common show function, all directory all will register this function, traverse this directory next all file, found name same of file after call this file register of show function, to get data */
+static ssize_t udma_sysfs_common_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct udma_sysfs_head *head = to_sysfs_head_by_kobject(kobj);
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(head->base);
+ struct udma_sysfs_child_node_info *child_info = &head->node->child_info;
+ struct udma_sysfs_node *child_node = NULL;
+ ssize_t ret = -EIO;
+
+ child_node = udma_sysfs_get_node_from_child_list_by_name(child_info,
+ attr->name);
+ if (child_node == NULL) {
+ return ret;
+ }
+
+ if (child_node->ops.show == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "%s Unregistered 'show' function.\n",
+ child_node->attr.name);
+ return ret;
+ }
+
+ mutex_lock(&head->mutex);
+ ret = child_node->ops.show(udma_dev, head, child_node, buf);
+ mutex_unlock(&head->mutex);
+
+ return ret;
+}
+
+/* common store function, all directory all will register this function, traverse this directory next all file, found name same of file after call this file register of store function, to update data */
+ssize_t udma_sysfs_common_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
+{
+ struct udma_sysfs_head *head = to_sysfs_head_by_kobject(kobj);
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(head->base);
+ struct udma_sysfs_child_node_info *child_info = &head->node->child_info;
+ struct udma_sysfs_node *child_node = NULL;
+ ssize_t ret = -EIO;
+
+ child_node = udma_sysfs_get_node_from_child_list_by_name(child_info,
+ attr->name);
+ if (child_node == NULL) {
+ return ret;
+ }
+
+ if (child_node->ops.store == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "%s Unregistered 'store' function.\n",
+ child_node->attr.name);
+ return ret;
+ }
+
+ mutex_lock(&head->mutex);
+ ret = child_node->ops.store(udma_dev, head, child_node, buf);
+ mutex_unlock(&head->mutex);
+
+ return (ret == (ssize_t)0) ? (ssize_t)count : ret;
+}
+
+/* register common callback, as directory context file of callback inport */
+struct sysfs_ops udma_sysfs_common_ops = { .show = udma_sysfs_common_show,
+ .store = udma_sysfs_common_store };
+static void udma_sysfs_default_release(struct kobject *kobj)
+{
+}
+struct kobj_type udma_sysfs_common_ktype = {
+ .release = udma_sysfs_default_release,
+ .sysfs_ops = &udma_sysfs_common_ops,
+};
+
+static int udma_sysfs_init_sysfs_nodes(struct udma_device *udma_dev,
+ struct kobject *parent_kobj,
+ void *parent_addr,
+ struct udma_sysfs_res *base,
+ struct udma_sysfs_node *child_nodes,
+ int child_nodes_num);
+static void udma_sysfs_deinit_sysfs_nodes(struct udma_device *udma_dev,
+ void *parent_addr,
+ struct kobject *parent_kobj,
+ struct udma_sysfs_node *child_nodes,
+ int child_nodes_num);
+
+/**
+ * @brief recursively initialize kobj create file or subdirectory
+ * @param[in] udma_dev: device information
+ * @param[in] parent_kobj: parent directory of kobj
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] base: filesystem object
+ * @param[in] node: configuration node corresponding to current file
+ * @details recursively initialize kobj create file
+ * @return
+ * - zero: success
+ * - not zero: failure
+ */
+static int udma_sysfs_init_dir_node(struct udma_device *udma_dev,
+ struct kobject *parent_kobj,
+ void *parent_addr,
+ struct udma_sysfs_res *base,
+ struct udma_sysfs_node *node)
+{
+ void *start_address = NULL;
+ struct udma_sysfs_head *head = NULL;
+ char name[UDMA_SYSFS_NAME_MAX_LEN] = "";
+ u32 i = 0;
+ int ret = 0;
+
+ start_address = udma_sysfs_get_child_value(parent_addr,
+ node->position_info.offset);
+
+ for (i = 0; i < node->position_info.array_num; ++i) {
+ head = (struct udma_sysfs_head
+ *)(start_address +
+ i * node->position_info.element_size);
+
+ head->node = node;
+ head->base = base;
+ head->parent_addr = parent_addr;
+ ret = node->name_ext.get_name_func(node->attr.name, (int)i,
+ node->name_ext.ext_value,
+ name);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "kobject(%s, %d), get name failed, ret: %d\n",
+ node->attr.name, i, ret);
+ return ret;
+ }
+ mutex_init(&head->mutex);
+ ret = kobject_init_and_add(&head->kobj,
+ &udma_sysfs_common_ktype,
+ parent_kobj, name);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to add kobject(%s, %d), name: %s, ret: %d\n",
+ node->attr.name, i, name, ret);
+ kobject_put(&head->kobj);
+ mutex_destroy(&head->mutex);
+ return ret;
+ }
+ head->kobj_flag = UDMA_SYSFS_INITIALIZED;
+ ret = udma_sysfs_init_sysfs_nodes(udma_dev, &head->kobj, head,
+ head->base,
+ node->child_info.node_list,
+ node->child_info.length);
+ if (ret != 0) {
+ break;
+ }
+ if (node->ext_update == NULL) {
+ continue;
+ }
+ ret = node->ext_update(udma_dev, head);
+ if (ret != 0) {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief free node corresponding directory next resource and corresponding kobj
+ * @param[in] udma_dev: device information
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] node: configuration node corresponding to current file
+ * @details if node corresponding directory already initialize, free directory next resource and kobj, directory lock
+ * @return void
+ */
+static void udma_sysfs_deinit_dir_node(struct udma_device *udma_dev,
+ void *parent_addr,
+ struct udma_sysfs_node *node)
+{
+ void *start_address = NULL;
+ struct udma_sysfs_head *head = NULL;
+ u32 i = 0;
+
+ start_address = udma_sysfs_get_child_value(parent_addr,
+ node->position_info.offset);
+
+ for (i = 0; i < node->position_info.array_num; ++i) {
+ head = (struct udma_sysfs_head
+ *)(start_address +
+ i * node->position_info.element_size);
+ if (head->kobj_flag == UDMA_SYSFS_UNINITIALIZED) {
+ continue;
+ }
+ udma_sysfs_deinit_sysfs_nodes(udma_dev, head, &head->kobj,
+ node->child_info.node_list,
+ node->child_info.length);
+ kobject_put(&head->kobj);
+ mutex_destroy(&head->mutex);
+ head->kobj_flag = UDMA_SYSFS_UNINITIALIZED;
+ }
+}
+
+/**
+ * @brief create node corresponding file
+ * @param[in] udma_dev: device information
+ * @param[in] parent_kobj: parent directory of kobj
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] node: configuration node corresponding to current file
+ * @param[in] index: index of current file in parent directory
+ * @details create node corresponding file and initialize corresponding parameters
+ * @return
+ * - zero: success
+ * - not zero: failure
+ */
+static int udma_sysfs_init_file_node(struct udma_device *udma_dev,
+ struct kobject *parent_kobj,
+ void *parent_addr,
+ struct udma_sysfs_node *node, int index)
+{
+ void *value = NULL;
+ struct udma_sysfs_head *parent_head =
+ (struct udma_sysfs_head *)parent_addr;
+ int ret = 0;
+
+ value = udma_sysfs_get_child_value(parent_addr,
+ node->position_info.offset);
+ if (node->value.set_def_value != NULL) {
+ node->value.set_def_value(value, node->value.def,
+ node->position_info.array_num);
+ }
+
+ ret = sysfs_create_file(parent_kobj, &node->attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to create the file(%s), ret: %d\n",
+ node->attr.name, ret);
+ return ret;
+ }
+ parent_head->file_flag[index] = UDMA_SYSFS_INITIALIZED;
+
+ if (node->ext_update == NULL) {
+ return 0;
+ }
+
+ return node->ext_update(udma_dev, parent_addr);
+}
+
+/**
+ * @brief free node corresponding file
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] parent_kobj: parent directory of kobj
+ * @param[in] node: configuration node corresponding to current file
+ * @param[in] index: index of current file in parent directory
+ * @details if node corresponding file already initialize, free this file
+ * @return void
+ */
+static void udma_sysfs_deinit_file_node(void *parent_addr,
+ struct kobject *parent_kobj,
+ struct udma_sysfs_node *node, int index)
+{
+ struct udma_sysfs_head *parent_head =
+ (struct udma_sysfs_head *)parent_addr;
+
+ if (parent_head->file_flag[index] == UDMA_SYSFS_UNINITIALIZED) {
+ return;
+ }
+
+ sysfs_remove_file(parent_kobj, &node->attr);
+ parent_head->file_flag[index] = UDMA_SYSFS_UNINITIALIZED;
+}
+
+/**
+ * @brief recursively initialize kobj create file or subdirectory
+ * @param[in] udma_dev: device information
+ * @param[in] parent_kobj: parent directory of kobj
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] base: filesystem object
+ * @param[in] child_nodes: subdirectory files of parent directory
+ * @param[in] child_nodes_num: count of subdirectory files of parent directory
+ * @details recursively initialize kobj create file
+ * @return
+ * - zero: success
+ * - not zero: failure
+ */
+static int udma_sysfs_init_sysfs_nodes(struct udma_device *udma_dev,
+ struct kobject *parent_kobj,
+ void *parent_addr,
+ struct udma_sysfs_res *base,
+ struct udma_sysfs_node *child_nodes,
+ int child_nodes_num)
+{
+ int ret = 0;
+ int i = 0;
+
+ /* cannot exceed file flag array of size */
+ if (child_nodes_num > UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "sub-items in the dir num(%d) exceeded max num(%d).\n",
+ child_nodes_num, UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < child_nodes_num; ++i) {
+ /* check this node whether need in this version this func load */
+ if (udma_sysfs_func_type_and_version_check(
+ udma_dev, &(child_nodes[i].support_info)) ==
+ false) {
+ udma_debug(udma_dev->dev, UDMA_M_SYSFS,
+ "kobject %s Not loaded.\n",
+ child_nodes[i].attr.name);
+ continue;
+ }
+
+ if (child_nodes[i].type == UDMA_SYSFS_NODE_DIR) {
+ ret = udma_sysfs_init_dir_node(udma_dev, parent_kobj,
+ parent_addr, base,
+ &child_nodes[i]);
+ } else {
+ ret = udma_sysfs_init_file_node(udma_dev, parent_kobj,
+ parent_addr,
+ &child_nodes[i], i);
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief recursive free kobj delete file or subdirectory
+ * @param[in] udma_dev: device information
+ * @param[in] parent_addr: base address of parent data structure
+ * @param[in] parent_kobj: parent directory of kobj
+ * @param[in] child_nodes: subdirectory files of parent directory
+ * @param[in] child_nodes_num: count of subdirectory files of parent directory
+ * @details recursive free kobj delete file
+ * @return void
+ */
+static void udma_sysfs_deinit_sysfs_nodes(struct udma_device *udma_dev,
+ void *parent_addr,
+ struct kobject *parent_kobj,
+ struct udma_sysfs_node *child_nodes,
+ int child_nodes_num)
+{
+ int i = 0;
+
+ /* cannot exceed file flag array of size, and init for symmetry */
+ if (child_nodes_num > UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM) {
+ return;
+ }
+
+ for (i = 0; i < child_nodes_num; ++i) {
+ /* check this node whether in this version this func load (done), and init for symmetry */
+ if (udma_sysfs_func_type_and_version_check(
+ udma_dev, &(child_nodes[i].support_info)) ==
+ false) {
+ continue;
+ }
+
+ if (child_nodes[i].type == UDMA_SYSFS_NODE_DIR) {
+ udma_sysfs_deinit_dir_node(udma_dev, parent_addr,
+ &child_nodes[i]);
+ } else {
+ udma_sysfs_deinit_file_node(parent_addr, parent_kobj,
+ &child_nodes[i], i);
+ }
+ }
+}
+
+int udma_init_sysfs(struct udma_sysfs_res *sysfs_res)
+{
+ int ret = 0;
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(sysfs_res);
+ struct kobject *base_kobj = &udma_dev->ndev->dev.kobj;
+ struct udma_sysfs_node *config_info = udma_sysfs_get_config_info();
+ int config_len = udma_sysfs_get_config_length();
+
+ if (udma_dev->device_type == UDMA_DEV_TYPE_UNKNOWN) {
+ return -EINVAL;
+ }
+
+ ret = udma_sysfs_init_sysfs_nodes(udma_dev, base_kobj, sysfs_res,
+ sysfs_res, config_info, config_len);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to init sysfs, ret: %d\n", ret);
+ udma_sysfs_deinit_sysfs_nodes(udma_dev, sysfs_res, base_kobj,
+ config_info, config_len);
+ return ret;
+ }
+
+ return 0;
+}
+
+void udma_remove_sysfs(struct udma_sysfs_res *sysfs_res)
+{
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(sysfs_res);
+ struct kobject *base_kobj = &udma_dev->ndev->dev.kobj;
+ struct udma_sysfs_node *config_info = udma_sysfs_get_config_info();
+ int config_len = udma_sysfs_get_config_length();
+
+ if (udma_dev->device_type == UDMA_DEV_TYPE_UNKNOWN) {
+ return;
+ }
+
+ udma_sysfs_deinit_sysfs_nodes(udma_dev, sysfs_res, base_kobj,
+ config_info, config_len);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.h b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.h
new file mode 100644
index 000000000..b93a14a2d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs.h
@@ -0,0 +1,158 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_SYSFS_H
+#define UDMA_SYSFS_H
+
+#include "udma_sysfs_api.h"
+#include "udma_common.h"
+
+#define DSCP_ARRAY_LEN 8
+#define LDCP_PATTERN_ARRAY_LEN 8
+#define CAQM_PATTERN_ARRAY_LEN 3
+#define USER_DEFINED_PATTERN_ARRAY_LEN 8
+#define USER_DEFINED_TEMPLATE_NUM 2
+
+#define UDMA_SYSFS_NAME_MAX_LEN 32 /* file or directory name maximum length */
+#define UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM 20 /* max number of sub-items in directory */
+
+//LDPC
+#define UDMA_DEFAULT_INIT_WND 1
+#define UDMA_DEFAULT_ALPHA 4
+#define UDMA_DEFAULT_BETA 6
+#define UDMA_DEFAULT_GAMMA 45
+#define UDMA_DEFAULT_ETA 31
+#define UDMA_DEFAULT_WND_MIN 31
+#define UDMA_DEFAULT_CC_UNIT 6
+
+#define UDMA_MIN_LDCP_PARA 0
+#define UDMA_MAX_LDCP_PARA 127
+#define UDMA_MIN_CAQM_PARA 0
+#define UDMA_MAX_CAQM_PARA 127
+
+//RX_RATE_LIMITE ACC PARAM DEFAULT
+#define UDMA_ACC_DEFAULT_DOWN_PERIOD 32
+#define UDMA_ACC_DEFAULT_UP_PERIOD 160
+#define UDMA_ACC_DEFAULT_ALPHA1 1 //8Kb/s
+#define UDMA_ACC_DEFAULT_N1 10
+#define UDMA_ACC_DEFAULT_ALPHA2 128 //1024Kb/s
+#define UDMA_ACC_DEFAULT_N2 15
+#define UDMA_ACC_DEFAULT_ALPHA3 500 //4000Kb/s
+#define UDMA_ACC_DEFAULT_BETA 13
+#define UDMA_ACC_DEFAULT_MIN_RATE 128 //1024Kb/s
+#define UDMA_ACC_DEFAULT_INIT_RATE 10 //80Kb/s
+
+//CAQM TODO, may be modified
+#define UDMA_MIN_INIT_RATE 0
+#define UDMA_MAX_INIT_RATE 65536
+
+//RX_RATE_LIMITE ACC PARAM RANGE
+#define UDMA_ACC_MIN_DOWN_PERIOD 0
+#define UDMA_ACC_MAX_DOWN_PERIOD 1024
+#define UDMA_ACC_MIN_BETA 0
+#define UDMA_ACC_MAX_BETA 64
+#define UDMA_ACC_MIN_UP_PERIOD 0
+#define UDMA_ACC_MAX_UP_PERIOD 1024
+#define UDMA_ACC_MIN_ALPHA1 0
+#define UDMA_ACC_MAX_ALPHA1 1023
+#define UDMA_ACC_MIN_ALPHA2 0
+#define UDMA_ACC_MAX_ALPHA2 1023
+#define UDMA_ACC_MIN_ALPHA3 0
+#define UDMA_ACC_MAX_ALPHA3 4095
+#define UDMA_ACC_MIN_N1 0
+#define UDMA_ACC_MAX_N1 32
+#define UDMA_ACC_MIN_N2 0
+#define UDMA_ACC_MAX_N2 32
+#define UDMA_ACC_MIN_MIN_RATE 0
+#define UDMA_ACC_MAX_MIN_RATE 65536
+#define UDMA_ACC_MIN_INIT_RATE 0
+#define UDMA_ACC_MAX_INIT_RATE 65536
+#define UDMA_ACC_MAX_WRED_IDX 127
+#define UDMA_ACC_MAX_WRED_VAL 65535
+
+#define UDMA_MAX_TOKEN_ID_PARA 1048575
+#define UDMA_MAX_EID_PARA 1048575
+
+enum udma_sysfs_node_type {
+ UDMA_SYSFS_NODE_DIR, /* directory */
+ UDMA_SYSFS_NODE_FILE, /* file */
+};
+
+enum udma_sysfs_func_type {
+ UDMA_SYSFS_TPF, /* tpf */
+ UDMA_SYSFS_TAF, /* include pf and vf */
+ UDMA_SYSFS_ALL /* tpf and taf */
+};
+
+typedef void (*udma_sysfs_set_def_value)(void *value, u32 def, u32 array_num);
+
+struct udma_sysfs_attr_value {
+ u32 min; /* file parameters maximum less value */
+ u32 def; /* file parameters of default value */
+ u32 max; /* file parameters maximum value */
+ udma_sysfs_set_def_value set_def_value; /* used for update default value */
+};
+
+typedef int (*udma_sysfs_get_name_func)(const char *name, int index,
+ void *ext_value, char *out_name);
+
+struct udma_sysfs_name_ext {
+ udma_sysfs_get_name_func get_name_func;
+ void *ext_value;
+};
+
+struct udma_sysfs_position_info {
+ u32 offset; /* indicates this configuration corresponding data which count data structure in of 那 field */
+ u32 array_num; /* indicates in same level exist 几 should use this configured same subdirectory, or indicates file corresponding array of array size */
+ u32 element_size; /* element size, used for not perceive element data structure traverse array use */
+};
+
+struct udma_sysfs_child_node_info {
+ struct udma_sysfs_node
+ *node_list; /* directory valid, record this directory context file or subdirectory of configuration */
+ int length; /* directory valid, record this directory next node of total data */
+};
+
+struct udma_sysfs_support_info {
+ enum udma_sysfs_func_type
+ func_type; /* indicates this configuration will in which func type load, @see > enum udma_sysfs_func_type */
+ u32 func_ver; /* indicates this configuration will in which version load, @see > enum udma_device_type */
+};
+
+struct udma_sysfs_ops {
+ ssize_t (*show)(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ char *buf); /* file corresponding to show function */
+ ssize_t (*store)(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf); /* file corresponding to store function */
+};
+
+struct udma_sysfs_node {
+ struct attribute attr; /* file name or directory name */
+ struct udma_sysfs_name_ext name_ext; /* used for custom file name */
+ enum udma_sysfs_node_type
+ type; /* configuration type, @see > enum udma_sysfs_node_type */
+ struct udma_sysfs_support_info
+ support_info; /* used for record node in which scenario generatevalid */
+ struct udma_sysfs_position_info
+ position_info; /* used for record this node corresponding parameters of offset, element count, element size */
+ struct udma_sysfs_attr_value
+ value; /* file valid, used for file parameters of initialize and modify check */
+ struct udma_sysfs_ops ops; /* file valid, according to parameters need specifies corresponding to callback function */
+ int (*ext_update)(
+ struct udma_device *udma_dev,
+ void *parent_addr); /* extension update function, when parameters or parameters group initialize after need data update to other module when use */
+ struct udma_sysfs_child_node_info
+ child_info; /* directory valid, record this directory context file or subdirectory of configuration */
+};
+
+/* field in data structure in of offset, based on this data structure object of base address 拿 to this field of address */
+void *udma_sysfs_get_child_value(void *parent, u32 offset);
+ssize_t udma_sysfs_common_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_api.h b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_api.h
new file mode 100644
index 000000000..bf239f56b
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_api.h
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2021-2025. All rights reserved.
+
+
+#ifndef UDMA_SYSFS_API_H
+#define UDMA_SYSFS_API_H
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+#define UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM 20 /* max number of sub-items in directory */
+#define DSCP_ARRAY_LEN 8
+#define LDCP_PATTERN_ARRAY_LEN 8
+#define CAQM_PATTERN_ARRAY_LEN 3
+#define USER_DEFINED_PATTERN_ARRAY_LEN 8
+#define USER_DEFINED_TEMPLATE_NUM 2
+
+typedef struct udma_sysfs_node udma_sysfs_node_t;
+
+enum udma_sysfs_init_type {
+ UDMA_SYSFS_UNINITIALIZED, /* default value, indicates not initialize */
+ UDMA_SYSFS_INITIALIZED /* initialize, free when according to this free */
+};
+
+/* only in directory layer level use, constraint: as data structure of start */
+struct udma_sysfs_head {
+ struct kobject kobj; /* current directory of filesystem kobj */
+ struct mutex mutex; /* current directory context file of read write lock */
+ udma_sysfs_node_t *node; /* current directory corresponding sysfs related configuration */
+ struct udma_sysfs_res *base; /* sysfs module of base object */
+ void *parent_addr; /* parent directory of base address */
+ enum udma_sysfs_init_type kobj_flag; /* current directory whether complete (done) initialize */
+ enum udma_sysfs_init_type file_flag
+ [UDMA_SYSFS_ITEM_IN_DIR_MAX_NUM]; /* initialize when allocate of array, use to record directory context file initialize of status, directory free when cleanup */
+};
+
+struct udma_dfx_perf_pattern {
+ struct udma_sysfs_head head;
+ u32 huge_page_en;
+ u32 pi_on_chip_dis;
+ u32 dwqe_dis;
+ u32 vf_start_xid;
+ u32 xid_low_3_bit;
+ u32 jetty_slice_en;
+ u32 ta2tp_type;
+ u32 tp_depth_shift;
+ u32 fis_en; /* enable fast inline send flag switch, only used for fast path scenario */
+ u32 cfg_dscp_en;
+ u32 cfg_dscp[DSCP_ARRAY_LEN];
+};
+
+struct udma_dfx_ctx {
+ struct udma_sysfs_head head;
+ u32 debug_en;
+ u32 drop_aeqe_en;
+ u32 dump_tp_en;
+ u32 tid;
+ u32 eid;
+ u32 hbm_en;
+ struct udma_dfx_perf_pattern perf;
+};
+
+struct udma_ldcp_pattern_ctx {
+ struct udma_sysfs_head head;
+ u32 init_wnd;
+ u32 alpha;
+ u32 beta;
+ u32 gamma;
+ u32 eta;
+ u32 wnd_min;
+};
+
+struct udma_cc_ldcp_ctx {
+ struct udma_sysfs_head head;
+ struct udma_ldcp_pattern_ctx pattern[LDCP_PATTERN_ARRAY_LEN];
+};
+
+struct udma_caqm_pattern_ctx {
+ struct udma_sysfs_head head;
+ u32 alpha;
+ u32 beta;
+ u32 eta;
+ u32 wnd_min;
+ u32 init_wnd;
+ u32 cc_unit;
+};
+
+struct udma_cc_caqm_ctx {
+ struct udma_sysfs_head head;
+ struct udma_caqm_pattern_ctx pattern[CAQM_PATTERN_ARRAY_LEN];
+};
+
+struct udma_user_defined_pattern_ctx {
+ struct udma_sysfs_head head;
+ u32 dw0;
+ u32 dw1;
+ u32 dw2;
+ u32 dw3;
+};
+
+struct udma_cc_user_defined_ctx {
+ struct udma_sysfs_head head;
+ struct udma_user_defined_pattern_ctx
+ pattern[USER_DEFINED_PATTERN_ARRAY_LEN];
+};
+
+struct udma_cc_ctx {
+ struct udma_sysfs_head head;
+ struct udma_cc_ldcp_ctx ldcp;
+ struct udma_cc_caqm_ctx caqm;
+ struct udma_cc_user_defined_ctx user_defined[USER_DEFINED_TEMPLATE_NUM];
+};
+
+struct udma_rx_rate_limit_wred {
+ u32 cmd;
+ u32 wred_idx;
+ u32 start_val;
+ u32 end_val;
+};
+
+struct udma_rx_rate_limit_ctx {
+ struct udma_sysfs_head head;
+ u16 down_period;
+ u16 up_period;
+ u16 alpha1;
+ u16 n1;
+ u16 alpha2;
+ u16 alpha3;
+ u16 min_rate;
+ u16 init_rate;
+ u8 n2;
+ u8 beta;
+ struct udma_rx_rate_limit_wred wred;
+};
+
+struct udma_sysfs_res {
+ struct udma_dfx_ctx dfx_ctx;
+ struct udma_cc_ctx cc_ctx;
+ struct udma_rx_rate_limit_ctx rx_rate_limit_ctx;
+};
+
+int udma_init_sysfs(struct udma_sysfs_res *sysfs_res);
+void udma_remove_sysfs(struct udma_sysfs_res *sysfs_res);
+
+/**
+ * @brief get driver func level debug_en
+ * @param[in] sysfs_res: current func of filesystem
+ * @details use to get driver func level debug_en
+ */
+bool udma_sysfs_get_debug_en(struct udma_sysfs_res *sysfs_res);
+
+/**
+ * @brief get allocate jetty xid low bit match value
+ * @param[in] sysfs_res: current func of filesystem
+ * @param[out] out_value: get to of low bit match value (not enable debug_en or configuration value invalid when will initialize is 0)
+ * @details get allocate jetty xid low bit match value
+ * @return true: out_value is valid value
+ * false: out_value is invalid value
+ */
+bool udma_sysfs_get_xid_low_3_bit(struct udma_sysfs_res *sysfs_res,
+ u32 *out_value);
+
+/**
+ * @brief get dwqe_dis
+ * @param[in] sysfs_res: current func of filesystem
+ * @details get dwqe_dis, set when disable dwqe path
+ * @return dwqe_dis value
+ */
+u32 udma_sysfs_get_dwqe_dis(struct udma_sysfs_res *sysfs_res);
+
+/**
+ * @brief get tp_q_depth
+ * @param[in] sysfs_res: current func of filesystem
+ * @details get tp_q_depth, used for allocate tp queue buf
+ * @return tp_q_depth value
+ */
+u32 udma_sysfs_get_tp_depth(struct udma_sysfs_res *sysfs_res);
+
+/**
+ * @brief set tp_q_depth
+ * @param[in] sysfs_res: current func of filesystem
+ * @param[in] new_value: to set new value
+ * @details set tp_q_depth, need seek value is 2 of power
+ * @return max at 0: set success
+ * less at 0: set failure
+ */
+int udma_sysfs_set_tp_depth(struct udma_sysfs_res *sysfs_res, u32 new_value);
+
+/**
+ * @brief get mtt_pro_en
+ * @param[in] sysfs_res: current func of filesystem
+ * @param[out] mtt_pro_en: get to of mtt_pro_en value
+ * @details get mtt_pro_en, if filesystem in not enable, from mpu get
+ * @return 0: get success
+ * non- 0: get fails
+ */
+int udma_sysfs_get_mtt_pro_en(struct udma_sysfs_res *sysfs_res,
+ u32 *mtt_pro_en);
+
+/**
+ * @brief get huge_page_en
+ * @param[in] sysfs_res: current func of filesystem
+ * @details get huge_page_en
+ * @return huge_page_en value
+ */
+u32 udma_sysfs_get_huge_page_en(struct udma_sysfs_res *sysfs_res);
+
+/**
+ * @brief get fis_en
+ * @param[in] sysfs_res: current func of filesystem
+ * @details get fis_en
+ * @return fis_en value
+ */
+bool udma_sysfs_get_fis_en(struct udma_sysfs_res *sysfs_res);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.c b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.c
new file mode 100644
index 000000000..29baa00cc
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.c
@@ -0,0 +1,715 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include "ub_dw_index.h"
+#include "udma_sysfs.h"
+#include "udma_sysfs_api.h"
+#include "udma_misc.h"
+#include "udma_cmd.h"
+#include "ub_pub_cmd.h"
+#include "udma_resource.h"
+#include "udma_sysfs_common.h"
+
+#define TP_Q_DEF_DEPTH 128
+#define UDMA_SYSFS_VALUE_TYPE_SIZE_U8 sizeof(u8)
+#define UDMA_SYSFS_VALUE_TYPE_SIZE_U16 sizeof(u16)
+#define UDMA_SYSFS_VALUE_TYPE_SIZE_U32 sizeof(u32)
+
+int udma_sysfs_set_rx_rate_limit(struct udma_device *udma_dev,
+ void *parent_addr)
+{
+ struct udma_rx_rate_limit_ctx *parent =
+ (struct udma_rx_rate_limit_ctx *)parent_addr;
+ struct ub_rx_rate_limit_params rx_rate_limit_param = { 0 };
+ int ret;
+
+ rx_rate_limit_param.down_period = parent->down_period;
+ rx_rate_limit_param.up_period = parent->up_period;
+ rx_rate_limit_param.alpha1 = parent->alpha1;
+ rx_rate_limit_param.n1 = parent->n1;
+ rx_rate_limit_param.alpha2 = parent->alpha2;
+ rx_rate_limit_param.n2 = parent->n2;
+ rx_rate_limit_param.alpha3 = parent->alpha3;
+ rx_rate_limit_param.beta = parent->beta;
+ rx_rate_limit_param.min_rate = parent->min_rate;
+ rx_rate_limit_param.init_rate = parent->init_rate;
+
+ ret = udma_rx_rate_limit_set_para(udma_dev, &rx_rate_limit_param);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to update rx rate limit pattern, ret: %d\n",
+ ret);
+ return ret;
+ }
+ return 0;
+}
+
+static u32
+udma_sysfs_get_index_in_parent_array(struct udma_sysfs_head *node_head)
+{
+ uintptr_t start_addr = (uintptr_t)udma_sysfs_get_child_value(
+ node_head->parent_addr, node_head->node->position_info.offset);
+ u32 element_size = node_head->node->position_info.element_size;
+ u32 array_num = node_head->node->position_info.array_num;
+ u32 i = 0;
+
+ for (i = 0; i < array_num; ++i) {
+ if ((start_addr + i * element_size) == (uintptr_t)node_head) {
+ break;
+ }
+ }
+
+ return i;
+}
+
+static int udma_sysfs_set_ta2tp_type(struct udma_device *udma_dev,
+ void *parent_addr)
+{
+ struct ub_cmd_func_attr func_attr = { 0 };
+ struct udma_dfx_perf_pattern *parent =
+ (struct udma_dfx_perf_pattern *)parent_addr;
+ bool debug_en = false;
+
+ debug_en = udma_sysfs_get_debug_en(&udma_dev->sysfs_res);
+ /* debug_en not generatevalid, returns directly failure */
+ if (!debug_en) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "The debug_en(%d) is not taking effect.\n", debug_en);
+ return -EINVAL;
+ }
+
+ SET_FUNC_TBL_ATTR_VAL_WITH_MASK(func_attr, attr2, ta2tp_type,
+ (u8)parent->ta2tp_type);
+
+ return udma_set_func_attr(
+ udma_dev, hinic5_global_func_id(udma_dev->hwdev), &func_attr);
+}
+
+int udma_sysfs_set_ldcp(struct udma_device *udma_dev, void *parent_addr)
+{
+ struct udma_ldcp_pattern_ctx *parent =
+ (struct udma_ldcp_pattern_ctx *)parent_addr;
+ struct ub_cc_params cc_param = { 0 };
+ int ret = 0;
+
+ cc_param.ub_cc_algo = UB_CC_ALGO_LDCP;
+ cc_param.index =
+ (u8)udma_sysfs_get_index_in_parent_array(&(parent->head));
+ cc_param.init_wnd = (u8)parent->init_wnd;
+ cc_param.alpha = (u8)parent->alpha;
+ cc_param.beta = (u8)parent->beta;
+ cc_param.gamma = (u8)parent->gamma;
+ cc_param.eta = (u8)parent->eta;
+ cc_param.wnd_min = (u8)parent->wnd_min;
+
+ ret = udma_cc_set_para(udma_dev, &cc_param);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to update cc pattern, algo: %d, index: %d, ret: %d\n",
+ cc_param.ub_cc_algo, cc_param.index, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_sysfs_set_caqm(struct udma_device *udma_dev, void *parent_addr)
+{
+ struct udma_caqm_pattern_ctx *parent =
+ (struct udma_caqm_pattern_ctx *)parent_addr;
+ struct ub_cc_params cc_param = { 0 };
+ int ret = 0;
+
+ cc_param.ub_cc_algo = UB_CC_ALGO_CAQM;
+ cc_param.index =
+ (u8)udma_sysfs_get_index_in_parent_array(&(parent->head));
+ cc_param.alpha = (u8)parent->alpha;
+ cc_param.beta = (u8)parent->beta;
+ cc_param.eta = (u8)parent->eta;
+ cc_param.wnd_min = (u8)parent->wnd_min;
+ cc_param.init_wnd = (u8)parent->init_wnd;
+ cc_param.cc_unit = (u8)parent->cc_unit;
+
+ ret = udma_cc_set_para(udma_dev, &cc_param);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to update cc pattern, algo: %d, index: %d, ret: %d\n",
+ cc_param.ub_cc_algo, cc_param.index, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_sysfs_set_user_defined(struct udma_device *udma_dev, void *parent_addr)
+{
+ struct udma_user_defined_pattern_ctx *parent =
+ (struct udma_user_defined_pattern_ctx *)parent_addr;
+ struct ub_cc_params cc_param = { 0 };
+ int ret = 0;
+ u32 template_index = 0;
+ u8 algo[USER_DEFINED_TEMPLATE_NUM] = { UB_CC_ALGO_USER_1,
+ UB_CC_ALGO_USER_2 };
+
+ template_index = udma_sysfs_get_index_in_parent_array(
+ (struct udma_sysfs_head *)parent->head.parent_addr);
+ if (template_index >= USER_DEFINED_TEMPLATE_NUM) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to get user_defined cc, index: %d not in [0, %d).\n",
+ template_index, USER_DEFINED_TEMPLATE_NUM);
+ return -EINVAL;
+ }
+ cc_param.ub_cc_algo = algo[template_index];
+ cc_param.index =
+ (u8)udma_sysfs_get_index_in_parent_array(&(parent->head));
+ cc_param.dw[DW_IDX0] = parent->dw0;
+ cc_param.dw[DW_IDX1] = parent->dw1;
+ cc_param.dw[DW_IDX2] = parent->dw2;
+ cc_param.dw[DW_IDX3] = parent->dw3;
+
+ ret = udma_cc_set_para(udma_dev, &cc_param);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to update cc pattern, algo: %d, index: %d, ret: %d\n",
+ cc_param.ub_cc_algo, cc_param.index, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void udma_sysfs_set_def_value_u8(void *value_addr, u32 def, u32 array_num)
+{
+ u8 *value = (u8 *)value_addr;
+
+ for (u32 i = 0; i < array_num; ++i) {
+ value[i] = (u8)def;
+ }
+}
+
+void udma_sysfs_set_def_value_u16(void *value_addr, u32 def, u32 array_num)
+{
+ u16 *value = (u16 *)value_addr;
+
+ for (u32 i = 0; i < array_num; ++i) {
+ value[i] = (u16)def;
+ }
+}
+
+void udma_sysfs_set_def_value_u32(void *value_addr, u32 def, u32 array_num)
+{
+ u32 *value = (u32 *)value_addr;
+
+ for (u32 i = 0; i < array_num; ++i) {
+ value[i] = def;
+ }
+}
+
+void udma_sysfs_set_def_value_wred(void *value_addr, u32 def, u32 array_num)
+{
+ struct udma_rx_rate_limit_wred *wred =
+ (struct udma_rx_rate_limit_wred *)value_addr;
+
+ wred->cmd = def;
+ wred->wred_idx = def;
+ wred->start_val = def;
+ wred->end_val = def;
+}
+
+/**
+ * @brief u8 class parameters show processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @details use to handle u8 type parameters of show dynamic as
+ */
+ssize_t udma_sysfs_show_u8(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf)
+{
+ u8 *value = (u8 *)udma_sysfs_get_child_value(
+ head, node->position_info.offset);
+
+ return sprintf_s(buf, PAGE_SIZE - 1, "%u\n", *value);
+}
+
+/**
+ * @brief u16 class parameters show processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @details use to handle u16 type parameters of show dynamic as
+ */
+ssize_t udma_sysfs_show_u16(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf)
+{
+ u16 *value = (u16 *)udma_sysfs_get_child_value(
+ head, node->position_info.offset);
+
+ return sprintf_s(buf, PAGE_SIZE - 1, "%u\n", *value);
+}
+
+/**
+ * @brief u32 class parameters show processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @details use to handle u32 type parameters of show dynamic as
+ */
+ssize_t udma_sysfs_show_u32(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf)
+{
+ u32 *value = (u32 *)udma_sysfs_get_child_value(
+ head, node->position_info.offset);
+
+ return sprintf_s(buf, PAGE_SIZE - 1, "%u\n", *value);
+}
+/**
+ * @brief struct udma_rx_rate_limit_wred class parameters show processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @details use to handle struct udma_rx_rate_limit_wred type parameters of show dynamic as
+ */
+ssize_t udma_sysfs_show_wred(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf)
+{
+ struct udma_rx_rate_limit_wred *wred =
+ (struct udma_rx_rate_limit_wred *)udma_sysfs_get_child_value(
+ head, node->position_info.offset);
+
+ return sprintf_s(buf, PAGE_SIZE - 1,
+ "wred_idx=%u start_val=%u end_val=%u\n",
+ wred->wred_idx, wred->start_val, wred->end_val);
+}
+
+u32 udma_sysfs_read_u32(const void *value, u32 type_size)
+{
+ switch (type_size) {
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U8:
+ return (u32)(*(u8 *)value);
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U16:
+ return (u32)(*(u16 *)value);
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U32:
+ return *(u32 *)value;
+ default:
+ return 0;
+ }
+}
+
+void udma_sysfs_write_u32(const void *value, u32 type_size, u32 new_value)
+{
+ switch (type_size) {
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U8:
+ *(u8 *)value = (u8)new_value;
+ break;
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U16:
+ *(u16 *)value = (u16)new_value;
+ break;
+ case UDMA_SYSFS_VALUE_TYPE_SIZE_U32:
+ *(u32 *)value = new_value;
+ break;
+ default:
+ break;
+ }
+}
+
+typedef int (*udma_sysfs_u32_post_proc_func)(struct udma_device *udma_dev,
+ void *parent_addr);
+/**
+ * @brief store handle base function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @param[in] post_proc_func: post-processing function
+ * @param[in] type_size: handle when data of type
+ * @details use to handle parameters of store common dynamic as, its in will according to configuration information check value range, and call call handle custom update
+ */
+static int udma_sysfs_store_base(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf,
+ udma_sysfs_u32_post_proc_func post_proc_func,
+ u32 type_size)
+{
+ void *value =
+ udma_sysfs_get_child_value(head, node->position_info.offset);
+ u32 new_value = 0, old_value = udma_sysfs_read_u32(value, type_size);
+ int ret = 0;
+
+ ret = sscanf_s(buf, "%u", &new_value);
+ if (ret != 1) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "Failed to get %s value, ret: %d\n", node->attr.name,
+ ret);
+ return -EIO;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_SYSFS,
+ "%s old value:%u, new value:%u\n", node->attr.name,
+ old_value, new_value);
+ if (new_value == old_value) {
+ return 0;
+ }
+
+ if (new_value < node->value.min || new_value > node->value.max) {
+ udma_err(udma_dev->dev, UDMA_M_SYSFS,
+ "Invalid param: %s, new value(%u) not in [%u, %u]\n",
+ node->attr.name, new_value, node->value.min,
+ node->value.max);
+ return -EINVAL;
+ }
+
+ udma_sysfs_write_u32(value, type_size, new_value);
+ if (post_proc_func != NULL) {
+ ret = post_proc_func(udma_dev, (void *)head);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_SYSFS,
+ "%s, post_proc_func execution Failed, ret = %d\n",
+ node->attr.name, ret);
+ udma_sysfs_write_u32(value, type_size, old_value);
+ return ret;
+ }
+ }
+ udma_debug(udma_dev->dev, UDMA_M_SYSFS, "%s now value:%u\n",
+ node->attr.name, new_value);
+
+ return 0;
+}
+
+/**
+ * @brief u8 class parameters store processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @param[in] post_proc_func: post-processing function
+ * @details use to handle u8 type parameters of store dynamic as, its in will according to configuration information check value range, and call call handle custom update
+ */
+static ssize_t
+udma_sysfs_store_u8_base(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf,
+ udma_sysfs_u32_post_proc_func post_proc_func)
+{
+ return (ssize_t)udma_sysfs_store_base(udma_dev, head, node, buf,
+ post_proc_func, sizeof(u8));
+}
+
+/**
+ * @brief u16 class parameters store processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @param[in] post_proc_func: post-processing function
+ * @details use to handle u16 type parameters of store dynamic as, its in will according to configuration information check value range, and call call handle custom update
+ */
+static ssize_t
+udma_sysfs_store_u16_base(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf,
+ udma_sysfs_u32_post_proc_func post_proc_func)
+{
+ return udma_sysfs_store_base(udma_dev, head, node, buf, post_proc_func,
+ sizeof(u16));
+}
+
+/**
+ * @brief u32 class parameters store processing function
+ * @param[in] udma_dev: udma device information
+ * @param[in] head: data information of the directory where file is located
+ * @param[in] node: configuration information of file
+ * @param[in] buf: user modify of information
+ * @param[in] post_proc_func: post-processing function
+ * @details use to handle u32 type parameters of store dynamic as, its in will according to configuration information check value range, and call call handle custom update
+ */
+static ssize_t
+udma_sysfs_store_u32_base(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf,
+ udma_sysfs_u32_post_proc_func post_proc_func)
+{
+ return udma_sysfs_store_base(udma_dev, head, node, buf, post_proc_func,
+ sizeof(u32));
+}
+
+ssize_t udma_sysfs_store_u32(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf)
+{
+ return udma_sysfs_store_u32_base(udma_dev, head, node, buf, NULL);
+}
+
+ssize_t udma_sysfs_store_u32_set_ta2tp_type(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u32_base(udma_dev, head, node, buf,
+ udma_sysfs_set_ta2tp_type);
+}
+
+ssize_t udma_sysfs_store_u32_set_ldcp(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u32_base(udma_dev, head, node, buf,
+ udma_sysfs_set_ldcp);
+}
+
+ssize_t udma_sysfs_store_u32_set_caqm(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u32_base(udma_dev, head, node, buf,
+ udma_sysfs_set_caqm);
+}
+
+ssize_t udma_sysfs_store_u32_set_user_defined(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u32_base(udma_dev, head, node, buf,
+ udma_sysfs_set_user_defined);
+}
+ssize_t udma_sysfs_store_u8_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u8_base(udma_dev, head, node, buf,
+ udma_sysfs_set_rx_rate_limit);
+}
+ssize_t udma_sysfs_store_u16_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ return udma_sysfs_store_u16_base(udma_dev, head, node, buf,
+ udma_sysfs_set_rx_rate_limit);
+}
+
+/* sysfs wred config usage:
+ * echo wr id start end > /sysfs/.../wred
+ * echo rd id > /sysfs/.../wred
+ * cat /sysfs/.../wred */
+#define UDMA_MAX_WRED_CMD_STR_LEN 3
+#define UDMA_WRED_WR_ARGC 3
+#define UDMA_WRED_RD_ARGC 1
+
+static int udma_get_wred_cmd(struct udma_device *udma_dev,
+ struct udma_rx_rate_limit_wred *wred,
+ const char *buf)
+{
+ int ret;
+ u32 cmd = 0, idx = 0, start = 0, end = 0;
+ const char *argv_str = NULL;
+
+ if (strlen(buf) <= UDMA_MAX_WRED_CMD_STR_LEN) {
+ goto wred_str_err;
+ }
+
+ argv_str = buf + UDMA_MAX_WRED_CMD_STR_LEN;
+ if (strncmp(buf, "wr ", UDMA_MAX_WRED_CMD_STR_LEN) == 0) {
+ ret = sscanf_s(argv_str, "%u %u %u", &idx, &start, &end);
+ if (ret != UDMA_WRED_WR_ARGC) {
+ goto wred_str_err;
+ }
+ } else if (strncmp(buf, "rd ", UDMA_MAX_WRED_CMD_STR_LEN) == 0) {
+ ret = sscanf_s(argv_str, "%u", &idx);
+ if (ret != UDMA_WRED_RD_ARGC) {
+ goto wred_str_err;
+ }
+ cmd = 1;
+ } else {
+ goto wred_str_err;
+ }
+
+ if (idx > UDMA_ACC_MAX_WRED_IDX || end > UDMA_ACC_MAX_WRED_VAL ||
+ start > end) {
+ udma_err(udma_dev->dev, UDMA_M_RX_RATE_LIMITE,
+ "Invalid wred args: %u %u %u\n", idx, start, end);
+ goto wred_str_err;
+ }
+
+ wred->cmd = cmd;
+ wred->wred_idx = idx;
+ wred->start_val = start;
+ wred->end_val = end;
+
+ return 0;
+wred_str_err:
+ udma_err(udma_dev->dev, UDMA_M_RX_RATE_LIMITE, "Invalid wred cmd %s\n",
+ buf);
+ return -EINVAL;
+}
+
+ssize_t udma_sysfs_store_wred_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf)
+{
+ struct udma_rx_rate_limit_wred *wred =
+ (struct udma_rx_rate_limit_wred *)udma_sysfs_get_child_value(
+ head, node->position_info.offset);
+ int ret = 0;
+
+ ret = udma_get_wred_cmd(udma_dev, wred, buf);
+ if (ret != 0) {
+ return (ssize_t)ret;
+ }
+
+ ret = udma_rx_rate_limit_cfg_wred(udma_dev, wred->cmd, wred->wred_idx,
+ &wred->start_val, &wred->end_val);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_RX_RATE_LIMITE,
+ "Config wred value failed: %d\n", ret);
+ }
+
+ return (ssize_t)ret;
+}
+
+int udma_sysfs_name_oneself(const char *name, int index, void *ext_value,
+ char *out_name)
+{
+ return sprintf_s(out_name, UDMA_SYSFS_NAME_MAX_LEN, "%s", name);
+}
+
+int udma_sysfs_name_index(const char *name, int index, void *ext_value,
+ char *out_name)
+{
+ return sprintf_s(out_name, UDMA_SYSFS_NAME_MAX_LEN, "%d", index);
+}
+
+int udma_sysfs_name_oneself_index_plus_one(const char *name, int index,
+ void *ext_value, char *out_name)
+{
+ return sprintf_s(out_name, UDMA_SYSFS_NAME_MAX_LEN, "%s_%d", name,
+ index + 1);
+}
+
+int udma_sysfs_get_mtt_pro_en(struct udma_sysfs_res *sysfs_res, u32 *mtt_pro_en)
+{
+ struct udma_dfx_perf_pattern *perf = &sysfs_res->dfx_ctx.perf;
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(sysfs_res);
+ int ret = 0;
+
+ *mtt_pro_en = perf->huge_page_en;
+ if (*mtt_pro_en == 1) {
+ return 0;
+ }
+
+ ret = udma_get_mtt_protect_state(udma_dev, mtt_pro_en);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "update mtt protect state failed, ret = %d\n", ret);
+ }
+
+ return ret;
+}
+
+u32 udma_sysfs_get_huge_page_en(struct udma_sysfs_res *sysfs_res)
+{
+ struct udma_dfx_perf_pattern *perf = &sysfs_res->dfx_ctx.perf;
+
+ return perf->huge_page_en;
+}
+
+bool udma_sysfs_get_debug_en(struct udma_sysfs_res *sysfs_res)
+{
+ return (sysfs_res->dfx_ctx.debug_en == 1);
+}
+
+bool udma_sysfs_get_fis_en(struct udma_sysfs_res *sysfs_res)
+{
+ return (sysfs_res->dfx_ctx.perf.fis_en == 1);
+}
+
+#define UDMA_SYSFS_XID_LOW_3_BIT_VALID_MASK 0x1
+#define UDMA_SYSFS_XID_LOW_3_BIT_VALID_SHIFT 0x1
+bool udma_sysfs_get_xid_low_3_bit(struct udma_sysfs_res *sysfs_res,
+ u32 *out_value)
+{
+ u32 num = 0;
+
+ num = sysfs_res->dfx_ctx.perf.xid_low_3_bit;
+
+ if ((num & UDMA_SYSFS_XID_LOW_3_BIT_VALID_MASK) == 0) {
+ return false;
+ }
+
+ *out_value = num >> UDMA_SYSFS_XID_LOW_3_BIT_VALID_SHIFT;
+
+ return true;
+}
+
+int udma_sysfs_init_dwqe_dis(struct udma_device *udma_dev, void *parent_addr)
+{
+ struct udma_dfx_perf_pattern *parent =
+ (struct udma_dfx_perf_pattern *)parent_addr;
+
+ parent->dwqe_dis = udma_dev->ub_cap.dev_cap.dwqe_dis;
+
+ return 0;
+}
+
+u32 udma_sysfs_get_dwqe_dis(struct udma_sysfs_res *sysfs_res)
+{
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(sysfs_res);
+
+ return udma_dev->ub_cap.dev_cap.dwqe_dis;
+}
+
+u32 udma_sysfs_get_tp_depth(struct udma_sysfs_res *sysfs_res)
+{
+ struct udma_device *udma_dev = to_udma_dev_by_sysfs(sysfs_res);
+
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ return TP_Q_DEF_DEPTH;
+ }
+
+ return (1 << sysfs_res->dfx_ctx.perf.tp_depth_shift);
+}
+
+int udma_sysfs_set_tp_depth(struct udma_sysfs_res *sysfs_res, u32 new_value)
+{
+#define DWORD_BITS 32
+ struct udma_dfx_perf_pattern *perf = &sysfs_res->dfx_ctx.perf;
+ struct attribute attr = { .name = "tp_depth_shift" };
+ char buf[UDMA_SYSFS_NAME_MAX_LEN];
+ u32 new_value_shift = 0;
+ int count = 0;
+
+ new_value_shift = (u32)ilog2(new_value);
+ if (new_value_shift >= DWORD_BITS) {
+ return -EINVAL;
+ }
+ if (new_value != (1 << new_value_shift)) {
+ return -EINVAL;
+ }
+
+ count = sprintf_s(buf, UDMA_SYSFS_NAME_MAX_LEN, "%u", new_value_shift);
+ if (count < 0) {
+ return count;
+ }
+
+ return (int)udma_sysfs_common_store(&perf->head.kobj, &attr, buf,
+ (size_t)count);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.h b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.h
new file mode 100644
index 000000000..44e50b784
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_common.h
@@ -0,0 +1,88 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_SYSFS_COMMON_H
+#define UDMA_SYSFS_COMMON_H
+
+#include "udma_sysfs.h"
+#include "udma_common.h"
+
+static inline struct udma_device *
+to_udma_dev_by_sysfs(const struct udma_sysfs_res *sysfs)
+{
+ return (struct udma_device *)container_of(sysfs, struct udma_device,
+ sysfs_res);
+}
+
+static inline struct udma_sysfs_head *
+to_sysfs_head_by_kobject(const struct kobject *kobject)
+{
+ return (struct udma_sysfs_head *)container_of(
+ kobject, struct udma_sysfs_head, kobj);
+}
+
+void udma_sysfs_set_def_value_u8(void *value_addr, u32 def, u32 array_num);
+void udma_sysfs_set_def_value_u16(void *value_addr, u32 def, u32 array_num);
+void udma_sysfs_set_def_value_u32(void *value_addr, u32 def, u32 array_num);
+void udma_sysfs_set_def_value_wred(void *value_addr, u32 def, u32 array_num);
+ssize_t udma_sysfs_show_u8(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf);
+ssize_t udma_sysfs_show_u16(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf);
+ssize_t udma_sysfs_show_u32(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf);
+ssize_t udma_sysfs_show_wred(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, char *buf);
+ssize_t udma_sysfs_store_u32(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node, const char *buf);
+ssize_t udma_sysfs_store_u32_set_ta2tp_type(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_u32_set_ldcp(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_u32_set_caqm(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_u32_set_user_defined(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_u8_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_u16_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+ssize_t udma_sysfs_store_wred_set_rx_rate_limit(struct udma_device *udma_dev,
+ struct udma_sysfs_head *head,
+ struct udma_sysfs_node *node,
+ const char *buf);
+
+int udma_sysfs_name_oneself(const char *name, int index, void *ext_value,
+ char *out_name);
+int udma_sysfs_name_index(const char *name, int index, void *ext_value,
+ char *out_name);
+int udma_sysfs_name_oneself_index_plus_one(const char *name, int index,
+ void *ext_value, char *out_name);
+
+int udma_sysfs_set_rx_rate_limit(struct udma_device *udma_dev,
+ void *parent_addr);
+int udma_sysfs_set_ldcp(struct udma_device *udma_dev, void *parent_addr);
+int udma_sysfs_set_caqm(struct udma_device *udma_dev, void *parent_addr);
+int udma_sysfs_set_user_defined(struct udma_device *udma_dev,
+ void *parent_addr);
+int udma_sysfs_init_dwqe_dis(struct udma_device *udma_dev, void *parent_addr);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.c b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.c
new file mode 100644
index 000000000..9d0820001
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#include <linux/stat.h>
+
+#include "udma_sysfs.h"
+#include "udma_sysfs_common.h"
+#include "udma_sysfs_config.h"
+
+#define UDMA_SYSFS_FILE_MODE (S_IWUGO | S_IRUGO)
+#define UDMA_SYSFS_NAME_INIT(_name) \
+ { \
+ .name = (_name), .mode = UDMA_SYSFS_FILE_MODE \
+ }
+#define UDMA_SYSFS_OPS_INIT(_show, _store) \
+ { \
+ .show = (_show), .store = (_store) \
+ }
+#define UDMA_SYSFS_NODE_VALUE_INIT(_min, _def, _max, _set_def_value) \
+ { \
+ .min = (_min), .def = (_def), .max = (_max), \
+ .set_def_value = (_set_def_value) \
+ }
+#define UDMA_SYSFS_NODE_VALUE_INIT_U8(_min, _def, _max) \
+ UDMA_SYSFS_NODE_VALUE_INIT((_min), (_def), (_max), \
+ (udma_sysfs_set_def_value_u8))
+#define UDMA_SYSFS_NODE_VALUE_INIT_U16(_min, _def, _max) \
+ UDMA_SYSFS_NODE_VALUE_INIT((_min), (_def), (_max), \
+ (udma_sysfs_set_def_value_u16))
+#define UDMA_SYSFS_NODE_VALUE_INIT_U32(_min, _def, _max) \
+ UDMA_SYSFS_NODE_VALUE_INIT((_min), (_def), (_max), \
+ udma_sysfs_set_def_value_u32)
+#define UDMA_SYSFS_NAME_EXT_INIT(_func, _ext_value) \
+ { \
+ .get_name_func = (_func), .ext_value = (_ext_value) \
+ }
+#define UDMA_SYSFS_SUPPORT_INIT(_type, _version) \
+ { \
+ .func_type = (_type), .func_ver = (_version) \
+ }
+#define UDMA_SYSFS_CHILD_NODE_INIT(child_node_list) \
+ { \
+ .node_list = child_node_list, \
+ .length = ARRAY_SIZE(child_node_list) \
+ }
+#define UDMA_SYSFS_POSITION_INFO_INIT(_parent_type, _member, _oneself_type, \
+ _array_num) \
+ { \
+ .offset = offsetof(_parent_type, _member), \
+ .array_num = (_array_num), \
+ .element_size = sizeof(_oneself_type) \
+ }
+
+/* corresponding dfx->perf directory content, see @ > struct udma_dfx_perf_pattern */
+static struct udma_sysfs_node g_sysfs_dir_dfx_perf[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("jetty_slice_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, jetty_slice_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 1, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("ta2tp_type"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, ta2tp_type, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 3),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ta2tp_type) },
+ { .attr = UDMA_SYSFS_NAME_INIT("xid_low_3_bit"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, xid_low_3_bit, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 15),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ {
+ .attr = UDMA_SYSFS_NAME_INIT("dwqe_dis"),
+ .name_ext =
+ UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(
+ UDMA_SYSFS_TAF, UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, dwqe_dis, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32),
+ .ext_update = udma_sysfs_init_dwqe_dis,
+ },
+ { .attr = UDMA_SYSFS_NAME_INIT("tp_depth_shift"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, tp_depth_shift, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(6, 7, 11),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("huge_page_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, huge_page_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("fis_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_perf_pattern, fis_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+};
+
+/* corresponding dfx directory content, see @ > struct udma_dfx_ctx */
+static struct udma_sysfs_node g_sysfs_dir_dfx[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("perf"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_ALL,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_dfx_ctx, perf, struct udma_dfx_perf_pattern, 1),
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_dfx_perf) },
+ { .attr = UDMA_SYSFS_NAME_INIT("debug_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_ALL,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ debug_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("drop_aeqe_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_ALL,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ drop_aeqe_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("dump_tp_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ dump_tp_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 1, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("tid"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ tid, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UDMA_MAX_TOKEN_ID_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("eid"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ eid, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UDMA_MAX_EID_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+ { .attr = UDMA_SYSFS_NAME_INIT("hbm_en"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TAF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(struct udma_dfx_ctx,
+ hbm_en, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, 1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32) },
+};
+
+/* corresponding cc->ldcp->pattern directory content, see @ > struct udma_ldcp_pattern_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_ldcp_pattern[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("init_wnd"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, init_wnd, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(UDMA_MIN_LDCP_PARA,
+ UDMA_DEFAULT_INIT_WND,
+ UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("alpha"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, alpha, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_LDCP_PARA, UDMA_DEFAULT_ALPHA, UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("beta"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, beta, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_LDCP_PARA, UDMA_DEFAULT_BETA, UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("gamma"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, gamma, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_LDCP_PARA, UDMA_DEFAULT_GAMMA, UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("eta"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, eta, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_LDCP_PARA, UDMA_DEFAULT_ETA, UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("wnd_min"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_ldcp_pattern_ctx, wnd_min, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_LDCP_PARA, UDMA_DEFAULT_WND_MIN, UDMA_MAX_LDCP_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_ldcp) },
+};
+
+/* corresponding cc->ldcp directory content, see @ > struct udma_cc_ldcp_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_ldcp[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("pattern"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_index, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_ldcp_ctx, pattern,
+ struct udma_ldcp_pattern_ctx, LDCP_PATTERN_ARRAY_LEN),
+ .ext_update = udma_sysfs_set_ldcp,
+ .child_info =
+ UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc_ldcp_pattern) },
+};
+
+/* corresponding cc->caqm->pattern directory content, see @ > struct udma_caqm_pattern_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_caqm_pattern[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_alpha"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, alpha, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_CAQM_PARA, UDMA_DEFAULT_ALPHA, UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_beta"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, beta, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_CAQM_PARA, UDMA_DEFAULT_BETA, UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_eta"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, eta, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_CAQM_PARA, UDMA_DEFAULT_ETA, UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_wnd_min"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, wnd_min, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_CAQM_PARA, UDMA_DEFAULT_WND_MIN, UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_init_wnd"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, init_wnd, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(UDMA_MIN_CAQM_PARA,
+ UDMA_DEFAULT_INIT_WND,
+ UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm_cc_unit"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_caqm_pattern_ctx, cc_unit, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(
+ UDMA_MIN_CAQM_PARA, UDMA_DEFAULT_CC_UNIT, UDMA_MAX_CAQM_PARA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_caqm) },
+};
+
+/* corresponding cc->caqm directory content, see @ > struct udma_cc_caqm_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_caqm[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("pattern"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_index, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_caqm_ctx, pattern,
+ struct udma_caqm_pattern_ctx, CAQM_PATTERN_ARRAY_LEN),
+ .ext_update = udma_sysfs_set_caqm,
+ .child_info =
+ UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc_caqm_pattern) },
+};
+
+/* corresponding cc->user_defined->pattern directory content, see @ > struct udma_user_defined_pattern_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_user_defined_pattern[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("dw0"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_user_defined_pattern_ctx, dw0, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UINT_MAX),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_user_defined) },
+ { .attr = UDMA_SYSFS_NAME_INIT("dw1"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_user_defined_pattern_ctx, dw1, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UINT_MAX),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_user_defined) },
+ { .attr = UDMA_SYSFS_NAME_INIT("dw2"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_user_defined_pattern_ctx, dw2, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UINT_MAX),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_user_defined) },
+ { .attr = UDMA_SYSFS_NAME_INIT("dw3"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_user_defined_pattern_ctx, dw3, u32, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U32(0, 0, UINT_MAX),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u32,
+ udma_sysfs_store_u32_set_user_defined) },
+};
+
+/* corresponding cc->user_defined directory of content, see @ > struct udma_cc_user_defined_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc_user_defined[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("pattern"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_index, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_user_defined_ctx, pattern,
+ struct udma_user_defined_pattern_ctx,
+ USER_DEFINED_PATTERN_ARRAY_LEN),
+ //.ext_update = udma_sysfs_set_user_defined, // todo mpu side not adaptation, pending mpu side adaptation after place enable
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(
+ g_sysfs_dir_cc_user_defined_pattern) },
+};
+
+/* corresponding cc directory content, see @ > struct udma_cc_ctx */
+static struct udma_sysfs_node g_sysfs_dir_cc[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("ldcp"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_ctx, ldcp, struct udma_cc_ldcp_ctx, 1),
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc_ldcp) },
+ { .attr = UDMA_SYSFS_NAME_INIT("caqm"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_ctx, caqm, struct udma_cc_caqm_ctx, 1),
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc_caqm) },
+ { .attr = UDMA_SYSFS_NAME_INIT("user_defined"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(
+ udma_sysfs_name_oneself_index_plus_one, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_cc_ctx, user_defined,
+ struct udma_cc_user_defined_ctx, USER_DEFINED_TEMPLATE_NUM),
+ .child_info =
+ UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc_user_defined) },
+};
+
+/* corresponding cc directory content, see @ > struct udma_cc_ctx */
+static struct udma_sysfs_node g_sysfs_dir_rx_rate_limit[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("down_period"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, down_period, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_DOWN_PERIOD,
+ UDMA_ACC_DEFAULT_DOWN_PERIOD,
+ UDMA_ACC_MAX_DOWN_PERIOD),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("up_period"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, up_period, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_UP_PERIOD,
+ UDMA_ACC_DEFAULT_UP_PERIOD,
+ UDMA_ACC_MAX_UP_PERIOD),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("alpha1"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, alpha1, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_ALPHA1,
+ UDMA_ACC_DEFAULT_ALPHA1,
+ UDMA_ACC_MAX_ALPHA1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("n1"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, n1, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(
+ UDMA_ACC_MIN_N1, UDMA_ACC_DEFAULT_N1, UDMA_ACC_MAX_N1),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("alpha2"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, alpha2, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_ALPHA2,
+ UDMA_ACC_DEFAULT_ALPHA2,
+ UDMA_ACC_MAX_ALPHA2),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("alpha3"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, alpha3, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_ALPHA3,
+ UDMA_ACC_DEFAULT_ALPHA3,
+ UDMA_ACC_MAX_ALPHA3),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("min_rate"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, min_rate, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(UDMA_ACC_MIN_MIN_RATE,
+ UDMA_ACC_DEFAULT_MIN_RATE,
+ UDMA_ACC_MAX_MIN_RATE),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("init_rate"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, init_rate, u8, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U8(UDMA_MIN_INIT_RATE,
+ UDMA_ACC_DEFAULT_INIT_RATE,
+ UDMA_MAX_INIT_RATE),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u16,
+ udma_sysfs_store_u16_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("n2"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, n2, u8, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U8(
+ UDMA_ACC_MIN_N2, UDMA_ACC_DEFAULT_N2, UDMA_ACC_MAX_N2),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u8,
+ udma_sysfs_store_u8_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("beta"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, beta, u16, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT_U16(
+ UDMA_ACC_MIN_BETA, UDMA_ACC_DEFAULT_BETA, UDMA_ACC_MIN_BETA),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_u8,
+ udma_sysfs_store_u8_set_rx_rate_limit) },
+ { .attr = UDMA_SYSFS_NAME_INIT("wred"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_FILE,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_rx_rate_limit_ctx, wred,
+ struct udma_rx_rate_limit_wred, 1),
+ .value = UDMA_SYSFS_NODE_VALUE_INIT(0, 0, UINT_MAX,
+ udma_sysfs_set_def_value_u32),
+ .ops = UDMA_SYSFS_OPS_INIT(udma_sysfs_show_wred,
+ udma_sysfs_store_wred_set_rx_rate_limit) },
+};
+
+/* directory structure:
+ * ├── dfx (see @ > g_sysfs_dir_dfx)
+ * │ ├── perf (see @ > g_sysfs_dir_dfx_perf)
+ * │ │ ├── jetty_slice_en
+ * │ │ ├── xid_low_3_bit
+ * │ │ ├── dwqe_dis
+ * │ │ ├── tp_depth_shift
+ * │ │ ├── huge_page_en
+ * │ │ └── ta2tp_type
+ * │ ├── debug_en
+ * │ ├── drop_aeqe_en
+ * │ └── dump_tp_en
+ * ├── rx_rate_limit (see @ > g_sysfs_dir_rx_rate_limit)
+ * │ ├── down_period
+ * │ ├── up_period
+ * │ ├── alpha1
+ * │ ├── n1
+ * │ ├── alpha2
+ * │ ├── alpha3
+ * │ ├── min_rate
+ * │ ├── init_rate
+ * │ ├── n2
+ * │ ├── beta
+ * │ └── wred
+ * └── cc (see @ > g_sysfs_dir_cc)
+ * ├── ldcp (see @ > g_sysfs_dir_cc_ldcp)
+ * │ └── pattern (see @ > g_sysfs_dir_cc_ldcp_pattern) // actual directory name is 0-7, total 8(count word) directory
+ * │ ├── init_wnd
+ * │ ├── alpha
+ * │ ├── beta
+ * │ ├── gamma
+ * │ ├── eta
+ * │ └── wnd_min
+ * ├── caqm (see @ > g_sysfs_dir_cc_caqm)
+ * │ └── pattern (see @ > g_sysfs_dir_cc_caqm_pattern) // actual directory name is 0-2, total 3(count word) directory
+ * │ ├── caqm_alpha
+ * │ ├── caqm_beta
+ * │ ├── caqm_eta
+ * │ ├── caqm_wnd_min
+ * │ ├── caqm_init_wnd
+ * │ └── caqm_cc_unit
+ * └── user_defined (see @ > g_sysfs_dir_cc_user_defined) // actual directory name is user_defined_1-2, total 2(count word) directory
+ * └── pattern (see @ > g_sysfs_dir_cc_user_defined_pattern) // actual directory name is 0-7, total 8(count word) directory
+ * ├── dw0
+ * ├── dw1
+ * ├── dw2
+ * └── dw3
+ * */
+
+/* corresponding sysfs root directory content, see @ > struct udma_sysfs_res */
+static struct udma_sysfs_node g_sysfs_config_info[] = {
+ { .attr = UDMA_SYSFS_NAME_INIT("dfx"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_ALL,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_sysfs_res, dfx_ctx, struct udma_dfx_ctx, 1),
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_dfx) },
+ { .attr = UDMA_SYSFS_NAME_INIT("cc"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_sysfs_res, cc_ctx, struct udma_cc_ctx, 1),
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_cc) },
+ { .attr = UDMA_SYSFS_NAME_INIT("rx_rate_limit"),
+ .name_ext = UDMA_SYSFS_NAME_EXT_INIT(udma_sysfs_name_oneself, NULL),
+ .type = UDMA_SYSFS_NODE_DIR,
+ .support_info = UDMA_SYSFS_SUPPORT_INIT(UDMA_SYSFS_TPF,
+ UDMA_DEV_TYPE_HI1825_V100),
+ .position_info = UDMA_SYSFS_POSITION_INFO_INIT(
+ struct udma_sysfs_res, rx_rate_limit_ctx,
+ struct udma_rx_rate_limit_ctx, 1),
+ .ext_update = udma_sysfs_set_rx_rate_limit,
+ .child_info = UDMA_SYSFS_CHILD_NODE_INIT(g_sysfs_dir_rx_rate_limit) },
+};
+
+struct udma_sysfs_node *udma_sysfs_get_config_info(void)
+{
+ return g_sysfs_config_info;
+}
+
+int udma_sysfs_get_config_length(void)
+{
+ return ARRAY_SIZE(g_sysfs_config_info);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.h b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.h
new file mode 100644
index 000000000..6d7d1ae77
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/sysfs/udma_sysfs_config.h
@@ -0,0 +1,13 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+
+
+#ifndef UDMA_SYSFS_CONFIG_H
+#define UDMA_SYSFS_CONFIG_H
+
+#include "udma_sysfs.h"
+
+struct udma_sysfs_node *udma_sysfs_get_config_info(void);
+int udma_sysfs_get_config_length(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.c b/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.c
new file mode 100644
index 000000000..1543c35ec
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.c
@@ -0,0 +1,330 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <net/ipv6.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/iommu.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include "ubcore_api.h"
+/*
+ * Generally, a driver should not include ubcore_uapi.h for kernel users,
+ * the udma_pci driver for simluation calls ubcore_find_jfs/jfrin the ubcore_uapi.h to reduce complexity
+ */
+#include "hinic5_crm.h"
+#include "hinic5_profile.h"
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "udma_cmd.h"
+#include "udma_cmd_sip.h"
+#include "udma_cmd_eid.h"
+#include "udma_net.h"
+
+static void udma_fill_sip_update_cmd(struct ub_sip_attr *sip_attr,
+ const struct ubcore_net_addr *net_addr)
+{
+ vlan_u vlan = { 0 };
+
+ if (net_addr->type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ sip_attr->sip3 = net_addr->net_addr.in4.addr;
+ sip_attr->dw6.sip_type = 0;
+ } else {
+ sip_attr->sip0 = net_addr->net_addr.in6.subnet_prefix &
+ 0xffffffff;
+ sip_attr->sip1 =
+ (net_addr->net_addr.in6.subnet_prefix >> 0x20) &
+ 0xffffffff;
+ sip_attr->sip2 = net_addr->net_addr.in6.interface_id &
+ 0xffffffff;
+ sip_attr->sip3 = (net_addr->net_addr.in6.interface_id >> 0x20) &
+ 0xffffffff;
+ sip_attr->dw6.sip_type = 1;
+ }
+ sip_attr->dw6.smac_h16 =
+ UDMA_GET_MAC_HI(net_addr->mac[0], net_addr->mac[1]);
+ sip_attr->smac_l32 =
+ UDMA_GET_MAC_LO(net_addr->mac[0x2], net_addr->mac[0x3],
+ net_addr->mac[0x4], net_addr->mac[0x5]);
+
+ vlan.value = (u16)net_addr->vlan;
+ sip_attr->dw4.cvlan = vlan.bs.vlan;
+ sip_attr->dw4.vlan_cfi = vlan.bs.cfi;
+ sip_attr->dw4.vlan_pri = vlan.bs.pri;
+ sip_attr->dw6.tag = (vlan.bs.vlan != 0) ? VLAN_VALID : VLAN_INVALID;
+
+ sip_attr->sip0 = be32_to_cpu(sip_attr->sip0);
+ sip_attr->sip1 = be32_to_cpu(sip_attr->sip1);
+ sip_attr->sip2 = be32_to_cpu(sip_attr->sip2);
+ sip_attr->sip3 = be32_to_cpu(sip_attr->sip3);
+}
+
+static void udma_show_sip_info(struct udma_device *udma_dev,
+ const struct ub_sip_attr *sip_attr)
+{
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "sip0:0x%x\n", sip_attr->sip0);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "sip1:0x%x\n", sip_attr->sip1);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "sip2:0x%x\n", sip_attr->sip2);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "sip3:0x%x\n", sip_attr->sip3);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "dw4:0x%x\n",
+ sip_attr->dw4.dw4_value);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "dw5:0x%x\n",
+ sip_attr->dw5.dw5_value);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "dw6:0x%x\n",
+ sip_attr->dw6.dw6_value);
+ udma_debug(udma_dev->dev, UDMA_M_DEV, "smac_l32:0x%x\n",
+ sip_attr->smac_l32);
+}
+
+int udma_query_sip(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr)
+{
+ int ret;
+
+ if (sip_idx >= UDMA_SIP_NUM_MAX) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "sip index in valied, sip_index:%u, maxnum:%d\n",
+ sip_idx, UDMA_SIP_NUM_MAX);
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_sip_query(udma_dev, sip_idx, sip_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "query sip failed, sip_index:%u\n", sip_idx);
+ return ret;
+ }
+ udma_show_sip_info(udma_dev, sip_attr);
+
+ return ret;
+}
+
+int udma_add_netaddr(struct ubcore_device *dev,
+ struct ubcore_net_addr *net_addr, u32 index)
+{
+ struct udma_device *udma_dev = NULL;
+ struct cmd_mpu_addr_info addr_info = { 0 };
+ struct ub_sip_attr sip_attr = { 0 };
+ int ret;
+
+ if (dev == NULL || net_addr == NULL) {
+ udma_pr_err(UDMA_M_DEV,
+ "parameters is incorrect, dev(%d), net_addr(%d).\n",
+ !!dev, !!net_addr);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(dev);
+
+ udma_info(udma_dev->dev, UDMA_M_DEV, "start\n");
+
+ /* issue to MPU */
+ if (net_addr->type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ addr_info.ip_addr.ipv4.val = net_addr->net_addr.in4.addr;
+ addr_info.ip_ver = 0;
+ } else {
+ addr_info.ip_addr.ipv6.high =
+ net_addr->net_addr.in6.subnet_prefix;
+ addr_info.ip_addr.ipv6.low =
+ net_addr->net_addr.in6.interface_id;
+ addr_info.ip_ver = 1;
+ }
+ ret = udma_cfg_ipsu_tbl_ipaddr(udma_dev, &addr_info, TYPE_MPU_IPSU_ADD);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "cfg tbl ip addr failed\n");
+ return ret;
+ }
+
+ /* issue to NPU */
+ udma_fill_sip_update_cmd(&sip_attr, net_addr);
+ ret = udma_cmd_sip_add(udma_dev, index, &sip_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "add sip failed, ret:%d, index:%u\n", ret, index);
+ return ret;
+ }
+
+ ret = udma_query_sip(udma_dev, index, &sip_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "query sip failed, ret:%d\n", ret);
+ }
+
+ return ret;
+}
+
+int udma_del_netaddr(struct ubcore_device *dev, const u32 index)
+{
+ struct udma_device *udma_dev = NULL;
+ struct ub_sip_attr sip_attr = { 0 };
+ struct cmd_mpu_addr_info addr_info = { 0 };
+ int ret;
+
+ if (dev == NULL) {
+ udma_pr_err(UDMA_M_DEV, "parameters is incorrect, dev(%d).\n",
+ !!dev);
+ return -EINVAL;
+ }
+ udma_dev = to_udma_dev(dev);
+ udma_info(udma_dev->dev, UDMA_M_DEV, "delete net addr\n");
+
+ ret = udma_query_sip(udma_dev, index, &sip_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "query sip faild\n");
+ return ret;
+ }
+ if (sip_attr.dw6.sip_type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ addr_info.ip_ver = 0;
+ addr_info.ip_addr.ipv4.val = sip_attr.sip3;
+ } else {
+ addr_info.ip_ver = 1;
+ addr_info.ip_addr.ipv6.high = sip_attr.sip1;
+ addr_info.ip_addr.ipv6.high =
+ (addr_info.ip_addr.ipv6.high << 0x20) | sip_attr.sip0;
+ addr_info.ip_addr.ipv6.low = sip_attr.sip3;
+ addr_info.ip_addr.ipv6.low =
+ (addr_info.ip_addr.ipv6.low << 0x20) | sip_attr.sip2;
+ }
+ ret = udma_cfg_ipsu_tbl_ipaddr(udma_dev, &addr_info, TYPE_MPU_IPSU_DEL);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "unset ip addr failed\n");
+ return ret;
+ }
+
+ ret = udma_cmd_sip_del(udma_dev, index);
+ if (ret != 0)
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "del sip failed, ret:%d, index:%u\n", ret, index);
+
+ return ret;
+}
+
+void udma_fill_ueid_info(struct udma_device *udma_dev,
+ struct ubcore_ueid_cfg *cfg,
+ struct cmd_mpu_ueid_addr_info *addr_info)
+{
+ if (udma_dev->ub_dev.cfg.pattern == UBCORE_PATTERN_1) {
+ addr_info->nlp = 0;
+ if (udma_dev->ub_dev.sip_table.entry->sip_info.addr.type ==
+ UBCORE_NET_ADDR_TYPE_IPV4) {
+ addr_info->ip.ipv4.val = cfg->eid.in4.addr;
+ addr_info->ip_ver = UBCORE_NET_ADDR_TYPE_IPV4;
+ } else {
+ addr_info->ip.ipv6.high = cfg->eid.in6.subnet_prefix;
+ addr_info->ip.ipv6.low = cfg->eid.in6.interface_id;
+ addr_info->ip_ver = UBCORE_NET_ADDR_TYPE_IPV6;
+ }
+ } else {
+ addr_info->nlp = 1;
+ addr_info->upi = cfg->upi;
+ if ((memcpy_s(addr_info->ip.eid.id,
+ sizeof(addr_info->ip.eid.id), cfg->eid.raw,
+ sizeof(cfg->eid.raw))) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "Copy ip eid fail.\n");
+ }
+ }
+}
+
+int udma_cmd_ueid_add(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ struct cmd_mpu_ueid_addr_info addr_info = { 0 };
+
+ int ret;
+ int roll_ret;
+
+ if ((dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_DEV,
+ "Invalid parameter: dev(%d), cfg(%d).\n", !!dev,
+ !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ udma_info(udma_dev->dev, UDMA_M_DEV,
+ "add ueid, vfid: %u, upi: 0x%08x, idx: %u\n", vf_id, cfg->upi,
+ cfg->eid_index);
+
+ if (udma_dev_is_tpf(udma_dev) == 1 &&
+ (vf_id == EID_ERR_VFID ||
+ vf_id == hinic5_global_func_id(udma_dev->hwdev))) {
+ udma_warn(udma_dev->dev, UDMA_M_DEV,
+ "tpf not support add ueid\n");
+ return 0;
+ }
+ /* issue to MPU */
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ udma_fill_ueid_info(udma_dev, cfg, &addr_info);
+ ret = udma_ipsu_ta_vf_ipaddr(udma_dev, &addr_info,
+ TYPE_MPU_IPSU_ADD, vf_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "ta vf add mpu failed, ret: %d \n", ret);
+ return ret;
+ }
+ }
+ /* issue to NPU */
+ ret = udma_ueid_add_npu_cmdq(dev, vf_id, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "npu add ueid failed, ret:%d\n", ret);
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ goto err_add_ueid_to_npu;
+ }
+ return ret;
+ }
+ return 0;
+
+err_add_ueid_to_npu:
+ roll_ret = udma_ipsu_ta_vf_ipaddr(udma_dev, &addr_info,
+ TYPE_MPU_IPSU_DEL, vf_id);
+ if (roll_ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "ta vf ip delete failed ret: %d \n", roll_ret);
+ }
+ return ret;
+}
+
+int udma_cmd_ueid_delete(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+ struct cmd_mpu_ueid_addr_info addr_info = { 0 };
+ int ret;
+
+ if ((dev == NULL) || (cfg == NULL)) {
+ udma_pr_err(UDMA_M_DEV,
+ "Invalid parameter: dev(%d), cfg(%d).\n", !!dev,
+ !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ udma_info(udma_dev->dev, UDMA_M_DEV,
+ "delete ueid, vfid: %u, upi: 0x%08x, idx: %u\n", vf_id,
+ cfg->upi, cfg->eid_index);
+
+ ret = delete_ueid_cmd(dev, vf_id, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV, "Delete ueid failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* issue to mpu */
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100) {
+ udma_fill_ueid_info(udma_dev, cfg, &addr_info);
+ ret = udma_ipsu_ta_vf_ipaddr(udma_dev, &addr_info,
+ TYPE_MPU_IPSU_DEL, vf_id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_DEV,
+ "ta vf ip delete failed ret:%d \n", ret);
+ }
+ }
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.h b/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.h
new file mode 100644
index 000000000..eca88d7a2
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/table_manage/udma_net.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#ifndef UDMA_NET_H
+#define UDMA_NET_H
+
+#include "udma_common.h"
+#include "udma_cmd_sip.h"
+
+#define UDMA_SIP_NUM_MAX (16) // need and sdk in specification corresponding
+
+#define MTU_VAL_256 256
+#define MTU_VAL_512 512
+#define MTU_VAL_1024 1024
+#define MTU_VAL_2048 2048
+#define MTU_VAL_4096 4096
+#define MTU_VAL_8192 8192
+
+#define UDMA_GET_MAC_HI(a, b) (((a) << 8) | (b))
+#define UDMA_GET_MAC_LO(a, b, c, d) \
+ (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+#define VLAN_INVALID 0
+#define VLAN_VALID 1
+
+typedef union tag_vlan {
+ struct {
+#if (BYTE_ORDER == BIG_ENDIAN)
+ u16 pri : 3;
+ u16 cfi : 1;
+ u16 vlan : 12;
+#else
+ u16 vlan : 12;
+ u16 cfi : 1;
+ u16 pri : 3;
+#endif
+ } bs;
+ u16 value;
+} vlan_u;
+
+static inline enum ubcore_mtu udma_mtu_int_to_enum(u32 mtu)
+{
+ if (mtu >= MTU_VAL_8192)
+ return UBCORE_MTU_8192;
+ else if (mtu >= MTU_VAL_4096)
+ return UBCORE_MTU_4096;
+ else if (mtu >= MTU_VAL_2048)
+ return UBCORE_MTU_2048;
+ else if (mtu >= MTU_VAL_1024)
+ return UBCORE_MTU_1024;
+ else if (mtu >= MTU_VAL_512)
+ return UBCORE_MTU_512;
+ else
+ return UBCORE_MTU_256;
+}
+
+static inline enum ubcore_mtu udma_get_support_mtu(u32 mtu)
+{
+ if (mtu >= UBCORE_MTU_8192)
+ return UBCORE_MTU_8192;
+ else if (mtu >= UBCORE_MTU_4096)
+ return UBCORE_MTU_4096;
+ else
+ return UBCORE_MTU_1024;
+}
+
+int udma_add_netaddr(struct ubcore_device *dev,
+ struct ubcore_net_addr *net_addr, u32 index);
+int udma_del_netaddr(struct ubcore_device *dev, const u32 index);
+int udma_query_sip(struct udma_device *udma_dev, u32 sip_idx,
+ struct ub_sip_attr *sip_attr);
+int udma_cmd_ueid_add(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg);
+int udma_cmd_ueid_delete(struct ubcore_device *dev, u16 vf_id,
+ struct ubcore_ueid_cfg *cfg);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.c
new file mode 100644
index 000000000..22410060a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.c
@@ -0,0 +1,1809 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+
+#include "udma_cmd.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_com.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_tpg.h"
+#include "udma_net.h"
+#include "udma_misc.h"
+#include "udma_jetty.h"
+#include "ubcore_uapi.h"
+#include "udma_ubrc_comp.h"
+#include "udma_cmd_tp.h"
+#include "udma_vram.h"
+#include "udma_tp.h"
+
+#define UB_TP_DIP_MASK 0xffffffff
+#define UB_TP_DIP_OFFSET 0x20
+#define RIGHT_SHIFT_NUM 2
+
+enum { UDMA_MULTI_MTU_DISABLE = 0, UDMA_MULTI_MTU_ENABLE };
+
+u32 g_multi_mtu_enable = UDMA_MULTI_MTU_DISABLE;
+module_param(g_multi_mtu_enable, uint, 0664);
+MODULE_PARM_DESC(g_multi_mtu_enable,
+ "0 for only support 4K, 1 for support 1K/4K/8K");
+
+static void udma_tp_kref_release(struct kref *ref_cnt)
+{
+ struct udma_tp *tp = container_of(ref_cnt, struct udma_tp, ref_cnt);
+
+ complete(&tp->comp);
+}
+
+void udma_tp_put(void *obj)
+{
+ struct udma_tp *tp = (struct udma_tp *)obj;
+
+ if (tp != NULL) {
+ kref_put(&tp->ref_cnt, udma_tp_kref_release);
+ }
+}
+
+void udma_tp_get(void *obj)
+{
+ struct udma_tp *tp = (struct udma_tp *)obj;
+
+ kref_get(&tp->ref_cnt);
+}
+
+struct udma_tp *udma_find_tp(struct udma_device *udev, u32 tpn)
+{
+ struct udma_tp *udma_tp = NULL;
+ struct mutex *lock = NULL;
+
+ lock = &udev->device_res->tpn_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(udma_tp, &udev->device_res->tpn_list.node, node) {
+ if (udma_tp->tp_info->xid == tpn) {
+ udma_tp_get(udma_tp);
+ mutex_unlock(lock);
+ return udma_tp;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static int udma_tpn_alloc(struct udma_device *udma_dev,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp)
+{
+ struct udma_tpg *ub_tpg = NULL;
+ struct ubcore_tp *tp = &ub_tp->tp;
+ u32 tp_all_num;
+ u32 i;
+
+ if (cfg->tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "Not support no tpg\n");
+ return -EINVAL;
+ }
+
+ ub_tpg = to_udma_tpg(cfg->tpg);
+ tp->tpg = cfg->tpg;
+ tp_all_num = ub_tpg->tp_num;
+ for (i = 0; i < tp_all_num; i++) {
+ if (ub_tpg->tp_used[i] == 0) {
+ ub_tp->tp_info = ub_tpg->tpinfo_list[i];
+ tp->tpn = ub_tpg->tpinfo_list[i]->xid;
+ ub_tpg->tp_used[i] = 1;
+ ub_tp->tp_info->priv = (void *)ub_tp;
+ ub_tp->entry_cnt = ub_tpg->tp_q_depth;
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "index(%u), tpn(%u)\n", i, tp->tpn);
+ break;
+ }
+ }
+ if (ub_tp->tp_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "The tp is not found in tpg.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct tag_cqm_queue *udma_create_pcqc(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp)
+{
+ return cqm5_object_rdma_queue_create(udma_dev->hwdev, SERVICE_T_UB,
+ CQM_OBJECT_RDMA_SCQ, TP_PCQC_SIZE,
+ NULL, false, ub_tp->tp_info->xid,
+ 0, 0);
+}
+
+static void udma_tpn_free(struct udma_device *udma_dev, struct udma_tp *ub_tp)
+{
+ struct ubcore_tp *tp = &ub_tp->tp;
+ struct udma_tpg *ub_tpg = NULL;
+ u32 i;
+
+ if (tp->tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "Not support no tpg\n");
+ tp->tpn = TPN_INVALID_NUM;
+ return;
+ }
+
+ ub_tpg = to_udma_tpg(tp->tpg);
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ if (ub_tpg->tpinfo_list[i] != NULL &&
+ ub_tpg->tpinfo_list[i]->xid == tp->tpn) {
+ ub_tpg->tp_used[i] = 0;
+ }
+ }
+
+ tp->tpn = TPN_INVALID_NUM;
+}
+
+static void udma_create_qp_kernel_set_attr(struct udma_tp *ub_tp)
+{
+ ub_tp->buf.direct.buf = ub_tp->tp_buf_info->q_room_buf_1.direct.va;
+ ub_tp->buf.direct.map = ub_tp->tp_buf_info->q_room_buf_1.direct.pa;
+ ub_tp->buf.page_shift =
+ ilog2(ub_tp->tp_buf_info->q_room_buf_1.buf_size);
+
+ ub_tp->kdb->db_record =
+ (__be32 *)(void *)(&ub_tp->tp_buf_info->q_header_vaddr
+ ->doorbell_record);
+ ub_tp->kdb->dma = ub_tp->tp_buf_info->q_header_paddr;
+
+ ub_tp->tp_buf_info->q_header_vaddr->doorbell_record = 0;
+ ub_tp->tp_buf_info_xid = ub_tp->tp_buf_info->index;
+}
+
+static int udma_create_queue_kernel_normal(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp)
+{
+ struct tag_cqm_queue *tp_buf_info = NULL;
+ int ret;
+
+ ub_tp->kdb =
+ (struct udma_kdb *)kzalloc(sizeof(struct udma_kdb), GFP_KERNEL);
+ if (ub_tp->kdb == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to alloc mem for tp(%u) queue db.\n",
+ ub_tp->tp.tpn);
+ return -ENOMEM;
+ }
+
+ tp_buf_info = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_QP,
+ (u32)ub_tp->buf_size, ub_tp, true, CQM_INDEX_INVALID, 0, 0);
+ if (tp_buf_info == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "failed to create udma queue by cqm object, func_id:%u\n",
+ (u32)hinic5_global_func_id(udma_dev->hwdev));
+ ret = -ENOMEM;
+ goto err_alloc_queue;
+ }
+
+ (void)memset_s(tp_buf_info->q_room_buf_1.direct.va,
+ (u32)ub_tp->buf_size, 0xff, (u32)ub_tp->buf_size);
+
+ ub_tp->ub_mtt.mtt_type = MTT_CMTT_TYPE;
+ ret = hmm_mtt_alloc(udma_dev->hwdev,
+ tp_buf_info->q_room_buf_1.buf_number,
+ (u32)ilog2(tp_buf_info->q_room_buf_1.buf_size),
+ &ub_tp->ub_mtt, SERVICE_T_UB);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to allocate udma mtt, func_id:%u\n",
+ (u32)hinic5_global_func_id(udma_dev->hwdev));
+ goto err_alloc_mtt;
+ }
+
+ ret = udma_buf_write_mtt(udma_dev, &ub_tp->ub_mtt,
+ &tp_buf_info->q_room_buf_1);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to write udma mtt, func_id:%u\n",
+ (u32)hinic5_global_func_id(udma_dev->hwdev));
+ goto err_write_mtt;
+ }
+ ub_tp->tp_buf_info = tp_buf_info;
+ udma_create_qp_kernel_set_attr(ub_tp);
+
+ return 0;
+
+err_write_mtt:
+ hmm_mtt_free(udma_dev->hwdev, &ub_tp->ub_mtt, SERVICE_T_UB);
+err_alloc_mtt:
+ cqm5_object_delete(&tp_buf_info->object);
+err_alloc_queue:
+ kfree(ub_tp->kdb);
+ ub_tp->kdb = NULL;
+ return ret;
+}
+
+static void udma_destroy_queue_kernel_normal(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp)
+{
+ kfree(ub_tp->kdb);
+ ub_tp->kdb = NULL;
+
+ hmm_mtt_free(udma_dev->hwdev, &ub_tp->ub_mtt, SERVICE_T_UB);
+
+ cqm5_object_delete(&ub_tp->tp_buf_info->object);
+ ub_tp->tp_buf_info = NULL;
+}
+
+int udma_tp_create_ubrc_table(struct udma_device *udma_dev,
+ const struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask mask,
+ struct udma_tp *ub_tp)
+{
+ struct udma_comp_priv *comp_priv = NULL;
+ int ret = 0;
+
+ if (udma_dev == NULL || attr == NULL) {
+ udma_pr_err(UDMA_M_TP,
+ "Invalid parameter: udma_dev(%d),attr(%d).\n",
+ !!udma_dev, !!attr);
+ return -EINVAL;
+ }
+
+ if (mask.bs.flag == 0) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "mask not enable, oor_en:%u\n",
+ attr->flag.bs.oor_en);
+ return 0;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "oor enable:%u\n",
+ attr->flag.bs.oor_en);
+ /* same tp channel only allocate once */
+ if (attr->flag.bs.oor_en != 1 || ub_tp->oor_en != 0) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "oor has already configured\n");
+ return ret;
+ }
+
+ comp_priv = (struct udma_comp_priv *)(void *)get_hmm_comp_priv(
+ udma_dev->hwdev, SERVICE_T_UB);
+ if (comp_priv == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to get hmm comp priv.\n");
+ return -EINVAL;
+ }
+ ub_tp->rc_table_num = comp_priv->ub_cap.ubrc_depth;
+ ub_tp->rc_log_ubrc_seg = comp_priv->ub_cap.log_ubrc_seg;
+ ret = udma_ubrc_alloc(udma_dev, ub_tp->rc_table_num, &ub_tp->rc_table);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "failed alloc ub rc.\n");
+ return ret;
+ }
+
+ ret = udma_cmd_tp_create_ubrc(udma_dev, ub_tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed send create_ubrc cmd.\n");
+ udma_ubrc_free(udma_dev, &ub_tp->rc_table);
+ return ret;
+ }
+ ub_tp->oor_en = 1;
+
+ return ret;
+}
+
+static void udma_tp_free_ubrc_table(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp)
+{
+ if (ub_tp->rc_table.vaddr != NULL)
+ udma_ubrc_free(udma_dev, &ub_tp->rc_table);
+}
+
+static int udma_queue_alloc(struct udma_device *udma_dev,
+ const struct ubcore_tp_cfg *cfg,
+ struct udma_tp *ub_tp)
+{
+ int ret;
+
+ ret = udma_tpn_alloc(udma_dev, cfg, ub_tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp: failed to allocate tpn\n");
+ return -ENOMEM;
+ }
+
+ ub_tp->pcqc_info = udma_create_pcqc(udma_dev, ub_tp);
+ if (ub_tp->pcqc_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to create pcqc, xid: %u\n",
+ ub_tp->tp_info->xid);
+ goto err_create_pcqc;
+ }
+
+ ub_tp->entry_size = TP_Q_WQEBB;
+ ub_tp->buf_size = ub_tp->entry_cnt * ub_tp->entry_size;
+
+ ret = udma_create_queue_kernel_normal(udma_dev, ub_tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to create tp queue, ret:%d\n", ret);
+ goto err_alloc_queue;
+ }
+
+ return 0;
+
+err_alloc_queue:
+ cqm5_object_delete(&ub_tp->pcqc_info->object);
+ ub_tp->pcqc_info = NULL;
+err_create_pcqc:
+ udma_tpn_free(udma_dev, ub_tp);
+ ub_tp->tp_info = NULL;
+ return -ENOMEM;
+}
+
+struct ubcore_tp *udma_create_tp(struct ubcore_device *ub_dev,
+ struct ubcore_tp_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ uint64_t cycle_start = 0;
+ struct ubcore_tp *tp[1] = { 0 };
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ int ret;
+
+ if (udma_dev == NULL) {
+ pr_err("Invalid parameter. udma_dev(%d) .\n", !!udma_dev);
+ return (struct ubcore_tp *)ERR_PTR(-EINVAL);
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+
+ ret = udma_create_multi_tp(ub_dev, 1, cfg, udata, tp);
+ if (ret == 1) {
+ return tp[0];
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(to_udma_dev(ub_dev)->dev, UDMA_M_TP,
+ "[PERF]udma_create_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+
+ return (struct ubcore_tp *)ERR_PTR(-EFAULT);
+}
+
+static int udma_modify_tp_mtu_check(struct udma_device *udma_dev,
+ const struct ubcore_tp_attr *attr)
+{
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "modify tp mt_1k_en:%u, g_multi_mtu_enable:%u\n",
+ udma_dev->mtu_1k_en, g_multi_mtu_enable);
+ if (udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ /* DFX tool supports 1K mtu configuration */
+ if (((udma_dev->mtu_1k_en == 0) ||
+ (attr->mtu != UBCORE_MTU_1024)) &&
+ (attr->mtu != UBCORE_MTU_4096) &&
+ (attr->mtu != UBCORE_MTU_8192)) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ " modify tp: don't support mtu:%u\n",
+ attr->mtu);
+ return -EINVAL;
+ }
+ } else {
+ if ((g_multi_mtu_enable == UDMA_MULTI_MTU_DISABLE &&
+ attr->mtu != UBCORE_MTU_4096) ||
+ (g_multi_mtu_enable == UDMA_MULTI_MTU_ENABLE &&
+ (attr->mtu != UBCORE_MTU_1024 &&
+ attr->mtu != UBCORE_MTU_4096 &&
+ attr->mtu != UBCORE_MTU_8192))) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ " modify tp mtu check failed: don't support mtu:%u\n",
+ attr->mtu);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int udma_modify_attr_check(struct udma_device *udma_dev,
+ struct ubcore_tp *tp,
+ const struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask mask)
+{
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "attr.data_udp_start:%u attr.ack_udp_start:%u\n",
+ attr->data_udp_start, attr->ack_udp_start);
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "mask.data_udp_start:%u mask.ack_udp_start:%u\n",
+ mask.bs.data_udp_start, mask.bs.ack_udp_start);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "mask:%u\n", mask.value);
+
+ if (mask.bs.flag != 0) {
+ if ((attr->flag.bs.sr_en == 1) &&
+ (udma_dev->ub_cap.dev_cap.feature.bs.selective_retrans ==
+ 0)) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "modify tp: don't support selective retrans");
+ return -EINVAL;
+ }
+ if ((attr->flag.bs.oor_en == 1) &&
+ (udma_dev->ub_cap.dev_cap.feature.bs.oor == 0)) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "modify tp: don't support oor");
+ return -EINVAL;
+ }
+ }
+ if (mask.bs.mtu == 1) {
+ return udma_modify_tp_mtu_check(udma_dev, attr);
+ }
+ return 0;
+}
+
+void udma_modify_tp_for_host(struct ubcore_tp *tp,
+ const struct udma_tp_modify_dfx *tp_dfx)
+{
+ if (tp_dfx->mask.peer_tpn == 1)
+ tp->peer_tpn = tp_dfx->attr.peer_tpn;
+
+ if (tp_dfx->mask.state == 1)
+ tp->state = (enum ubcore_tp_state)tp_dfx->attr.state;
+
+ if (tp_dfx->mask.tx_psn == 1)
+ tp->tx_psn = tp_dfx->attr.tx_psn;
+
+ if (tp_dfx->mask.rx_psn == 1)
+ tp->rx_psn = tp_dfx->attr.rx_psn;
+
+ if (tp_dfx->mask.mtu == 1)
+ tp->mtu = (enum ubcore_mtu)tp_dfx->attr.mtu;
+
+ if (tp_dfx->mask.cc_pattern_idx == 1)
+ tp->cc_pattern_idx = tp_dfx->attr.cc_pattern_idx;
+
+ if (tp_dfx->mask.flag == 1) {
+ tp->flag.bs.oor_en = tp_dfx->attr.oor_en;
+ tp->flag.bs.sr_en = tp_dfx->attr.sr_en;
+ tp->flag.bs.cc_en = tp_dfx->attr.cc_en;
+ tp->flag.bs.cc_alg = tp_dfx->attr.cc_alg;
+ tp->flag.bs.spray_en = tp_dfx->attr.spray_en;
+ }
+}
+
+int udma_modify_tp(struct ubcore_tp *tp, struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask mask)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct ubcore_tp *fail_tp[1] = { NULL };
+ int modify_num;
+
+ if (tp == NULL || tp->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter. tp(%d) .\n", !!tp);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(tp->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+
+ modify_num = udma_modify_multi_tp(1, &tp, attr, &mask, fail_tp);
+ if (modify_num != 1) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "modify tp failed, tpn(0x%x)\n", tp->tpn);
+ return -EINVAL;
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_modify_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "success, tpn(0x%x)\n", tp->tpn);
+
+ return 0;
+}
+
+int udma_query_tpc(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ub_dfx_tp_ctx_query *val)
+{
+ int ret;
+
+ ret = udma_cmd_tp_query_ctx(udma_dev, key, val);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to query tp, key:0x%x\n",
+ key->key);
+ return ret;
+ }
+
+ return 0;
+}
+
+int udma_query_tpc_info(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct tag_ub_tp_query_info_outbuf *val)
+{
+ int ret;
+
+ ret = udma_cmd_tp_query_ctx_info(udma_dev, key, val);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to query tp info, key:0x%x\n",
+ key->key);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+udma_fill_res_ret_val_info(const struct udma_device *udma_dev,
+ struct ubcore_res_val *val, u32 buf_len,
+ struct tag_ub_tp_query_info_outbuf *outbuf,
+ struct ubcore_res_tp_val *ret_val)
+{
+ val->len = buf_len;
+
+ ret_val->tpn = outbuf->srctpn;
+ ret_val->oor_en = outbuf->dw0.oor_en;
+ ret_val->selective_retrans_en = outbuf->dw0.srp_en;
+ ret_val->state = outbuf->dw0.state;
+ ret_val->tx_psn = outbuf->next_epsn;
+ ret_val->rx_psn = outbuf->next_send_psn;
+ ret_val->dscp = outbuf->dw0.tclass >> RIGHT_SHIFT_NUM;
+ ret_val->data_udp_start = outbuf->dw1.data_udp_srcport;
+ ret_val->ack_udp_start = outbuf->dw1.ack_udp_srcport;
+
+ ret_val->spray_en = 0; // not support
+ ret_val->udp_range = 0; // not support
+}
+
+int udma_query_res_tp(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_tp_val *ret_val =
+ (struct ubcore_res_tp_val *)(uintptr_t)val->addr;
+ struct tag_ub_tp_query_info_outbuf *outbuf = NULL;
+ int ret;
+
+ ret = check_tp_query_ret_val(ret_val, val->len,
+ sizeof(struct ubcore_res_tp_val),
+ udma_dev->dev, key);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to check return vaule, key:0x%x\n",
+ key->key);
+ return ret;
+ }
+
+ outbuf = (struct tag_ub_tp_query_info_outbuf *)kzalloc(
+ sizeof(struct tag_ub_tp_query_info_outbuf), GFP_KERNEL);
+ if (outbuf == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to alloc\n");
+ return -ENOMEM;
+ }
+ ret = udma_cmd_tp_query_ctx_info(udma_dev, key, outbuf);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query tp res: failed to query tp, key:0x%x\n",
+ key->key);
+ kfree(outbuf);
+ return ret;
+ }
+ udma_fill_res_ret_val_info(udma_dev, val,
+ sizeof(struct ubcore_res_tp_val), outbuf,
+ ret_val);
+ kfree(outbuf);
+
+ return 0;
+}
+
+static int udma_tp_cache_out_cmd(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp)
+{
+ u64 wb_dma = 0;
+ void *wb_va = NULL;
+ int ret;
+
+ wb_va = dma_alloc_coherent(udma_dev->dev, (size_t)4UL, &wb_dma,
+ GFP_KERNEL);
+ if (wb_va == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to alloc dma wb_va\n");
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_tp_send_cache_out(udma_dev, cnt, tp, wb_dma);
+
+ dma_free_coherent(udma_dev->dev, sizeof(u32), wb_va, wb_dma);
+
+ return ret;
+}
+
+static int udma_change_tp_to_err(struct ubcore_tp *tp)
+{
+ union ubcore_tp_attr_mask mask;
+ struct ubcore_tp_attr attr;
+
+ mask.value = 0;
+ mask.bs.state = 1;
+
+ attr.state = UBCORE_TP_STATE_ERR;
+
+ if (udma_modify_tp(tp, &attr, mask) != 0)
+ return -1;
+
+ tp->state = UBCORE_TP_STATE_ERR;
+ return 0;
+}
+
+int udma_destroy_tp(struct ubcore_tp *tp)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_tp *ub_tp = NULL;
+ int destroy_num;
+ u32 tpn;
+ int ret;
+
+ if (tp == NULL || tp->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter, tp(%d)\n", !!tp);
+ return -EINVAL;
+ }
+
+ tpn = tp->tpn;
+ udma_dev = to_udma_dev(tp->ub_dev);
+ ub_tp = to_udma_tp(tp);
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "destroy tp start, tpn(%u), peer_tpn(%u)\n", tpn,
+ tp->peer_tpn);
+
+ if (tp->state != UBCORE_TP_STATE_ERR &&
+ tp->state != UBCORE_TP_STATE_RESET) {
+ ub_tp->refuse_report_flush_done = 1;
+
+ ret = udma_change_tp_to_err(tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "change tp to err failed, tp->state(%d)\n",
+ tp->state);
+ return -EFAULT;
+ }
+ }
+
+ destroy_num = udma_destroy_multi_tp(1, &tp);
+ if (destroy_num != 1) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "destroy tp failed, tpn(%u)\n", tpn);
+ return -EFAULT;
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_destroy_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_info(udma_dev->dev, UDMA_M_TP, "destroy tp success, tpn(%u)\n",
+ tpn);
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_TP, tpn, &ub_tp->cmdq_rtt);
+ return 0;
+}
+
+int udma_query_tp_wqe_from_host(struct udma_device *udma_dev, u32 tpn,
+ u32 wqe_id, struct ub_tp_wqe *outbuf,
+ u32 outbuf_size)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_tp *ub_tp = NULL;
+ u64 tpqe_offset = 0; // target ci of address offset
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX, tpn,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to get cqm object, tpn:%u\n", tpn);
+ return -EINVAL;
+ }
+ ub_tp = udma_find_tp(udma_dev, tpn);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to find tp, tpn = %u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ udma_tp_put(ub_tp);
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL || ub_tp->tp_buf_info == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "tp addr is null, check tpn(%u) is right\n", tpn);
+ ret = -EFAULT;
+ goto cleanup;
+ }
+
+ if (wqe_id >= (ub_tp->entry_cnt / UB_TP_WQE_NUM_WQEBB)) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "wqe_id exceeds the max wqe num, tpn(%u) wqe_id(%u) entry_cnt(%u)\n",
+ tpn, wqe_id, ub_tp->entry_cnt);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ tpqe_offset = wqe_id * outbuf_size;
+ memcpy_fromio(
+ (void *)outbuf,
+ (void *)((uintptr_t)ub_tp->tp_buf_info->q_room_buf_1.direct.va +
+ tpqe_offset),
+ outbuf_size);
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp wqe from host success, tpn:%u, wqe_id:%u\n", tpn,
+ wqe_id);
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
+
+static int udma_create_tp_host(struct udma_device *udma_dev,
+ struct udma_tp **ub_tp, struct ubcore_tp **tp,
+ const struct ubcore_tp_cfg *cfg)
+{
+ int ret;
+
+ *ub_tp = (struct udma_tp *)udma_vram_kzalloc(udma_dev->dev,
+ UDMA_VRAM_TYPE_TP,
+ sizeof(struct udma_tp),
+ GFP_KERNEL);
+ if (*ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp: failed to allocate tp memory\n");
+ return -ENOMEM;
+ }
+ (*ub_tp)->pri = cfg->dscp;
+ *tp = &((*ub_tp)->tp);
+ (*tp)->tpg = NULL;
+ (*ub_tp)->cqm_priv_type = UDMA_CQM_PRIV_TYPE_TP;
+ udma_cmdq_rtt_statistic_init(&(*ub_tp)->cmdq_rtt);
+ (void)memcpy_s(&(*ub_tp)->cfg, sizeof(struct ubcore_tp_cfg), cfg,
+ sizeof(struct ubcore_tp_cfg));
+
+ ret = udma_queue_alloc(udma_dev, cfg, (*ub_tp));
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp: failed to allocate info\n");
+ udma_vram_kfree(udma_dev->dev, *ub_tp, UDMA_VRAM_TYPE_TP);
+ return -ENOMEM;
+ }
+
+ kref_init(&(*ub_tp)->ref_cnt);
+ init_completion(&(*ub_tp)->comp);
+
+ udma_store_list(udma_dev, &(*ub_tp)->node,
+ &udma_dev->device_res->tpn_list);
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "success, tpn:%u\n",
+ (*ub_tp)->tp.tpn);
+
+ return 0;
+}
+
+static void udma_destroy_tp_host(struct udma_device *udma_dev,
+ struct udma_tp *ub_tp, bool del_object)
+{
+ u32 tpn = 0;
+
+ if ((udma_dev == NULL) || (ub_tp == NULL)) {
+ udma_pr_err(UDMA_M_TP,
+ "Invalid parameter: udma_dev(%d), ub_tp(%d).\n",
+ !!udma_dev, !!ub_tp);
+ return;
+ }
+ tpn = ub_tp->tp.tpn; // udma_tpn_free will set tpn is invalid, because this here first record tpn used for log print
+
+ udma_delete_list(udma_dev, &ub_tp->node,
+ &udma_dev->device_res->tpn_list);
+ udma_tp_put(ub_tp);
+ wait_for_completion(&ub_tp->comp);
+
+ udma_tpn_free(udma_dev, ub_tp);
+ if (del_object) {
+ cqm5_object_delete(&ub_tp->tp_info->object);
+ }
+ ub_tp->tp_info = NULL;
+
+ udma_tp_free_ubrc_table(udma_dev, ub_tp); // modify tp flow created in
+ udma_destroy_queue_kernel_normal(udma_dev, ub_tp);
+
+ cqm5_object_delete(&ub_tp->pcqc_info->object);
+ ub_tp->pcqc_info = NULL;
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "destroy tp success, tpn(%u)\n",
+ tpn);
+ udma_vram_kfree(udma_dev->dev, ub_tp, UDMA_VRAM_TYPE_TP);
+}
+
+static void udma_print_tp_cfg(const struct ubcore_tp_cfg *cfg,
+ struct udma_device *udma_dev, u32 cnt)
+{
+ u32 i;
+
+ for (i = 0; i < cnt; i++) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "start print ubcore tp cfg[%u]\n", i);
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "flag:%u, local_jetty_id:%u, fe_idx:%u, peer_jetty_id:%u\n",
+ cfg[i].flag.bs.target, cfg[i].local_jetty.id,
+ adapted_ue_idx(&cfg[i]), cfg[i].peer_jetty.id);
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "trans_mode:%u, retry_num:%u, retry_factor:%u, ack_timeout:%u\n",
+ cfg[i].trans_mode, cfg[i].retry_num,
+ cfg[i].retry_factor, cfg[i].ack_timeout);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "dscp:%u, oor_cnt:%u\n",
+ cfg[i].dscp, cfg[i].oor_cnt);
+ if (cfg[i].tpg == NULL)
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "cfg->tpg is null.\n");
+ else
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "cfg->tpg->tpgn:%u\n", cfg[i].tpg->tpgn);
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "end print ubcore tp cfg[%u]\n", i);
+ }
+}
+
+/* function description: create multi tp, at most same when create UB_CMD_TP_CNT_MAX
+ * return value: success created count
+ */
+int udma_create_multi_tp(struct ubcore_device *dev, u32 cnt,
+ struct ubcore_tp_cfg *cfg, struct ubcore_udata *udata,
+ struct ubcore_tp **tp)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_tp *ub_tp[UB_CMD_TP_CNT_MAX] = { NULL };
+ u32 host_create_num = 0;
+ u32 cmd_create_num = 0;
+ u32 i;
+ int ret;
+
+ if (dev == NULL || cfg == NULL || tp == NULL) {
+ udma_pr_err(UDMA_M_TP,
+ "Invalid parameter: dev(%d), cfg(%d), tp(%d)\n",
+ !!dev, !!cfg, !!tp);
+ return 0;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ udma_print_tp_cfg(cfg, udma_dev, cnt);
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+
+ if (cnt > UB_CMD_TP_CNT_MAX) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "max number is %d, cnt %d is larger than UB_CMD_TP_CNT_MAX.\n",
+ UB_CMD_TP_CNT_MAX, cnt);
+ return 0;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ ret = udma_create_tp_host(udma_dev, &ub_tp[i], &tp[i], cfg + i);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "fail to create tp no.%u\n", i);
+ host_create_num = i;
+ goto err_alloc_tp_host; // free already allocated memory, return 0
+ }
+ }
+
+ cmd_create_num = udma_cmd_tp_create_ctx(dev, cnt, cfg,
+ ub_tp); // return create success of count
+ if (cmd_create_num != cnt) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, %u tp success\n",
+ cmd_create_num);
+ goto err_create_tp_cmd; // free no success send_cmd of tp
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_create_multi_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "create %u tp succeed\n",
+ cmd_create_num);
+
+ return (int)cmd_create_num;
+
+err_create_tp_cmd:
+ for (i = cmd_create_num; i < cnt; i++)
+ udma_destroy_tp_host(udma_dev, ub_tp[i], false);
+ return (int)cmd_create_num;
+
+err_alloc_tp_host:
+ for (i = 0; i < host_create_num; i++)
+ udma_destroy_tp_host(udma_dev, ub_tp[i], false);
+ return 0;
+}
+
+/* return value: destroy cmd destroy of tp count */
+static u32 udma_send_destroy_multi_tp_cmd(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp)
+{
+ u32 delete_destroy_num;
+ int ret;
+
+ delete_destroy_num = udma_cmd_tp_destroy_ctx(udma_dev, cnt, tp);
+ if (delete_destroy_num != cnt)
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "delete_destroy_num(%u) not equal to cnt(%u)\n",
+ delete_destroy_num, cnt);
+
+ /* mtt of cacheinvalidate only needs execute once */
+ ret = udma_tp_cache_out_cmd(udma_dev, delete_destroy_num, tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "tp:0x%06x cache invalid\n",
+ tp[0]->tpn);
+ return 0; // return cacheout success destroy of count
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_TP, "delete_destroy_num(%u)\n",
+ delete_destroy_num);
+
+ return delete_destroy_num;
+}
+
+/* function description: destroy multi tp, at most same when destroy UB_CMD_TP_CNT_MAX
+ * return value: success destroy of count
+ */
+int udma_destroy_multi_tp(u32 cnt, struct ubcore_tp **tp)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_tp *ub_tp = NULL;
+ u32 destroy_num = 0; // success destroy of tp count
+ u32 i;
+
+ if (tp == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter, tp is null\n");
+ return 0;
+ }
+
+ if (cnt == 0 || cnt > UB_CMD_TP_CNT_MAX) {
+ udma_pr_err(
+ UDMA_M_TP,
+ "cnt(%d) is zero or larger than UB_CMD_TP_CNT_MAX(%d)\n",
+ cnt, UB_CMD_TP_CNT_MAX);
+ return 0;
+ }
+ if (tp[0]->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter: ub_dev(%d).\n",
+ !!tp[0]->ub_dev);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(tp[0]->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+
+ destroy_num = udma_send_destroy_multi_tp_cmd(udma_dev, cnt, tp);
+ if (destroy_num != cnt)
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "destroy cmd failed, %u tp destroyed, cnt(%u)\n",
+ destroy_num, cnt);
+
+ for (i = 0; i < destroy_num;
+ i++) { // destroy host in cmdq destroy success of basebase on execute
+ ub_tp = to_udma_tp(tp[i]);
+ udma_destroy_tp_host(udma_dev, ub_tp, true);
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_destroy_multi_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: destroy_num(%u) tp success, cnt(%u)\n", __func__,
+ destroy_num, cnt);
+ return (int)destroy_num;
+}
+
+/* return value: via attr check of tp count */
+static u32 udma_tp_get_valid_attr_num_for_modify(
+ struct udma_device *udma_dev, u32 cnt, struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr, union ubcore_tp_attr_mask *mask)
+{
+ int ret;
+ u32 i;
+
+ for (i = 0; i < cnt; ++i) {
+ if (tp[i] == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: tp[%u] is NULL, cnt(%u)\n", __func__, i,
+ cnt);
+ return i;
+ }
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "%s: index(%u), tpn(%u), cc_en(%u), cc_alg(%u), cc_pat_idx(%u)\n",
+ __func__, i, tp[i]->tpn, attr[i].flag.bs.cc_en,
+ attr[i].flag.bs.cc_alg, attr[i].cc_pattern_idx);
+ ret = udma_modify_attr_check(udma_dev, tp[i], &attr[i],
+ mask[i]);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: invalid attr, tpn(%u), index(%u)\n",
+ __func__, tp[i]->tpn, i);
+ return i;
+ }
+ }
+
+ return cnt;
+}
+
+/* return value: success create ubrc table of tp count */
+static u32 udma_multi_tp_create_ubrc_table(struct udma_device *udma_dev,
+ u32 cnt, struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask)
+{
+ struct udma_tp *ub_tp = NULL;
+ int ret;
+ u32 i;
+
+ for (i = 0; i < cnt; ++i) {
+ ub_tp = to_udma_tp(tp[i]);
+ ret = udma_tp_create_ubrc_table(udma_dev, &attr[i], mask[i],
+ ub_tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "%s: create ubrc failed, tpn(%u), index(%u)\n",
+ __func__, tp[i]->tpn, i);
+ return i;
+ }
+ }
+
+ return cnt;
+}
+
+/* return value: success get cos of tp count */
+static u32 udma_modify_multi_get_cos(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ const union ubcore_tp_attr_mask *mask)
+{
+ struct ub_sip_attr sip = { 0 };
+ struct udma_tp *ub_tp = NULL;
+ int ret;
+ u32 i;
+
+ for (i = 0; i < cnt; ++i) {
+ if (mask[i].bs.local_net_addr_idx == 0)
+ continue;
+
+ ub_tp = to_udma_tp(tp[i]);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "to_udma_tp failed, tp index:%d.\n", i);
+ return 0;
+ }
+ ret = udma_query_sip(udma_dev, attr[i].local_net_addr_idx,
+ &sip);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query sip failed, index(%u), ret(%d), sip_idx(%u)\n",
+ i, ret, attr[i].local_net_addr_idx);
+ return i;
+ }
+
+ ret = udma_get_dcb_cfg_cos(udma_dev, &sip, ub_tp->pri,
+ &ub_tp->cos, 0);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "get cos failed, index(%u), tpn(%u), ret(%d), sip_idx(%u), pri(%u)\n",
+ i, tp[i]->tpn, ret, attr[i].local_net_addr_idx,
+ ub_tp->pri);
+ return i;
+ }
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "Get cos from dcb info successful, index(%u), cos(%u)\n",
+ i, ub_tp->cos);
+ }
+
+ return cnt;
+}
+
+/* func: calculate modify need send down of cmdq count
+ * input @cmd_modify_tp_cnt: need send down cmdq of tp count
+ */
+static inline u32 udma_modify_cmd_times_calculate(u32 cmd_modify_tp_cnt)
+{
+ if (cmd_modify_tp_cnt == 0)
+ return 0;
+ else if (cmd_modify_tp_cnt > 0 &&
+ cmd_modify_tp_cnt <= UB_CMD_TP_MODIFY_CNT_MAX)
+ return 1;
+ else
+ return 2; // need send down 2 time modify cmd
+}
+
+static u32 udma_modify_multi_tp_cmd_entry(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask)
+{
+ u32 success_num = 0, modify_total_success_num = 0;
+ u32 modify_cmd_times; // modify cmdq send down count
+ u32 left_cmd_cnt; // need send down cmdq of remaining tp count
+ u32 cmd_cnt; // once cmdq send down of tp count
+ u32 begin_idx = 0; // input parameter tp, attr, mask of start index
+ u32 i;
+
+ modify_cmd_times = udma_modify_cmd_times_calculate(cnt);
+
+ left_cmd_cnt = cnt;
+ for (i = 0; i < modify_cmd_times; ++i) {
+ cmd_cnt = (left_cmd_cnt > UB_CMD_TP_MODIFY_CNT_MAX) ?
+ UB_CMD_TP_MODIFY_CNT_MAX :
+ left_cmd_cnt;
+ left_cmd_cnt -= cmd_cnt;
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "%s: cmd_cnt(%u), left_cmd_cnt(%u)\n", __func__,
+ cmd_cnt, left_cmd_cnt);
+
+ success_num = udma_cmd_tp_modify_ctx(cmd_cnt, &tp[begin_idx],
+ &attr[begin_idx],
+ &mask[begin_idx]);
+ if (success_num != cmd_cnt) {
+ modify_total_success_num += success_num;
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "%s: modify cmd failed, success_num(%u), cmd_cnt(%u), "
+ "modify_total_success_num(%u)\n",
+ __func__, success_num, cmd_cnt,
+ modify_total_success_num);
+ return modify_total_success_num;
+ }
+ begin_idx += cmd_cnt;
+ modify_total_success_num += cmd_cnt;
+ }
+
+ return modify_total_success_num;
+}
+
+static int udma_tp_cfg_info_alloc(struct udma_device *udma_dev, u32 cnt,
+ struct udma_tp ***ub_tp,
+ struct ubcore_tp_cfg **cfg,
+ struct ubcore_tp **tp)
+{
+ u32 i;
+
+ *ub_tp = (struct udma_tp **)kcalloc(cnt, sizeof(struct udma_tp *),
+ GFP_KERNEL);
+ if (*ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP, "ub tp alloc failed\n");
+ return -ENOMEM;
+ }
+
+ *cfg = (struct ubcore_tp_cfg *)kcalloc(
+ cnt, sizeof(struct ubcore_tp_cfg), GFP_KERNEL);
+ if (*cfg == NULL) {
+ kfree(*ub_tp);
+ udma_err(udma_dev->dev, UDMA_M_TP, "tp cfg alloc failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ (*ub_tp)[i] = to_udma_tp(tp[i]);
+ if ((*ub_tp)[i]->tp_buf_info != NULL) {
+ (void)memset_s(
+ (*ub_tp)[i]->tp_buf_info->q_room_buf_1.direct.va,
+ (u32)(*ub_tp)[i]->buf_size, 0xff,
+ (u32)(*ub_tp)[i]->buf_size);
+ (*ub_tp)[i]
+ ->tp_buf_info->q_header_vaddr->doorbell_record =
+ 0;
+ }
+
+ (void)memcpy_s(&(*cfg)[i], sizeof(struct ubcore_tp_cfg),
+ &(*ub_tp)[i]->cfg, sizeof(struct ubcore_tp_cfg));
+ }
+
+ return 0;
+}
+
+static void udma_tp_cfg_info_free(struct udma_tp **ub_tp,
+ struct ubcore_tp_cfg *cfg)
+{
+ kfree(ub_tp);
+ kfree(cfg);
+}
+
+static u32 udma_handle_tp_create_ctx(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp)
+{
+ u32 cmd_create_num;
+ struct udma_tp **ub_tp = NULL;
+ struct ubcore_tp_cfg *cfg = NULL;
+ int ret = 0;
+
+ ret = udma_tp_cfg_info_alloc(udma_dev, cnt, &ub_tp, &cfg, tp);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "tp cfg info alloc failed, ret = %d\n", ret);
+ return (u32)ret;
+ }
+
+ cmd_create_num =
+ udma_cmd_tp_create_ctx(&udma_dev->ub_dev, cnt, cfg, ub_tp);
+ if (cmd_create_num != cnt) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to send cqm cmd, %u tp success\n",
+ cmd_create_num);
+ }
+ udma_tp_cfg_info_free(ub_tp, cfg);
+
+ return cmd_create_num;
+}
+
+static bool udma_check_reuse_state(struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask)
+{
+ return (tp[0]->state == UBCORE_TP_STATE_ERR && mask->bs.state == 1 &&
+ attr[0].state == UBCORE_TP_STATE_RESET);
+}
+
+static u32 udma_handle_tp_create_ubrc(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp)
+{
+ struct udma_tp *ub_tp = NULL;
+ int ret;
+ u32 i;
+
+ for (i = 0; i < cnt; i++) {
+ ub_tp = to_udma_tp(tp[i]);
+ /* oor_en no has enabled, description did not create ubrc, then tp restore when not need initialize ubrc */
+ if (ub_tp->oor_en == 0) {
+ continue;
+ }
+
+ ret = udma_cmd_tp_create_ubrc(udma_dev, ub_tp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp ubrc failed, i(%u)\n", i);
+ return i;
+ }
+ }
+
+ return cnt;
+}
+
+static u32 udma_handle_tp_reuse(struct udma_device *udma_dev, u32 cnt,
+ struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask)
+{
+ u32 destroy_num = 0;
+ u32 cmd_create_ctx_num = 0;
+ u32 cmd_create_urbc_num = 0;
+
+ if (udma_dev->device_type == UDMA_DEV_TYPE_HI1825_V100 ||
+ !udma_check_reuse_state(tp, attr, mask)) {
+ return cnt;
+ }
+
+ destroy_num = udma_send_destroy_multi_tp_cmd(udma_dev, cnt, tp);
+ if (destroy_num != cnt) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "destroy tp cmd failed, %u tp destroyed, cnt(%u)\n",
+ destroy_num, cnt);
+ }
+
+ cmd_create_ctx_num =
+ udma_handle_tp_create_ctx(udma_dev, destroy_num, tp);
+ if (cmd_create_ctx_num != destroy_num) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp cmd fail, %u tp ctx created, cnt(%u)\n",
+ cmd_create_ctx_num, destroy_num);
+ }
+
+ cmd_create_urbc_num =
+ udma_handle_tp_create_ubrc(udma_dev, cmd_create_ctx_num, tp);
+ if (cmd_create_urbc_num != cmd_create_ctx_num) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "create tp ubrc fail, %u tp ubrc created, cnt(%u)\n",
+ cmd_create_urbc_num, cmd_create_ctx_num);
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "tp reuse success, tp reuse num = %u\n",
+ cmd_create_urbc_num);
+ return cmd_create_urbc_num;
+}
+
+static void udma_print_multi_tp_attr(struct ubcore_tp_attr *attr,
+ const union ubcore_tp_attr_mask *mask,
+ struct udma_device *udma_dev, u32 cnt)
+{
+ u32 dip0 = 0;
+ u32 dip1 = 0;
+ u32 dip2 = 0;
+ u32 dip3 = 0;
+ u32 i;
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "%s Invalid parameter: udma_dev(%d).\n",
+ __func__, !!udma_dev);
+ return;
+ }
+
+ if (attr == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "ubcore vtp attr is null.\n");
+ return;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "start print ubcore tp attr[%u]\n", i);
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "flag:%u, peer_tpn:%u, state:%u, tx_psn:%u\n",
+ attr[i].flag.value, attr[i].peer_tpn, attr[i].state,
+ attr[i].tx_psn);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "rx_psn:%u, mtu:%u, cc_pattern_idx:%u, peer_ext_addr:%llu\n",
+ attr[i].rx_psn, attr[i].mtu, attr[i].cc_pattern_idx,
+ attr[i].peer_ext.addr);
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "oos_cnt:%u, local_net_addr_idx:%u, data_udp_start:%u, ack_udp_start:%u\n",
+ attr[i].oos_cnt, attr[i].local_net_addr_idx,
+ attr[i].data_udp_start, attr[i].ack_udp_start);
+ udma_debug(
+ udma_dev->dev, UDMA_M_TP,
+ "udp_range:%u, hop_limit:%u, flow_label:%u, port_id:%u\n",
+ attr[i].udp_range, attr[i].hop_limit,
+ attr[i].flow_label, attr[i].port_id);
+ udma_debug(udma_dev->dev, UDMA_M_TP, "mn:%u, mask:%u\n",
+ attr[i].mn, mask[i].value);
+
+ if (attr[i].peer_net_addr.type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ dip3 = attr[i].peer_net_addr.net_addr.in4.addr;
+ } else {
+ /* dip0 - dip3 */
+ dip0 = attr[i].peer_net_addr.net_addr.in6.subnet_prefix &
+ UB_TP_DIP_MASK;
+ dip1 = (attr[i].peer_net_addr.net_addr.in6
+ .subnet_prefix >>
+ UB_TP_DIP_OFFSET) &
+ UB_TP_DIP_MASK;
+ dip2 = attr[i].peer_net_addr.net_addr.in6.interface_id &
+ UB_TP_DIP_MASK;
+ dip3 = (attr[i].peer_net_addr.net_addr.in6
+ .interface_id >>
+ UB_TP_DIP_OFFSET) &
+ UB_TP_DIP_MASK;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "dsip0:0x%x, dsip1:0x%x, dsip2:0x%x, dsip3:0x%x\n",
+ dip0, dip1, dip2, dip3);
+
+ udma_debug(udma_dev->dev, UDMA_M_TP,
+ "end print ubcore tp attr[%u]\n", i);
+ }
+}
+
+int udma_modify_multi_tp(u32 cnt, struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask,
+ struct ubcore_tp **fail_tp)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ u32 ubrc_success_num = 0, cos_success_num = 0, modify_success_num = 0,
+ reuse_success_num = 0;
+ u32 k;
+
+ if (tp == NULL || fail_tp == NULL || attr == NULL || mask == NULL) {
+ udma_pr_err(
+ UDMA_M_TP,
+ "%s: Invalid parameter, tp(%d), fail_tp(%d), attr(%d), mask(%d)\n",
+ __func__, !!tp, !!fail_tp, !!attr, !!mask);
+ return 0;
+ }
+
+ if (cnt == 0 || cnt > UB_CMD_TP_CNT_MAX) {
+ udma_pr_err(
+ UDMA_M_TP,
+ "%s: cnt(%u) is zero or larger than UB_CMD_TP_CNT_MAX(%d)\n",
+ __func__, cnt, UB_CMD_TP_CNT_MAX);
+ return 0;
+ }
+ if (tp[0]->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TP, "Invalid parameter: ub_dev(%d).\n",
+ !!tp[0]->ub_dev);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(tp[0]->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+
+ udma_print_multi_tp_attr(attr, mask, udma_dev, cnt);
+
+ if (udma_tp_get_valid_attr_num_for_modify(udma_dev, cnt, tp, attr,
+ mask) != cnt) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "attr check failed, cnt(%u)\n", cnt);
+ return 0;
+ }
+
+ ubrc_success_num =
+ udma_multi_tp_create_ubrc_table(udma_dev, cnt, tp, attr, mask);
+
+ cos_success_num = udma_modify_multi_get_cos(udma_dev, ubrc_success_num,
+ tp, attr, mask);
+
+ modify_success_num = udma_modify_multi_tp_cmd_entry(
+ udma_dev, cos_success_num, tp, attr, mask);
+
+ reuse_success_num = udma_handle_tp_reuse(udma_dev, modify_success_num,
+ tp, attr, mask);
+
+ for (k = reuse_success_num; k < cnt; ++k)
+ fail_tp[k - reuse_success_num] = tp[k];
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_modify_multi_tp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TP, "modify %u tp succeed, cnt(%u)\n",
+ reuse_success_num, cnt);
+
+ return (int)reuse_success_num;
+}
+
+int udma_query_tp_ctx_from_host(struct udma_device *udma_dev, u32 tpn,
+ struct ub_dfx_tp_ctx_query *outbuf)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_tp *ub_tp = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX, tpn,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to get cqm object, tpn:%u\n", tpn);
+ return -EINVAL;
+ }
+ ub_tp = udma_find_tp(udma_dev, tpn);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to find tp, tpn = %u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ udma_tp_put(ub_tp);
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query ub_tp fail for tp ctx, tpn:%u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ memcpy_fromio((void *)outbuf, (void *)ub_tp->tp_info->vaddr,
+ sizeof(struct ub_dfx_tp_ctx_query));
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp ctx from host success, tpn:%u\n", tpn);
+
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
+
+int udma_query_tp_mpt_from_host(struct udma_device *udma_dev, u32 tpn,
+ struct ub_mapt_ctx_query *outbuf)
+{
+ struct udma_tp *ub_tp = NULL;
+ struct tag_cqm_object *cqm_obj = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX, tpn,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to get cqm object, tpn:%u\n", tpn);
+ return -EINVAL;
+ }
+ ub_tp = udma_find_tp(udma_dev, tpn);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to find tp, tpn = %u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ udma_tp_put(ub_tp);
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query ub_tp fail for tp mpt, tpn:%u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ (void)memcpy_s((void *)outbuf, sizeof(struct ub_mapt_ctx_query),
+ (void *)ub_tp->tp_info->vaddr,
+ sizeof(struct ub_mapt_ctx_query));
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp mpt from host success, tpn:%u\n", tpn);
+
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
+
+int udma_query_tp_pcqc_from_host(struct udma_device *udma_dev, u32 tpn,
+ ub_pcqc_query_rsp_s *outbuf)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_tp *ub_tp = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX, tpn,
+ false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to get cqm object, tpn:%u\n", tpn);
+ return -EINVAL;
+ }
+ ub_tp = udma_find_tp(udma_dev, tpn);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_DFX,
+ "failed to find tp, tpn = %u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ udma_tp_put(ub_tp);
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query ub_tp fail for tp pcqc, tpn:%u\n", tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ memcpy_fromio((void *)outbuf, (void *)ub_tp->pcqc_info->q_ctx_vaddr,
+ sizeof(ub_pcqc_query_rsp_s));
+
+ udma_info(udma_dev->dev, UDMA_M_TP,
+ "query tp pcqc from host success, tpn:%u\n", tpn);
+
+cleanup:
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
+
+static int udma_check_dscp_vl_params(struct ubcore_device *dev, const u8 *dscp,
+ const u8 *vl, u8 num)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if (dev == NULL || dscp == NULL || vl == NULL) {
+ udma_pr_err(
+ UDMA_M_TP,
+ "%s: Invalid parameter, dev(%d), dscp(%d), vl(%d)\n",
+ __func__, !!dev, !!dscp, !!vl);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ if (num > UDMA_DSCP_NUM) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "num is larger than UDMA_DSCP_NUM\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int udma_config_dscp_vl(struct ubcore_device *dev, u8 *dscp, u8 *vl, u8 num)
+{
+ struct udma_device *udma_dev = NULL;
+ u8 dscp2cos[UDMA_DSCP_NUM] = { 0 };
+ int ret;
+ u8 i;
+
+ ret = udma_check_dscp_vl_params(dev, dscp, vl, num);
+ if (ret != 0) {
+ return ret;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ ret = udma_dscp_cos_map(udma_dev, dscp2cos, sizeof(dscp2cos),
+ MGMT_MSG_CMD_OP_GET);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "get origin cos failed, err:%d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (dscp[i] > UDMA_DSCP_MAX || vl[i] > UDMA_COS_MAX) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "err dscp:%u cos:%u\n", dscp[i], vl[i]);
+ return -EINVAL;
+ }
+ dscp2cos[dscp[i]] = vl[i];
+ }
+
+ ret = udma_dscp_cos_map(udma_dev, dscp2cos, sizeof(dscp2cos),
+ MGMT_MSG_CMD_OP_SET);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "set port cos failed, err:%d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < num; i++) {
+ udma_dev->dscp2cos[dscp[i]] = vl[i];
+ udma_dev->dscp_bitmap |= BIT((u64)dscp[i]);
+ }
+
+ return 0;
+}
+
+int udma_query_dscp_vl(struct ubcore_device *dev, uint8_t *dscp, uint8_t num,
+ uint8_t *vl)
+{
+ struct udma_device *udma_dev = NULL;
+ int ret;
+ u8 i;
+
+ ret = udma_check_dscp_vl_params(dev, dscp, vl, num);
+ if (ret != 0) {
+ return ret;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ for (i = 0; i < num; i++) {
+ if (dscp[i] >= UDMA_DSCP_MAX) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "query dscp cos err dscp(%u)\n", dscp[i]);
+ return -EINVAL;
+ }
+ vl[i] = udma_dev->dscp2cos[dscp[i]];
+ }
+
+ return 0;
+}
+
+int udma_get_dscp_cos(struct udma_device *udma_dev, u8 *dscp, u32 size,
+ u8 is_dev)
+{
+ u8 dscp2cos[UDMA_DSCP_MAX_NUM] = { 0 };
+ int ret = 0;
+ u8 i;
+
+ if (is_dev == 0) {
+ ret = udma_dscp_cos_map(udma_dev, dscp2cos, sizeof(dscp2cos),
+ MGMT_MSG_CMD_OP_GET);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "get port cos failed, err:%d\n", ret);
+ return ret;
+ }
+ goto result;
+ }
+
+ for (i = 0; i < UDMA_DSCP_MAX_NUM; i++) {
+ if ((udma_dev->dscp_bitmap & BIT((u64)i)) == 0) {
+ ret = hinic5_get_cos_by_pri(udma_dev->hwdev, i,
+ &dscp2cos[i]);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "get nic cos failed, pri:%d, err:%d\n",
+ i, ret);
+ return ret;
+ }
+ } else {
+ dscp2cos[i] = udma_dev->dscp2cos[i];
+ }
+ }
+
+result:
+ (void)memcpy_s(dscp, size, dscp2cos, sizeof(dscp2cos));
+
+ return 0;
+}
+
+int udma_dfx_modify_tp_exec(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf)
+{
+ struct tag_cqm_object *cqm_obj = NULL;
+ struct udma_tp *ub_tp = NULL;
+ int ret = 0;
+
+ cqm_obj = cqm5_object_get(udma_dev->hwdev, CQM_OBJECT_SERVICE_CTX,
+ inbuf->tpn, false);
+ if (cqm_obj == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to get cqm object, tpn = %u\n", inbuf->tpn);
+ return -EINVAL;
+ }
+
+ ub_tp = udma_find_tp(udma_dev, inbuf->tpn);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to find tp, tpn = %u\n", inbuf->tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ ub_tp = cqmobj_to_ub_tp(cqm_obj);
+ if (ub_tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to get ub_tp for object, tpn = %u\n",
+ inbuf->tpn);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ ret = udma_cmd_tp_modify_dfx(udma_dev, ub_tp, &inbuf->tp_attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TP,
+ "failed to modify tp, tpn = %u ret = %d\n", inbuf->tpn,
+ ret);
+ goto cleanup;
+ }
+
+ udma_modify_tp_for_host(&ub_tp->tp, &inbuf->tp_attr);
+
+ udma_info(udma_dev->dev, UDMA_M_TP, "query object success, id:%u\n",
+ inbuf->tpn);
+
+cleanup:
+ udma_tp_put(ub_tp);
+ cqm5_object_put(cqm_obj);
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.h
new file mode 100644
index 000000000..7cbfdd5b7
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tp.h
@@ -0,0 +1,184 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef CPU_UDMA_TP_H
+#define CPU_UDMA_TP_H
+
+#include <linux/mutex.h>
+#include "ubcore_api.h"
+#include "udma_common.h"
+#include "hinic5_cqm.h"
+#include "udma_db.h"
+
+#define CPU_UBEP_MAX_TP 512
+#define MAX_HOP_LIMIT 255
+
+#define UBEP_PAGE_SHIFT 12
+#define UBEP_TP_CONTEXT_SIZE 1024
+#define UBEP_TPG_CONTEXT_SIZE 1024
+
+#define TPGN_INVALID 0xffffffff
+#define TPN_INVALID_NUM 0xffffffff
+#define TP_DEFAULT_RETRY_EXP 3
+
+#define TP_WQE_SHIFT 6
+#define TP_WQEBB_SIZE_SHIFT 4
+#define TP_WQEBB_SIZE_MASK 0x7
+#define TP_MTT_GPA_VALID 0x1
+#define TP_WQE_PREFETCH_MAXNUM 4
+#define TP_SQ_WQEBB_SIZE_SHIFT 4
+#define TP_SQ_WQEBB_SIZE_MASK 0x7
+#define TP_SQ_PD_MASK 0x3ffff
+#define TP_SQ_PAGE_SIZE_MASK 0xf
+#define TP_SQ_WQECNT_LTH 4
+#define TP_SQ_PREFETCH_MINNUM 2
+#define TP_SQ_PREFETCH_MAXNUM 4
+#define TP_SQ_SIZE_MASK 0x1f
+#define TP_SQ_CQN_MASK 0xfffff
+#define TP_RQ_WQECNT_LTH 0xe
+#define TP_RQ_MTT_PREFETCH_MAXLEN0 3
+#define TP_RQ_MTT_PREFETCH_MAXWQE 7
+#define TP_RQ_WQE_PREFETCH_MAXNUM 7
+#define TP_SRQ_INIT_STATE 0xf
+#define TP_MAX_PI_ON_CHIP_QPN 1024
+#define TP_QP_MAX_PFETCH_MTT_LAYER 3
+#define TP_QP_MAX_TIMER_NUM 5
+
+#define TP_PCQC_SIZE 128
+#define BIT_CNT_PER_BYTE 8
+#define DB_SIZE 4
+
+#define TP_GET_MAC_HI(a, b) (((a) << 8) | (b))
+#define TP_GET_MAC_LO(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+#define TP_Q_WQEBB 64
+#define TP_RC_GPA_H_SHIFT 40
+#define TP_RC_GPA_L_SHIFT 8
+
+#define UDMA_TP_OOR_64 64
+#define UDMA_TP_OOR_128 128
+#define UDMA_TP_OOR_256 256
+#define UDMA_TP_OOR_512 512
+#define UDMA_TP_OOR_1024 1024
+
+struct udma_buf_list {
+ void *buf;
+ dma_addr_t map;
+};
+
+struct udma_buf {
+ struct udma_buf_list direct;
+ int nbufs;
+
+ int npages;
+ int page_shift;
+};
+
+struct udma_tp {
+ u32 cqm_priv_type;
+ struct ubcore_tp tp;
+ struct ubcore_tp_cfg cfg;
+ struct udma_kdb *kdb;
+ struct tag_cqm_qpc_mpt *tp_info;
+ u32 entry_size;
+ u32 entry_cnt;
+ u8 pri;
+ u8 cos;
+ struct udma_buf buf;
+ u32 buf_size;
+ struct mtt ub_mtt;
+ struct tag_cqm_queue *tp_buf_info;
+ struct tag_cqm_queue *pcqc_info;
+ u32 tp_buf_info_xid;
+ u8 oor_en;
+ u8 refuse_report_flush_done;
+ u8 rsv[2];
+ struct ubrc rc_table;
+ u32 rc_table_num;
+ u32 rc_log_ubrc_seg;
+ struct list_head node;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+static inline struct udma_tp *to_udma_tp(const struct ubcore_tp *tp)
+{
+ return (struct udma_tp *)udma_container_of(tp, struct udma_tp, tp);
+}
+
+static inline struct udma_tp *
+cqmobj_to_ub_tp(const struct tag_cqm_object *object)
+{
+ struct tag_cqm_qpc_mpt *tp_info =
+ container_of(object, struct tag_cqm_qpc_mpt, object);
+ return (struct udma_tp *)tp_info->priv;
+}
+
+static inline int check_tp_query_ret_val(const void *ret_val, u32 val_len,
+ u32 ret_len, struct device *dev,
+ const struct ubcore_res_key *key)
+{
+ if (ret_val == NULL) {
+ udma_err(dev, UDMA_M_TP,
+ "failed to check ret_val, ret_val invalid (0x%x).\n",
+ key->key);
+ return -EDESTADDRREQ;
+ }
+ if (val_len < ret_len) {
+ udma_err(dev, UDMA_M_TP,
+ "Failed to check len, type: %u, val->len: %u.\n",
+ (u32)(key->type), val_len);
+ return (int)(ret_len);
+ }
+ return 0;
+}
+
+struct udma_tp *udma_find_tp(struct udma_device *udev, u32 tpn);
+struct ubcore_tp *udma_create_tp(struct ubcore_device *ub_dev,
+ struct ubcore_tp_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_dfx_modify_tp_exec(struct udma_device *udma_dev,
+ const struct ub_query_inbuf *inbuf,
+ union ub_query_outbuf *outbuf);
+int udma_modify_tp(struct ubcore_tp *tp, struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask mask);
+int udma_destroy_tp(struct ubcore_tp *tp);
+int udma_query_tpc(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ub_dfx_tp_ctx_query *val);
+int udma_query_tpc_info(struct udma_device *udma_dev,
+ struct ubcore_res_key *key,
+ struct tag_ub_tp_query_info_outbuf *val);
+int udma_query_res_tp(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+int udma_query_tp_wqe_from_host(struct udma_device *udma_dev, u32 tpn,
+ u32 wqe_id, struct ub_tp_wqe *outbuf,
+ u32 outbuf_size);
+
+int udma_create_multi_tp(struct ubcore_device *dev, u32 cnt,
+ struct ubcore_tp_cfg *cfg, struct ubcore_udata *udata,
+ struct ubcore_tp **tp);
+int udma_modify_multi_tp(u32 cnt, struct ubcore_tp **tp,
+ struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask *mask,
+ struct ubcore_tp **fail_tp);
+int udma_destroy_multi_tp(u32 cnt, struct ubcore_tp **tp);
+int udma_tp_create_ubrc_table(struct udma_device *udma_dev,
+ const struct ubcore_tp_attr *attr,
+ union ubcore_tp_attr_mask mask,
+ struct udma_tp *ub_tp);
+int udma_query_tp_ctx_from_host(struct udma_device *udma_dev, u32 tpn,
+ struct ub_dfx_tp_ctx_query *outbuf);
+int udma_query_tp_mpt_from_host(struct udma_device *udma_dev, u32 tpn,
+ struct ub_mapt_ctx_query *outbuf);
+int udma_query_tp_pcqc_from_host(struct udma_device *udma_dev, u32 tpn,
+ ub_pcqc_query_rsp_s *outbuf);
+int udma_config_dscp_vl(struct ubcore_device *dev, u8 *dscp, u8 *vl, u8 num);
+int udma_get_dscp_cos(struct udma_device *udma_dev, u8 *dscp, u32 size,
+ u8 is_dev);
+int udma_query_dscp_vl(struct ubcore_device *dev, uint8_t *dscp, uint8_t num,
+ uint8_t *vl);
+void udma_tp_put(void *obj);
+void udma_tp_get(void *obj);
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.c
new file mode 100644
index 000000000..6657f271a
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.c
@@ -0,0 +1,677 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_mtt.h"
+#include "udma_misc.h"
+#include "ubcore_uapi.h"
+#include "udma_tp.h"
+#include "udma_cmd_tpg.h"
+#include "udma_vram.h"
+#include "udma_tpg.h"
+
+#define UB_TP_CNT_16 16
+#define UB_TP_CNT_32 32
+
+static int udma_fill_tpg_res_ret_val(const struct udma_device *udma_dev,
+ struct ubcore_res_val *val, u32 buf_len,
+ struct udma_tpg *ub_tpg,
+ struct ubcore_res_tpg_val *ret_val)
+{
+ u32 i;
+
+ val->len = buf_len;
+ if (ub_tpg->tp_num > MAX_TP_CNT_IN_TPG) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TPG,
+ "query tpg res: tp num large than tp num max, tp_num:0x%x\n",
+ ub_tpg->tp_num);
+ return -EINVAL;
+ }
+
+ ret_val->tp_cnt = ub_tpg->tp_num;
+ ret_val->tp_list = (u32 *)vmalloc(sizeof(u32) * ret_val->tp_cnt);
+ if (ret_val->tp_list == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "tp_list vmalloc failed.\n");
+ return -ENOMEM;
+ }
+ ret_val->dscp = ub_tpg->sl;
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ if (ub_tpg->tp_used[i] == 0)
+ continue;
+ ret_val->tp_list[i] = ub_tpg->tpinfo_list[i]->xid;
+ }
+
+ return 0;
+}
+
+static inline int check_tpg_query_ret_val(const void *ret_val, u32 val_len,
+ u32 ret_len, struct device *dev,
+ const struct ubcore_res_key *key)
+{
+ if (ret_val == NULL) {
+ udma_err(dev, UDMA_M_TPG,
+ "failed to check ret_val, ret_val invalid (0x%x).\n",
+ key->key);
+ return -EDESTADDRREQ;
+ }
+ if (val_len < ret_len) {
+ udma_err(dev, UDMA_M_TPG,
+ "Failed to check len, type: %u, val->len: %u.\n",
+ (u32)key->type, val_len);
+ return (int)ret_len;
+ }
+ return 0;
+}
+
+int udma_query_res_tpg(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_tpg_val *ret_val =
+ (struct ubcore_res_tpg_val *)(uintptr_t)val->addr;
+ struct udma_tpg *ub_tpg = NULL;
+ int ret;
+
+ ret = check_tpg_query_ret_val(ret_val, val->len,
+ sizeof(struct ubcore_res_tpg_val),
+ udma_dev->dev, key);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TPG,
+ "query tpg res: failed to check return vaule, key:0x%x\n",
+ key->key);
+ return ret;
+ }
+
+ ub_tpg = udma_get_tpg_by_id(udma_dev, key->key);
+ if (ub_tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Failed to find tpg, id(%u)\n", key->key);
+ return -EINVAL;
+ }
+
+ ret = udma_fill_tpg_res_ret_val(udma_dev, val,
+ sizeof(struct ubcore_res_tp_val),
+ ub_tpg, ret_val);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "query tpg res: failed to fill tpg res, key:0x%x\n",
+ key->key);
+ }
+
+ udma_tpg_put(ub_tpg);
+ return ret;
+}
+
+int udma_query_tpg_flow(struct udma_device *udma_dev, struct ub_tpg_flow *val)
+{
+ struct tag_ub_tp_query_info_outbuf *tpcval = NULL;
+ struct ubcore_res_key key = { 0 };
+ struct udma_tpg *ub_tpg = NULL;
+ int ret = 0;
+ u32 i;
+
+ tpcval = (struct tag_ub_tp_query_info_outbuf *)kzalloc(
+ sizeof(struct tag_ub_tp_query_info_outbuf), GFP_KERNEL);
+ if (tpcval == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TPG,
+ "query tpg flow:failed to allocate memroy for tp ctx\n");
+ return -ENOMEM;
+ }
+
+ ub_tpg = udma_get_tpg_by_id(udma_dev, val->tpgn);
+ if (ub_tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Failed to find tpg, id(%u)\n", val->tpgn);
+ kfree(tpcval);
+ return -EINVAL;
+ }
+
+ val->tp_num = ub_tpg->tp_num;
+
+ for (i = 0; i < val->tp_num; i++) {
+ if (ub_tpg->tp_used[i] == 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "tp %u not in use.\n",
+ ub_tpg->tpinfo_list[i]->xid);
+ continue;
+ }
+ key.key = ub_tpg->tpinfo_list[i]->xid;
+ ret = udma_query_tpc_info(udma_dev, &key, tpcval);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TP,
+ "query tpg flow: failed to query tp context, key:0x%x\n",
+ key.key);
+ continue;
+ }
+
+ val->tp_flow_info[i].tpn = tpcval->srctpn;
+ val->tp_flow_info[i].send_cnt = tpcval->tp_msn;
+ val->tp_flow_info[i].infly = tpcval->infly_wr;
+ val->tp_flow_info[i].wr = tpcval->pending_wr;
+ }
+ udma_tpg_put(ub_tpg);
+ kfree(tpcval);
+
+ return ret;
+}
+
+static int udma_tpg_alloc_tpn(struct udma_device *udma_dev,
+ const struct ubcore_tpg_cfg *cfg,
+ struct udma_tpg *ub_tpg)
+{
+ u32 qpc_num = 0; //success created qpc count
+ u32 qpn_tmp;
+ u32 i;
+ u32 end;
+
+ ub_tpg->tp_num = cfg->tp_cnt;
+ mutex_lock(
+ &udma_dev->tp_mutex); //solve uvs multi thread and send scenario even现 tpg in tp xid not continuous problem (need ensure 16 or 32 tpn continuous)
+ qpn_tmp = CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE,
+ CQM_XID_LOW_BIT_NONE, 0);
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ end = udma_dev->ub_cap.dev_cap.max_tp;
+ ub_tpg->tpinfo_list[i] = udma_object_qpc_create(
+ udma_dev, UBEP_TP_CONTEXT_SIZE, NULL,
+ &udma_dev->tpn_record, qpn_tmp, 0, end);
+ if (ub_tpg->tpinfo_list[i] == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "tpn allocation failed, index(%u)\n", i);
+ qpc_num = i;
+ goto err_create_qpc;
+ }
+ }
+ mutex_unlock(&udma_dev->tp_mutex);
+ return 0;
+
+err_create_qpc:
+ for (i = 0; i < qpc_num; ++i) {
+ cqm5_object_delete(&ub_tpg->tpinfo_list[i]->object);
+ ub_tpg->tpinfo_list[i] = NULL;
+ }
+ mutex_unlock(&udma_dev->tp_mutex);
+ return -ENOMEM;
+}
+
+static void udma_tpg_free_tpn(struct udma_device *udma_dev,
+ struct udma_tpg *ub_tpg, bool del_object)
+{
+ u32 i;
+
+ mutex_lock(&udma_dev->tp_mutex);
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ if (del_object) {
+ cqm5_object_delete(&ub_tpg->tpinfo_list[i]->object);
+ }
+ ub_tpg->tpinfo_list[i] = NULL;
+ }
+ mutex_unlock(&udma_dev->tp_mutex);
+}
+
+static int udma_tpg_rm_alloc(struct udma_device *udma_dev,
+ const struct ubcore_tpg_cfg *cfg,
+ struct udma_tpg *ub_tpg)
+{
+ struct ubcore_tpg *tpg = &ub_tpg->tpg;
+ int ret = 0;
+
+ tpg->tpgn = udma_bitmap_alloc_id(udma_dev->bitmap); //via bitmap allocate
+ if (tpg->tpgn >= udma_dev->bitmap->size) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RM mode, tpgn allocation failed\n");
+ tpg->tpgn = 0;
+ return -EBUSY;
+ }
+
+ ret = udma_tpg_alloc_tpn(udma_dev, cfg, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RM mode, tpn allocation failed\n");
+ goto err_alloc_tpn;
+ }
+
+ ret = udma_cmd_tpg_create(udma_dev, cfg, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG, "send cmd failed.\n");
+ goto err_cmd_tpg_create;
+ }
+
+ return 0;
+
+err_cmd_tpg_create:
+ udma_tpg_free_tpn(udma_dev, ub_tpg, true);
+err_alloc_tpn:
+ udma_bitmap_free_id(udma_dev->bitmap, tpg->tpgn);
+ return ret;
+}
+
+static int udma_tpg_rm_free(struct udma_device *udma_dev,
+ struct udma_tpg *ub_tpg)
+{
+ int ret;
+
+ ret = udma_cmd_tpg_delete(udma_dev, ub_tpg->tpg.tpgn,
+ &ub_tpg->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RM mode. Failed to delete tp.\n");
+ return ret;
+ }
+
+ udma_tpg_free_tpn(udma_dev, ub_tpg, false);
+
+ udma_bitmap_free_id(udma_dev->bitmap, ub_tpg->tpg.tpgn);
+
+ return 0;
+}
+
+static int udma_tpg_rc_alloc(struct udma_device *udma_dev,
+ const struct ubcore_tpg_cfg *cfg,
+ struct udma_tpg *ub_tpg)
+{
+ struct ubcore_tpg *tpg = &ub_tpg->tpg;
+ int ret = 0;
+
+ tpg->tpgn = udma_bitmap_alloc_id(udma_dev->bitmap); //via bitmap allocate
+ if (tpg->tpgn >= udma_dev->bitmap->size) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RC mode, tpgn allocation failed\n");
+ tpg->tpgn = 0;
+ return -EBUSY;
+ }
+
+ ret = udma_tpg_alloc_tpn(udma_dev, cfg, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RC mode, tpn allocation failed\n");
+ goto err_alloc_tpn;
+ }
+
+ return 0;
+
+err_alloc_tpn:
+ udma_bitmap_free_id(udma_dev->bitmap, tpg->tpgn);
+ return ret;
+}
+
+static void udma_tpg_rc_free(struct udma_device *udma_dev,
+ struct udma_tpg *ub_tpg)
+{
+ udma_bitmap_free_id(udma_dev->bitmap, ub_tpg->tpg.tpgn);
+ udma_tpg_free_tpn(udma_dev, ub_tpg, false);
+}
+
+static void udma_tpg_kref_release(struct kref *ref_cnt)
+{
+ struct udma_tpg *tpg = container_of(ref_cnt, struct udma_tpg, ref_cnt);
+
+ complete(&tpg->comp);
+}
+
+void udma_tpg_put(void *obj)
+{
+ struct udma_tpg *tpg = obj;
+
+ if (tpg != NULL) {
+ kref_put(&tpg->ref_cnt, udma_tpg_kref_release);
+ }
+}
+
+void udma_tpg_get(void *obj)
+{
+ struct udma_tpg *tpg = obj;
+
+ kref_get(&tpg->ref_cnt);
+}
+
+struct udma_tpg *udma_get_tpg_by_id(struct udma_device *udma_dev, u32 tpgn)
+{
+ struct udma_tpg *tpg_now = NULL;
+ struct mutex *lock = NULL;
+
+ udma_info(udma_dev->dev, UDMA_M_TPG, "query tpg id: %u\n", tpgn);
+
+ lock = &udma_dev->device_res->tpg_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(tpg_now, &udma_dev->device_res->tpg_list.node,
+ node) {
+ if (tpg_now->tpg.tpgn == tpgn) {
+ udma_tpg_get(tpg_now);
+ mutex_unlock(lock);
+ return tpg_now;
+ }
+ }
+ mutex_unlock(lock);
+
+ return NULL;
+}
+
+static void udma_print_tpg_cfg(const struct ubcore_tpg_cfg *cfg,
+ struct udma_device *udma_dev)
+{
+ u32 dip0 = 0;
+ u32 dip1 = 0;
+ u32 dip2 = 0;
+ u32 dip3 = 0;
+
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "start print ubcore tpg cfg.\n");
+
+ dip0 = cfg->local_eid.in6.subnet_prefix & 0xffffffff;
+ dip1 = (cfg->local_eid.in6.subnet_prefix >> 0x20) &
+ 0xffffffff; //after assembling 0x20 bit
+ dip2 = cfg->local_eid.in6.interface_id & 0xffffffff;
+ dip3 = (cfg->local_eid.in6.interface_id >> 0x20) &
+ 0xffffffff; //after assembling 0x20 bit
+
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "local_eid:0x%x %x %x %x\n", dip0,
+ dip1, dip2, dip3);
+
+ dip0 = cfg->peer_eid.in6.subnet_prefix & 0xffffffff;
+ dip1 = (cfg->peer_eid.in6.subnet_prefix >> 0x20) &
+ 0xffffffff; //after assembling 0x20 bit
+ dip2 = cfg->peer_eid.in6.interface_id & 0xffffffff;
+ dip3 = (cfg->peer_eid.in6.interface_id >> 0x20) &
+ 0xffffffff; //after assembling 0x20 bit
+
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "peer_eid:0x%x %x %x %x\n", dip0,
+ dip1, dip2, dip3);
+
+ udma_debug(udma_dev->dev, UDMA_M_TPG,
+ "trans_mode:%u, dscp:%u, cc_alg:%u, cc_pattern_idx:%u\n",
+ cfg->trans_mode, cfg->dscp, cfg->cc_alg,
+ cfg->cc_pattern_idx);
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "tp_cnt:%u\n", cfg->tp_cnt);
+
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "end print ubcore tpg cfg.\n");
+}
+
+static int udma_check_create_tpg_params(struct ubcore_device *ub_dev,
+ struct ubcore_tpg_cfg *cfg)
+{
+ struct udma_device *udma_dev = NULL;
+
+ if (ub_dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_TPG,
+ "Invalid parameter, ub_dev(%d), cfg(%d)\n",
+ !!ub_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ udma_print_tpg_cfg(cfg, udma_dev);
+
+ if ((cfg->trans_mode == UBCORE_TP_RC) &&
+ (cfg->tp_cnt != 2)) { //RC mode 1(count word) TPG has 2(count word) TP
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RC mode, tp num(%u) is wrong.\n", cfg->tp_cnt);
+ return -EINVAL;
+ }
+
+ if (cfg->trans_mode == UBCORE_TP_UM) {
+ udma_err(udma_dev->dev, UDMA_M_TPG, "wrong trans mode: UM.\n");
+ return -EINVAL;
+ }
+
+ if ((cfg->trans_mode != UBCORE_TP_RC) &&
+ (cfg->tp_cnt != UB_TP_CNT_16) && (cfg->tp_cnt != UB_TP_CNT_32)) {
+ udma_err(udma_dev->dev, UDMA_M_RC_TABLE,
+ "tp_cnt should be 16 or 32. cur_value: %d.\n",
+ cfg->tp_cnt);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct ubcore_tpg *udma_create_tpg(struct ubcore_device *ub_dev,
+ struct ubcore_tpg_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct ubcore_tpg *tpg = NULL;
+ struct udma_tpg *ub_tpg = NULL;
+ int ret;
+
+ ret = udma_check_create_tpg_params(ub_dev, cfg);
+ if (ret != 0) {
+ return ERR_PTR(ret);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ ub_tpg = (struct udma_tpg *)udma_vram_kzalloc(udma_dev->dev,
+ UDMA_VRAM_TYPE_TPG,
+ sizeof(struct udma_tpg),
+ GFP_KERNEL);
+ if (ub_tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "memory allocation failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ tpg = &ub_tpg->tpg;
+ tpg->ub_dev = ub_dev;
+
+ tpg->tpg_cfg.trans_mode = cfg->trans_mode;
+ ub_tpg->sl = cfg->dscp;
+
+ if (tpg->tpg_cfg.trans_mode == UBCORE_TP_RC) {
+ ret = udma_tpg_rc_alloc(udma_dev, cfg, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RC mode, tpg failed, ret(%d)\n", ret);
+ goto err_tpg_alloc;
+ }
+ } else {
+ ret = udma_tpg_rm_alloc(udma_dev, cfg, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RM mode, tpg failed, ret(%d)\n", ret);
+ goto err_tpg_alloc;
+ }
+ }
+
+ kref_init(&ub_tpg->ref_cnt);
+ init_completion(&ub_tpg->comp);
+ udma_store_list(udma_dev, &ub_tpg->node,
+ &udma_dev->device_res->tpg_list);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_create_tpg cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_TPG, "create tpg %u succeed\n",
+ tpg->tpgn);
+
+ return tpg;
+
+err_tpg_alloc:
+ udma_vram_kfree(udma_dev->dev, ub_tpg, UDMA_VRAM_TYPE_TPG);
+ return ERR_PTR(ret);
+}
+
+int udma_destroy_tpg(struct ubcore_tpg *tpg)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_tpg *ub_tpg = NULL;
+ int ret;
+ u32 i;
+
+ if (tpg == NULL || tpg->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_TPG, "Invalid parameter, tpg(%d)\n", !!tpg);
+ return -EINVAL;
+ }
+
+ udma_dev = to_udma_dev(tpg->ub_dev);
+ ub_tpg = to_udma_tpg(tpg);
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ udma_info(udma_dev->dev, UDMA_M_TPG, "start to destroy tpg, id: %u.\n",
+ tpg->tpgn);
+
+ if (tpg->tpg_cfg.trans_mode == UBCORE_TP_UM) {
+ udma_err(udma_dev->dev, UDMA_M_TPG, "wrong trans mode: UM.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ if (ub_tpg->tp_used[i] == 1) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Failed to destroy tpg, tp %u still in use.\n",
+ ub_tpg->tpinfo_list[i]->xid);
+ return -EBUSY;
+ }
+ }
+ udma_delete_list(udma_dev, &ub_tpg->node,
+ &udma_dev->device_res->tpg_list);
+ udma_tpg_put(ub_tpg);
+ wait_for_completion(&ub_tpg->comp);
+ if (tpg->tpg_cfg.trans_mode == UBCORE_TP_RC) {
+ udma_tpg_rc_free(udma_dev, ub_tpg);
+ } else { //RM mode
+ ret = udma_tpg_rm_free(udma_dev, ub_tpg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "RM mode. Failed to delete tp.\n");
+ goto ERR_DESTORY_OUT;
+ }
+ }
+
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_TPG, tpg->tpgn,
+ &ub_tpg->cmdq_rtt);
+ udma_vram_kfree(udma_dev->dev, ub_tpg, UDMA_VRAM_TYPE_TPG);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_destroy_tpg cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ return 0;
+ERR_DESTORY_OUT:
+ kref_init(&ub_tpg->ref_cnt);
+ init_completion(&ub_tpg->comp);
+ udma_store_list(udma_dev, &ub_tpg->node,
+ &udma_dev->device_res->tpg_list);
+ return ret;
+}
+
+static int udma_tp_latch_tpg_alloc(struct udma_device *udma_dev,
+ u32 expect_tpgn)
+{
+ u32 tpgn;
+ int ret = 0;
+
+ tpgn = udma_bitmap_alloc_id(udma_dev->bitmap); //via bitmap allocate
+ if (tpgn >= udma_dev->bitmap->size || tpgn != expect_tpgn) {
+ udma_err(
+ udma_dev->dev, UDMA_M_TPG,
+ "TP latch, tpgn allocation failed, tpgn:%u, expect_tpgn:%u.\n",
+ tpgn, expect_tpgn);
+ udma_bitmap_free_id(udma_dev->bitmap, tpgn);
+ return -EBUSY;
+ }
+
+ ret = udma_cmd_tp_latch_tpg_create(udma_dev, tpgn);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Send tp latch create tpg cmd failed, ret = %d.\n",
+ ret);
+ udma_bitmap_free_id(udma_dev->bitmap, tpgn);
+ return ret;
+ }
+
+ return 0;
+}
+
+void udma_tp_latch_tpg_free(struct udma_device *udma_dev, u32 tpgn)
+{
+ if (udma_cmd_tpg_delete(udma_dev, tpgn, NULL) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Failed to delete tp latch tpg(%u).\n", tpgn);
+ }
+ udma_bitmap_free_id(udma_dev->bitmap, tpgn);
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "Delete tp latch tpg(%u) successful.\n", tpgn);
+ return;
+}
+
+int udma_create_tp_latch_tpg(struct udma_device *udma_dev)
+{
+ int ret;
+ u32 cur_idx;
+
+ /* non- TPF not reserved 0 ~ 15 of TPG */
+ if (!udma_dev->ub_dev.attr.tp_maintainer ||
+ udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ udma_info(
+ udma_dev->dev, UDMA_M_TPG,
+ "Non-TPF(%u) or non-HI1825(%u) not create tp latch tpg.\n",
+ udma_dev->ub_dev.attr.tp_maintainer,
+ udma_dev->device_type);
+ return 0;
+ }
+ /* if already create TP Latch TPG, then not again repeat create */
+ if (udma_dev->latch_tpg_configured == 1) {
+ return 0;
+ }
+
+ for (cur_idx = 0; cur_idx < UB_TP_LATCH_RSV_TPG_NUM; cur_idx++) {
+ ret = udma_tp_latch_tpg_alloc(udma_dev, cur_idx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_TPG,
+ "Create tp latch tpg(%u) ret:%d.\n", cur_idx,
+ ret);
+ goto ERR_TPG_ALLOC;
+ }
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "Create tp latch tpg(%u) successful.\n", cur_idx);
+ }
+ udma_dev->latch_tpg_configured = 1;
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "Create tp latch tpg successful.\n");
+ return 0;
+
+ERR_TPG_ALLOC:
+ /* free already allocate of TPG resource */
+ for (u32 i = 0; i < cur_idx; i++) {
+ udma_tp_latch_tpg_free(udma_dev, i);
+ }
+ udma_dev->latch_tpg_configured = 0;
+ return -EFAULT;
+}
+
+void udma_destroy_tp_latch_tpg(struct udma_device *udma_dev)
+{
+ /* non- TPF did not create TP latch tpg */
+ if (!udma_dev->ub_dev.attr.tp_maintainer ||
+ udma_dev->device_type != UDMA_DEV_TYPE_HI1825_V100) {
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "Non-TPF not create tp latch tpg, no delete.\n");
+ return;
+ }
+
+ if (udma_dev->latch_tpg_configured == 0) {
+ udma_info(udma_dev->dev, UDMA_M_TPG,
+ "Not create tp latch tpg, no delete.\n");
+ return;
+ }
+
+ for (u32 i = 0; i < UB_TP_LATCH_RSV_TPG_NUM; i++) {
+ udma_tp_latch_tpg_free(udma_dev, i);
+ }
+ udma_dev->latch_tpg_configured = 0;
+ return;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.h
new file mode 100644
index 000000000..d003cee33
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_tpg.h
@@ -0,0 +1,54 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef CPU_UDMA_TPG_H
+#define CPU_UDMA_TPG_H
+
+#include <linux/mutex.h>
+#include "ubcore_api.h"
+#include "udma_common.h"
+#include "ub_npu_tp_cmd_defs.h"
+#include "ub_npu_tpg_cmd_defs.h"
+#include "hinic5_cqm.h"
+#include "udma_comp.h"
+
+#define TPG_BITMAP_SIZE 16384 //16K=256K/16
+#define UB_TP_LATCH_RSV_TPG_NUM 16
+
+struct udma_tpg {
+ struct ubcore_tpg tpg;
+ struct tag_cqm_queue *tpg_info;
+ enum ubcore_transport_mode trans_mode;
+ u32 tp_num;
+ u32 tp_q_depth;
+ struct tag_cqm_qpc_mpt *tpinfo_list[MAX_TP_CNT_IN_TPG];
+ u8 tp_used[MAX_TP_CNT_IN_TPG]; //indicates this tp whether already create
+ u8 sl;
+ struct list_head node;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+};
+
+static inline struct udma_tpg *to_udma_tpg(const struct ubcore_tpg *tpg)
+{
+ return (struct udma_tpg *)udma_container_of(tpg, struct udma_tpg, tpg);
+}
+
+int udma_query_res_tpg(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+
+int udma_query_tpg_flow(struct udma_device *udma_dev, struct ub_tpg_flow *val);
+
+struct ubcore_tpg *udma_create_tpg(struct ubcore_device *ub_dev,
+ struct ubcore_tpg_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_destroy_tpg(struct ubcore_tpg *tpg);
+struct udma_tpg *udma_get_tpg_by_id(struct udma_device *udma_dev, u32 tpgn);
+void udma_tpg_put(void *obj);
+void udma_tpg_get(void *obj);
+int udma_create_tp_latch_tpg(struct udma_device *udma_dev);
+void udma_destroy_tp_latch_tpg(struct udma_device *udma_dev);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.c
new file mode 100644
index 000000000..d8d1ed0a0
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.c
@@ -0,0 +1,209 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_comp.h"
+#include "udma_tp.h"
+#include "udma_net.h"
+#include "udma_misc.h"
+#include "ubcore_uapi.h"
+#include "udma_cmd_utp.h"
+#include "udma_utp.h"
+
+#define UB_UTP_DIP_OFFSET 0x20
+
+static void udma_free_utp(struct udma_device *udma_dev, struct udma_utp *utp)
+{
+ cqm5_object_delete(&utp->cqm_utpn->object);
+ kfree(utp);
+}
+
+static struct udma_utp *udma_alloc_utp(struct udma_device *udma_dev)
+{
+ struct udma_utp *utp = NULL;
+ u32 xid_end;
+
+ utp = (struct udma_utp *)kzalloc(sizeof(struct udma_utp), GFP_KERNEL);
+ if (utp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Alloc utpn: alloc utpn failed.\n");
+ return NULL;
+ }
+ utp->cqm_priv_type = UDMA_CQM_PRIV_TYPE_UTP;
+ xid_end = SCQC_UTP_START(udma_dev) +
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_utp;
+ utp->cqm_utpn = udma_object_queue_create(
+ udma_dev, CQM_OBJECT_RDMA_SCQ, 0, utp, &udma_dev->utpn_record,
+ false,
+ CQM_DYNAMIC_XID_MOD(CQM_XID_SEARCH_RANGE, CQM_XID_LOW_BIT_NONE,
+ 0),
+ SCQC_UTP_START(udma_dev), xid_end);
+ if (utp->cqm_utpn == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Alloc utpn: create cqm utpn failed.\n");
+ goto err_alloc_cqm;
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_UTP, "alloc utpn success: %u\n",
+ utp->cqm_utpn->index);
+
+ return utp;
+
+err_alloc_cqm:
+ kfree(utp);
+
+ return NULL;
+}
+
+static int udma_utp_cfg_check(struct udma_device *udma_dev,
+ const struct ubcore_utp_cfg *cfg)
+{
+ u64 dip;
+
+ udma_info(udma_dev->dev, UDMA_M_UTP, "udp_start:%u\n", cfg->udp_start);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "udp_range:%u\n", cfg->udp_range);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "local_net_addr_idx:%u\n",
+ cfg->local_net_addr_idx);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "desp:%u\n", cfg->dscp);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "flow_label:%u\n",
+ cfg->flow_label);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "hop_limit:%u\n", cfg->hop_limit);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "port id:%u\n", cfg->port_id);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "mtu:%u\n", cfg->mtu);
+
+ if (cfg->peer_net_addr.type == UBCORE_NET_ADDR_TYPE_IPV4) {
+ udma_info(udma_dev->dev, UDMA_M_UTP, "peer is ipv4\n");
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dip3:0x%x\n",
+ cfg->peer_net_addr.net_addr.in4.addr);
+ } else {
+ udma_info(udma_dev->dev, UDMA_M_UTP, "peer is ipv6\n");
+ /* dip0 - dip3 */
+ dip = cfg->peer_net_addr.net_addr.in6.subnet_prefix;
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dip0:0x%llx\n", dip);
+ dip = cfg->peer_net_addr.net_addr.in6.subnet_prefix >>
+ UB_UTP_DIP_OFFSET;
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dip1:0x%llx\n", dip);
+ dip = cfg->peer_net_addr.net_addr.in6.interface_id;
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dip2:0x%llx\n", dip);
+ dip = cfg->peer_net_addr.net_addr.in6.interface_id >>
+ UB_UTP_DIP_OFFSET;
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dip3:0x%llx\n", dip);
+ }
+
+ udma_info(udma_dev->dev, UDMA_M_UTP, "vlan:%u\n",
+ (u32)cfg->peer_net_addr.vlan);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dmac_h16:%u\n",
+ (u32)UDMA_GET_MAC_HI(cfg->peer_net_addr.mac[0],
+ cfg->peer_net_addr.mac[1]));
+ udma_info(udma_dev->dev, UDMA_M_UTP, "dmac_l32:%u\n",
+ (u32)UDMA_GET_MAC_LO(cfg->peer_net_addr.mac[0x2],
+ cfg->peer_net_addr.mac[0x3],
+ cfg->peer_net_addr.mac[0x4],
+ cfg->peer_net_addr.mac[0x5]));
+ if ((cfg->mtu != UBCORE_MTU_1024) && (cfg->mtu != UBCORE_MTU_4096) &&
+ (cfg->mtu != UBCORE_MTU_8192)) {
+ udma_err(udma_dev->dev, UDMA_M_UTP, "mtu:%u not support\n",
+ cfg->mtu);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct ubcore_utp *udma_create_utp(struct ubcore_device *dev,
+ struct ubcore_utp_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_utp *utp = NULL;
+ int ret;
+
+ if (dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_UTP, "Invalid parameter, dev(%d), cfg(%d)\n",
+ !!dev, !!cfg);
+ return NULL;
+ }
+
+ udma_dev = to_udma_dev(dev);
+ ret = udma_utp_cfg_check(udma_dev, cfg);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "create utp: utp cfg err\n");
+ return NULL;
+ }
+
+ utp = udma_alloc_utp(udma_dev);
+ if (utp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "create utp: failed to allocate info\n");
+ return NULL;
+ }
+
+ ret = udma_cmd_create_utp(udma_dev, cfg, utp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "create utp: failed to send cqm cmd\n");
+ goto err_create_utp_cmd;
+ }
+
+ utp->base.utpn = utp->cqm_utpn->index;
+
+ udma_store_list(udma_dev, &utp->node, &udma_dev->device_res->utp_list);
+
+ return &utp->base;
+
+err_create_utp_cmd:
+ udma_free_utp(udma_dev, utp);
+
+ return NULL;
+}
+
+int udma_destroy_utp(struct ubcore_utp *utp)
+{
+ struct udma_device *udma_dev = NULL;
+ struct udma_utp *udma_utp = NULL;
+ int ret;
+
+ if (utp == NULL || utp->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_UTP, "Invalid parameter, utp(%d)\n", !!utp);
+ return -EINVAL;
+ }
+
+ udma_utp = to_udma_utp(utp);
+ udma_dev = to_udma_dev(utp->ub_dev);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "Destroy utp, utpn: %u",
+ utp->utpn);
+
+ ret = udma_cmd_destroy_utp(udma_dev, udma_utp);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Destroy utp: msg cmd failed\n");
+ return ret;
+ }
+
+ udma_delete_list(udma_dev, &udma_utp->node,
+ &udma_dev->device_res->utp_list);
+ udma_free_utp(udma_dev, udma_utp);
+ udma_info(udma_dev->dev, UDMA_M_UTP, "Destroy utp success\n");
+
+ return 0;
+}
+
+int udma_query_utp(struct udma_device *udma_dev, u32 utpn,
+ struct ub_dip_ctx_query *utp_ctx)
+{
+ int ret;
+
+ ret = udma_cmd_query_utp(udma_dev, utpn, utp_ctx);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_UTP,
+ "Faield query utp ctx, utpn:%u\n", utpn);
+ return ret;
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.h
new file mode 100644
index 000000000..62c305c1f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_utp.h
@@ -0,0 +1,32 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+
+#ifndef UDMA_UTP_H
+#define UDMA_UTP_H
+
+#include "ubcore_types.h"
+#include "ubcore_api.h"
+#include "hinic5_cqm.h"
+#include "udma_common.h"
+#include "ub_npu_utp_cmd_defs.h"
+
+typedef struct udma_utp {
+ u32 cqm_priv_type;
+ struct ubcore_utp base;
+ struct tag_cqm_queue *cqm_utpn;
+ struct list_head node;
+} udma_utp_t;
+
+static inline struct udma_utp *to_udma_utp(const struct ubcore_utp *utp)
+{
+ return (struct udma_utp *)udma_container_of(utp, struct udma_utp, base);
+}
+
+struct ubcore_utp *udma_create_utp(struct ubcore_device *dev,
+ struct ubcore_utp_cfg *cfg,
+ struct ubcore_udata *udata);
+int udma_destroy_utp(struct ubcore_utp *utp);
+int udma_query_utp(struct udma_device *udma_dev, u32 utpn,
+ struct ub_dip_ctx_query *utp_ctx);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.c
new file mode 100644
index 000000000..ac762c678
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.c
@@ -0,0 +1,1011 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+#include "ubcore_types.h"
+
+#include "udma_common.h"
+#include "udma_cqm.h"
+#include "udma_misc.h"
+#include "udma_cmd.h"
+#include "udma_cmd_vtp.h"
+#include "udma_vram.h"
+#include "udma_vtp.h"
+
+#define UB_VTP_DIP_MASK 0xffffffff
+#define UB_VTP_DIP_OFFSET 0x20
+
+static int udma_fill_vtp_buf_node(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg,
+ struct udma_vtp_buf *buf)
+{
+ struct ub_cmd_restore_vtp_node *node = NULL;
+
+ node = (struct ub_cmd_restore_vtp_node
+ *)((u8 *)buf->addr +
+ cfg->vtpn * sizeof(struct ub_cmd_restore_vtp_node));
+ if (node->vld == UDMA_MIG_BUF_USED) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "vtpn node already exist, vtpn:%u vfid:%u\n",
+ cfg->vtpn, buf->func_id);
+ return -EINVAL;
+ }
+
+ if (udma_fill_vtp_node(udma_dev, cfg, node) != 0) {
+ return -EINVAL;
+ }
+
+ node->vld = UDMA_MIG_BUF_USED;
+ buf->total++;
+ return 0;
+}
+
+static int udma_destroy_vtp_node(struct udma_device *udma_dev,
+ const struct ubcore_vtp *vtp,
+ struct udma_vtp_buf *buf)
+{
+ struct ub_cmd_restore_vtp_node *node = NULL;
+
+ node = (struct ub_cmd_restore_vtp_node
+ *)((u8 *)buf->addr +
+ vtp->cfg.vtpn *
+ sizeof(struct ub_cmd_restore_vtp_node));
+ if (node->vld == UDMA_MIG_BUF_IDLE) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to destroy vtpn in buf, node is idle, vtpn:%u, vfid:%u\n",
+ vtp->cfg.vtpn, adapted_ue_idx(&vtp->cfg));
+ return -EINVAL;
+ }
+ node->vld = UDMA_MIG_BUF_IDLE;
+ buf->total--;
+ return 0;
+}
+
+int udma_restore_all_vtp_cmd(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf)
+{
+ int ret = 0;
+ u32 num;
+
+ while (buf->total > 0) {
+ num = (buf->total < UB_VTP_RESTORE_NUM_MAX) ?
+ buf->total :
+ UB_VTP_RESTORE_NUM_MAX;
+ ret = udma_cmd_restore_vtp_create_multi_vld(udma_dev, buf, num);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to send all restore_vtp cmd, ret:%d, cur_idx:%u\n",
+ ret, buf->cur_idx);
+ return -EFAULT;
+ }
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "Send vtp cmd msg, total:%u cur_idx:%u\n",
+ buf->total, buf->cur_idx);
+ }
+ return ret;
+}
+
+// by before plane of flow ensure restore_vtp in has at least 1(count word) not be use of BUF
+int udma_create_vtp_buf(struct udma_device *udma_dev, struct udma_vtp_buf *buf)
+{
+ u64 buf_size = sizeof(struct ub_cmd_restore_vtp_node) * UB_MAX_VTP_NUM;
+ struct tag_cqm_cmd_buf *cqm_cmd_buf = NULL;
+ struct ub_cmd_vtp_restore *inbuf = NULL;
+ int ret = -ENOMEM;
+
+ mutex_lock(&buf->vf_mutex);
+ buf->addr = vmalloc(buf_size);
+ if (buf->addr == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "create_vtp_buf: failed to alloc buffer for restore vtp\n");
+ goto out;
+ }
+ (void)memset_s(buf->addr, buf_size, 0, buf_size);
+ buf->total = 0;
+ buf->cur_idx = 0;
+ buf->mig_sts = UDMA_MIG_FULL_VOLUME;
+
+ buf->cqm_cmd_buf =
+ udma_cmd_restore_vtp_get_cqm_cmd_buf(udma_dev, buf->func_id);
+ if (buf->cqm_cmd_buf == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "create_vtp_buf: failed to alloc buffer for cqm_cmd_buf\n");
+ buf->mig_sts = UDMA_MIG_IDLE;
+ vfree(buf->addr);
+ buf->addr = NULL;
+ goto out;
+ }
+ cqm_cmd_buf = (struct tag_cqm_cmd_buf *)buf->cqm_cmd_buf;
+ inbuf = (struct ub_cmd_vtp_restore *)cqm_cmd_buf->buf;
+ inbuf->body.num = 0;
+ ret = 0;
+out:
+ mutex_unlock(&buf->vf_mutex);
+ return ret;
+}
+
+void udma_free_vtp_buf(struct udma_device *udma_dev, struct udma_vtp_buf *buf)
+{
+ if (buf->addr != NULL) {
+ vfree(buf->addr);
+ buf->addr = NULL;
+ }
+
+ if (buf->cqm_cmd_buf != NULL) {
+ udma_cqm5_cmd_free_inoutbuf(udma_dev->hwdev, buf->cqm_cmd_buf,
+ NULL);
+ buf->cqm_cmd_buf = NULL;
+ }
+}
+
+int udma_restore_vtp(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg, struct cmdq_rtt *rtt)
+{
+ struct udma_vtp_buf *buf = NULL;
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Recv restore vtp: vtpn:%u vf:%u\n", cfg->vtpn,
+ adapted_ue_idx(cfg));
+
+ buf = udma_mig_get_vf_buf(udma_dev, adapted_ue_idx(cfg));
+ if (!UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "Create VTP: vf:%u status idle.\n",
+ adapted_ue_idx(cfg));
+ return udma_cmd_create_vtp(udma_dev, cfg, rtt);
+ }
+
+ mutex_lock(&buf->vf_mutex);
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Restore vtp: vtpn:%u vf:%u sts:%u\n", cfg->vtpn,
+ adapted_ue_idx(cfg), buf->mig_sts);
+ if (buf->mig_sts == UDMA_MIG_IDLE) {
+ ret = udma_cmd_create_vtp(udma_dev, cfg, rtt);
+ } else if (buf->mig_sts == UDMA_MIG_FULL_VOLUME) {
+ ret = udma_fill_vtp_buf_node(udma_dev, cfg, buf);
+ } else if (buf->mig_sts == UDMA_MIG_INCREMENTAL) {
+ ret = udma_cmd_restore_vtp_create_vtpn(udma_dev, cfg, buf);
+ } else {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Mig create VTP: faild, vf:%u sts:%u.\n",
+ adapted_ue_idx(cfg), buf->mig_sts);
+ ret = -EPERM;
+ }
+ mutex_unlock(&buf->vf_mutex);
+
+ return ret;
+}
+
+static void udma_print_vtp_cfg(const struct ubcore_vtp_cfg *cfg,
+ const struct udma_device *udma_dev)
+{
+ u32 dip0 = 0;
+ u32 dip1 = 0;
+ u32 dip2 = 0;
+ u32 dip3 = 0;
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "start print ubcore vtp cfg.\n");
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "fe_idx:%u, vtpn:%u, local_jetty:%u, peer_jetty:%u\n",
+ adapted_ue_idx(cfg), cfg->vtpn, cfg->local_jetty,
+ cfg->peer_jetty);
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "flag:%u\n", cfg->flag.value);
+
+ dip0 = cfg->local_eid.in6.subnet_prefix & UB_VTP_DIP_MASK;
+ dip1 = (cfg->local_eid.in6.subnet_prefix >> UB_VTP_DIP_OFFSET) &
+ UB_VTP_DIP_MASK;
+ dip2 = cfg->local_eid.in6.interface_id & UB_VTP_DIP_MASK;
+ dip3 = (cfg->local_eid.in6.interface_id >> UB_VTP_DIP_OFFSET) &
+ UB_VTP_DIP_MASK;
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "local_eid:0x%x %x %x %x\n", dip0,
+ dip1, dip2, dip3);
+
+ dip0 = cfg->peer_eid.in6.subnet_prefix & UB_VTP_DIP_MASK;
+ dip1 = (cfg->peer_eid.in6.subnet_prefix >> UB_VTP_DIP_OFFSET) &
+ UB_VTP_DIP_MASK;
+ dip2 = cfg->peer_eid.in6.interface_id & UB_VTP_DIP_MASK;
+ dip3 = (cfg->peer_eid.in6.interface_id >> UB_VTP_DIP_OFFSET) &
+ UB_VTP_DIP_MASK;
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "peer_eid:0x%x %x %x %x\n", dip0,
+ dip1, dip2, dip3);
+
+ switch (cfg->trans_mode) {
+ case UBCORE_TP_RM:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n", cfg->trans_mode,
+ UB_VTP_TYPE_TPG, cfg->tpg->tpgn);
+ break;
+ case UBCORE_TP_RC:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n", cfg->trans_mode,
+ UB_VTP_TYPE_TP, cfg->tp->tpn);
+ break;
+ case UBCORE_TP_UM:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n", cfg->trans_mode,
+ UB_VTP_TYPE_DIP, cfg->utp->utpn);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP, "Unknown trans_mode: %u\n",
+ cfg->trans_mode);
+ return;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "end print ubcore vtp cfg.\n");
+}
+
+static int udma_check_vtp_cfg(const struct ubcore_vtp_cfg *cfg,
+ const struct udma_device *udma_dev)
+{
+ if (udma_dev == NULL || cfg == NULL) {
+ udma_pr_err(UDMA_M_VTP,
+ "Invalid parameter: udma_dev(%d), cfg(%d).\n",
+ !!udma_dev, !!cfg);
+ return -EINVAL;
+ }
+
+ if (cfg->vtpn >= UB_MAX_VTP_NUM) { // VTPN take value [64, 128k-1]
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Invalid parameter, vtpn:%u invalid\n", cfg->vtpn);
+ return -EINVAL;
+ }
+
+ switch (cfg->trans_mode) {
+ case UBCORE_TP_RM:
+ if (cfg->tpg == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Invalid parameter, tpg is null\n");
+ return -EINVAL;
+ }
+ return 0;
+ case UBCORE_TP_RC:
+ if (cfg->tp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Invalid parameter, tp is null\n");
+ return -EINVAL;
+ }
+ return 0;
+ case UBCORE_TP_UM:
+ if (cfg->utp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Invalid parameter, utp is null\n");
+ return -EINVAL;
+ }
+ return 0;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Invalid parameter, trans_mode:%u\n", cfg->trans_mode);
+ return -EINVAL;
+ }
+}
+
+struct ubcore_vtp *udma_create_vtp(struct ubcore_device *ub_dev,
+ struct ubcore_vtp_cfg *cfg,
+ struct ubcore_udata *udata)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = to_udma_dev(ub_dev);
+ struct udma_vtp *vtp = NULL;
+ int ret;
+
+ if (udma_dev == NULL) {
+ pr_err("Invalid parameter. udma_dev(%d) .\n", !!udma_dev);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ ret = udma_check_vtp_cfg(cfg, udma_dev);
+ if (ret != 0) {
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_print_vtp_cfg(cfg, udma_dev);
+
+ udma_debug(
+ udma_dev->dev, UDMA_M_VTP,
+ "Create vtp, vtpn: %u, vfid: %u, trans_mode: %u, migrate: %u\n",
+ cfg->vtpn, adapted_ue_idx(cfg), cfg->trans_mode,
+ cfg->flag.bs.migrate);
+
+ vtp = (struct udma_vtp *)udma_vram_kzalloc(udma_dev->dev,
+ UDMA_VRAM_TYPE_VTP,
+ sizeof(struct udma_vtp),
+ GFP_KERNEL);
+ if (vtp == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Create vtp: alloc vtp failed, vtpn: %u, vfid: %u\n",
+ cfg->vtpn, adapted_ue_idx(cfg));
+ return ERR_PTR(-ENOMEM);
+ }
+
+ udma_cmdq_rtt_statistic_init(&vtp->cmdq_rtt);
+ ret = (!UDMA_IS_MIG_VFID(adapted_ue_idx(cfg))) ?
+ udma_cmd_create_vtp(udma_dev, cfg, &vtp->cmdq_rtt) :
+ udma_restore_vtp(udma_dev, cfg, &vtp->cmdq_rtt);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Create vtp: send cmd failed, vtpn: %u, vfid: %u\n",
+ cfg->vtpn, adapted_ue_idx(cfg));
+ goto err_and_free_vtp;
+ }
+ (void)memcpy_s((void *)&vtp->base.cfg, sizeof(struct ubcore_vtp_cfg),
+ cfg, sizeof(struct ubcore_vtp_cfg));
+ udma_store_list(udma_dev, &vtp->node, &udma_dev->device_res->vtp_list);
+
+ kref_init(&vtp->ref_cnt);
+ init_completion(&vtp->comp);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_create_vtp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+
+ return &vtp->base;
+
+err_and_free_vtp:
+ udma_vram_kfree(udma_dev->dev, vtp, UDMA_VRAM_TYPE_VTP);
+
+ return ERR_PTR(-EFAULT);
+}
+
+struct ubcore_vtpn *udma_alloc_vtpn(struct ubcore_device *ub_dev)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_vtpn *vtpn = NULL;
+ u32 qpn_tmp;
+
+ if (ub_dev == NULL) {
+ udma_pr_err(UDMA_M_VTP, "Invalid parameter, ub_dev is null\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ udma_dev = to_udma_dev(ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ vtpn = (struct udma_vtpn *)kzalloc(sizeof(struct udma_vtpn),
+ GFP_KERNEL);
+ if (vtpn == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Alloc vtpn: alloc vtpn failed.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ qpn_tmp = udma_get_qpn_mod(udma_dev, CQM_XID_LOW_BIT_NONE, 0);
+ vtpn->cqm_priv_type = UDMA_CQM_PRIV_TYPE_VTPN;
+ vtpn->cqm_vtpn = udma_object_queue_create(
+ udma_dev, CQM_OBJECT_RDMA_SCQ, UB_VTPC_SIZE, vtpn,
+ &udma_dev->vtpn_record, false, qpn_tmp,
+ SCQC_VTP_START(udma_dev),
+ udma_dev->ub_cap.dev_cap_res.sdk_res.max_vtp);
+ if (vtpn->cqm_vtpn == NULL) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Alloc vtpn: create cqm vtpn failed.\n");
+ goto err_alloc_cqm;
+ }
+
+ vtpn->base.vtpn = vtpn->cqm_vtpn->index;
+ udma_store_list(udma_dev, &vtpn->node, &udma_dev->device_res->vtp_list);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_alloc_vtpn cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "alloc vtpn success: %u\n",
+ vtpn->base.vtpn);
+
+ return &vtpn->base;
+
+err_alloc_cqm:
+ kfree(vtpn);
+
+ return ERR_PTR(-EFAULT);
+}
+
+void udma_set_vtp_buf_idle(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ u8 origin_mig_sts;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Start to set vtp buf idle : vfid:%u\n", buf->func_id);
+
+ mutex_lock(&mig_mgt->mig_vf_mgt_mutex);
+
+ mutex_lock(&buf->vf_mutex);
+ origin_mig_sts = buf->mig_sts;
+ buf->total = 0;
+ buf->cur_idx = 0;
+ buf->mig_sts = UDMA_MIG_IDLE;
+ udma_free_vtp_buf(udma_dev, buf);
+ mutex_unlock(&buf->vf_mutex);
+
+ mig_mgt->migrating_num = (origin_mig_sts == UDMA_MIG_IDLE) ?
+ mig_mgt->migrating_num :
+ mig_mgt->migrating_num - 1;
+ mutex_unlock(&mig_mgt->mig_vf_mgt_mutex);
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Set vtp buf idle done: vfid:%u migrating_num:%u\n",
+ buf->func_id, mig_mgt->migrating_num);
+}
+
+/*
+ * need consider call this function of scenario contain:
+ * 1. live migration the once full same step VTP before: from 128K buf in delete corresponding node;
+ * 2. live migration the once full same step VTP complete ~ destination end restore during: destroy operation cache in size as 32 of inoutbuf in, full 32 then flush down;
+ * 3. live migration complete after: receive to before live migration during created VTP request corresponding to destroy, directly send to microcode, this when ub_en already is 1
+ */
+static int udma_mig_destroy_vtp(struct ubcore_vtp *vtp,
+ struct udma_device *udma_dev, u32 vfid)
+{
+ struct udma_vtp_buf *buf = NULL;
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Recv mig destroy VTP: vfid:%u vtpn:%u\n", vfid,
+ vtp->cfg.vtpn);
+
+ buf = udma_mig_get_vf_buf(udma_dev, vfid);
+ if (!UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ return udma_cmd_destroy_vtp(udma_dev, vtp);
+ }
+
+ mutex_lock(&buf->vf_mutex);
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Mig destroy VTP: vf:%u vtpn:%u sts:%u\n", vfid,
+ vtp->cfg.vtpn, buf->mig_sts);
+ if (buf->mig_sts == UDMA_MIG_IDLE) {
+ ret = udma_cmd_destroy_vtp(udma_dev, vtp);
+ } else if (buf->mig_sts == UDMA_MIG_FULL_VOLUME) {
+ ret = udma_destroy_vtp_node(udma_dev, vtp, buf);
+ } else if (buf->mig_sts == UDMA_MIG_INCREMENTAL) {
+ ret = udma_cmd_restore_vtp_destroy_vtpn(udma_dev, vtp, buf);
+ } else {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Mig destroy VTP: vf:%u recv unexpected req.\n", vfid);
+ ret = -EPERM;
+ }
+ mutex_unlock(&buf->vf_mutex);
+
+ return ret;
+}
+
+int udma_destroy_vtp(struct ubcore_vtp *vtp)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_vtp *ub_vtp = NULL;
+ int ret;
+ u32 vfid;
+
+ if (vtp == NULL || vtp->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_VTP, "Invalid parameter, vtp(%d)\n", !!vtp);
+ return -EINVAL;
+ }
+
+ ub_vtp = to_udma_vtp(vtp);
+ udma_dev = to_udma_dev(vtp->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ vfid = adapted_ue_idx(&vtp->cfg);
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "Destroy vtp, vtpn:%u vfid:%u mig:%u\n", vtp->cfg.vtpn, vfid,
+ vtp->cfg.flag.bs.migrate);
+
+ if (vtp->cfg.vtpn >= UB_MAX_VTP_NUM) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Destroy vtp, vtpn:%u invalid. vfid:%u\n",
+ vtp->cfg.vtpn, vfid);
+ return -EINVAL;
+ }
+
+ udma_delete_list(udma_dev, &ub_vtp->node,
+ &udma_dev->device_res->vtp_list);
+ udma_vtp_put(ub_vtp);
+ wait_for_completion(&ub_vtp->comp);
+
+ ret = (!UDMA_IS_MIG_VFID(vfid)) ?
+ udma_cmd_destroy_vtp(udma_dev, vtp) :
+ udma_mig_destroy_vtp(vtp, udma_dev, vfid);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Destroy vtp: msg cmd failed\n");
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "Destroy vtp success, vtpn: %u, vfid: %u\n", vtp->cfg.vtpn,
+ vfid);
+ udma_print_cmdq_rtt_stat(udma_dev, UDMA_M_VTP, vtp->cfg.vtpn,
+ &ub_vtp->cmdq_rtt);
+ udma_vram_kfree(udma_dev->dev, ub_vtp, UDMA_VRAM_TYPE_VTP);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_destroy_vtp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+
+ return ret;
+}
+
+int udma_free_vtpn(struct ubcore_vtpn *vtpn)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ struct udma_vtpn *ub_vtpn = NULL;
+ u32 id;
+
+ if (vtpn == NULL || vtpn->ub_dev == NULL) {
+ udma_pr_err(UDMA_M_VTP, "Invalid parameter, vtpn(%d)\n",
+ !!vtpn);
+ return -EINVAL;
+ }
+
+ id = vtpn->vtpn;
+ ub_vtpn = to_udma_vtpn(vtpn);
+ udma_dev = to_udma_dev(vtpn->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ udma_info(udma_dev->dev, UDMA_M_VTP, "Free vtpn: %u\n", id);
+
+ udma_delete_list(udma_dev, &ub_vtpn->node,
+ &udma_dev->device_res->vtp_list);
+
+ if (ub_vtpn->cqm_vtpn != NULL) {
+ cqm5_object_delete(&ub_vtpn->cqm_vtpn->object);
+ }
+
+ kfree(ub_vtpn);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_free_vtpn cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+ udma_info(udma_dev->dev, UDMA_M_VTP, "Free vtpn %u success\n", id);
+
+ return 0;
+}
+
+static void udma_vtp_kref_release(struct kref *ref_cnt)
+{
+ struct udma_vtp *vtp = container_of(ref_cnt, struct udma_vtp, ref_cnt);
+
+ complete(&vtp->comp);
+}
+
+void udma_vtp_put(void *obj)
+{
+ struct udma_vtp *vtp = obj;
+
+ if (vtp != NULL) {
+ kref_put(&vtp->ref_cnt, udma_vtp_kref_release);
+ }
+}
+
+void udma_vtp_get(void *obj)
+{
+ struct udma_vtp *vtp = obj;
+
+ kref_get(&vtp->ref_cnt);
+}
+
+struct udma_vtp *udma_get_vtp_by_id(struct udma_device *udma_dev, u32 vtpn,
+ u32 function_id)
+{
+ struct udma_vtp *vtp_now = NULL;
+ struct mutex *lock = NULL;
+
+ udma_info_limit(udma_dev->dev, UDMA_M_VTP,
+ "query vtp id: %u, function_id:%u\n", vtpn,
+ function_id);
+
+ lock = &udma_dev->device_res->vtp_list.node_lock;
+ mutex_lock(lock);
+ list_for_each_entry(vtp_now, &udma_dev->device_res->vtp_list.node,
+ node) {
+ if (vtp_now->base.cfg.vtpn == vtpn &&
+ adapted_ue_idx(&vtp_now->base.cfg) == function_id) {
+ udma_vtp_get(vtp_now);
+ goto found;
+ }
+ }
+
+ vtp_now = NULL;
+found:
+ mutex_unlock(lock);
+ return vtp_now;
+}
+
+static int udma_get_vtp_trans_mode(const ub_vtp_ctx_info_s *vtp_ctx)
+{
+ switch (vtp_ctx->type) {
+ case UB_VTP_TYPE_TPG:
+ return UBCORE_TP_RM;
+ case UB_VTP_TYPE_TP:
+ return UBCORE_TP_RC;
+ case UB_VTP_TYPE_DIP:
+ return UBCORE_TP_UM;
+ default:
+ return -EINVAL;
+ }
+}
+
+int udma_query_res_vtp(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val)
+{
+ struct ubcore_res_vtp_val *vtp =
+ (struct ubcore_res_vtp_val *)(uintptr_t)(val->addr);
+ u32 vfid = key->key_ext;
+ struct ub_vtp_ctx_query *vtp_ctx = NULL;
+ ub_vtp_ctx_info_s *vtp_ctx_info = NULL;
+ u32 vtp_id = key->key;
+ int ret;
+
+ if (val->len < sizeof(struct ubcore_res_vtp_val)) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Failed to check len, type: %u, val->len: %u.\n",
+ (u32)key->type, val->len);
+ return (int)sizeof(struct ubcore_res_vtp_val);
+ }
+
+ vtp_ctx = (struct ub_vtp_ctx_query *)kzalloc(
+ sizeof(struct ub_vtp_ctx_query), GFP_KERNEL);
+ if (vtp_ctx == NULL) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "query vtp res:failed to allocate memroy for vtp ctx\n");
+ return -ENOMEM;
+ }
+
+ ret = udma_cmd_query_vtp(udma_dev, vfid, vtp_id, vtp_ctx);
+ if (ret != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "query vtp res: failed to query vtp context, key:0x%x\n",
+ key->key);
+ kfree(vtp_ctx);
+ return ret;
+ }
+ vtp_ctx_info = (ub_vtp_ctx_info_s *)(void *)vtp_ctx;
+ vtp_ctx_info->dw0 = be32_to_cpu(vtp_ctx_info->dw0);
+ adapted_ue_idx(vtp) = (u16)vfid;
+ vtp->vtpn = key->key;
+ (void)memcpy_s(&vtp->local_eid, UBCORE_EID_SIZE, vtp_ctx_info->seid,
+ UBCORE_EID_SIZE);
+ (void)memcpy_s(&vtp->peer_eid, UBCORE_EID_SIZE, vtp_ctx_info->deid,
+ UBCORE_EID_SIZE);
+ ret = udma_get_vtp_trans_mode(vtp_ctx_info);
+ if (ret < 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "query vtp res:failed to get vtp trans_mode:%d\n",
+ ret);
+ kfree(vtp_ctx);
+ return ret;
+ }
+ vtp->trans_mode = (u32)ret;
+ vtp->tpgn = vtp_ctx_info->index;
+
+ kfree(vtp_ctx);
+ return 0;
+}
+
+static void udma_print_vtp_attr(const struct ubcore_vtp *vtp,
+ const struct ubcore_vtp_attr *attr,
+ const union ubcore_vtp_attr_mask *mask)
+{
+ struct udma_device *udma_dev = to_udma_dev(vtp->ub_dev);
+
+ if (udma_dev == NULL) {
+ udma_pr_err(UDMA_M_VTP, "to_udma_dev failed.\n");
+ return;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "start print ubcore vtp attr.\n");
+ switch (vtp->cfg.trans_mode) {
+ case UBCORE_TP_RM:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n",
+ vtp->cfg.trans_mode, UB_VTP_TYPE_TPG,
+ attr->tp.tpg->tpgn);
+ break;
+ case UBCORE_TP_RC:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n",
+ vtp->cfg.trans_mode, UB_VTP_TYPE_TP,
+ attr->tp.tp->tpn);
+ break;
+ case UBCORE_TP_UM:
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "trans_mode:%u, type:%u, id:%u\n",
+ vtp->cfg.trans_mode, UB_VTP_TYPE_DIP,
+ attr->tp.utp->utpn);
+ break;
+ default:
+ udma_err(udma_dev->dev, UDMA_M_VTP, "Unknown trans_mode: %u\n",
+ vtp->cfg.trans_mode);
+ return;
+ }
+
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "mask:%u\n", mask->value);
+ udma_debug(udma_dev->dev, UDMA_M_VTP, "end print ubcore vtp attr.\n");
+}
+
+static int udma_modify_vtp_node(struct udma_device *udma_dev,
+ struct ubcore_vtp *vtp,
+ struct ubcore_vtp_attr *attr,
+ struct udma_vtp_buf *buf)
+{
+ struct ub_cmd_restore_vtp_node *node = NULL;
+ u32 new_tpn;
+ int ret;
+
+ node = (struct ub_cmd_restore_vtp_node
+ *)((u8 *)buf->addr +
+ vtp->cfg.vtpn *
+ sizeof(struct ub_cmd_restore_vtp_node));
+ if (node->vld == UDMA_MIG_BUF_IDLE) {
+ udma_err(
+ udma_dev->dev, UDMA_M_VTP,
+ "Failed to modify vtpn in buf, node is idle, vtpn:%u, vfid:%u\n",
+ vtp->cfg.vtpn, adapted_ue_idx(&vtp->cfg));
+ return -EINVAL;
+ }
+
+ ret = udma_cmd_modify_get_new_tpn(udma_dev, &vtp->cfg, attr, &new_tpn);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Get tpn failed, vtpn:%u vfid:%u\n", vtp->cfg.vtpn,
+ adapted_ue_idx(&vtp->cfg));
+ return ret;
+ }
+ node->id = new_tpn;
+ udma_info(udma_dev->dev, UDMA_M_VTP, "Modify vtpn:%u vf:%u tpn:%u\n",
+ vtp->cfg.vtpn, adapted_ue_idx(&vtp->cfg), new_tpn);
+
+ return 0;
+}
+
+int udma_flush_remain_modify(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf)
+{
+ struct ub_cmd_restore_vtp_node *node =
+ (struct ub_cmd_restore_vtp_node *)((u8 *)buf->addr);
+ int vtpn, ret;
+
+ for (vtpn = 0; vtpn < UB_MAX_VTP_NUM; vtpn++) {
+ if (buf->total == 0) {
+ break;
+ }
+ if (node->vld == UDMA_MIG_BUF_IDLE) {
+ node = (vtpn == UB_MAX_VTP_NUM - 1) ? node : node + 1;
+ continue;
+ }
+ ret = udma_cmd_send_modify(udma_dev, buf->func_id, vtpn,
+ node->id);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Send modify failed, vtpn:%u vfid:%u\n", vtpn,
+ buf->func_id);
+ return ret;
+ }
+ node->vld = UDMA_MIG_BUF_IDLE;
+ node++;
+ buf->total--;
+ }
+ return 0;
+}
+
+static int udma_modify_during_fls(struct udma_device *udma_dev,
+ struct ubcore_vtp *vtp,
+ struct udma_vtp_buf *buf,
+ struct ubcore_vtp_attr *attr)
+{
+ struct ub_cmd_restore_vtp_node *node = NULL;
+ u32 new_tpn;
+ int ret;
+
+ ret = udma_cmd_modify_get_new_tpn(udma_dev, &vtp->cfg, attr, &new_tpn);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Get tpn failed, vtpn:%u vfid:%u\n", vtp->cfg.vtpn,
+ adapted_ue_idx(&vtp->cfg));
+ return ret;
+ }
+
+ node = (struct ub_cmd_restore_vtp_node
+ *)((u8 *)buf->addr +
+ vtp->cfg.vtpn *
+ sizeof(struct ub_cmd_restore_vtp_node));
+ node->vld = UDMA_MIG_BUF_USED;
+ node->id = new_tpn;
+ buf->total++;
+ return 0;
+}
+
+static int udma_mig_modify_vtp(struct udma_device *udma_dev,
+ struct ubcore_vtp *vtp,
+ struct ubcore_vtp_attr *attr)
+{
+ struct udma_vtp_buf *buf = NULL;
+ u16 vfid = adapted_ue_idx(&vtp->cfg);
+ int ret = 0;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Mig Modify VTP: vtpn:%u vfid:%u\n", vtp->cfg.vtpn, vfid);
+
+ buf = udma_mig_get_vf_buf(udma_dev, vfid);
+ if (!UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ udma_debug(udma_dev->dev, UDMA_M_VTP,
+ "Mig Modify VTP: vtpn:%u vfid:%u\n", vtp->cfg.vtpn,
+ vfid);
+ return udma_cmd_modify_vtp(udma_dev, vtp, attr);
+ }
+
+ mutex_lock(&buf->vf_mutex);
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Mig Modify VTP: vtpn:%u vf:%u sts:%u\n", vtp->cfg.vtpn, vfid,
+ buf->mig_sts);
+ if (buf->mig_sts == UDMA_MIG_FULL_VOLUME) {
+ ret = udma_modify_vtp_node(udma_dev, vtp, attr, buf);
+ } else if (buf->mig_sts == UDMA_MIG_INCREMENTAL) {
+ ret = udma_cmd_restore_vtp_modify_vtpn(udma_dev, &vtp->cfg, buf,
+ attr);
+ } else if (buf->mig_sts == UDMA_MIG_INCREMENTAL_MODIFY) {
+ ret = udma_modify_during_fls(udma_dev, vtp, buf, attr);
+ } else if (buf->mig_sts == UDMA_MIG_NORMAL) {
+ ret = udma_cmd_modify_vtp(udma_dev, vtp, attr);
+ }
+ mutex_unlock(&buf->vf_mutex);
+
+ return ret;
+}
+
+int udma_modify_vtp(struct ubcore_vtp *vtp, struct ubcore_vtp_attr *attr,
+ union ubcore_vtp_attr_mask *mask)
+{
+ uint64_t cycle_start = 0;
+ struct udma_device *udma_dev = NULL;
+ int ret;
+
+ if (vtp == NULL || vtp->ub_dev == NULL || attr == NULL ||
+ mask == NULL) {
+ udma_pr_err(UDMA_M_VTP,
+ "Invalid parameter, vtp(%d), attr(%d), mask(%d)\n",
+ !!vtp, !!attr, !!mask);
+ return -EINVAL;
+ }
+ udma_print_vtp_attr(vtp, attr, mask);
+
+ udma_dev = to_udma_dev(vtp->ub_dev);
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ cycle_start = udma_get_cycles_dfx();
+ }
+ if (mask->bs.tp == 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Modify VTP: Invalid mask:0x%x vtpn:%u vfid:%u\n",
+ mask->value, vtp->cfg.vtpn, adapted_ue_idx(&vtp->cfg));
+ return -EINVAL;
+ }
+
+ ret = (!UDMA_IS_MIG_VFID(adapted_ue_idx(&vtp->cfg))) ?
+ udma_cmd_modify_vtp(udma_dev, vtp, attr) :
+ udma_mig_modify_vtp(udma_dev, vtp, attr);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Modify VTP: proc failed ret:%d vtpn:%u vfid:%u\n",
+ ret, vtp->cfg.vtpn, adapted_ue_idx(&vtp->cfg));
+ }
+ if (unlikely(udma_dev->sysfs_res.dfx_ctx.debug_en == 1)) {
+ udma_warn(udma_dev->dev, UDMA_M_TP,
+ "[PERF]udma_modify_vtp cost cycles:%llu\n",
+ udma_get_cycles_dfx() - cycle_start);
+ }
+
+ return ret;
+}
+
+static int udma_vf_migrate_start_proc(struct udma_device *udma_dev, u16 vfid)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ struct udma_vtp_buf *buf =
+ &mig_mgt->buf_array[UDMA_GET_MIG_VF_IDX(vfid)];
+
+ if (UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Duplicate proc, vf:%u is migrating, sts:%u\n", vfid,
+ buf->mig_sts);
+ return -EPERM;
+ }
+
+ mutex_lock(&mig_mgt->mig_vf_mgt_mutex);
+ if (mig_mgt->migrating_num == UDMA_MAX_MIG_VF_NUM) {
+ mutex_unlock(&mig_mgt->mig_vf_mgt_mutex);
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Migrating vf num has reached the upper limit.\n");
+ return -EPERM;
+ }
+
+ if (udma_create_vtp_buf(udma_dev, buf) != 0) {
+ mutex_unlock(&mig_mgt->mig_vf_mgt_mutex);
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Create vtp buf failed, vf:%u.\n", vfid);
+ return -ENOMEM;
+ }
+ mig_mgt->migrating_num += 1;
+ mutex_unlock(&mig_mgt->mig_vf_mgt_mutex);
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Mig start done: vf:%u, migrating:%u\n", vfid,
+ mig_mgt->migrating_num);
+
+ return 0;
+}
+
+int udma_vf_migrate_end_proc(struct udma_device *udma_dev, u16 vfid)
+{
+ struct udma_mig_vf_mgt *mig_mgt = &udma_dev->mig_vf_mgt;
+ struct udma_vtp_buf *buf =
+ &mig_mgt->buf_array[UDMA_GET_MIG_VF_IDX(vfid)];
+
+ if (!UDMA_IS_VF_MIGRATING(buf->mig_sts)) {
+ udma_info(udma_dev->dev, UDMA_M_VTP, "Migrate: vf:%u is idle\n",
+ vfid);
+ return 0;
+ }
+
+ udma_set_vtp_buf_idle(udma_dev,
+ buf); // UVS rollback scenario next, buf in may still exist node
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "Mig end Done: vf:%u, migrating:%u\n", vfid,
+ mig_mgt->migrating_num);
+
+ return 0;
+}
+
+// used for receive UVS notify of migration state change
+int udma_mig_status_change_proc(struct udma_device *udma_dev, void *para)
+{
+ struct udma_vf_mig_status_in *mig_status =
+ (struct udma_vf_mig_status_in *)para;
+ int ret;
+
+ udma_info(udma_dev->dev, UDMA_M_VTP,
+ "recv Mig change: vf:%u sts:%u migrating_num:%u\n",
+ mig_status->vfid, mig_status->sts,
+ udma_dev->mig_vf_mgt.migrating_num);
+
+ if (!udma_dev->ub_dev.attr.tp_maintainer) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Mig change: global func id:%u not tp maintainer.\n",
+ hinic5_global_func_id(udma_dev->hwdev));
+ return -EINVAL;
+ }
+
+ if (!UDMA_IS_MIG_VFID(mig_status->vfid)) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Mig change: vfid:%u invalid\n", mig_status->vfid);
+ return -EINVAL;
+ }
+
+ ret = (mig_status->sts == UDMA_VF_MIG_START) ?
+ udma_vf_migrate_start_proc(udma_dev, mig_status->vfid) :
+ udma_vf_migrate_end_proc(udma_dev, mig_status->vfid);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_VTP,
+ "Mig change: failed, vf:%u sts:%u\n", mig_status->vfid,
+ mig_status->sts);
+ }
+
+ return ret;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.h
new file mode 100644
index 000000000..3407d7a64
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/tp/udma_vtp.h
@@ -0,0 +1,66 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+
+
+#ifndef UDMA_VTP_H
+#define UDMA_VTP_H
+
+#include "udma_cmd_vtp.h"
+
+#define UB_VTPC_SIZE 128
+
+typedef struct udma_vtp {
+ struct ubcore_vtp base;
+ struct list_head node;
+ u64 mig_switch_time;
+ u64 mig_rollback_time;
+ struct cmdq_rtt cmdq_rtt;
+ struct kref ref_cnt; /** reference count */
+ struct completion comp; /** reference count */
+} udma_vtp_t;
+
+typedef struct udma_vtpn {
+ u32 cqm_priv_type;
+ struct ubcore_vtpn base;
+ struct list_head node;
+ struct tag_cqm_queue *cqm_vtpn;
+} udma_vtpn_t;
+
+static inline struct udma_vtp *to_udma_vtp(const struct ubcore_vtp *vtp)
+{
+ return (struct udma_vtp *)udma_container_of(vtp, struct udma_vtp, base);
+}
+
+static inline struct udma_vtpn *to_udma_vtpn(const struct ubcore_vtpn *vtpn)
+{
+ return (struct udma_vtpn *)udma_container_of(vtpn, struct udma_vtpn,
+ base);
+}
+
+int udma_mig_status_change_proc(struct udma_device *udma_dev, void *para);
+struct ubcore_vtp *udma_create_vtp(struct ubcore_device *ub_dev,
+ struct ubcore_vtp_cfg *cfg,
+ struct ubcore_udata *udata);
+struct ubcore_vtpn *udma_alloc_vtpn(struct ubcore_device *ub_dev);
+int udma_destroy_vtp(struct ubcore_vtp *vtp);
+int udma_free_vtpn(struct ubcore_vtpn *vtpn);
+int udma_query_res_vtp(struct udma_device *udma_dev, struct ubcore_res_key *key,
+ struct ubcore_res_val *val);
+int udma_restore_vtp(struct udma_device *udma_dev,
+ const struct ubcore_vtp_cfg *cfg, struct cmdq_rtt *rtt);
+struct udma_vtp *udma_get_vtp_by_id(struct udma_device *udma_dev, u32 vtpn,
+ u32 function_id);
+int udma_modify_vtp(struct ubcore_vtp *vtp, struct ubcore_vtp_attr *attr,
+ union ubcore_vtp_attr_mask *mask);
+int udma_restore_all_vtp_cmd(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf);
+void udma_free_vtp_buf(struct udma_device *udma_dev, struct udma_vtp_buf *buf);
+void udma_set_vtp_buf_idle(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf);
+int udma_flush_remain_modify(struct udma_device *udma_dev,
+ struct udma_vtp_buf *buf);
+int udma_vf_migrate_end_proc(struct udma_device *udma_dev, u16 vfid);
+void udma_vtp_put(void *obj);
+void udma_vtp_get(void *obj);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.c b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.c
new file mode 100644
index 000000000..5701864c3
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.c
@@ -0,0 +1,96 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include "udma_log.h"
+#include "udma_userctl_uvs.h"
+#include "udma_userctl_dfx.h"
+#include "udma_userctl.h"
+
+enum udma_user_ctl_op_feat {
+ UDMA_USER_CTL_OP_FEAT_UVS,
+ UDMA_USER_CTL_OP_FEAT_DFX,
+};
+
+static struct udma_user_ctl_op_entry g_udma_user_ctl_op_feats[] = {
+ { UDMA_USER_CTL_OP_FEAT_UVS, udma_userctl_uvs_dispatch },
+ { UDMA_USER_CTL_OP_FEAT_DFX, udma_userctl_dfx_dispatch },
+};
+
+int udma_user_ctl(struct ubcore_device *dev, struct ubcore_user_ctl *user_ctl)
+{
+ struct udma_device *udev = NULL;
+ udma_user_ctl_op_func op_func = NULL;
+ int ret;
+
+ if (dev == NULL || user_ctl == NULL) {
+ udma_pr_err(
+ UDMA_M_USER_CTL,
+ "User_ctl invalid parameter. dev(%d), user_ctl(%d).\n",
+ !!dev, !!user_ctl);
+ return -EINVAL;
+ }
+
+ udev = to_udma_dev(dev);
+
+ udma_info(udev->dev, UDMA_M_USER_CTL, "Udma user_ctl, opcode(%u).\n",
+ user_ctl->in.opcode);
+
+ op_func = UDMA_USER_CTL_GET_OP_ENTRY_FUNC(
+ g_udma_user_ctl_op_feats,
+ UDMA_USER_CTL_GET_OP_FEAT(user_ctl->in.opcode));
+ if (op_func == NULL) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to get feature callback, opcode(%u).\n",
+ user_ctl->in.opcode);
+ return -EINVAL;
+ }
+
+ ret = op_func(udev, user_ctl);
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_USER_CTL,
+ "Failed to execute the function of opcode(%u), ret(%d).\n",
+ user_ctl->in.opcode, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int32_t udma_check_cmd_out_param(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl,
+ uint64_t valid_size)
+{
+ if (user_ctl->out.len < valid_size) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! user_ctl->out.len(%u).\n",
+ user_ctl->out.len);
+ return -EINVAL;
+ }
+ if (user_ctl->out.addr == 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! user_ctl->out.addr(0x%llx).\n",
+ user_ctl->out.addr);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int32_t udma_check_cmd_in_param(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl,
+ uint64_t valid_size)
+{
+ if (user_ctl->in.len != valid_size) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! user_ctl->in.len(%u).\n",
+ user_ctl->in.len);
+ return -EINVAL;
+ }
+ if (user_ctl->in.addr == 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! user_ctl->in.addr(0x%llx).\n",
+ user_ctl->in.addr);
+ return -EINVAL;
+ }
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.h b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.h
new file mode 100644
index 000000000..a2d82cc3f
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl.h
@@ -0,0 +1,51 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef UDMA_USERCTL_H
+#define UDMA_USERCTL_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+/* The size of opcode is 32 bits. The format of opcode is as follows:
+ * [31:16]-reserved, [15:8]-feature, [7:0]-function */
+#define UDMA_USER_CTL_OP_FEAT_SHIFT 8
+#define UDMA_USER_CTL_OP_FEAT_MASK 0xff
+#define UDMA_USER_CTL_OP_FUNC_MASK 0xff
+
+#define UDMA_USER_CTL_GET_OP_FEAT(opcode) \
+ (((opcode) >> UDMA_USER_CTL_OP_FEAT_SHIFT) & UDMA_USER_CTL_OP_FEAT_MASK)
+#define UDMA_USER_CTL_GET_OP_FUNC(opcode) ((opcode)&UDMA_USER_CTL_OP_FUNC_MASK)
+
+typedef int (*udma_user_ctl_op_func)(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl);
+
+struct udma_user_ctl_op_entry {
+ u32 id;
+ udma_user_ctl_op_func func;
+};
+
+static inline udma_user_ctl_op_func
+udma_user_ctl_get_op_entry_func(struct udma_user_ctl_op_entry *op_list,
+ u32 list_size, u32 id)
+{
+ u32 index;
+ for (index = 0; index < list_size; ++index) {
+ if (op_list[index].id == id) {
+ return op_list[index].func;
+ }
+ }
+ return NULL;
+}
+
+#define UDMA_USER_CTL_GET_OP_ENTRY_FUNC(op_list, id) \
+ ({ udma_user_ctl_get_op_entry_func(op_list, ARRAY_SIZE(op_list), id); })
+
+int32_t udma_check_cmd_in_param(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl,
+ uint64_t valid_size);
+int32_t udma_check_cmd_out_param(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl,
+ uint64_t valid_size);
+
+#endif /* UDMA_USERCTL_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.c b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.c
new file mode 100644
index 000000000..a478bae88
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/build_bug.h>
+#include "ubcore_types.h"
+#include "udma_log.h"
+#include "udma_userctl.h"
+#include "udma_resource.h"
+#include "udma_dfx_latch.h"
+#include "udma_userctl_intf.h"
+#include "udma_jetty.h"
+#include "udma_cmd_jetty.h"
+#include "udma_cmd_jfc.h"
+#include "udma_cmd_tp.h"
+#include "udma_cmd_tpg.h"
+#include "udma_userctl_dfx.h"
+
+enum udma_user_ctl_opcode_dfx_func {
+ UDMA_USER_CTL_OP_DFX_PRINT_RC_TABLE,
+ UDMA_USER_CTL_OP_DFX_TA_STAUS,
+ UDMA_USER_CTL_OP_DFX_JETTY_DUMP,
+ UDMA_USER_CTL_OP_DFX_TP_DUMP
+};
+
+static int32_t udma_user_ctl_dfx_jetty_dump(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ struct ub_user_ctl_dfx_dump_in in_data = { 0 };
+ struct ub_user_ctl_dfx_jetty_dump_out out_data = { 0 };
+ struct ub_ta_context_query *jetty_entry =
+ (struct ub_ta_context_query *)&out_data;
+ struct ub_jfc_ctx_query *jfc_entry =
+ (struct ub_jfc_ctx_query *)&out_data;
+ uint32_t obj_type = 0;
+ int32_t ret = 0;
+
+ BUILD_BUG_ON_MSG(sizeof(jetty_entry->ctx) != sizeof(out_data.ctx),
+ "The size of ctx needs to be consistent.");
+
+ ret = udma_check_cmd_in_param(udev, user_ctl,
+ sizeof(struct ub_user_ctl_dfx_dump_in));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ return ret;
+ }
+
+ ret = udma_check_cmd_out_param(
+ udev, user_ctl, sizeof(struct ub_user_ctl_dfx_jetty_dump_out));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ return ret;
+ }
+
+ ret = (int32_t)copy_from_user(&in_data,
+ (void *)(uintptr_t)(user_ctl->in.addr),
+ sizeof(in_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from user failed to copy: %d\n",
+ ret);
+ return -EFAULT;
+ }
+
+ obj_type = in_data.flag.obj_type;
+ if (obj_type == UB_USER_CTL_JFC) {
+ ret = udma_cmd_jfc_query_ctx(udev, in_data.xid, jfc_entry);
+ } else if (obj_type == UB_USER_CTL_JETTY ||
+ obj_type == UB_USER_CTL_JFS || obj_type == UB_USER_CTL_JFR) {
+ ret = udma_cmd_jetty_query_ctx(udev, in_data.xid, NULL,
+ jetty_entry);
+ } else {
+ udma_err(udev->hwdev, UDMA_M_USER_CTL,
+ "unsupported obj type(%d).\n", obj_type);
+ return -EINVAL;
+ }
+
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to query obj_type(%d) from cache! obj_id(%u)",
+ in_data.flag.obj_type, in_data.xid);
+ return ret;
+ }
+
+ ret = (int32_t)copy_to_user((void *)(uintptr_t)(user_ctl->out.addr),
+ &out_data, sizeof(out_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from kernel failed to copy: %d\n",
+ ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int32_t udma_user_ctl_dfx_tp_dump(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ struct ub_user_ctl_dfx_dump_in in_data = { 0 };
+ struct ub_user_ctl_dfx_tp_dump_out out_data = { 0 };
+ struct ub_dfx_tp_ctx_query *tp_entry =
+ (struct ub_dfx_tp_ctx_query *)out_data.tp_ctx;
+ struct ub_tpg_ctx_query *tpg_entry =
+ (struct ub_tpg_ctx_query *)out_data.tpg_ctx_req;
+ struct udma_tp *ub_tp = NULL;
+ struct udma_tpg *ub_tpg = NULL;
+ int32_t ret = 0;
+ struct ubcore_res_key key = { 0 };
+
+ if (udev->sysfs_res.dfx_ctx.dump_tp_en == 0) {
+ udma_warn(udev->dev, UDMA_M_USER_CTL,
+ "Dump TP is not enabled.\n");
+ return 0;
+ }
+
+ BUILD_BUG_ON_MSG(sizeof(tp_entry->ctx) != sizeof(out_data.tp_ctx),
+ "The size of ctx needs to be consistent.");
+ BUILD_BUG_ON_MSG(sizeof(tpg_entry->ctx_req) !=
+ sizeof(out_data.tpg_ctx_req),
+ "The size of ctx needs to be consistent.");
+
+ ret = udma_check_cmd_in_param(udev, user_ctl,
+ sizeof(struct ub_user_ctl_dfx_dump_in));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ return ret;
+ }
+
+ ret = udma_check_cmd_out_param(
+ udev, user_ctl, sizeof(struct ub_user_ctl_dfx_tp_dump_out));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ return ret;
+ }
+
+ ret = (int32_t)copy_from_user(&in_data,
+ (void *)(uintptr_t)(user_ctl->in.addr),
+ sizeof(in_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from user failed to copy: %d\n",
+ ret);
+ return -EFAULT;
+ }
+
+ ub_tp = udma_find_tp(udev, in_data.xid);
+ if (ub_tp == NULL) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to get tp, tp_id(%u)\n", in_data.xid);
+ return -EINVAL;
+ }
+
+ key.type = UBCORE_RES_KEY_TP;
+ key.key = in_data.xid;
+ ret = udma_cmd_tp_query_ctx(udev, &key, tp_entry);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to query tp from cache! tp_id(%u)",
+ in_data.xid);
+ udma_tp_put(ub_tp);
+ return ret;
+ }
+
+ ub_tpg = to_udma_tpg(ub_tp->cfg.tpg);
+
+ ret = udma_cmd_tpg_query_ctx_from_cache(
+ udev, ub_tpg->tpg.tpgn, tpg_entry,
+ sizeof(struct ub_tpg_ctx_query));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to query tpg from cache! tpg_id(%u)",
+ ub_tpg->tpg.tpgn);
+ udma_tp_put(ub_tp);
+ return ret;
+ }
+
+ udma_tp_put(ub_tp);
+
+ ret = (int32_t)copy_to_user((void *)(uintptr_t)(user_ctl->out.addr),
+ &out_data, sizeof(out_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from kernel failed to copy: %d\n",
+ ret);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int udma_user_ctl_dfx_print_rc_table(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ udma_info(udev->dev, UDMA_M_USER_CTL,
+ "udma print dfx data:rc table.\n");
+ udma_dump_ta_latch_info(
+ udev); /* item before only has 1825 supports exception cqe do dump,@see ub_1825v100_poll_jfc_one */
+
+ return 0;
+}
+
+static struct udma_user_ctl_op_entry g_udma_user_ctl_dfx_funcs[] = {
+ { UDMA_USER_CTL_OP_DFX_PRINT_RC_TABLE,
+ udma_user_ctl_dfx_print_rc_table },
+ { UDMA_USER_CTL_OP_DFX_JETTY_DUMP, udma_user_ctl_dfx_jetty_dump },
+ { UDMA_USER_CTL_OP_DFX_TP_DUMP, udma_user_ctl_dfx_tp_dump },
+};
+
+int udma_userctl_dfx_dispatch(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ udma_user_ctl_op_func op_func = NULL;
+ int ret;
+
+ op_func = UDMA_USER_CTL_GET_OP_ENTRY_FUNC(
+ g_udma_user_ctl_dfx_funcs,
+ UDMA_USER_CTL_GET_OP_FUNC(user_ctl->in.opcode));
+ if (op_func == NULL) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to get DFX callback, opcode(%u).\n",
+ user_ctl->in.opcode);
+ return -EINVAL;
+ }
+
+ ret = op_func(udev, user_ctl);
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_USER_CTL,
+ "Failed to execute the function of DFX, opcode(%u), ret(%d).\n",
+ user_ctl->in.opcode, ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.h b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.h
new file mode 100644
index 000000000..a21e104d1
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_dfx.h
@@ -0,0 +1,14 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef UDMA_USERCTL_DFX_H
+#define UDMA_USERCTL_DFX_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+
+int udma_userctl_dfx_dispatch(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl);
+int32_t udma_user_ctl_dfx_print_rc_table(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl);
+#endif /* UDMA_USERCTL_DFX_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.c b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.c
new file mode 100644
index 000000000..488fe0463
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.c
@@ -0,0 +1,364 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#include <linux/uaccess.h>
+#include "ubcore_types.h"
+#include "ub_npu_base_cmd.h"
+#include "ub_npu_userctl_defs.h"
+#include "udma_log.h"
+#include "udma_userctl_intf.h"
+#include "udma_userctl.h"
+#include "udma_common.h"
+#include "udma_cmd.h"
+#include "udma_cqm.h"
+#include "udma_vtp.h"
+#include "udma_cmd_com.h"
+#include "udma_userctl_uvs.h"
+
+void udma_fill_cmd_userctl_ctx(struct ub_cmd_userctl *cmd_buf, u8 cmd_type,
+ u8 cmd_subtype)
+{
+ u16 cmd_len = sizeof(*cmd_buf);
+ udma_fill_cmd_header(&cmd_buf->header, cmd_type, cmd_subtype, cmd_len,
+ 0);
+}
+
+static int32_t udma_cqm_send(struct udma_device *dev,
+ struct tag_cqm_cmd_buf *in,
+ struct tag_cqm_cmd_buf *out, u8 cmd_subtype,
+ u64 func_id)
+{
+ int32_t ret = 0;
+ struct ub_cmd_userctl *cmd_buf = NULL;
+ cmd_buf = (struct ub_cmd_userctl *)in->buf;
+ cmd_buf->body.func_id = func_id;
+
+ udma_fill_cmd_userctl_ctx(cmd_buf, UB_CMD_TYPE_USERCTL, cmd_subtype);
+ udma_cpu_to_be32(cmd_buf, sizeof(*cmd_buf));
+ ret = udma_send_cmd_box(dev, cmd_subtype, in, out, NULL, NULL);
+ return ret;
+}
+
+int32_t udma_user_ctl_uvs_trunk_pfc_status(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ ub_user_ctl_uvs_trunk_pfc_status_out_s out_data = { 0 };
+ struct mag_cmd_port_stats stats = { 0 };
+ int32_t ret = 0;
+
+ ret = udma_check_cmd_out_param(
+ udev, user_ctl, sizeof(ub_user_ctl_uvs_trunk_pfc_status_out_s));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ return ret;
+ }
+
+ ret = hinic5_get_phy_port_stats(udev->hwdev, &stats);
+ if (ret != 0) {
+ udma_err(udev->hwdev, UDMA_M_USER_CTL,
+ "Failed to get PFC stats from hinic5, ret: %d.\n",
+ ret);
+ return ret;
+ }
+
+ out_data.rx_pfc_packets = stats.mac_rx_pfc_pkt_num;
+ (void)memcpy_s(&out_data.rx_pri_pfc_packets, sizeof(u64) * PFC_PRIORITY,
+ (void *)&stats.mac_rx_pfc_pri0_pkt_num,
+ sizeof(u64) * PFC_PRIORITY);
+ out_data.tx_pfc_packets = stats.mac_tx_pfc_pkt_num;
+ (void)memcpy_s(&out_data.tx_pri_pfc_packets, sizeof(u64) * PFC_PRIORITY,
+ (void *)&stats.mac_tx_pfc_pri0_pkt_num,
+ sizeof(u64) * PFC_PRIORITY);
+
+ ret = (int32_t)copy_to_user((void *)(uintptr_t)(user_ctl->out.addr),
+ &out_data, sizeof(out_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from kernel failed to copy: %d\n",
+ ret);
+ ret = -EFAULT;
+ }
+
+ return ret;
+}
+
+static int32_t udma_user_ctl_uvs_trunk_status(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ ub_user_ctl_uvs_card_status_out_s out_data = { 0 };
+ int32_t ret = 0;
+ uint64_t func_id = 0;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+
+ ret = udma_check_cmd_out_param(
+ udev, user_ctl, sizeof(ub_user_ctl_uvs_card_status_out_s));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ goto err_out;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udev->hwdev, &cqm_cmd_inbuf, (u16)sizeof(struct ub_cmd_userctl),
+ &cqm_cmd_outbuf, sizeof(ub_user_ctl_uvs_card_status_out_s));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ goto err_out;
+ }
+
+ ret = udma_cqm_send(udev, cqm_cmd_inbuf, cqm_cmd_outbuf,
+ UB_CMD_TRUNK_STATS, func_id);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_out;
+ }
+ udma_be32_to_cpu((void *)cqm_cmd_outbuf->buf,
+ UVS_TRUNK_STATUS_FISRT_FOUR_FIELDS);
+ udma_be64_to_cpu((void *)cqm_cmd_outbuf->buf +
+ UVS_TRUNK_STATUS_FISRT_FOUR_FIELDS,
+ UVS_TRUNK_STATUS_LAST_FOUR_FIELDS);
+
+ (void)memcpy_s(&out_data, sizeof(ub_user_ctl_uvs_card_status_out_s),
+ (void *)cqm_cmd_outbuf->buf,
+ sizeof(ub_user_ctl_uvs_card_status_out_s));
+
+ udma_debug(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "rx_err_packets(%u) rx_loss_packets(%u) rx_ce_packets(%u)"
+ "tx_port_err_packets(%u) tx_port_pkts(%llu) tx_port_bytes(%llu) rx_port_pkts(%llu) rx_port_bytes(%llu)\n",
+ out_data.rx_err_packets, out_data.rx_loss_packets,
+ out_data.rx_ce_packets, out_data.tx_port_err_packets,
+ out_data.tx_port_pkts, out_data.tx_port_bytes,
+ out_data.rx_port_pkts, out_data.rx_port_bytes);
+
+ ret = (int32_t)copy_to_user((void *)(uintptr_t)(user_ctl->out.addr),
+ &out_data, sizeof(out_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from kernel failed to copy: %d\n",
+ ret);
+ ret = -EFAULT;
+ goto err_out;
+ }
+ udma_cqm5_cmd_free_inoutbuf(udev->hwdev, cqm_cmd_inbuf, cqm_cmd_outbuf);
+ return 0;
+
+err_out:
+ udma_cqm5_cmd_free_inoutbuf(udev->hwdev, cqm_cmd_inbuf, cqm_cmd_outbuf);
+ return ret;
+}
+
+static int32_t udma_user_ctl_uvs_vf_status(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ ub_user_ctl_uvs_vf_status_out_s out_data = { 0 };
+ struct ub_user_ctl_uvs_vf_status_in in_data = { 0 };
+ int32_t ret = 0;
+ struct tag_cqm_cmd_buf *cqm_cmd_outbuf = NULL;
+ struct tag_cqm_cmd_buf *cqm_cmd_inbuf = NULL;
+ ret = udma_check_cmd_out_param(udev, user_ctl,
+ sizeof(ub_user_ctl_uvs_vf_status_out_s));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ goto err_out;
+ }
+ ret = udma_check_cmd_in_param(
+ udev, user_ctl, sizeof(struct ub_user_ctl_uvs_vf_status_in));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Invalid parameter! ret: %d.\n", ret);
+ goto err_out;
+ }
+
+ ret = udma_cqm_cmd_zalloc_inoutbuf(
+ udev->hwdev, &cqm_cmd_inbuf, (u16)sizeof(struct ub_cmd_userctl),
+ &cqm_cmd_outbuf, sizeof(ub_user_ctl_uvs_vf_status_out_s));
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "failed to alloc cqm cmd inoutbuf, ret(%d)\n", ret);
+ goto err_out;
+ }
+
+ ret = (int32_t)copy_from_user(&in_data,
+ (void *)(uintptr_t)(user_ctl->in.addr),
+ user_ctl->in.len);
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from user failed to copy: %d\n",
+ ret);
+ ret = -EFAULT;
+ goto err_out;
+ }
+ ret = udma_cqm_send(udev, cqm_cmd_inbuf, cqm_cmd_outbuf,
+ UB_CMD_VF_STATS, in_data.func_id);
+ if (ret != 0) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "failed to send cqm cmd, ret(%d)\n", ret);
+ goto err_out;
+ }
+ udma_be64_to_cpu((void *)cqm_cmd_outbuf->buf,
+ sizeof(ub_user_ctl_uvs_vf_status_out_s));
+
+ (void)memcpy_s(&out_data, sizeof(ub_user_ctl_uvs_vf_status_out_s),
+ (void *)cqm_cmd_outbuf->buf,
+ sizeof(ub_user_ctl_uvs_vf_status_out_s));
+
+ udma_debug(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "func_id(%d) rx_packets(%lld) rx_bytes(%lld) tx_packets(%lld) tx_bytes(%lld)"
+ "rx_err_pkt_cnt(%lld) rx_ce_pkt_cnt(%lld) rx_not_ready_cnt(%lld) tx_timeout_cnt(%lld) tx_no_vld_tp_cnt(%lld)\n",
+ in_data.func_id, out_data.rx_packets, out_data.rx_bytes,
+ out_data.tx_packets, out_data.tx_bytes, out_data.rx_err_pkt_cnt,
+ out_data.rx_ce_pkt_cnt, out_data.rx_not_ready_cnt,
+ out_data.tx_timeout_cnt, out_data.tx_no_vld_tp_cnt);
+
+ ret = (int32_t)copy_to_user((void *)(uintptr_t)(user_ctl->out.addr),
+ &out_data, sizeof(out_data));
+ if (ret != 0) {
+ udma_err(
+ udev->hwdev, UDMA_M_USER_CTL,
+ "The number of data bytes from kernel failed to copy: %d\n",
+ ret);
+ ret = -EFAULT;
+ goto err_out;
+ }
+ udma_cqm5_cmd_free_inoutbuf(udev->hwdev, cqm_cmd_inbuf, cqm_cmd_outbuf);
+ return 0;
+err_out:
+ udma_cqm5_cmd_free_inoutbuf(udev->hwdev, cqm_cmd_inbuf, cqm_cmd_outbuf);
+ return ret;
+}
+
+int udma_user_ctl_uvs_mig_status_change(struct udma_device *udma_dev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ struct udma_vf_mig_status_out mig_rst = { 0 };
+ struct udma_vf_mig_status_in mig_sts = { 0 };
+ int ret;
+
+ if (user_ctl->in.len != sizeof(struct udma_vf_mig_status_in) ||
+ user_ctl->out.len != sizeof(struct udma_vf_mig_status_out)) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig sts change] len invalid, in:%u out:%u\n",
+ user_ctl->in.len, user_ctl->out.len);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&mig_sts, (void *)(uintptr_t)(user_ctl->in.addr),
+ user_ctl->in.len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig sts change] copy from user failed\n");
+ return -EINVAL;
+ }
+ udma_info(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig sts change] vf:%u sts:%u.\n", mig_sts.vfid,
+ mig_sts.sts);
+
+ ret = udma_mig_status_change_proc(udma_dev, (void *)&mig_sts);
+ if (ret != 0) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig sts change] failed, vf:%u sts:%u rst:%d.\n",
+ mig_sts.vfid, mig_sts.sts, ret);
+ }
+ mig_rst.result = ret;
+ if (copy_to_user((void *)(uintptr_t)(user_ctl->out.addr), &mig_rst,
+ user_ctl->out.len) != 0) {
+ udma_err(
+ udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig sts change] copy to user failed, vf:%u sts:%u.\n",
+ mig_sts.vfid, mig_sts.sts);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int udma_user_ctl_uvs_mig_vf_status(struct udma_device *udma_dev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ struct udma_mig_vf_status_in data_in = { 0 };
+ struct udma_mig_vf_status_out data_out = { 0 };
+ int ret;
+
+ if (user_ctl->in.len != sizeof(struct udma_mig_vf_status_in) ||
+ user_ctl->out.len != sizeof(struct udma_mig_vf_status_out)) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig vf status] len invalid, in:%u out:%u\n",
+ user_ctl->in.len, user_ctl->out.len);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&data_in, (void *)user_ctl->in.addr,
+ user_ctl->in.len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig vf status] copy from user failed\n");
+ return -EINVAL;
+ }
+ udma_info(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig vf status] vf:%u \n", data_in.vfid);
+
+ ret = udma_query_mig_vf_status(udma_dev, data_in.vfid);
+ data_out.result = ret;
+ udma_info(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig vf status] vm status is %d \n", ret);
+ if (copy_to_user((void *)user_ctl->out.addr, &data_out,
+ user_ctl->out.len) != 0) {
+ udma_err(udma_dev->dev, UDMA_M_USER_CTL,
+ "[UVS][Mig vf status] copy to user failed\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+enum udma_user_ctl_opcode_uvs_func {
+ UDMA_USER_CTL_OP_UVS_TRUNK_PFC_STATUS,
+ UDMA_USER_CTL_OP_UVS_TRUNK_STATUS,
+ UDMA_USER_CTL_OP_UVS_VF_STATUS,
+ UDMA_USER_CTL_OP_UVS_MIG_STATUS_CHANGE,
+ UDMA_USER_CTL_OP_UVS_MIG_VF_STATUS
+};
+
+static struct udma_user_ctl_op_entry g_udma_user_ctl_uvs_funcs[] = {
+ { UDMA_USER_CTL_OP_UVS_TRUNK_PFC_STATUS,
+ udma_user_ctl_uvs_trunk_pfc_status },
+ { UDMA_USER_CTL_OP_UVS_TRUNK_STATUS, udma_user_ctl_uvs_trunk_status },
+ { UDMA_USER_CTL_OP_UVS_VF_STATUS, udma_user_ctl_uvs_vf_status },
+ { UDMA_USER_CTL_OP_UVS_MIG_STATUS_CHANGE,
+ udma_user_ctl_uvs_mig_status_change },
+ { UDMA_USER_CTL_OP_UVS_MIG_VF_STATUS, udma_user_ctl_uvs_mig_vf_status },
+};
+
+int udma_userctl_uvs_dispatch(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl)
+{
+ udma_user_ctl_op_func op_func = NULL;
+ int ret;
+
+ op_func = UDMA_USER_CTL_GET_OP_ENTRY_FUNC(
+ g_udma_user_ctl_uvs_funcs,
+ UDMA_USER_CTL_GET_OP_FUNC(user_ctl->in.opcode));
+ if (op_func == NULL) {
+ udma_err(udev->dev, UDMA_M_USER_CTL,
+ "Failed to get UVS callback, opcode(%u).\n",
+ user_ctl->in.opcode);
+ return -EINVAL;
+ }
+
+ ret = op_func(udev, user_ctl);
+ if (ret != 0) {
+ udma_err(
+ udev->dev, UDMA_M_USER_CTL,
+ "Failed to execute the function of UVS, opcode(%u), ret(%d).\n",
+ user_ctl->in.opcode, ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.h b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.h
new file mode 100644
index 000000000..b38a74433
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/userctl/udma_userctl_uvs.h
@@ -0,0 +1,23 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. All rights reserved.
+
+#ifndef UDMA_USERCTL_UVS_H
+#define UDMA_USERCTL_UVS_H
+
+#include "ubcore_types.h"
+#include "udma_common.h"
+#include "ub_npu_base_cmd.h"
+#include "ub_npu_userctl_defs.h"
+
+#define UVS_TRUNK_STATUS_FISRT_FOUR_FIELDS (4 * sizeof(u32))
+#define UVS_TRUNK_STATUS_LAST_FOUR_FIELDS (4 * sizeof(u64))
+typedef struct ub_cmd_userctl {
+ ub_cmd_com_header_s header;
+ ub_cmd_body_userctl_s body;
+} ub_cmd_userctl_s;
+
+int udma_userctl_uvs_dispatch(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl);
+int32_t udma_user_ctl_uvs_trunk_pfc_status(struct udma_device *udev,
+ struct ubcore_user_ctl *user_ctl);
+#endif /* UDMA_USERCTL_UVS_H */
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.c
new file mode 100644
index 000000000..a26053996
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.c
@@ -0,0 +1,225 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+
+#include "udma_vram_base.h"
+#include "udma_vram_mem.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_type_dev.h"
+#include "udma_vram_type_tpg.h"
+#include "udma_vram_type_tp.h"
+#include "udma_vram_type_vtp.h"
+#include "udma_vram.h"
+
+typedef int (*udma_vram_type_register)(void);
+
+static const udma_vram_type_register g_vram_type_reg_arr[] = {
+ udma_vram_device_register, udma_vram_tpg_register,
+ udma_vram_tp_register, udma_vram_vtp_register
+};
+
+int udma_get5_use_vram_flag(void)
+{
+ return udma_get_use_vram_base_flag();
+}
+
+int udma_vram5_get_kexec_flag(void)
+{
+ return udma_vram_get_kexec_base_flag();
+}
+
+void *udma_vram_kzalloc(void *dev, u32 type, size_t size, gfp_t flag)
+{
+ if (type >= UDMA_VRAM_TYPE_MAX) {
+ udma_pr_err(UDMA_M_VRAM, "type(%d) is out of range(%d).\n",
+ type, UDMA_VRAM_TYPE_MAX);
+ return NULL;
+ }
+
+ if (udma_get5_use_vram_flag() == 0) {
+ return type == UDMA_VRAM_TYPE_DEV ?
+ devm_kzalloc((struct device *)dev, size, flag) :
+ kzalloc(size, flag);
+ }
+
+ return udma_vram_kzalloc_from_block(type, size);
+}
+
+void udma_vram_kfree(void *dev, void *ptr, u32 type)
+{
+ if (type >= UDMA_VRAM_TYPE_MAX) {
+ udma_pr_err(UDMA_M_VRAM, "type(%d) is out of range(%d).\n",
+ type, UDMA_VRAM_TYPE_MAX);
+ return;
+ }
+
+ if (udma_get5_use_vram_flag() == 0) {
+ return type == UDMA_VRAM_TYPE_DEV ?
+ devm_kfree((struct device *)dev, ptr) :
+ kfree(ptr);
+ }
+
+ return udma_vram_kfree_from_block(ptr, type);
+}
+
+int udma_vram_mem_manager_recover(void)
+{
+ if (udma_get5_use_vram_flag() == 0) {
+ return 0;
+ }
+
+ return udma_vram_block_recover();
+}
+
+static int udma_vram_type_register_all(void)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(g_vram_type_reg_arr); i++) {
+ ret = g_vram_type_reg_arr[i]();
+ if (ret < 0) {
+ udma_pr_err(UDMA_M_VRAM,
+ "vram type(id: %d) register failed.\n", i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int udma_vram_block_node(u32 type, struct udma_vram_block *block)
+{
+ udma_vram_recover_func callback = NULL;
+ u32 max_num = block->node_num;
+ void *node = NULL;
+ u32 index;
+ int ret;
+
+ for (index = 0; index < max_num; index++) {
+ if (test_bit(index, (const unsigned long *)block->bitmap) ==
+ 1) {
+ node = (void *)((u8 *)block->buf +
+ index * block->node_size);
+ callback = udma_vram_cfg_get_recover(type);
+ ret = callback(node);
+ if (ret < 0) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "vram block node(index: %u) recover failed.\n",
+ index);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void udma_store_block_addr(struct udma_vram_block_header *header)
+{
+ header->block->last_block_addr = (uintptr_t)(header->block);
+}
+
+static int udma_vram_mem_block_node_recover(void)
+{
+ struct udma_vram_header *vram_header = NULL;
+ u32 i;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "vram header get failed.\n");
+ return -EINVAL;
+ }
+
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "vram header recover success. vram_header->vram_name is %s\n",
+ vram_header->vram_name);
+ for (i = 0; i < UDMA_VRAM_TYPE_MAX; i++) {
+ if (!udma_vram_cfg_enable(i)) {
+ continue;
+ }
+
+ if (udma_vram_block_node(i, vram_header->header[i].block) !=
+ 0) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "vram block node(vram type: %d) recover failed.\n",
+ i);
+ return -EINVAL;
+ }
+ udma_store_block_addr(&vram_header->header[i]);
+ }
+
+ return 0;
+}
+
+int udma_vram_init(void)
+{
+ int ret;
+
+ if (udma_get5_use_vram_flag() == 0) {
+ udma_pr_warn(UDMA_M_VRAM,
+ "%s: This system does not support VRAM!\n",
+ __func__);
+ return 0;
+ }
+
+ ret = udma_vram_type_register_all();
+ if (ret < 0) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram type register failed.\n",
+ __func__);
+ return ret;
+ }
+
+ return udma_vram_mem_init();
+}
+
+void udma_vram_uninit(void)
+{
+ if (udma_get5_use_vram_flag() == 0) {
+ udma_pr_warn(UDMA_M_VRAM,
+ "%s: This system does not support VRAM!\n",
+ __func__);
+ return;
+ }
+
+ udma_vram_mem_deinit();
+}
+
+int udma_vram_mem_manager_init(void)
+{
+ int ret;
+
+ udma_vram_base_init();
+ if (udma_vram5_get_kexec_flag() == 0) {
+ return udma_vram_init();
+ }
+
+ ret = udma_vram_type_register_all();
+ if (ret < 0) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram type register failed.\n",
+ __func__);
+ return ret;
+ }
+
+ return udma_vram_mem_manager_recover();
+}
+
+void udma_vram_mem_manager_uninit(void)
+{
+ udma_vram_uninit();
+ udma_vram_base_uninit();
+}
+
+int udma_vram_mem_obj_recover(void)
+{
+ if (udma_vram5_get_kexec_flag() == 1) {
+ return udma_vram_mem_block_node_recover();
+ }
+
+ return 0;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.h
new file mode 100644
index 000000000..a6c32d820
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram.h
@@ -0,0 +1,95 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_H
+#define UDMA_VRAM_H
+
+#include <linux/types.h>
+
+#include "udma_common.h"
+
+enum {
+ UDMA_VRAM_TYPE_DEV = 0,
+ UDMA_VRAM_TYPE_TPG,
+ UDMA_VRAM_TYPE_TP,
+ UDMA_VRAM_TYPE_VTP,
+ UDMA_VRAM_TYPE_MAX,
+};
+
+/**
+* get kexec flag. kexec flag set means OS is in hot replace state.
+* @param[in] [Required] void
+* Return: 1 means kexec flag is set, 0 means not.
+*/
+int udma_vram5_get_kexec_flag(void);
+
+/**
+* get vram use flag. vram use flag set means OS support vram management.
+* @param[in] [Required] void
+* Return: 1 means vram use flag is set, 0 means not.
+*/
+int udma_get5_use_vram_flag(void);
+
+/**
+* vram memroy allocate interface.
+* @param[in] [Required] dev: dev related.
+* @param[in] [Required] type: vram type, see UDMA_VRAM_TYPE.
+* @param[in] [Required] size: size to allocate vram memory.
+* @param[in] [Required] flag: Kernel get free pages flag.
+* Return: void*.
+*/
+void *udma_vram_kzalloc(void *dev, u32 type, size_t size, gfp_t flag);
+
+/**
+* vram memroy free interface.
+* @param[in] [Required] dev: dev related.
+* @param[in] [Required] ptr: vram memory to free.
+* @param[in] [Required] type: vram type, see UDMA_VRAM_TYPE.
+* Return: void.
+*/
+void udma_vram_kfree(void *dev, void *ptr, u32 type);
+
+/**
+* vram memroy manager recover, include vram header and block recover.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+int udma_vram_mem_manager_recover(void);
+
+/**
+* vram memroy obj recover, include block node recover.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+int udma_vram_mem_obj_recover(void);
+
+/**
+* vram memroy unint, include vram header and block uninit.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+void udma_vram_uninit(void);
+
+/**
+* vram memroy int, include vram header and block init.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+int udma_vram_init(void);
+
+/**
+* vram memroy manager int.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+int udma_vram_mem_manager_init(void);
+
+/**
+* vram memroy manager unint.
+* @param[in] [Required] void.
+* Return: 0 on success, other value on error.
+*/
+void udma_vram_mem_manager_uninit(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.c
new file mode 100644
index 000000000..8f969de98
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.c
@@ -0,0 +1,104 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include <linux/kallsyms.h>
+
+#include "ossl_knl.h"
+
+#include "udma_vram_base.h"
+
+static vram_kfree_t _udma_vram_kfree = NULL;
+static vram_kalloc_t _udma_vram_kalloc = NULL;
+static get5_use_vram_flag_t _udma_get5_use_vram_flag = NULL;
+static vram5_get_kexec_flag_t _udma_vram5_get_kexec_flag = NULL;
+
+void *udma_vram_base_kalloc(char *name, u64 size)
+{
+ if (_udma_vram_kalloc != NULL && name != NULL) {
+ return _udma_vram_kalloc(name, size);
+ }
+
+ return NULL;
+}
+
+void udma_vram_base_kfree(void *vaddr, char *name, u64 size)
+{
+ if (_udma_vram_kfree != NULL && vaddr != NULL && name != NULL) {
+ _udma_vram_kfree(vaddr, name, size);
+ }
+}
+
+int udma_get_use_vram_base_flag(void)
+{
+ if (_udma_get5_use_vram_flag != NULL) {
+ return _udma_get5_use_vram_flag();
+ }
+
+ return 0;
+}
+
+int udma_vram_get_kexec_base_flag(void)
+{
+ if (_udma_vram5_get_kexec_flag != NULL) {
+ return _udma_vram5_get_kexec_flag();
+ }
+
+ return 0;
+}
+
+void udma_vram_base_init(void)
+{
+ _udma_vram_kalloc =
+ (vram_kalloc_t)(uintptr_t)symbol_get(hi5_vram_kalloc);
+ if (_udma_vram_kalloc == NULL) {
+ udma_pr_info(UDMA_M_VRAM, "_udma_vram_kalloc is NULL.\n");
+ return;
+ }
+
+ _udma_vram_kfree = (vram_kfree_t)(uintptr_t)symbol_get(hi5_vram_kfree);
+ if (_udma_vram_kfree == NULL) {
+ udma_pr_info(UDMA_M_VRAM, "_udma_vram_kfree is NULL.\n");
+ return;
+ }
+
+ _udma_get5_use_vram_flag =
+ (get5_use_vram_flag_t)(uintptr_t)symbol_get(get5_use_vram_flag);
+ if (_udma_get5_use_vram_flag == NULL) {
+ udma_pr_info(UDMA_M_VRAM,
+ "_udma_get5_use_vram_flag is NULL.\n");
+ return;
+ }
+
+ _udma_vram5_get_kexec_flag =
+ (vram5_get_kexec_flag_t)(uintptr_t)symbol_get(
+ vram5_get_kexec_flag);
+ if (_udma_vram5_get_kexec_flag == NULL) {
+ udma_pr_info(UDMA_M_VRAM,
+ "_udma_vram5_get_kexec_flag is NULL.\n");
+ return;
+ }
+}
+
+void udma_vram_base_uninit(void)
+{
+ if (_udma_vram5_get_kexec_flag != NULL) {
+ symbol_put(vram5_get_kexec_flag);
+ _udma_vram5_get_kexec_flag = NULL;
+ }
+
+ if (_udma_get5_use_vram_flag != NULL) {
+ symbol_put(get5_use_vram_flag);
+ _udma_get5_use_vram_flag = NULL;
+ }
+
+ if (_udma_vram_kfree != NULL) {
+ symbol_put(hi5_vram_kfree);
+ _udma_vram_kfree = NULL;
+ }
+
+ if (_udma_vram_kalloc != NULL) {
+ symbol_put(hi5_vram_kalloc);
+ _udma_vram_kalloc = NULL;
+ }
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.h
new file mode 100644
index 000000000..dae0651bd
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_base.h
@@ -0,0 +1,22 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_BASE_H
+#define UDMA_VRAM_BASE_H
+
+#include "udma_common.h"
+
+typedef void __iomem *(*vram_kalloc_t)(char *name, u64 size);
+typedef void (*vram_kfree_t)(void __iomem *vaddr, char *name, u64 size);
+typedef int (*get5_use_vram_flag_t)(void);
+typedef int (*vram5_get_kexec_flag_t)(void);
+
+void *udma_vram_base_kalloc(char *name, u64 size);
+void udma_vram_base_kfree(void *vaddr, char *name, u64 size);
+int udma_get_use_vram_base_flag(void);
+int udma_vram_get_kexec_base_flag(void);
+void udma_vram_base_init(void);
+void udma_vram_base_uninit(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.c
new file mode 100644
index 000000000..a8d1441ec
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.c
@@ -0,0 +1,108 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include "udma_vram_mem.h"
+#include "udma_vram_common.h"
+#include "udma_vram_cfg.h"
+
+struct udma_vram_cfg_table {
+ char name[UDMA_VRAM_NAME_SIZE];
+ bool enable; /* support ECS or storage service */
+ u32 node_num;
+ u32 node_size;
+ udma_vram_recover_func recover;
+};
+
+static struct udma_vram_cfg_table g_cfg_table[UDMA_VRAM_TYPE_MAX] = { 0 };
+
+int udma_vram_cfg_register(const char *name, u32 type, u32 node_num,
+ u32 node_size, udma_vram_recover_func callback)
+{
+ int ret;
+
+ if (type >= UDMA_VRAM_TYPE_MAX) {
+ udma_pr_err(UDMA_M_VRAM, "type(%d) is out of range(%d).\n",
+ type, UDMA_VRAM_TYPE_MAX);
+ return -ERANGE;
+ }
+
+ g_cfg_table[type].enable = true;
+ g_cfg_table[type].node_num = node_num;
+ g_cfg_table[type].node_size = node_size;
+ g_cfg_table[type].recover = callback;
+ ret = strncpy_s(g_cfg_table[type].name, sizeof(g_cfg_table[type].name),
+ (const char *)name, sizeof(g_cfg_table[type].name) - 1);
+ if (ret != 0) {
+ udma_pr_err(UDMA_M_VRAM,
+ "%s: type(%d) name strncpy_s failed, ret:%d.\n",
+ __func__, type, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+bool udma_vram_cfg_enable(u32 type)
+{
+ if (type >= UDMA_VRAM_TYPE_MAX) {
+ udma_pr_err(UDMA_M_VRAM, "%s: type(%d) is out of range(%d).\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX);
+ return 0;
+ }
+
+ return g_cfg_table[type].enable;
+}
+
+u32 udma_vram_cfg_get_num(u32 type)
+{
+ if ((type >= UDMA_VRAM_TYPE_MAX) || !udma_vram_cfg_enable(type)) {
+ udma_pr_err(UDMA_M_VRAM, "%s: type(%d) is out of range(%d).\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX);
+ return 0;
+ }
+
+ return g_cfg_table[type].node_num;
+}
+
+u32 udma_vram_cfg_get_size(u32 type)
+{
+ if ((type >= UDMA_VRAM_TYPE_MAX) || !udma_vram_cfg_enable(type)) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: type(%d) is out of range(%d), enable flag is %d.\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX,
+ udma_vram_cfg_enable(type));
+ return 0;
+ }
+
+ return g_cfg_table[type].node_size;
+}
+
+char *udma_vram_cfg_get_name(u32 type)
+{
+ if ((type >= UDMA_VRAM_TYPE_MAX) || !udma_vram_cfg_enable(type)) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: type(%d) is out of range(%d), enable flag is %d.\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX,
+ udma_vram_cfg_enable(type));
+ return NULL;
+ }
+
+ return g_cfg_table[type].name;
+}
+
+udma_vram_recover_func udma_vram_cfg_get_recover(u32 type)
+{
+ if ((type >= UDMA_VRAM_TYPE_MAX) || !udma_vram_cfg_enable(type)) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: type(%d) is out of range(%d), enable flag is %d.\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX,
+ udma_vram_cfg_enable(type));
+ return NULL;
+ }
+
+ return g_cfg_table[type].recover;
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.h
new file mode 100644
index 000000000..b3c4b25db
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_cfg.h
@@ -0,0 +1,20 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_CFG_H
+#define UDMA_VRAM_CFG_H
+
+#include "udma_vram.h"
+
+typedef int (*udma_vram_recover_func)(void *node);
+
+int udma_vram_cfg_register(const char *name, u32 type, u32 node_num,
+ u32 node_size, udma_vram_recover_func callback);
+bool udma_vram_cfg_enable(u32 type);
+u32 udma_vram_cfg_get_num(u32 type);
+u32 udma_vram_cfg_get_size(u32 type);
+char *udma_vram_cfg_get_name(u32 type);
+udma_vram_recover_func udma_vram_cfg_get_recover(u32 type);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_common.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_common.h
new file mode 100644
index 000000000..4f2a1faa8
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_common.h
@@ -0,0 +1,25 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_COMMON_H
+#define UDMA_VRAM_COMMON_H
+
+#define UDMA_VRAM_HEADER_NAME "UB_HEADER"
+#define UDMA_DEV_NAME "UB_DEVICE"
+#define UDMA_TP_NAME "UB_TP"
+#define UDMA_TPG_NAME "UB_TPG"
+#define UDMA_VTP_NAME "UB_VTP"
+#define UDMA_TP_MTT_NAME "UB_TP_MTT"
+
+#define UDMA_VRAM_NAME_SIZE 15
+
+#define UDMA_DEVICE_NODE 2
+#define UDMA_TP_NODE 1024
+#define UDMA_TPG_NODE 1024
+#define UDMA_VTP_NODE 1024
+
+#define UDMA_NUM_BIT_DW 64
+#define UDMA_INVALID_ID 0xFFFFFFFF
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.c
new file mode 100644
index 000000000..c66d92d4c
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.c
@@ -0,0 +1,412 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+
+#include "udma_vram.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_base.h"
+#include "udma_vram_common.h"
+#include "udma_vram_mem.h"
+
+struct udma_vram_header *udma_get_vram_header(void)
+{
+ struct udma_vram_header *header = NULL;
+
+ header = (struct udma_vram_header *)udma_vram_base_kalloc(
+ (char *)UDMA_VRAM_HEADER_NAME, sizeof(struct udma_vram_header));
+ if (header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "header alloc failed.\n");
+ return NULL;
+ }
+
+ return header;
+}
+
+static void udma_vram_bitmap_free_id(struct udma_vram_block *block, u32 id)
+{
+ spin_lock(&block->bitmap_lock);
+ clear_bit(id, (unsigned long *)block->bitmap);
+ block->used_node_cnt--;
+ spin_unlock(&block->bitmap_lock);
+}
+
+static u32 udma_vram_get_bitmap_id(const void *ptr,
+ const struct udma_vram_block *block)
+{
+ u32 index;
+
+ for (index = 0; index < block->node_num; index++) {
+ if (ptr ==
+ (void *)((u8 *)block->buf + index * block->node_size)) {
+ return index;
+ }
+ }
+
+ return 0;
+}
+
+void udma_vram_kfree_from_block(void *ptr, u32 type)
+{
+ struct udma_vram_header *vram_header = NULL;
+ struct udma_vram_block *block = NULL;
+ u32 index;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "vram header get failed.\n");
+ return;
+ }
+
+ block = vram_header->header[type].block;
+ index = udma_vram_get_bitmap_id((const void *)ptr,
+ (const struct udma_vram_block *)block);
+ udma_vram_bitmap_free_id(block, index);
+}
+
+static u32 udma_vram_bitmap_alloc_id(struct udma_vram_block *block)
+{
+ unsigned long *table = (unsigned long *)block->bitmap;
+ u32 offset = block->bitmap_item_last;
+ u32 max_num = block->node_num;
+ u32 index;
+
+ spin_lock(&block->bitmap_lock);
+
+ if (block->used_node_cnt >= max_num) {
+ udma_pr_err(UDMA_M_VRAM,
+ "used node cnt(%u) execeed max node num(%u).\n",
+ block->used_node_cnt, block->node_num);
+ spin_unlock(&block->bitmap_lock);
+ return UDMA_INVALID_ID;
+ }
+
+ /* Search for an idle bit from the offset position. */
+ index = (u32)find_next_zero_bit(table, max_num, offset);
+ /* The preceding search fails. Search for an idle bit
+ * from the beginning.
+ */
+ if (index >= max_num) {
+ offset = 0;
+ index = (u32)find_next_zero_bit(table, max_num, offset);
+ }
+
+ /* Set the found bit to 1 and reset offset. */
+ if (index < max_num) {
+ set_bit(index, table);
+ block->bitmap_item_last = index;
+ }
+
+ block->used_node_cnt++;
+ spin_unlock(&block->bitmap_lock);
+ return index;
+}
+
+static void *udma_vram_get_node(struct udma_vram_block *block)
+{
+ u32 idx;
+
+ idx = udma_vram_bitmap_alloc_id(block);
+ if (idx == UDMA_INVALID_ID) {
+ udma_pr_err(UDMA_M_VRAM, "vram bitmap alloc invalid idx.\n");
+ return NULL;
+ }
+
+ return (void *)((u8 *)block->buf + block->node_size * idx);
+}
+
+void *udma_vram_kzalloc_from_block(u32 type, size_t size)
+{
+ struct udma_vram_header *vram_header = NULL;
+ struct udma_vram_block *block = NULL;
+ void *addr = NULL;
+ int ret;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram header get failed.\n",
+ __func__);
+ return NULL;
+ }
+
+ block = vram_header->header[type].block;
+ addr = udma_vram_get_node(block);
+ if (addr == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: udma vram get node failed.\n",
+ __func__);
+ return NULL;
+ }
+
+ ret = memset_s(addr, size, 0, size);
+ if (ret != EOK) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram object memset_s failed.\n",
+ __func__);
+ return NULL;
+ }
+
+ return addr;
+}
+
+static int udma_vram_block_header_init(u32 type,
+ struct udma_vram_block_header *header)
+{
+ int ret;
+
+ header->node_num = udma_vram_cfg_get_num(type);
+ header->node_size = udma_vram_cfg_get_size(type);
+ ret = strncpy_s(header->name, sizeof(header->name),
+ udma_vram_cfg_get_name(type), sizeof(header->name) - 1);
+ if (ret != EOK) {
+ udma_pr_err(UDMA_M_VRAM, "%s: header name copy failed.\n",
+ __func__);
+ }
+ udma_pr_warn(UDMA_M_VRAM,
+ "%s: header_init success. type: %u, header->name is %s\n",
+ __func__, type, header->name);
+
+ return ret;
+}
+
+static int udma_vram_block_obj_init(struct udma_vram_block_header *header)
+{
+ u32 vram_block_head_size;
+ u32 bitmap_size;
+ int ret;
+
+ vram_block_head_size = sizeof(struct udma_vram_block);
+ bitmap_size = ALIGN(header->node_num, UDMA_NUM_BIT_DW) >>
+ UDMA_BYTE_BIT_SHIFT;
+ header->block_size = vram_block_head_size + bitmap_size +
+ header->node_num * header->node_size;
+
+ header->block = (struct udma_vram_block *)udma_vram_base_kalloc(
+ (char *)header->name, header->block_size);
+ if (header->block == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram block alloc failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ret = memset_s(header->block, header->block_size, 0,
+ header->block_size);
+ if (ret != EOK) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram block memset_s failed.\n",
+ __func__);
+ udma_vram_base_kfree(header->block, (char *)header->name,
+ header->block_size);
+ header->block = NULL;
+ return -EINVAL;
+ }
+
+ header->block->last_block_addr = (uintptr_t)header->block;
+ header->block->node_num = header->node_num;
+ header->block->node_size = header->node_size;
+ header->block->buf = (void *)((u8 *)header->block +
+ vram_block_head_size + bitmap_size);
+ header->block->used_node_cnt = 0;
+ spin_lock_init(&header->block->bitmap_lock);
+
+ udma_pr_warn(
+ UDMA_M_VRAM,
+ "%s: block_init success. header->block_size is %llu, header->block->node_num:%u\n",
+ __func__, header->block_size, header->block->node_num);
+
+ return 0;
+}
+
+static int udma_vram_block_init(struct udma_vram_header *vram_header)
+{
+ u32 i;
+ int ret;
+
+ for (i = 0; i < UDMA_VRAM_TYPE_MAX; i++) {
+ if (!udma_vram_cfg_enable(i)) {
+ continue;
+ }
+ ret = udma_vram_block_header_init(i, &vram_header->header[i]);
+ if (ret != EOK) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: vram header block header init failed, type:%d\n",
+ __func__, i);
+ return ret;
+ }
+
+ ret = udma_vram_block_obj_init(&vram_header->header[i]);
+ if (ret < 0) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: vram block obj init failed, type:%d.\n",
+ __func__, i);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int udma_vram_mem_init(void)
+{
+ struct udma_vram_header *vram_header = NULL;
+ int ret;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram header get failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ret = strncpy_s((char *)vram_header->vram_name,
+ sizeof(vram_header->vram_name), UDMA_VRAM_HEADER_NAME,
+ sizeof(vram_header->vram_name) - 1);
+ if (ret != EOK) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram_header name copy failed.\n",
+ __func__);
+ udma_vram_base_kfree(vram_header, (char *)UDMA_VRAM_HEADER_NAME,
+ sizeof(struct udma_vram_header));
+ return -EINVAL;
+ }
+ udma_pr_warn(
+ UDMA_M_VRAM,
+ "%s: vram header malloc success. vram_header->vram_name is %s\n",
+ __func__, vram_header->vram_name);
+
+ return udma_vram_block_init(vram_header);
+}
+
+static void udma_vram_old_addr_to_new(void **addr,
+ struct udma_vram_block *block)
+{
+ uintptr_t old_addr = (uintptr_t)(*addr);
+
+ *addr = (void *)((u8 *)(block) + old_addr - block->last_block_addr);
+}
+
+void udma_vram_update_addr(void **addr, u32 type)
+{
+ struct udma_vram_header *vram_header = NULL;
+
+ if (type >= UDMA_VRAM_TYPE_MAX) {
+ udma_pr_err(UDMA_M_VRAM, "%s: type(%d) is out of range(%d).\n",
+ __func__, type, UDMA_VRAM_TYPE_MAX);
+ return;
+ }
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram header get failed.\n",
+ __func__);
+ return;
+ }
+
+ udma_vram_old_addr_to_new(addr, vram_header->header[type].block);
+}
+
+static struct udma_vram_block *
+udma_vram_recover_block(struct udma_vram_block_header *header)
+{
+ struct udma_vram_block *block = NULL;
+
+ block = (struct udma_vram_block *)udma_vram_base_kalloc(
+ (char *)header->name, header->block_size);
+ if (block == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram block alloc failed.\n",
+ __func__);
+ return NULL;
+ }
+
+ return block;
+}
+static int udma_vram_recover_block_addr(struct udma_vram_block_header *header)
+{
+ header->block = udma_vram_recover_block(header);
+ if (header->block == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram block recover failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: block recover success. header->block->node_size is %u\n",
+ __func__, header->block->node_size);
+ udma_vram_old_addr_to_new(&header->block->buf, header->block);
+ udma_vram_old_addr_to_new((void **)&header->block->bitmap,
+ header->block);
+
+ return 0;
+}
+
+static int udma_vram_block_recover_cfg(struct udma_vram_header *header)
+{
+ u32 i;
+
+ for (i = 0; i < UDMA_VRAM_TYPE_MAX; i++) {
+ if (!udma_vram_cfg_enable(i)) {
+ continue;
+ }
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: vram header recover success. type:%u, header_name:%s\n",
+ __func__, i, header->header[i].name);
+ if (udma_vram_recover_block_addr(&header->header[i]) != 0) {
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: vram block addr recover failed, type index:%d.\n",
+ __func__, i);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int udma_vram_block_recover(void)
+{
+ struct udma_vram_header *vram_header = NULL;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram header get failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: vram header recover success. vram_header->vram_name:%s,\n",
+ __func__, vram_header->vram_name);
+ if (udma_vram_block_recover_cfg(vram_header) != 0) {
+ udma_pr_err(UDMA_M_VRAM, "%s: vram block recover cfg failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void udma_vram_mem_deinit(void)
+{
+ struct udma_vram_block_header *header = NULL;
+ struct udma_vram_header *vram_header = NULL;
+ u32 i;
+
+ vram_header = udma_get_vram_header();
+ if (vram_header == NULL) {
+ return;
+ }
+
+ for (i = 0; i < UDMA_VRAM_TYPE_MAX; i++) {
+ if (!udma_vram_cfg_enable(i)) {
+ continue;
+ }
+ header = &vram_header->header[i];
+ udma_vram_base_kfree((void *)header->block, header->name,
+ header->block_size);
+ }
+
+ udma_vram_base_kfree((void *)vram_header, (char *)UDMA_VRAM_HEADER_NAME,
+ sizeof(struct udma_vram_header));
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.h
new file mode 100644
index 000000000..b6414e02d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_mem.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_BLOCK_H
+#define UDMA_VRAM_BLOCK_H
+
+#include "udma_vram.h"
+#include "udma_common.h"
+#include "udma_vram_common.h"
+
+struct udma_vram_block {
+ u32 node_num; /* block in contain maximum max node count */
+ u32 node_size; /* node of size */
+ u32 used_node_cnt; /* already allocate node count */
+ u32 bitmap_item_last;
+ spinlock_t bitmap_lock;
+ uintptr_t last_block_addr; /* record on once allocate of block address */
+ void *buf; /* node first address */
+ u64 bitmap[0]; /* node allocate used bitmap */
+};
+
+struct udma_vram_block_header {
+ struct udma_vram_block *block;
+ char name[UDMA_VRAM_NAME_SIZE]; /* block name, use to vram allocate memory */
+ u32 node_num; /* block in contain maximum max node count */
+ u32 node_size; /* node of size */
+ u64 block_size; /* block of size */
+};
+
+struct udma_vram_header {
+ const char vram_name[UDMA_VRAM_NAME_SIZE];
+ struct udma_vram_block_header header[UDMA_VRAM_TYPE_MAX];
+};
+
+void *udma_vram_kzalloc_from_block(u32 type, size_t size);
+void udma_vram_kfree_from_block(void *ptr, u32 type);
+int udma_vram_mem_init(void);
+int udma_vram_block_recover(void);
+void udma_vram_mem_deinit(void);
+struct udma_vram_header *udma_get_vram_header(void);
+void udma_vram_update_addr(void **addr, u32 type);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.c
new file mode 100644
index 000000000..170eb1efa
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.c
@@ -0,0 +1,37 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include "ubcore_api.h"
+
+#include "udma_common.h"
+#include "udma_misc.h"
+#include "udma_vram.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_mem.h"
+#include "udma_vram_common.h"
+#include "udma_vram_type_dev.h"
+
+static int udma_vram_recover_device(void *node)
+{
+ struct udma_device *udma_dev = (struct udma_device *)node;
+
+ (void)udma_dev;
+
+ /* legacy restore */
+ //rc_queue;
+
+ udma_pr_err(
+ UDMA_M_VRAM,
+ "%s: udma_dev recover success, udma_dev->dev_name is %s .\n",
+ __func__, udma_dev->dev_name);
+ return 0;
+}
+
+int udma_vram_device_register(void)
+{
+ return udma_vram_cfg_register(UDMA_DEV_NAME, UDMA_VRAM_TYPE_DEV,
+ UDMA_DEVICE_NODE,
+ sizeof(struct udma_device),
+ udma_vram_recover_device);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.h
new file mode 100644
index 000000000..d442b28ed
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_dev.h
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_TYPE_DEV_H
+#define UDMA_VRAM_TYPE_DEV_H
+
+int udma_vram_device_register(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.c
new file mode 100644
index 000000000..8323034fe
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.c
@@ -0,0 +1,89 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include "ubcore_api.h"
+
+#include "udma_tp.h"
+#include "udma_tpg.h"
+#include "udma_common.h"
+#include "udma_misc.h"
+#include "udma_vram.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_mem.h"
+#include "udma_vram_common.h"
+#include "udma_vram_type_tp.h"
+
+static struct tag_cqm_qpc_mpt *udma_get_tp_info(struct udma_tpg *ub_tpg,
+ uint32_t tpn)
+{
+ int i;
+
+ for (i = 0; i < MAX_TP_CNT_IN_TPG; i++) {
+ if (tpn == ub_tpg->tpinfo_list[i]->xid) {
+ return ub_tpg->tpinfo_list[i];
+ }
+ }
+
+ return NULL;
+}
+
+static int udma_vram_recover_tp(void *node)
+{
+ struct udma_tp *ub_tp = (struct udma_tp *)node;
+ struct udma_device *udma_dev = NULL;
+ struct udma_tpg *ub_tpg = NULL;
+
+#ifdef UBCORE_EN
+ int ret;
+
+ ret = ubcore_recover_from_udma(UDMA_VRAM_TYPE_TP, &ub_tp->tp);
+ if (ret) {
+ udma_pr_err(UDMA_M_VRAM,
+ "%s: ubcore recover failed failed. type:%d\n",
+ __func__, UDMA_VRAM_TYPE_TP);
+ return -EINVAL;
+ }
+#endif
+ udma_vram_update_addr((void **)&ub_tp->tp.ub_dev, UDMA_VRAM_TYPE_DEV);
+ udma_vram_update_addr((void **)&ub_tp->tp.tpg, UDMA_VRAM_TYPE_TPG);
+ ub_tpg = to_udma_tpg(ub_tp->tp.tpg);
+ ub_tp->tp_info = udma_get_tp_info(ub_tpg, ub_tp->tp.tpn);
+
+ udma_dev = to_udma_dev(ub_tp->tp.ub_dev);
+ ub_tp->tp_buf_info = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_QP,
+ (u32)ub_tp->buf_size, ub_tp, true, ub_tp->tp_buf_info_xid, 0,
+ 0);
+ if (ub_tp->tp_buf_info == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: tp buf info recover failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ub_tp->pcqc_info = cqm5_object_rdma_queue_create(
+ udma_dev->hwdev, SERVICE_T_UB, CQM_OBJECT_RDMA_SCQ,
+ TP_PCQC_SIZE, NULL, false, ub_tp->tp_info->xid, 0, 0);
+ if (ub_tp->pcqc_info == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: tp pcqc info recover failed.\n",
+ __func__);
+ cqm5_object_delete(&ub_tp->tp_buf_info->object);
+ return -EINVAL;
+ }
+
+ ub_tp->buf.direct.buf = ub_tp->tp_buf_info->q_room_buf_1.direct.va;
+
+ //to do: ub_mtt, rc_table
+
+ udma_store_list(udma_dev, &ub_tp->node,
+ &udma_dev->device_res->tpn_list);
+
+ return 0;
+}
+
+int udma_vram_tp_register(void)
+{
+ return udma_vram_cfg_register(UDMA_TP_NAME, UDMA_VRAM_TYPE_TP,
+ UDMA_TP_NODE, sizeof(struct udma_tp),
+ udma_vram_recover_tp);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.h
new file mode 100644
index 000000000..de1e214c7
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tp.h
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_TYPE_TP_H
+#define UDMA_VRAM_TYPE_TP_H
+
+int udma_vram_tp_register(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.c
new file mode 100644
index 000000000..3eccb9197
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.c
@@ -0,0 +1,69 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include "ubcore_api.h"
+
+#include "udma_tpg.h"
+#include "udma_tp.h"
+#include "udma_common.h"
+#include "udma_misc.h"
+#include "udma_vram.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_mem.h"
+#include "udma_vram_common.h"
+#include "udma_vram_type_tpg.h"
+
+static int udma_vram_recover_tpg(void *node)
+{
+ struct udma_tpg *ub_tpg = (struct udma_tpg *)node;
+ struct udma_device *udma_dev = NULL;
+ u32 i;
+#ifdef UBCORE_EN
+ int ret;
+
+ ret = ubcore_recover_from_udma(UDMA_VRAM_TYPE_TPG, &ub_tpg->tpg);
+ if (ret) {
+ udma_pr_err(UDMA_M_VRAM,
+ "%s: ubcore recover failed failed. type:%d\n",
+ __func__, UDMA_VRAM_TYPE_TPG);
+ return -EINVAL;
+ }
+#endif
+
+ udma_vram_update_addr((void **)&ub_tpg->tpg.ub_dev, UDMA_VRAM_TYPE_DEV);
+
+ udma_dev = to_udma_dev(ub_tpg->tpg.ub_dev);
+ ub_tpg->tpg_info = udma_object_queue_create(
+ udma_dev, CQM_OBJECT_RDMA_SCQ, UBEP_TPG_CONTEXT_SIZE, ub_tpg,
+ NULL, false, ub_tpg->tpg.tpgn, ub_tpg->tpg.tpgn, 0);
+ if (ub_tpg->tpg_info == NULL) {
+ udma_pr_err(UDMA_M_VRAM, "%s: tpg info recover failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ub_tpg->tp_num; i++) {
+ ub_tpg->tpinfo_list[i] = udma_object_qpc_create(
+ udma_dev, UBEP_TP_CONTEXT_SIZE, NULL,
+ &udma_dev->tpn_record, ub_tpg->tpg.tpgn,
+ udma_dev->ub_cap.dev_cap.max_tp, 0);
+ if (ub_tpg->tpinfo_list[i] == NULL) {
+ udma_pr_err(UDMA_M_VRAM,
+ "%s: tpg tpinfo list recover failed.\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+ udma_store_list(udma_dev, &ub_tpg->node,
+ &udma_dev->device_res->tpg_list);
+ return 0;
+}
+
+int udma_vram_tpg_register(void)
+{
+ return udma_vram_cfg_register(UDMA_TPG_NAME, UDMA_VRAM_TYPE_TPG,
+ UDMA_TPG_NODE, sizeof(struct udma_tpg),
+ udma_vram_recover_tpg);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.h
new file mode 100644
index 000000000..d7493200d
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_tpg.h
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_TYPE_TPG_H
+#define UDMA_VRAM_TYPE_TPG_H
+
+int udma_vram_tpg_register(void);
+
+#endif
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.c b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.c
new file mode 100644
index 000000000..49bae0f62
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.c
@@ -0,0 +1,45 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#include "ubcore_api.h"
+
+#include "udma_vtp.h"
+#include "udma_common.h"
+#include "udma_misc.h"
+#include "udma_vram.h"
+#include "udma_vram_cfg.h"
+#include "udma_vram_mem.h"
+#include "udma_vram_common.h"
+#include "udma_vram_type_vtp.h"
+
+static int udma_vram_recover_vtp(void *node)
+{
+ struct udma_vtp *ub_vtp = (struct udma_vtp *)node;
+ struct udma_device *udma_dev = NULL;
+#ifdef UBCORE_EN
+ int ret;
+
+ ret = ubcore_recover_from_udma(UDMA_VRAM_TYPE_VTP, &ub_vtp->base);
+ if (ret) {
+ udma_pr_err(UDMA_M_VRAM,
+ "%s: ubcore recover failed failed. type:%d\n",
+ __func__, UDMA_VRAM_TYPE_VTP);
+ return -EINVAL;
+ }
+#endif
+ udma_vram_update_addr((void **)&ub_vtp->base.ub_dev,
+ UDMA_VRAM_TYPE_VTP);
+ udma_dev = to_udma_dev(ub_vtp->base.ub_dev);
+ udma_store_list(udma_dev, &ub_vtp->node,
+ &udma_dev->device_res->vtp_list);
+
+ return 0;
+}
+
+int udma_vram_vtp_register(void)
+{
+ return udma_vram_cfg_register(UDMA_VTP_NAME, UDMA_VRAM_TYPE_VTP,
+ UDMA_VTP_NODE, sizeof(struct udma_vtp),
+ udma_vram_recover_vtp);
+}
diff --git a/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.h b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.h
new file mode 100644
index 000000000..47c672978
--- /dev/null
+++ b/drivers/ub/urma/hw/hiudma5/kernel/module/vram/udma_vram_type_vtp.h
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+//Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
+
+
+#ifndef UDMA_VRAM_TYPE_VTP_H
+#define UDMA_VRAM_TYPE_VTP_H
+
+int udma_vram_vtp_register(void);
+
+#endif
--
2.37.7
2
1
[PATCH OLK-6.6] Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()
by Chen Jinghuang 03 Aug '26
by Chen Jinghuang 03 Aug '26
03 Aug '26
From: Siwei Zhang <oss(a)fourdim.xyz>
stable inclusion
from stable-v6.6.145
commit 8c37e4338c801ebb8cee52436c01c41e009f6e87
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16859
CVE: CVE-2026-64557
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 6fef032af0092ed5ccb767239a9ac1bc38c08a40 ]
l2cap_sock_new_connection_cb() returned l2cap_pi(sk)->chan after
release_sock(parent). Once the parent lock is dropped the newly
enqueued child socket sk is reachable via the accept queue, so another
task can accept and free it before the callback dereferences sk,
resulting in a use-after-free.
Rework the ->new_connection() op so the core, rather than the callback,
owns the child channel's lifetime. The op now receives a pre-allocated
new_chan and returns an errno instead of allocating and returning a
channel. l2cap_new_connection() allocates the child channel and links
it into the conn list via __l2cap_chan_add() before invoking the
callback, so the conn-list reference keeps the channel alive once
release_sock(parent) exposes the socket to other tasks.
Channel configuration that was duplicated in l2cap_sock_init() and the
various new_connection callbacks is consolidated into
l2cap_chan_set_defaults(), which now inherits from the parent channel
when one is supplied.
Fixes: 8ffb929098a5 ("Bluetooth: Remove parent socket usage from l2cap_core.c")
Cc: stable(a)kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Siwei Zhang <oss(a)fourdim.xyz>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
net/bluetooth/6lowpan.c
[a trival context conflict]
Signed-off-by: Chen Jinghuang <chenjinghuang2(a)huawei.com>
---
include/net/bluetooth/l2cap.h | 10 ++--
net/bluetooth/6lowpan.c | 18 +-----
net/bluetooth/l2cap_core.c | 78 ++++++++++++++++++++-----
net/bluetooth/l2cap_sock.c | 103 ++++++++++++++++------------------
net/bluetooth/smp.c | 27 ++-------
5 files changed, 127 insertions(+), 109 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 2c0356e7b571..136036b48e6d 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -614,7 +614,8 @@ struct l2cap_chan {
struct l2cap_ops {
char *name;
- struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan);
+ int (*new_connection)(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan);
int (*recv) (struct l2cap_chan * chan,
struct sk_buff *skb);
void (*teardown) (struct l2cap_chan *chan, int err);
@@ -879,9 +880,10 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq)
return (seq + 1) % (chan->tx_win_max + 1);
}
-static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan)
+static inline int l2cap_chan_no_new_connection(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
- return NULL;
+ return -EOPNOTSUPP;
}
static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -957,7 +959,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail);
int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
-void l2cap_chan_set_defaults(struct l2cap_chan *chan);
+void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan);
int l2cap_ertm_init(struct l2cap_chan *chan);
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index b3132079573d..34b9599f2cde 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -631,7 +631,7 @@ static struct l2cap_chan *chan_create(void)
if (!chan)
return NULL;
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
chan->mode = L2CAP_MODE_LE_FLOWCTL;
@@ -744,21 +744,6 @@ static inline void chan_ready_cb(struct l2cap_chan *chan)
ifup(dev->netdev);
}
-static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan)
-{
- struct l2cap_chan *chan;
-
- chan = chan_create();
- if (!chan)
- return NULL;
-
- chan->ops = pchan->ops;
-
- BT_DBG("chan %p pchan %p", chan, pchan);
-
- return chan;
-}
-
static void delete_netdev(struct work_struct *work)
{
struct lowpan_btle_dev *entry = container_of(work,
@@ -880,7 +865,6 @@ static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
static const struct l2cap_ops bt_6lowpan_chan_ops = {
.name = "L2CAP 6LoWPAN channel",
- .new_connection = chan_new_conn_cb,
.recv = chan_recv_cb,
.close = chan_close_cb,
.state_change = chan_state_change_cb,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8181174f75d9..1da65bc37779 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -525,7 +525,10 @@ void l2cap_chan_put(struct l2cap_chan *c)
}
EXPORT_SYMBOL_GPL(l2cap_chan_put);
-void l2cap_chan_set_defaults(struct l2cap_chan *chan)
+/* Initialise @chan with default values, inheriting from the parent channel
+ * @pchan when it is given.
+ */
+void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan)
{
chan->fcs = L2CAP_FCS_CRC16;
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
@@ -539,6 +542,31 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+ if (pchan) {
+ BT_DBG("chan %p pchan %p", chan, pchan);
+
+ chan->chan_type = pchan->chan_type;
+ chan->imtu = pchan->imtu;
+ chan->omtu = pchan->omtu;
+ chan->mode = pchan->mode;
+ chan->fcs = pchan->fcs;
+ chan->max_tx = pchan->max_tx;
+ chan->tx_win = pchan->tx_win;
+ chan->tx_win_max = pchan->tx_win_max;
+ chan->sec_level = pchan->sec_level;
+ chan->conf_state = pchan->conf_state;
+ chan->flags = pchan->flags;
+ chan->tx_credits = pchan->tx_credits;
+ chan->rx_credits = pchan->rx_credits;
+
+ if (chan->chan_type == L2CAP_CHAN_FIXED) {
+ chan->scid = pchan->scid;
+ chan->dcid = pchan->scid;
+ }
+
+ return;
+ }
+
chan->conf_state = 0;
set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
@@ -3959,6 +3987,38 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
return 0;
}
+/* Allocate and initialise a channel for an incoming connection.
+ *
+ * The channel inherits its configuration from @pchan and is linked into @conn
+ * before ->new_connection() runs, so the conn list reference keeps it alive if
+ * the callback exposes it (e.g. via the socket accept queue) before this
+ * returns. The l2cap_chan_create() reference is taken over by the subsystem on
+ * success and dropped here on failure.
+ */
+static struct l2cap_chan *l2cap_new_connection(struct l2cap_conn *conn,
+ struct l2cap_chan *pchan)
+{
+ struct l2cap_chan *chan;
+
+ chan = l2cap_chan_create();
+ if (!chan)
+ return NULL;
+
+ l2cap_chan_set_defaults(chan, pchan);
+ chan->ops = pchan->ops;
+
+ __l2cap_chan_add(conn, chan);
+
+ if (pchan->ops->new_connection &&
+ pchan->ops->new_connection(pchan, chan) < 0) {
+ l2cap_chan_del(chan, 0);
+ l2cap_chan_put(chan);
+ return NULL;
+ }
+
+ return chan;
+}
+
static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
u8 *data, u8 rsp_code)
{
@@ -4005,7 +4065,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
goto response;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan)
goto response;
@@ -4023,8 +4083,6 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
chan->psm = psm;
chan->dcid = scid;
- __l2cap_chan_add(conn, chan);
-
dcid = chan->scid;
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
@@ -4893,7 +4951,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
goto response_unlock;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
goto response_unlock;
@@ -4908,8 +4966,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
-
l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits));
dcid = chan->scid;
@@ -5118,7 +5174,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
continue;
}
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (!chan) {
result = L2CAP_CR_LE_NO_MEM;
continue;
@@ -5133,8 +5189,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
chan->omtu = mtu;
chan->remote_mps = mps;
- __l2cap_chan_add(conn, chan);
-
l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
/* Init response */
@@ -7400,14 +7454,12 @@ static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
goto next;
l2cap_chan_lock(pchan);
- chan = pchan->ops->new_connection(pchan);
+ chan = l2cap_new_connection(conn, pchan);
if (chan) {
bacpy(&chan->src, &hcon->src);
bacpy(&chan->dst, &hcon->dst);
chan->src_type = bdaddr_src_type(hcon);
chan->dst_type = dst_type;
-
- __l2cap_chan_add(conn, chan);
}
l2cap_chan_unlock(pchan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 3e9b27d3a610..47f0d5dcbb7f 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -45,7 +45,8 @@ static struct bt_sock_list l2cap_sk_list = {
static const struct proto_ops l2cap_sock_ops;
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern);
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan);
static void l2cap_sock_cleanup_listen(struct sock *parent);
bool l2cap_is_socket(struct socket *sock)
@@ -1240,6 +1241,23 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
return err;
}
+/* Release the sock's ref on chan and clear the pointer so that the ref is
+ * dropped exactly once even if both l2cap_sock_kill() and
+ * l2cap_sock_destruct() run. Setting chan->data to NULL first stops any other
+ * task from dereferencing the now-dead sock pointer.
+ */
+static void l2cap_sock_put_chan(struct sock *sk)
+{
+ struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+
+ if (!chan)
+ return;
+
+ chan->data = NULL;
+ l2cap_pi(sk)->chan = NULL;
+ l2cap_chan_put(chan);
+}
+
/* Kill socket (only if zapped and orphan)
* Must be called on unlocked socket, with l2cap channel lock.
*/
@@ -1250,13 +1268,9 @@ static void l2cap_sock_kill(struct sock *sk)
BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
- /* Sock is dead, so set chan data to NULL, avoid other task use invalid
- * sock pointer.
- */
- l2cap_pi(sk)->chan->data = NULL;
- /* Kill poor orphan */
+ l2cap_sock_put_chan(sk);
- l2cap_chan_put(l2cap_pi(sk)->chan);
+ /* Kill poor orphan */
sock_set_flag(sk, SOCK_DEAD);
sock_put(sk);
}
@@ -1499,12 +1513,13 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
}
}
-static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
+static int l2cap_sock_new_connection_cb(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
struct sock *sk, *parent = chan->data;
if (!parent)
- return NULL;
+ return -EINVAL;
lock_sock(parent);
@@ -1512,25 +1527,28 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
release_sock(parent);
- return NULL;
+ return -ENOBUFS;
}
sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
- GFP_ATOMIC, 0);
+ GFP_ATOMIC, 0, new_chan);
if (!sk) {
release_sock(parent);
- return NULL;
- }
+ return -ENOMEM;
+ }
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
l2cap_sock_init(sk, parent);
+ /* The conn list reference taken by l2cap_new_connection() keeps new_chan
+ * alive once release_sock() lets another task free this socket.
+ */
bt_accept_enqueue(parent, sk, false);
release_sock(parent);
- return l2cap_pi(sk)->chan;
+ return 0;
}
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
@@ -1828,10 +1846,7 @@ static void l2cap_sock_destruct(struct sock *sk)
BT_DBG("sk %p", sk);
- if (l2cap_pi(sk)->chan) {
- l2cap_pi(sk)->chan->data = NULL;
- l2cap_chan_put(l2cap_pi(sk)->chan);
- }
+ l2cap_sock_put_chan(sk);
list_for_each_entry_safe(rx_busy, next, &l2cap_pi(sk)->rx_busy, list) {
kfree_skb(rx_busy->skb);
@@ -1863,30 +1878,12 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
BT_DBG("sk %p", sk);
if (parent) {
- struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
-
sk->sk_type = parent->sk_type;
bt_sk(sk)->flags = bt_sk(parent)->flags;
- chan->chan_type = pchan->chan_type;
- chan->imtu = pchan->imtu;
- chan->omtu = pchan->omtu;
- chan->conf_state = pchan->conf_state;
- chan->mode = pchan->mode;
- chan->fcs = pchan->fcs;
- chan->max_tx = pchan->max_tx;
- chan->tx_win = pchan->tx_win;
- chan->tx_win_max = pchan->tx_win_max;
- chan->sec_level = pchan->sec_level;
- chan->flags = pchan->flags;
- chan->tx_credits = pchan->tx_credits;
- chan->rx_credits = pchan->rx_credits;
-
- if (chan->chan_type == L2CAP_CHAN_FIXED) {
- chan->scid = pchan->scid;
- chan->dcid = pchan->scid;
- }
-
+ /* Channel configuration is inherited from the parent by
+ * l2cap_new_connection().
+ */
security_sk_clone(parent, sk);
} else {
switch (sk->sk_type) {
@@ -1912,7 +1909,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
chan->mode = L2CAP_MODE_BASIC;
}
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
}
/* Default config options */
@@ -1931,10 +1928,10 @@ static struct proto l2cap_proto = {
};
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
- int proto, gfp_t prio, int kern)
+ int proto, gfp_t prio, int kern,
+ struct l2cap_chan *chan)
{
struct sock *sk;
- struct l2cap_chan *chan;
sk = bt_sock_alloc(net, sock, &l2cap_proto, proto, prio, kern);
if (!sk)
@@ -1945,16 +1942,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
INIT_LIST_HEAD(&l2cap_pi(sk)->rx_busy);
- chan = l2cap_chan_create();
- if (!chan) {
- sk_free(sk);
- if (sock)
- sock->sk = NULL;
- return NULL;
- }
-
- l2cap_chan_hold(chan);
-
+ /* The sock takes ownership of the caller's reference on chan. */
l2cap_pi(sk)->chan = chan;
return sk;
@@ -1964,6 +1952,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
+ struct l2cap_chan *chan;
BT_DBG("sock %p", sock);
@@ -1978,10 +1967,16 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
sock->ops = &l2cap_sock_ops;
- sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);
- if (!sk)
+ chan = l2cap_chan_create();
+ if (!chan)
return -ENOMEM;
+ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern, chan);
+ if (!sk) {
+ l2cap_chan_put(chan);
+ return -ENOMEM;
+ }
+
l2cap_sock_init(sk, NULL);
bt_sock_link(&l2cap_sk_list, sk);
return 0;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index de34bdf1802d..df192797eda9 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -3235,34 +3235,19 @@ static const struct l2cap_ops smp_chan_ops = {
.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
};
-static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
+static inline int smp_new_conn_cb(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
{
- struct l2cap_chan *chan;
-
- BT_DBG("pchan %p", pchan);
-
- chan = l2cap_chan_create();
- if (!chan)
- return NULL;
-
- chan->chan_type = pchan->chan_type;
- chan->ops = &smp_chan_ops;
- chan->scid = pchan->scid;
- chan->dcid = chan->scid;
- chan->imtu = pchan->imtu;
- chan->omtu = pchan->omtu;
- chan->mode = pchan->mode;
+ new_chan->ops = &smp_chan_ops;
/* Other L2CAP channels may request SMP routines in order to
* change the security level. This means that the SMP channel
* lock must be considered in its own category to avoid lockdep
* warnings.
*/
- atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
-
- BT_DBG("created chan %p", chan);
+ atomic_set(&new_chan->nesting, L2CAP_NESTING_SMP);
- return chan;
+ return 0;
}
static const struct l2cap_ops smp_root_chan_ops = {
@@ -3333,7 +3318,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
l2cap_add_scid(chan, cid);
- l2cap_chan_set_defaults(chan);
+ l2cap_chan_set_defaults(chan, NULL);
if (cid == L2CAP_CID_SMP) {
u8 bdaddr_type;
--
2.34.1
2
1
Bradley Morgan (1):
bpf: Disable xfrm_decode_session hook attachment
Jann Horn (1):
bpf,fork: wipe ->bpf_storage before bailouts that access it
Matt Bobrowski (1):
bpf: Fix UAF in sock clone early bailouts
kernel/bpf/bpf_lsm.c | 3 +++
kernel/fork.c | 9 +++++----
net/core/bpf_sk_storage.c | 2 --
net/core/sock.c | 3 +++
4 files changed, 11 insertions(+), 6 deletions(-)
--
2.34.1
2
4
03 Aug '26
From: Jann Horn <jannh(a)google.com>
stable inclusion
from stable-v6.6.145
commit c3fd6f28c7ce1142a3b23dbb840eaa4777de1d74
category: bugfix
bugzilla: https://atomgit.com/openeuler/kernel/issues/9693
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 9b51a6155d14389876916726430da30eabb1d4ed upstream.
Currently, copy_process() can bail out to free_task() before p->bpf_storage
has been initialized, with this call graph (shown here for the
!CONFIG_MEMCG case):
copy_process
dup_task_struct
arch_dup_task_struct
[copies the entire task_struct, including ->bpf_storage member]
[RLIMIT_NPROC check fails]
delayed_free_task
free_task
bpf_task_storage_free
rcu_dereference(task->bpf_storage)
bpf_local_storage_destroy
In this case, the nascent task's ->bpf_storage member that
bpf_local_storage_destroy() operates on is a plain copy of the parent's
->bpf_storage pointer, not a real initialized pointer.
This leads to badness (kernel hangs, UAF).
This is reachable as long as the process calling fork() has been inserted
into a task storage map.
Cc: stable(a)kernel.org
Fixes: a10787e6d58c ("bpf: Enable task local storage for tracing programs")
Signed-off-by: Jann Horn <jannh(a)google.com>
Signed-off-by: Andrii Nakryiko <andrii(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
kernel/fork.c
[ctx conflicts]
Signed-off-by: Pu Lehui <pulehui(a)huawei.com>
---
kernel/fork.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 04d934eabbc7..e92ddc0a0c66 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1290,6 +1290,11 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
tsk->migrate_from_cpu = -1;
#endif
+#ifdef CONFIG_BPF_SYSCALL
+ RCU_INIT_POINTER(tsk->bpf_storage, NULL);
+ tsk->bpf_ctx = NULL;
+#endif
+
#ifdef CONFIG_FAST_SYSCALL
tsk->xinfo = NULL;
#endif
@@ -2608,10 +2613,6 @@ __latent_entropy struct task_struct *copy_process(
p->sequential_io = 0;
p->sequential_io_avg = 0;
#endif
-#ifdef CONFIG_BPF_SYSCALL
- RCU_INIT_POINTER(p->bpf_storage, NULL);
- p->bpf_ctx = NULL;
-#endif
/* Perform scheduler related setup. Assign this task to a CPU. */
retval = sched_fork(clone_flags, p);
--
2.34.1
2
1
[PATCH OLK-6.6] i2c: i801: fix hardware state machine corruption in error path
by Zhang Yuwei 03 Aug '26
by Zhang Yuwei 03 Aug '26
03 Aug '26
From: Mingyu Wang <25181214217(a)stu.xidian.edu.cn>
mainline inclusion
from mainline-v7.2-rc1
commit 10dd1a736d557e310a77117832874729a0175d57
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16512
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
A severe livelock and subsequent Hung Task panic were observed in the
i2c-i801 driver during concurrent Fuzzing. The crash is caused by an
unconditional hardware register cleanup in the error handling path of
i801_access().
When i801_check_pre() fails (e.g., returning -EBUSY because the SMBus
controller is actively used by BIOS/ACPI), the kernel does not actually
acquire the hardware ownership. However, the code jumps to the 'out'
label and executes:
iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
This forcefully clears the INUSE_STS lock and resets the hardware status
flags without owning the controller. Doing so interrupts ongoing BIOS/ACPI
transactions and totally corrupts the SMBus hardware state machine.
Consequently, all subsequent i801_access() calls fail at the pre-check
stage, triggering an endless stream of "SMBus is busy, can't use it!"
error logs. Over a slow serial console, this printk flood monopolizes
the CPU (Console Livelock), starving other processes trying to acquire
the mmap_lock down_read semaphore, ultimately triggering the hung task
watchdog.
Fix this by moving the 'out' label below the hardware register cleanup.
If i801_check_pre() fails, we safely bypass the iowrite8() and only
release the software locks (pm_runtime and mutex), strictly adhering to
the rule of not releasing resources that were never acquired.
Fixes: 1f760b87e54c ("i2c: i801: Call i801_check_pre() from i801_access()")
Signed-off-by: Mingyu Wang <25181214217(a)stu.xidian.edu.cn>
Cc: <stable(a)vger.kernel.org> # v6.3+
Signed-off-by: Andi Shyti <andi.shyti(a)kernel.org>
Link: https://lore.kernel.org/r/20260512093534.348655-1-w15303746062@163.com
Conflicts:
drivers/i2c/busses/i2c-i801.c
[contxt conflict]
Signed-off-by: Zhang Yuwei <zhangyuwei20(a)huawei.com>
---
drivers/i2c/busses/i2c-i801.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 89fdc75cdcfa..b0429fa3f573 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -918,13 +918,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
*/
if (hwpec)
outb_p(inb_p(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
-out:
/*
* Unlock the SMBus device for use by BIOS/ACPI,
* and clear status flags if not done already.
*/
outb_p(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
+out:
pm_runtime_mark_last_busy(&priv->pci_dev->dev);
pm_runtime_put_autosuspend(&priv->pci_dev->dev);
mutex_unlock(&priv->acpi_lock);
--
2.22.0
2
1
[PATCH OLK-5.10] bpf, skmsg: fix verdict sk_data_ready racing with ktls rx
by superdcc97@163.com 03 Aug '26
by superdcc97@163.com 03 Aug '26
03 Aug '26
From: Xingwang Xiang <v3rdant.xiang(a)gmail.com>
mainline inclusion
from mainline-v7.1-rc5
commit ddf8029623a1af20e984c040e89ff918158397ab
category: bugfix
bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16350
CVE: CVE-2026-64025
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
sk_psock_strp_data_ready() already checks tls_sw_has_ctx_rx() and
defers to psock->saved_data_ready when a TLS RX context is present,
avoiding a conflict with the TLS strparser's ownership of the receive
queue (commit e91de6afa81c ("bpf: Fix running sk_skb program types
with ktls")).
sk_psock_verdict_data_ready() has no equivalent guard. When a socket
is inserted into a sockmap (BPF_SK_SKB_VERDICT) before TLS RX is
configured, tls_sw_strparser_arm() saves sk_psock_verdict_data_ready
as rx_ctx->saved_data_ready. On data arrival:
tls_data_ready -> tls_strp_data_ready -> tls_rx_msg_ready
-> saved_data_ready() = sk_psock_verdict_data_ready()
-> tcp_read_skb() drains sk_receive_queue via __skb_unlink()
without calling tcp_eat_skb(), so copied_seq is not advanced.
tls_strp_msg_load() then finds tcp_inq() >= full_len (stale), calls
tcp_recv_skb() on the now-empty queue, hits WARN_ON_ONCE(!first), and
returns with rx_ctx->strp.anchor.frag_list pointing at a psock-owned
(potentially freed) skb. tls_decrypt_sg() subsequently walks that
frag_list: use-after-free.
Apply the same fix as sk_psock_strp_data_ready(): if a TLS RX context
is present, call psock->saved_data_ready (sock_def_readable) to wake
recv() waiters and return immediately, leaving the receive queue
untouched. TLS retains sole ownership of the queue and decrypts the
record normally through tls_sw_recvmsg().
Fixes: ef5659280eb1 ("bpf, sockmap: Allow skipping sk_skb parser program")
Signed-off-by: Xingwang Xiang <v3rdant.xiang(a)gmail.com>
Link: https://patch.msgid.link/20260517145630.20521-2-v3rdant.xiang@gmail.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/core/skmsg.c
[Adaptation notes:
- The upstream mainline function uses rcu_read_lock(), sk_psock(),
READ_ONCE(sk->sk_socket) and ops->read_skb. The OLK-5.10 version of
sk_psock_verdict_data_ready() uses the legacy sock->ops->read_sock path
without RCU protection.
- Transplanted the TLS RX guard by taking rcu_read_lock(), obtaining
struct sk_psock *psock, and calling psock->parser.saved_data_ready(sk)
(in 5.10 saved_data_ready lives inside struct sk_psock_parser) before
returning, leaving the receive queue untouched for ktls.
- This preserves the same logic as sk_psock_strp_data_ready() which already
performs tls_sw_has_ctx_rx() detection in this tree.]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/core/skmsg.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 5150fc93dd9b..b979a4cba4d2 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -1056,11 +1056,21 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
static void sk_psock_verdict_data_ready(struct sock *sk)
{
struct socket *sock = sk->sk_socket;
+ struct sk_psock *psock;
read_descriptor_t desc;
if (unlikely(!sock || !sock->ops || !sock->ops->read_sock))
return;
+ rcu_read_lock();
+ psock = sk_psock(sk);
+ if (psock && tls_sw_has_ctx_rx(sk)) {
+ psock->parser.saved_data_ready(sk);
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+
desc.arg.data = sk;
desc.error = 0;
desc.count = 1;
--
2.43.0
2
1